]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/commitdiff
Xen-Support vorruebergehend wieder entfernt, da die Entwickler keine Reaktion zeigen.
authorms <ms@ea5c0bd1-69bd-2848-81d8-4f18e57aeed8>
Mon, 9 Jul 2007 22:20:53 +0000 (22:20 +0000)
committerms <ms@ea5c0bd1-69bd-2848-81d8-4f18e57aeed8>
Mon, 9 Jul 2007 22:20:53 +0000 (22:20 +0000)
Vielleicht wirds ja was im naechsten Release.

git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@668 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8

config/kernel/kernel.config.i586.xen [deleted file]
lfs/linux
make.sh
src/paks/ipfireseeder/install.sh
src/patches/xen-3.0.4-2.6.16.x.patch [deleted file]
src/patches/xen-3.0.4-layer7-fix.patch [deleted file]
src/patches/xen-3.0.4-netfilter-fix.patch [deleted file]

diff --git a/config/kernel/kernel.config.i586.xen b/config/kernel/kernel.config.i586.xen
deleted file mode 100644 (file)
index 57f8bfe..0000000
+++ /dev/null
@@ -1,1975 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16.50-ipfire
-# Fri May 25 12:38:06 2007
-#
-CONFIG_X86_32=y
-CONFIG_SEMAPHORE_SLEEPERS=y
-CONFIG_X86=y
-CONFIG_MMU=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-CONFIG_DMI=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_AUDIT=y
-CONFIG_AUDITSYSCALL=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
-CONFIG_VM86=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-CONFIG_SLAB=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Processor type and features
-#
-# CONFIG_X86_PC is not set
-CONFIG_X86_XEN=y
-# CONFIG_X86_ELAN is not set
-# CONFIG_X86_VOYAGER is not set
-# CONFIG_X86_NUMAQ is not set
-# CONFIG_X86_SUMMIT is not set
-# CONFIG_X86_BIGSMP is not set
-# CONFIG_X86_VISWS is not set
-# CONFIG_X86_GENERICARCH is not set
-# CONFIG_X86_ES7000 is not set
-# CONFIG_M386 is not set
-# CONFIG_M486 is not set
-CONFIG_M586=y
-# CONFIG_M586TSC is not set
-# CONFIG_M586MMX is not set
-# CONFIG_M686 is not set
-# CONFIG_MPENTIUMII is not set
-# CONFIG_MPENTIUMIII is not set
-# CONFIG_MPENTIUMM is not set
-# CONFIG_MPENTIUM4 is not set
-# CONFIG_MK6 is not set
-# CONFIG_MK7 is not set
-# CONFIG_MK8 is not set
-# CONFIG_MCRUSOE is not set
-# CONFIG_MEFFICEON is not set
-# CONFIG_MWINCHIPC6 is not set
-# CONFIG_MWINCHIP2 is not set
-# CONFIG_MWINCHIP3D is not set
-# CONFIG_MGEODEGX1 is not set
-# CONFIG_MGEODE_LX is not set
-# CONFIG_MCYRIXIII is not set
-# CONFIG_MVIAC3_2 is not set
-CONFIG_X86_GENERIC=y
-CONFIG_X86_CMPXCHG=y
-CONFIG_X86_XADD=y
-CONFIG_X86_L1_CACHE_SHIFT=7
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_X86_PPRO_FENCE=y
-CONFIG_X86_WP_WORKS_OK=y
-CONFIG_X86_INVLPG=y
-CONFIG_X86_BSWAP=y
-CONFIG_X86_POPAD_OK=y
-CONFIG_X86_CMPXCHG64=y
-CONFIG_X86_ALIGNMENT_16=y
-CONFIG_X86_INTEL_USERCOPY=y
-# CONFIG_SMP is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_TOSHIBA is not set
-# CONFIG_I8K is not set
-CONFIG_X86_REBOOTFIXUPS=y
-CONFIG_X86_CPUID=y
-CONFIG_SWIOTLB=y
-
-#
-# Firmware Drivers
-#
-# CONFIG_DELL_RBU is not set
-# CONFIG_DCDBAS is not set
-# CONFIG_NOHIGHMEM is not set
-CONFIG_HIGHMEM4G=y
-# CONFIG_HIGHMEM64G is not set
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_3G_OPT is not set
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_HIGHMEM=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_REGPARM is not set
-CONFIG_SECCOMP=y
-CONFIG_HZ_100=y
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=100
-# CONFIG_CRASH_DUMP is not set
-CONFIG_PHYSICAL_START=0x100000
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-CONFIG_PCI=y
-# CONFIG_PCI_GOBIOS is not set
-# CONFIG_PCI_GOMMCONFIG is not set
-# CONFIG_PCI_GODIRECT is not set
-# CONFIG_PCI_GOXEN_FE is not set
-CONFIG_PCI_GOANY=y
-CONFIG_PCI_DIRECT=y
-CONFIG_XEN_PCIDEV_FRONTEND=y
-# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_DEBUG is not set
-CONFIG_ISA_DMA_API=y
-# CONFIG_SCx200 is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_ASK_IP_FIB_HASH=y
-# CONFIG_IP_FIB_TRIE is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_IP_ROUTE_FWMARK is not set
-CONFIG_IP_ROUTE_MULTIPATH=y
-# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
-CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-CONFIG_IPSEC_NAT_TRAVERSAL=y
-CONFIG_INET_AH=y
-CONFIG_INET_ESP=y
-CONFIG_INET_IPCOMP=y
-CONFIG_INET_TUNNEL=y
-CONFIG_INET_DIAG=m
-CONFIG_INET_TCP_DIAG=m
-CONFIG_TCP_CONG_ADVANCED=y
-
-#
-# TCP congestion control
-#
-CONFIG_TCP_CONG_BIC=m
-CONFIG_TCP_CONG_CUBIC=m
-CONFIG_TCP_CONG_WESTWOOD=m
-CONFIG_TCP_CONG_HTCP=m
-CONFIG_TCP_CONG_HSTCP=m
-CONFIG_TCP_CONG_HYBLA=m
-CONFIG_TCP_CONG_VEGAS=m
-CONFIG_TCP_CONG_SCALABLE=m
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-CONFIG_NETFILTER_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CONNTRACK_EVENTS=y
-CONFIG_IP_NF_CONNTRACK_NETLINK=m
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_NETBIOS_NS=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_PPTP=m
-CONFIG_IP_NF_H323=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_LAYER7=m
-# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_POLICY=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_PPTP=m
-CONFIG_IP_NF_NAT_H323=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_NAT_MMS=m
-CONFIG_IP_NF_MMS=m
-CONFIG_IP_NF_NAT_SIP=m
-CONFIG_IP_NF_SIP=m
-
-#
-# Bridge: Netfilter Configuration
-#
-CONFIG_BRIDGE_NF_EBTABLES=m
-CONFIG_BRIDGE_EBT_BROUTE=m
-CONFIG_BRIDGE_EBT_T_FILTER=m
-CONFIG_BRIDGE_EBT_T_NAT=m
-CONFIG_BRIDGE_EBT_802_3=m
-CONFIG_BRIDGE_EBT_AMONG=m
-CONFIG_BRIDGE_EBT_ARP=m
-CONFIG_BRIDGE_EBT_IP=m
-CONFIG_BRIDGE_EBT_LIMIT=m
-CONFIG_BRIDGE_EBT_MARK=m
-CONFIG_BRIDGE_EBT_PKTTYPE=m
-CONFIG_BRIDGE_EBT_STP=m
-CONFIG_BRIDGE_EBT_VLAN=m
-CONFIG_BRIDGE_EBT_ARPREPLY=m
-CONFIG_BRIDGE_EBT_DNAT=m
-CONFIG_BRIDGE_EBT_MARK_T=m
-CONFIG_BRIDGE_EBT_REDIRECT=m
-CONFIG_BRIDGE_EBT_SNAT=m
-CONFIG_BRIDGE_EBT_LOG=m
-# CONFIG_BRIDGE_EBT_ULOG is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-CONFIG_ATM=m
-CONFIG_ATM_CLIP=m
-CONFIG_ATM_CLIP_NO_ICMP=y
-# CONFIG_ATM_LANE is not set
-CONFIG_ATM_BR2684=m
-# CONFIG_ATM_BR2684_IPFILTER is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CLK_JIFFIES=y
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-# CONFIG_NET_SCH_CLK_CPU is not set
-
-#
-# Queueing/Scheduling
-#
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_INGRESS=m
-
-#
-# Classification
-#
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-# CONFIG_CLS_U32_PERF is not set
-CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=y
-CONFIG_NET_EMATCH=y
-CONFIG_NET_EMATCH_STACK=32
-CONFIG_NET_EMATCH_CMP=m
-CONFIG_NET_EMATCH_NBYTE=m
-CONFIG_NET_EMATCH_U32=m
-CONFIG_NET_EMATCH_META=m
-CONFIG_NET_EMATCH_TEXT=m
-# CONFIG_NET_CLS_ACT is not set
-CONFIG_NET_CLS_POLICE=y
-CONFIG_NET_CLS_IND=y
-CONFIG_NET_ESTIMATOR=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-# CONFIG_IEEE80211_CRYPT_CCMP is not set
-# CONFIG_IEEE80211_CRYPT_TKIP is not set
-CONFIG_KLIPS=m
-
-#
-# KLIPS options
-#
-CONFIG_KLIPS_ESP=y
-CONFIG_KLIPS_AH=y
-CONFIG_KLIPS_AUTH_HMAC_MD5=y
-CONFIG_KLIPS_AUTH_HMAC_SHA1=y
-CONFIG_KLIPS_ENC_CRYPTOAPI=y
-CONFIG_KLIPS_ENC_1DES=y
-CONFIG_KLIPS_ENC_3DES=y
-CONFIG_KLIPS_ENC_AES=y
-# CONFIG_KLIPS_ENC_NULL is not set
-CONFIG_KLIPS_IPCOMP=y
-CONFIG_KLIPS_DEBUG=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_FW_LOADER=m
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=m
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_PARTITIONS is not set
-
-#
-# User Modules And Translation Layers
-#
-# CONFIG_MTD_CHAR is not set
-# CONFIG_MTD_BLOCK is not set
-# CONFIG_MTD_BLOCK_RO is not set
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_TS5500 is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
-# CONFIG_MTD_ONENAND is not set
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-# CONFIG_PARPORT_SERIAL is not set
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=m
-# CONFIG_PARIDE is not set
-CONFIG_BLK_CPQ_DA=m
-CONFIG_BLK_CPQ_CISS_DA=m
-# CONFIG_CISS_SCSI_TAPE is not set
-CONFIG_BLK_DEV_DAC960=m
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_SX8=m
-CONFIG_BLK_DEV_UB=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=m
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-CONFIG_BLK_DEV_CMD640=y
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=m
-CONFIG_BLK_DEV_OPTI621=m
-CONFIG_BLK_DEV_RZ1000=m
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_AEC62XX=m
-CONFIG_BLK_DEV_ALI15X3=m
-# CONFIG_WDC_ALI15X3 is not set
-CONFIG_BLK_DEV_AMD74XX=m
-CONFIG_BLK_DEV_ATIIXP=m
-CONFIG_BLK_DEV_CMD64X=m
-CONFIG_BLK_DEV_TRIFLEX=m
-CONFIG_BLK_DEV_CY82C693=m
-CONFIG_BLK_DEV_CS5520=m
-CONFIG_BLK_DEV_CS5530=m
-# CONFIG_BLK_DEV_CS5535 is not set
-CONFIG_BLK_DEV_HPT34X=m
-# CONFIG_HPT34X_AUTODMA is not set
-CONFIG_BLK_DEV_HPT366=m
-CONFIG_BLK_DEV_SC1200=m
-CONFIG_BLK_DEV_PIIX=m
-CONFIG_BLK_DEV_IT821X=m
-CONFIG_BLK_DEV_NS87415=m
-CONFIG_BLK_DEV_PDC202XX_OLD=m
-# CONFIG_PDC202XX_BURST is not set
-CONFIG_BLK_DEV_PDC202XX_NEW=m
-CONFIG_BLK_DEV_SVWKS=m
-CONFIG_BLK_DEV_SIIMAGE=m
-CONFIG_BLK_DEV_SIS5513=m
-CONFIG_BLK_DEV_SLC90E66=m
-CONFIG_BLK_DEV_TRM290=m
-CONFIG_BLK_DEV_VIA82CXXX=m
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_RAID_ATTRS=y
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_CHR_DEV_SCH=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=m
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-CONFIG_SCSI_SAS_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-CONFIG_BLK_DEV_3W_XXXX_RAID=m
-CONFIG_SCSI_3W_9XXX=m
-CONFIG_SCSI_ACARD=m
-CONFIG_SCSI_AACRAID=m
-CONFIG_SCSI_AIC7XXX=m
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
-# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
-CONFIG_AIC7XXX_DEBUG_MASK=0
-# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-CONFIG_SCSI_AIC79XX=m
-CONFIG_AIC79XX_CMDS_PER_DEVICE=32
-CONFIG_AIC79XX_RESET_DELAY_MS=15000
-# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
-# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
-# CONFIG_AIC79XX_DEBUG_ENABLE is not set
-CONFIG_AIC79XX_DEBUG_MASK=0
-# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
-CONFIG_SCSI_DPT_I2O=m
-CONFIG_SCSI_ADVANSYS=m
-CONFIG_SCSI_ARCMSR=m
-CONFIG_MEGARAID_NEWGEN=y
-CONFIG_MEGARAID_MM=m
-CONFIG_MEGARAID_MAILBOX=m
-CONFIG_MEGARAID_LEGACY=m
-CONFIG_MEGARAID_SAS=m
-CONFIG_SCSI_SATA=m
-CONFIG_SCSI_SATA_AHCI=m
-CONFIG_SCSI_SATA_SVW=m
-CONFIG_SCSI_ATA_PIIX=m
-# CONFIG_SCSI_SATA_MV is not set
-CONFIG_SCSI_SATA_NV=m
-CONFIG_SCSI_PDC_ADMA=m
-CONFIG_SCSI_HPTIOP=m
-CONFIG_SCSI_SATA_QSTOR=m
-CONFIG_SCSI_SATA_PROMISE=m
-CONFIG_SCSI_SATA_SX4=m
-CONFIG_SCSI_SATA_SIL=m
-CONFIG_SCSI_SATA_SIL24=m
-CONFIG_SCSI_SATA_SIS=m
-CONFIG_SCSI_SATA_ULI=m
-CONFIG_SCSI_SATA_VIA=m
-CONFIG_SCSI_SATA_VITESSE=m
-CONFIG_SCSI_SATA_INTEL_COMBINED=y
-CONFIG_SCSI_BUSLOGIC=m
-# CONFIG_SCSI_OMIT_FLASHPOINT is not set
-CONFIG_SCSI_DMX3191D=m
-CONFIG_SCSI_EATA=m
-CONFIG_SCSI_EATA_TAGGED_QUEUE=y
-CONFIG_SCSI_EATA_LINKED_COMMANDS=y
-CONFIG_SCSI_EATA_MAX_TAGS=16
-CONFIG_SCSI_FUTURE_DOMAIN=m
-CONFIG_SCSI_GDTH=m
-CONFIG_SCSI_IPS=m
-CONFIG_SCSI_INITIO=m
-CONFIG_SCSI_INIA100=m
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-CONFIG_SCSI_SYM53C8XX_2=m
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-CONFIG_SCSI_QLOGIC_1280=m
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_LPFC is not set
-CONFIG_SCSI_DC395x=m
-CONFIG_SCSI_DC390T=m
-CONFIG_SCSI_NSP32=m
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-# CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=m
-# CONFIG_MD_RAID6 is not set
-CONFIG_MD_MULTIPATH=m
-# CONFIG_MD_FAULTY is not set
-# CONFIG_BLK_DEV_DM is not set
-
-#
-# Fusion MPT device support
-#
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=m
-CONFIG_FUSION_FC=m
-CONFIG_FUSION_SAS=m
-CONFIG_FUSION_MAX_SGE=128
-CONFIG_FUSION_CTL=m
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_BONDING=m
-CONFIG_EQUALIZER=m
-CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
-CONFIG_HAPPYMEAL=m
-CONFIG_SUNGEM=m
-CONFIG_CASSINI=m
-CONFIG_NET_VENDOR_3COM=y
-CONFIG_VORTEX=m
-CONFIG_TYPHOON=m
-
-#
-# Tulip family network device support
-#
-CONFIG_NET_TULIP=y
-CONFIG_DE2104X=m
-CONFIG_TULIP=m
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_TULIP_NAPI is not set
-CONFIG_DE4X5=m
-CONFIG_WINBOND_840=m
-CONFIG_DM9102=m
-CONFIG_ULI526X=m
-CONFIG_HP100=m
-CONFIG_NET_PCI=y
-CONFIG_PCNET32=m
-CONFIG_AMD8111_ETH=m
-# CONFIG_AMD8111E_NAPI is not set
-CONFIG_ADAPTEC_STARFIRE=m
-# CONFIG_ADAPTEC_STARFIRE_NAPI is not set
-CONFIG_B44=m
-CONFIG_FORCEDETH=m
-CONFIG_DGRS=m
-CONFIG_EEPRO100=m
-CONFIG_E100=m
-CONFIG_FEALNX=m
-CONFIG_NATSEMI=m
-CONFIG_NE2K_PCI=m
-CONFIG_8139CP=m
-CONFIG_8139TOO=m
-# CONFIG_8139TOO_PIO is not set
-CONFIG_8139TOO_TUNE_TWISTER=y
-CONFIG_8139TOO_8129=y
-# CONFIG_8139_OLD_RX_RESET is not set
-CONFIG_SIS900=m
-CONFIG_EPIC100=m
-CONFIG_SUNDANCE=m
-CONFIG_SUNDANCE_MMIO=y
-CONFIG_TLAN=m
-CONFIG_VIA_RHINE=m
-CONFIG_VIA_RHINE_MMIO=y
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-CONFIG_ACENIC=m
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
-CONFIG_DL2K=m
-CONFIG_E1000=m
-# CONFIG_E1000_NAPI is not set
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
-CONFIG_NS83820=m
-CONFIG_HAMACHI=m
-CONFIG_YELLOWFIN=m
-CONFIG_R8169=m
-# CONFIG_R8169_NAPI is not set
-CONFIG_R8169_VLAN=y
-CONFIG_SIS190=m
-CONFIG_SKGE=m
-CONFIG_SKY2=m
-CONFIG_SK98LIN=m
-CONFIG_VIA_VELOCITY=m
-CONFIG_TIGON3=m
-CONFIG_BNX2=m
-
-#
-# Ethernet (10000 Mbit)
-#
-CONFIG_CHELSIO_T1=m
-CONFIG_IXGB=m
-# CONFIG_IXGB_NAPI is not set
-CONFIG_S2IO=m
-# CONFIG_S2IO_NAPI is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_IPW2100=m
-CONFIG_IPW2100_MONITOR=y
-# CONFIG_IPW2100_DEBUG is not set
-CONFIG_IPW2200=m
-# CONFIG_IPW2200_DEBUG is not set
-CONFIG_AIRO=m
-CONFIG_HERMES=m
-CONFIG_PLX_HERMES=m
-CONFIG_TMD_HERMES=m
-CONFIG_NORTEL_HERMES=m
-CONFIG_PCI_HERMES=m
-CONFIG_ATMEL=m
-CONFIG_PCI_ATMEL=m
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-CONFIG_PRISM54=m
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set
-CONFIG_HOSTAP_PLX=m
-CONFIG_HOSTAP_PCI=m
-CONFIG_NET_WIRELESS=y
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# ATM drivers
-#
-# CONFIG_ATM_DUMMY is not set
-CONFIG_ATM_TCP=m
-CONFIG_ATM_LANAI=m
-CONFIG_ATM_ENI=m
-CONFIG_ATM_ENI_DEBUG=y
-CONFIG_ATM_ENI_TUNE_BURST=y
-CONFIG_ATM_ENI_BURST_TX_16W=y
-CONFIG_ATM_ENI_BURST_TX_8W=y
-CONFIG_ATM_ENI_BURST_TX_4W=y
-CONFIG_ATM_ENI_BURST_TX_2W=y
-CONFIG_ATM_ENI_BURST_RX_16W=y
-CONFIG_ATM_ENI_BURST_RX_8W=y
-CONFIG_ATM_ENI_BURST_RX_4W=y
-CONFIG_ATM_ENI_BURST_RX_2W=y
-CONFIG_ATM_FIRESTREAM=m
-CONFIG_ATM_ZATM=m
-# CONFIG_ATM_ZATM_DEBUG is not set
-CONFIG_ATM_NICSTAR=m
-CONFIG_ATM_NICSTAR_USE_SUNI=y
-CONFIG_ATM_NICSTAR_USE_IDT77105=y
-CONFIG_ATM_IDT77252=m
-# CONFIG_ATM_IDT77252_DEBUG is not set
-# CONFIG_ATM_IDT77252_RCV_ALL is not set
-CONFIG_ATM_IDT77252_USE_SUNI=y
-CONFIG_ATM_AMBASSADOR=m
-# CONFIG_ATM_AMBASSADOR_DEBUG is not set
-CONFIG_ATM_HORIZON=m
-# CONFIG_ATM_HORIZON_DEBUG is not set
-CONFIG_ATM_IA=m
-# CONFIG_ATM_IA_DEBUG is not set
-CONFIG_ATM_FORE200E_MAYBE=m
-CONFIG_ATM_FORE200E_PCA=y
-CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y
-CONFIG_ATM_FORE200E_USE_TASKLET=y
-CONFIG_ATM_FORE200E_TX_RETRY=16
-CONFIG_ATM_FORE200E_DEBUG=0
-CONFIG_ATM_FORE200E=m
-CONFIG_ATM_HE=m
-CONFIG_ATM_HE_USE_SUNI=y
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPPOATM=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-CONFIG_ISDN=m
-
-#
-# Old ISDN4Linux
-#
-# CONFIG_ISDN_I4L is not set
-
-#
-# CAPI subsystem
-#
-CONFIG_ISDN_CAPI=m
-CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
-CONFIG_ISDN_CAPI_MIDDLEWARE=y
-CONFIG_ISDN_CAPI_CAPI20=m
-CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
-CONFIG_ISDN_CAPI_CAPIFS=m
-
-#
-# CAPI hardware drivers
-#
-
-#
-# Active AVM cards
-#
-CONFIG_CAPI_AVM=y
-CONFIG_ISDN_DRV_AVMB1_B1PCI=m
-CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
-CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
-CONFIG_ISDN_DRV_AVMB1_T1PCI=m
-CONFIG_ISDN_DRV_AVMB1_C4=m
-
-#
-# Active Eicon DIVA Server cards
-#
-# CONFIG_CAPI_EICON is not set
-
-#
-# Modular ISDN driver
-#
-CONFIG_MISDN_DRV=m
-# CONFIG_MISDN_MEMDEBUG is not set
-CONFIG_MISDN_AVM_FRITZ=y
-CONFIG_MISDN_NETJET=y
-CONFIG_MISDN_HFCPCI=y
-# CONFIG_MISDN_HFCMULTI is not set
-CONFIG_MISDN_HFCUSB=y
-CONFIG_MISDN_HFCMINI=y
-CONFIG_MISDN_XHFC=y
-CONFIG_MISDN_SPEEDFAX=y
-CONFIG_MISDN_W6692=y
-CONFIG_MISDN_DSP=y
-CONFIG_MISDN_LOOP=y
-CONFIG_MISDN_L1OIP=y
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-CONFIG_KEYBOARD_SUNKBD=y
-CONFIG_KEYBOARD_LKKBD=y
-CONFIG_KEYBOARD_XTKBD=y
-CONFIG_KEYBOARD_NEWTON=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_PCSPKR=y
-# CONFIG_INPUT_WISTRON_BTNS is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=m
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-CONFIG_PPDEV=m
-# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
-CONFIG_IPMI_HANDLER=m
-CONFIG_IPMI_PANIC_EVENT=y
-# CONFIG_IPMI_PANIC_STRING is not set
-CONFIG_IPMI_DEVICE_INTERFACE=m
-CONFIG_IPMI_SI=m
-CONFIG_IPMI_WATCHDOG=m
-CONFIG_IPMI_POWEROFF=m
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
-CONFIG_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-CONFIG_MWAVE=m
-# CONFIG_CS5535_GPIO is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-CONFIG_W1=m
-CONFIG_W1_MATROX=m
-CONFIG_W1_DS9490=m
-CONFIG_W1_DS9490_BRIDGE=m
-CONFIG_W1_THERM=m
-CONFIG_W1_SMEM=m
-CONFIG_W1_DS2433=m
-CONFIG_W1_DS2433_CRC=y
-
-#
-# Hardware Monitoring support
-#
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-CONFIG_SENSORS_K8TEMP=y
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_HDAPS is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ARC is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_VGA16 is not set
-CONFIG_FB_VESA=y
-CONFIG_VIDEO_SELECT=y
-# CONFIG_FB_HGA is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_I810 is not set
-# CONFIG_FB_INTEL is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_CYBLA is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_GEODE is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_HWDEP=m
-CONFIG_SND_RAWMIDI=m
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_RTCTIMER is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-CONFIG_SND_MPU401_UART=m
-CONFIG_SND_OPL3_LIB=m
-CONFIG_SND_VX_LIB=m
-CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_AC97_BUS=m
-CONFIG_SND_DUMMY=m
-CONFIG_SND_MTPAV=m
-CONFIG_SND_SERIAL_U16550=m
-CONFIG_SND_MPU401=m
-
-#
-# PCI devices
-#
-CONFIG_SND_AD1889=m
-CONFIG_SND_ALS4000=m
-CONFIG_SND_ALI5451=m
-CONFIG_SND_ATIIXP=m
-CONFIG_SND_ATIIXP_MODEM=m
-CONFIG_SND_AU8810=m
-CONFIG_SND_AU8820=m
-CONFIG_SND_AU8830=m
-CONFIG_SND_AZT3328=m
-CONFIG_SND_BT87X=m
-# CONFIG_SND_BT87X_OVERCLOCK is not set
-CONFIG_SND_CA0106=m
-CONFIG_SND_CMIPCI=m
-CONFIG_SND_CS4281=m
-CONFIG_SND_CS46XX=m
-# CONFIG_SND_CS46XX_NEW_DSP is not set
-CONFIG_SND_CS5535AUDIO=m
-CONFIG_SND_DARLA20=m
-CONFIG_SND_GINA20=m
-CONFIG_SND_LAYLA20=m
-CONFIG_SND_DARLA24=m
-CONFIG_SND_GINA24=m
-CONFIG_SND_LAYLA24=m
-CONFIG_SND_MONA=m
-CONFIG_SND_MIA=m
-CONFIG_SND_ECHO3G=m
-CONFIG_SND_INDIGO=m
-CONFIG_SND_INDIGOIO=m
-CONFIG_SND_INDIGODJ=m
-CONFIG_SND_EMU10K1=m
-CONFIG_SND_EMU10K1X=m
-CONFIG_SND_ENS1370=m
-CONFIG_SND_ENS1371=m
-CONFIG_SND_ES1938=m
-CONFIG_SND_ES1968=m
-CONFIG_SND_FM801=m
-# CONFIG_SND_FM801_TEA575X_BOOL is not set
-CONFIG_SND_HDA_INTEL=m
-CONFIG_SND_HDSP=m
-CONFIG_SND_HDSPM=m
-CONFIG_SND_ICE1712=m
-CONFIG_SND_ICE1724=m
-CONFIG_SND_INTEL8X0=m
-CONFIG_SND_INTEL8X0M=m
-CONFIG_SND_KORG1212=m
-CONFIG_SND_MAESTRO3=m
-CONFIG_SND_MIXART=m
-CONFIG_SND_NM256=m
-CONFIG_SND_PCXHR=m
-CONFIG_SND_RME32=m
-CONFIG_SND_RME96=m
-CONFIG_SND_RME9652=m
-CONFIG_SND_SONICVIBES=m
-CONFIG_SND_TRIDENT=m
-CONFIG_SND_VIA82XX=m
-CONFIG_SND_VIA82XX_MODEM=m
-CONFIG_SND_VX222=m
-CONFIG_SND_YMFPCI=m
-
-#
-# USB devices
-#
-CONFIG_SND_USB_AUDIO=m
-CONFIG_SND_USB_USX2Y=m
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-CONFIG_USB_DYNAMIC_MINORS=y
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-CONFIG_USB_ISP116X_HCD=m
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=m
-CONFIG_USB_SL811_HCD=m
-
-#
-# USB Device Class drivers
-#
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# may also be needed; see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-CONFIG_USB_HIDDEV=y
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_AX8817X=m
-CONFIG_USB_NET_CDCETHER=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_NET1080=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_NET_CDC_SUBSET=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_NET_ZAURUS=m
-CONFIG_USB_ZD1201=m
-# CONFIG_USB_MON is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-CONFIG_USB_ATM=m
-CONFIG_USB_SPEEDTOUCH=m
-CONFIG_USB_CXACRU=m
-# CONFIG_USB_UEAGLEATM is not set
-CONFIG_USB_XUSBATM=m
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-# CONFIG_EDAC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=m
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISER4_FS=m
-# CONFIG_REISER4_DEBUG is not set
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-CONFIG_REISERFS_PROC_INFO=y
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-CONFIG_JFS_FS=m
-CONFIG_JFS_POSIX_ACL=y
-CONFIG_JFS_SECURITY=y
-# CONFIG_JFS_DEBUG is not set
-CONFIG_JFS_STATISTICS=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-# CONFIG_XFS_RT is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-# CONFIG_QUOTA is not set
-CONFIG_QUOTACTL=y
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-# CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=850
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=m
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_SUMMARY is not set
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-# CONFIG_CRAMFS is not set
-CONFIG_SQUASHFS=y
-# CONFIG_SQUASHFS_EMBEDDED is not set
-CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
-# CONFIG_SQUASHFS_VMALLOC is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="cp850"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=y
-
-#
-# Instrumentation Support
-#
-# CONFIG_PROFILING is not set
-# CONFIG_KPROBES is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=17
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_HIGHMEM is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_VM is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_FORCED_INLINING is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_EARLY_PRINTK=y
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUG_RODATA is not set
-# CONFIG_4KSTACKS is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=m
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_AES_586=m
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-CONFIG_CRYPTO_DEFLATE=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
-CONFIG_CRYPTO_DEV_PADLOCK=m
-CONFIG_CRYPTO_DEV_PADLOCK_AES=y
-CONFIG_XEN=y
-CONFIG_XEN_INTERFACE_VERSION=0x00030203
-
-#
-# XEN
-#
-# CONFIG_XEN_PRIVILEGED_GUEST is not set
-CONFIG_XEN_UNPRIVILEGED_GUEST=y
-CONFIG_XEN_PRIVCMD=y
-CONFIG_XEN_XENBUS_DEV=y
-# CONFIG_XEN_BACKEND is not set
-CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_XEN_FRAMEBUFFER is not set
-CONFIG_XEN_SCRUB_PAGES=y
-CONFIG_XEN_DISABLE_SERIAL=y
-CONFIG_XEN_SYSFS=y
-CONFIG_XEN_COMPAT_030002_AND_LATER=y
-# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
-CONFIG_XEN_COMPAT_030002=y
-CONFIG_HAVE_ARCH_ALLOC_SKB=y
-CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
-CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
-CONFIG_NO_IDLE_HZ=y
-CONFIG_XEN_UTIL=y
-CONFIG_XEN_BALLOON=y
-CONFIG_XEN_DEVMEM=y
-CONFIG_XEN_SKBUFF=y
-CONFIG_XEN_REBOOT=y
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_X86_BIOS_REBOOT=y
-CONFIG_X86_NO_TSS=y
-CONFIG_X86_NO_IDT=y
-CONFIG_KTIME_SCALAR=y
index dd6911b98795980ac9f5a11b9003b71581dfb153..39e309d8b8abbb462d2a4344a62808bbf0b604cb 100644 (file)
--- a/lfs/linux
+++ b/lfs/linux
@@ -40,13 +40,9 @@ CXXFLAGS   =
 #
 ifeq "$(SMP)" "1"
        TARGET = $(DIR_INFO)/linux-$(VER)-smp
-else
-ifeq "$(XEN)" "1"
-       TARGET = $(DIR_INFO)/linux-$(VER)-xen
 else
        TARGET = $(DIR_INFO)/linux-$(VER)
 endif
-endif
 
 
 ###############################################################################
@@ -109,12 +105,6 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        @$(PREBUILD)
        @rm -rf $(DIR_APP) $(DIR_SRC)/linux $(DIR_SRC)/xen-* && cd $(DIR_SRC) && tar jxf $(DIR_DL)/$(DL_FILE)
        ln -s linux-$(VER) /usr/src/linux
-       
-ifeq "$(XEN)" "1"
-       # XEN
-       -cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/xen-3.0.4-2.6.16.x.patch
-       cd $(DIR_APP)/net/ipv4/netfilter && patch -Np0 < $(DIR_SRC)/src/patches/xen-3.0.4-netfilter-fix.patch
-endif
 
        # An UTF8 patch from LFS
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-2.6.16.27-utf8_input-1.patch
@@ -160,9 +150,6 @@ endif
        cd $(DIR_SRC) && rm -rf $(DIR_SRC)/netfilter-layer7-v2.9
        cd $(DIR_SRC) && tar xzf $(DIR_DL)/netfilter-layer7-v2.9.tar.gz
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/netfilter-layer7-v2.9/for_older_kernels/kernel-2.6.13-2.6.16-layer7-2.2.patch
-ifeq "$(XEN)" "1"
-       cd $(DIR_APP)/net/ipv4/netfilter && patch -Np0 < $(DIR_SRC)/src/patches/xen-3.0.4-layer7-fix.patch
-endif
 
        # Linux Intermediate Queueing Device
 ifeq "$(XEN)" ""
@@ -184,12 +171,8 @@ endif
 
 ifeq "$(SMP)" "1"
        cp $(DIR_SRC)/config/kernel/kernel.config.$(MACHINE).smp $(DIR_APP)/.config
-else
-ifeq "$(XEN)" "1"
-       cp $(DIR_SRC)/config/kernel/kernel.config.$(MACHINE).xen $(DIR_APP)/.config
 else
        cp $(DIR_SRC)/config/kernel/kernel.config.$(MACHINE) $(DIR_APP)/.config
-endif
 endif
 
        cd $(DIR_APP) && make CC="$(KGCC)" oldconfig
@@ -203,15 +186,6 @@ ifeq "$(SMP)" "1"
        ln -sf vmlinuz-$(VER)-ipfire-smp /boot/vmlinuz-ipfire-smp
        cd $(DIR_APP) && make CC="$(KGCC)" $(MAKETUNING) modules
        cd $(DIR_APP) && make CC="$(KGCC)" $(MAKETUNING) modules_install
-else
-ifeq "$(XEN)" "1"
-       cd $(DIR_APP) && sed -i -e 's/EXTRAVERSION\ =.*/EXTRAVERSION\ =\ $(PATCHLEVEL)-ipfire-xen/' Makefile
-       cd $(DIR_APP) && make $(MAKETUNING) CC="$(KGCC)" vmlinuz
-       cd $(DIR_APP) && cp -v vmlinuz /boot/vmlinuz-$(VER)-ipfire-xen
-       cd $(DIR_APP) && cp -v System.map /boot/System.map-$(VER)-ipfire-xen
-       ln -sf vmlinuz-$(VER)-ipfire-xen /boot/vmlinuz-ipfire-xen
-       cd $(DIR_APP) && make CC="$(KGCC)" $(MAKETUNING) modules
-       cd $(DIR_APP) && make CC="$(KGCC)" $(MAKETUNING) modules_install
 else
        cd $(DIR_APP) && sed -i -e 's/EXTRAVERSION\ =.*/EXTRAVERSION\ =\ $(PATCHLEVEL)-ipfire/' Makefile
        cd $(DIR_APP) && make $(MAKETUNING) CC="$(KGCC)" bzImage
@@ -222,17 +196,14 @@ else
        ln -sf System.map-$(VER)-ipfire /boot/System.map-ipfire
        cd $(DIR_APP) && make CC="$(KGCC)" $(MAKETUNING) modules
        cd $(DIR_APP) && make CC="$(KGCC)" $(MAKETUNING) modules_install
-endif
 endif
 
        # remove symlinked pcmcia directory
        -rm -rf /lib/modules/$(VER)-ipfire{,-smp}/pcmcia
 
 ifeq "$(SMP)" ""
-ifeq "$(XEN)" ""
        # Only do this once on the non-SMP pass 
        cd $(DIR_APP) && install -m 755 usr/gen_init_cpio /sbin/
-endif
 endif 
 
        @rm -rf $(DIR_SRC)/patch-o-matic* $(DIR_SRC)/iptables* $(DIR_SRC)/squashfs* $(DIR_SRC)/mISDN-* $(DIR_SRC)/netfilter-layer7-*
diff --git a/make.sh b/make.sh
index e45b28a20e944f3575af0e5161021bba2b06cf71..3c481d0feddca64352863f00a9968bfb6e461c2f 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -336,7 +336,6 @@ buildipfire() {
 #  ipfiremake promise-sata-300-tx      SMP=1
   ipfiremake zaptel                    SMP=1
   ipfiremake fuse                              SMP=1
-  #ipfiremake linux                    XEN=1
   ipfiremake linux
   ipfiremake ipp2p
   ipfiremake fcdsl
index a47a7831dc62dba77d122eb1f06347e98cb65ff9..97dd08cf785d153f927fa6cc073fd6f2a571ef97 100644 (file)
@@ -2,3 +2,4 @@
 . /opt/pakfire/lib/functions.sh
 
 extract_files
+/etc/init.d/ipfireseeder start
diff --git a/src/patches/xen-3.0.4-2.6.16.x.patch b/src/patches/xen-3.0.4-2.6.16.x.patch
deleted file mode 100644 (file)
index 77a3ad3..0000000
+++ /dev/null
@@ -1,113769 +0,0 @@
-diff -Nur linux-2.6.16.33-noxen/Documentation/networking/netdevices.txt linux-2.6.16.33/Documentation/networking/netdevices.txt
---- linux-2.6.16.33-noxen/Documentation/networking/netdevices.txt      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/Documentation/networking/netdevices.txt    2007-05-23 21:00:01.000000000 +0000
-@@ -42,9 +42,9 @@
-       Context: nominally process, but don't sleep inside an rwlock
- dev->hard_start_xmit:
--      Synchronization: dev->xmit_lock spinlock.
-+      Synchronization: netif_tx_lock spinlock.
-       When the driver sets NETIF_F_LLTX in dev->features this will be
--      called without holding xmit_lock. In this case the driver 
-+      called without holding netif_tx_lock. In this case the driver
-       has to lock by itself when needed. It is recommended to use a try lock
-       for this and return -1 when the spin lock fails. 
-       The locking there should also properly protect against 
-@@ -62,12 +62,12 @@
-         Only valid when NETIF_F_LLTX is set.
- dev->tx_timeout:
--      Synchronization: dev->xmit_lock spinlock.
-+      Synchronization: netif_tx_lock spinlock.
-       Context: BHs disabled
-       Notes: netif_queue_stopped() is guaranteed true
- dev->set_multicast_list:
--      Synchronization: dev->xmit_lock spinlock.
-+      Synchronization: netif_tx_lock spinlock.
-       Context: BHs disabled
- dev->poll:
-diff -Nur linux-2.6.16.33-noxen/arch/i386/Kconfig linux-2.6.16.33/arch/i386/Kconfig
---- linux-2.6.16.33-noxen/arch/i386/Kconfig    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/Kconfig  2007-01-08 15:00:45.000000000 +0000
-@@ -58,6 +58,15 @@
-       help
-         Choose this option if your computer is a standard PC or compatible.
-+config X86_XEN
-+      bool "Xen-compatible"
-+      select X86_UP_APIC if !SMP && XEN_PRIVILEGED_GUEST
-+      select X86_UP_IOAPIC if !SMP && XEN_PRIVILEGED_GUEST
-+      select SWIOTLB
-+      help
-+        Choose this option if you plan to run this kernel on top of the
-+        Xen Hypervisor.
-+
- config X86_ELAN
-       bool "AMD Elan"
-       help
-@@ -159,6 +168,7 @@
- config HPET_TIMER
-       bool "HPET Timer Support"
-+      depends on !X86_XEN
-       help
-         This enables the use of the HPET for the kernel's internal timer.
-         HPET is the next generation timer replacing legacy 8254s.
-@@ -202,6 +212,19 @@
-         If you don't know what to do here, say N.
-+config SMP_ALTERNATIVES
-+      bool "SMP alternatives support (EXPERIMENTAL)"
-+      depends on SMP && EXPERIMENTAL
-+      help
-+        Try to reduce the overhead of running an SMP kernel on a uniprocessor
-+        host slightly by replacing certain key instruction sequences
-+        according to whether we currently have more than one CPU available.
-+        This should provide a noticeable boost to performance when
-+        running SMP kernels on UP machines, and have negligible impact
-+        when running on an true SMP host.
-+
-+          If unsure, say N.
-+        
- config NR_CPUS
-       int "Maximum number of CPUs (2-255)"
-       range 2 255
-@@ -218,7 +241,7 @@
- config SCHED_SMT
-       bool "SMT (Hyperthreading) scheduler support"
--      depends on SMP
-+      depends on SMP && !X86_XEN
-       default off
-       help
-         SMT scheduler support improves the CPU scheduler's decision making
-@@ -230,7 +253,7 @@
- config X86_UP_APIC
-       bool "Local APIC support on uniprocessors"
--      depends on !SMP && !(X86_VISWS || X86_VOYAGER)
-+      depends on !SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)
-       help
-         A local APIC (Advanced Programmable Interrupt Controller) is an
-         integrated interrupt controller in the CPU. If you have a single-CPU
-@@ -255,12 +278,12 @@
- config X86_LOCAL_APIC
-       bool
--      depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER)
-+      depends on X86_UP_APIC || ((X86_VISWS || SMP) && !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST))
-       default y
- config X86_IO_APIC
-       bool
--      depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER))
-+      depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST))
-       default y
- config X86_VISWS_APIC
-@@ -268,9 +291,14 @@
-       depends on X86_VISWS
-       default y
-+config X86_TSC
-+      bool
-+      depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ && !X86_XEN
-+      default y
-+
- config X86_MCE
-       bool "Machine Check Exception"
--      depends on !X86_VOYAGER
-+      depends on !(X86_VOYAGER || X86_XEN)
-       ---help---
-         Machine Check Exception support allows the processor to notify the
-         kernel if it detects a problem (e.g. overheating, component failure).
-@@ -360,6 +388,7 @@
- config MICROCODE
-       tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
-+      depends on !XEN_UNPRIVILEGED_GUEST
-       ---help---
-         If you say Y here and also to "/dev file system support" in the
-         'File systems' section, you will be able to update the microcode on
-@@ -377,6 +406,7 @@
- config X86_MSR
-       tristate "/dev/cpu/*/msr - Model-specific register support"
-+      depends on !X86_XEN
-       help
-         This device gives privileged processes access to the x86
-         Model-Specific Registers (MSRs).  It is a character device with
-@@ -392,6 +422,10 @@
-         with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
-         /dev/cpu/31/cpuid.
-+config SWIOTLB
-+      bool
-+      default n
-+
- source "drivers/firmware/Kconfig"
- choice
-@@ -560,7 +594,7 @@
- config HIGHPTE
-       bool "Allocate 3rd-level pagetables from highmem"
--      depends on HIGHMEM4G || HIGHMEM64G
-+      depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN
-       help
-         The VM uses one page table entry for each page of physical memory.
-         For systems with a lot of RAM, this can be wasteful of precious
-@@ -569,6 +603,7 @@
- config MATH_EMULATION
-       bool "Math emulation"
-+      depends on !X86_XEN
-       ---help---
-         Linux can emulate a math coprocessor (used for floating point
-         operations) if you don't have one. 486DX and Pentium processors have
-@@ -594,6 +629,8 @@
- config MTRR
-       bool "MTRR (Memory Type Range Register) support"
-+      depends on !XEN_UNPRIVILEGED_GUEST
-+      default y if X86_XEN
-       ---help---
-         On Intel P6 family processors (Pentium Pro, Pentium II and later)
-         the Memory Type Range Registers (MTRRs) may be used to control
-@@ -628,7 +665,7 @@
- config EFI
-       bool "Boot from EFI support (EXPERIMENTAL)"
--      depends on ACPI
-+      depends on ACPI && !X86_XEN
-       default n
-       ---help---
-       This enables the the kernel to boot on EFI platforms using
-@@ -646,7 +683,7 @@
- config IRQBALANCE
-       bool "Enable kernel irq balancing"
--      depends on SMP && X86_IO_APIC
-+      depends on SMP && X86_IO_APIC && !X86_XEN
-       default y
-       help
-         The default yes will allow the kernel to do irq load balancing.
-@@ -689,7 +726,7 @@
- config KEXEC
-       bool "kexec system call (EXPERIMENTAL)"
--      depends on EXPERIMENTAL
-+      depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST
-       help
-         kexec is a system call that implements the ability to shutdown your
-         current kernel, and to start another kernel.  It is like a reboot
-@@ -743,6 +780,7 @@
- config DOUBLEFAULT
-       default y
-       bool "Enable doublefault exception handler" if EMBEDDED
-+      depends on !X86_NO_TSS
-       help
-           This option allows trapping of rare doublefault exceptions that
-           would otherwise cause a system to silently reboot. Disabling this
-@@ -756,18 +794,20 @@
-       depends on HIGHMEM
- menu "Power management options (ACPI, APM)"
--      depends on !X86_VOYAGER
-+      depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)
-+if !X86_XEN
- source kernel/power/Kconfig
-+endif
- source "drivers/acpi/Kconfig"
- menu "APM (Advanced Power Management) BIOS Support"
--depends on PM && !X86_VISWS
-+depends on PM && !(X86_VISWS || X86_XEN)
- config APM
-       tristate "APM (Advanced Power Management) BIOS support"
--      depends on PM
-+      depends on PM && PM_LEGACY
-       ---help---
-         APM is a BIOS specification for saving power using several different
-         techniques. This is mostly useful for battery powered laptops with
-@@ -952,6 +992,7 @@
- config PCI_GOBIOS
-       bool "BIOS"
-+      depends on !X86_XEN
- config PCI_GOMMCONFIG
-       bool "MMConfig"
-@@ -959,6 +1000,13 @@
- config PCI_GODIRECT
-       bool "Direct"
-+config PCI_GOXEN_FE
-+      bool "Xen PCI Frontend"
-+      depends on X86_XEN
-+      help
-+        The PCI device frontend driver allows the kernel to import arbitrary
-+        PCI devices from a PCI backend to support PCI driver domains.
-+
- config PCI_GOANY
-       bool "Any"
-@@ -966,7 +1014,7 @@
- config PCI_BIOS
-       bool
--      depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
-+      depends on !(X86_VISWS || X86_XEN) && PCI && (PCI_GOBIOS || PCI_GOANY)
-       default y
- config PCI_DIRECT
-@@ -979,6 +1027,18 @@
-       depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
-       default y
-+config XEN_PCIDEV_FRONTEND
-+      bool
-+      depends on PCI && X86_XEN && (PCI_GOXEN_FE || PCI_GOANY)
-+      default y
-+
-+config XEN_PCIDEV_FE_DEBUG
-+      bool "Xen PCI Frontend Debugging"
-+      depends on XEN_PCIDEV_FRONTEND
-+      default n
-+      help
-+        Enables some debug statements within the PCI Frontend.
-+
- source "drivers/pci/pcie/Kconfig"
- source "drivers/pci/Kconfig"
-@@ -989,7 +1049,7 @@
- config ISA
-       bool "ISA support"
--      depends on !(X86_VOYAGER || X86_VISWS)
-+      depends on !(X86_VOYAGER || X86_VISWS || X86_XEN)
-       help
-         Find out whether you have ISA slots on your motherboard.  ISA is the
-         name of a bus system, i.e. the way the CPU talks to the other stuff
-@@ -1016,7 +1076,7 @@
- source "drivers/eisa/Kconfig"
- config MCA
--      bool "MCA support" if !(X86_VISWS || X86_VOYAGER)
-+      bool "MCA support" if !(X86_VISWS || X86_VOYAGER || X86_XEN)
-       default y if X86_VOYAGER
-       help
-         MicroChannel Architecture is found in some IBM PS/2 machines and
-@@ -1078,6 +1138,8 @@
- source "crypto/Kconfig"
-+source "drivers/xen/Kconfig"
-+
- source "lib/Kconfig"
- #
-@@ -1103,7 +1165,7 @@
- config X86_HT
-       bool
--      depends on SMP && !(X86_VISWS || X86_VOYAGER)
-+      depends on SMP && !(X86_VISWS || X86_VOYAGER || X86_XEN)
-       default y
- config X86_BIOS_REBOOT
-@@ -1116,6 +1178,16 @@
-       depends on X86_SMP || (X86_VOYAGER && SMP)
-       default y
-+config X86_NO_TSS
-+      bool
-+      depends on X86_XEN
-+      default y
-+
-+config X86_NO_IDT
-+      bool
-+      depends on X86_XEN
-+      default y
-+
- config KTIME_SCALAR
-       bool
-       default y
-diff -Nur linux-2.6.16.33-noxen/arch/i386/Kconfig.cpu linux-2.6.16.33/arch/i386/Kconfig.cpu
---- linux-2.6.16.33-noxen/arch/i386/Kconfig.cpu        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/Kconfig.cpu      2007-01-08 15:00:45.000000000 +0000
-@@ -251,7 +251,7 @@
- config X86_F00F_BUG
-       bool
--      depends on M586MMX || M586TSC || M586 || M486 || M386
-+      depends on (M586MMX || M586TSC || M586 || M486 || M386) && !X86_NO_IDT
-       default y
- config X86_WP_WORKS_OK
-diff -Nur linux-2.6.16.33-noxen/arch/i386/Makefile linux-2.6.16.33/arch/i386/Makefile
---- linux-2.6.16.33-noxen/arch/i386/Makefile   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/Makefile 2007-01-08 15:00:45.000000000 +0000
-@@ -45,6 +45,11 @@
- CFLAGS += $(cflags-y)
-+cppflags-$(CONFIG_XEN) += \
-+      -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION)
-+
-+CPPFLAGS += $(cppflags-y)
-+
- # Default subarch .c files
- mcore-y  := mach-default
-@@ -68,6 +73,10 @@
- mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit
- mcore-$(CONFIG_X86_SUMMIT)  := mach-default
-+# Xen subarch support
-+mflags-$(CONFIG_X86_XEN)      := -Iinclude/asm-i386/mach-xen
-+mcore-$(CONFIG_X86_XEN)               := mach-xen
-+
- # generic subarchitecture
- mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-i386/mach-generic
- mcore-$(CONFIG_X86_GENERICARCH) := mach-default
-@@ -102,6 +111,19 @@
- .PHONY: zImage bzImage compressed zlilo bzlilo \
-       zdisk bzdisk fdimage fdimage144 fdimage288 install
-+ifdef CONFIG_XEN
-+CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS)
-+head-y := arch/i386/kernel/head-xen.o arch/i386/kernel/init_task-xen.o
-+boot := arch/i386/boot-xen
-+.PHONY: vmlinuz
-+all: vmlinuz
-+
-+vmlinuz: vmlinux
-+      $(Q)$(MAKE) $(build)=$(boot) $@
-+
-+install:
-+      $(Q)$(MAKE) $(build)=$(boot) XENGUEST=$(XENGUEST) $@
-+else
- all: bzImage
- # KBUILD_IMAGE specify target image being built
-@@ -124,6 +146,7 @@
- install:
-       $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
-+endif
- archclean:
-       $(Q)$(MAKE) $(clean)=arch/i386/boot
-@@ -139,3 +162,4 @@
- endef
- CLEAN_FILES += arch/$(ARCH)/boot/fdimage arch/$(ARCH)/boot/mtools.conf
-+CLEAN_FILES += vmlinuz vmlinux-stripped
-diff -Nur linux-2.6.16.33-noxen/arch/i386/boot-xen/Makefile linux-2.6.16.33/arch/i386/boot-xen/Makefile
---- linux-2.6.16.33-noxen/arch/i386/boot-xen/Makefile  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/boot-xen/Makefile        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,21 @@
-+
-+OBJCOPYFLAGS := -g --strip-unneeded
-+
-+vmlinuz: vmlinux-stripped FORCE
-+      $(call if_changed,gzip)
-+
-+vmlinux-stripped: vmlinux FORCE
-+      $(call if_changed,objcopy)
-+
-+INSTALL_ROOT := $(patsubst %/boot,%,$(INSTALL_PATH))
-+
-+XINSTALL_NAME ?= $(KERNELRELEASE)
-+install:
-+      mkdir -p $(INSTALL_ROOT)/boot
-+      ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_ROOT)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
-+      rm -f $(INSTALL_ROOT)/boot/vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+      install -m0644 vmlinuz $(INSTALL_ROOT)/boot/vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+      install -m0644 vmlinux $(INSTALL_ROOT)/boot/vmlinux-syms-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+      install -m0664 .config $(INSTALL_ROOT)/boot/config-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+      install -m0664 System.map $(INSTALL_ROOT)/boot/System.map-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
-+      ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_ROOT)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/Makefile linux-2.6.16.33/arch/i386/kernel/Makefile
---- linux-2.6.16.33-noxen/arch/i386/kernel/Makefile    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/Makefile  2007-01-08 15:00:45.000000000 +0000
-@@ -37,11 +37,18 @@
- obj-$(CONFIG_DOUBLEFAULT)     += doublefault.o
- obj-$(CONFIG_VM86)            += vm86.o
- obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
-+obj-$(CONFIG_SMP_ALTERNATIVES)        += smpalts.o
- EXTRA_AFLAGS   := -traditional
- obj-$(CONFIG_SCx200)          += scx200.o
-+ifdef CONFIG_XEN
-+vsyscall_note := vsyscall-note-xen.o
-+else
-+vsyscall_note := vsyscall-note.o
-+endif
-+
- # vsyscall.o contains the vsyscall DSO images as __initdata.
- # We must build both images before we can assemble it.
- # Note: kbuild does not track this dependency due to usage of .incbin
-@@ -62,7 +69,7 @@
- $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \
- $(obj)/vsyscall-%.so: $(src)/vsyscall.lds \
--                    $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE
-+                    $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE
-       $(call if_changed,syscall)
- # We also create a special relocatable object that should mirror the symbol
-@@ -74,5 +81,17 @@
- SYSCFLAGS_vsyscall-syms.o = -r
- $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
--                      $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE
-+                      $(obj)/vsyscall-sysenter.o $(obj)/$(vsyscall_note) FORCE
-       $(call if_changed,syscall)
-+
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y += fixup.o
-+microcode-$(subst m,y,$(CONFIG_MICROCODE)) := microcode-xen.o
-+n-obj-xen := i8259.o timers/ reboot.o smpboot.o trampoline.o
-+
-+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
-+obj-y := $(call cherrypickxen, $(obj-y))
-+extra-y := $(call cherrypickxen, $(extra-y))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/acpi/Makefile linux-2.6.16.33/arch/i386/kernel/acpi/Makefile
---- linux-2.6.16.33-noxen/arch/i386/kernel/acpi/Makefile       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/acpi/Makefile     2007-01-08 15:00:45.000000000 +0000
-@@ -6,3 +6,7 @@
- obj-y                         += cstate.o processor.o
- endif
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+obj-y := $(call cherrypickxen, $(obj-y), $(src))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/acpi/boot-xen.c linux-2.6.16.33/arch/i386/kernel/acpi/boot-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/acpi/boot-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/acpi/boot-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1161 @@
-+/*
-+ *  boot.c - Architecture-Specific Low-Level ACPI Boot Support
-+ *
-+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
-+ *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/config.h>
-+#include <linux/acpi.h>
-+#include <linux/efi.h>
-+#include <linux/module.h>
-+#include <linux/dmi.h>
-+#include <linux/irq.h>
-+
-+#include <asm/pgtable.h>
-+#include <asm/io_apic.h>
-+#include <asm/apic.h>
-+#include <asm/io.h>
-+#include <asm/mpspec.h>
-+
-+#ifdef        CONFIG_X86_64
-+
-+extern void __init clustered_apic_check(void);
-+
-+extern int gsi_irq_sharing(int gsi);
-+#include <asm/proto.h>
-+
-+static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; }
-+
-+
-+#else                         /* X86 */
-+
-+#ifdef        CONFIG_X86_LOCAL_APIC
-+#include <mach_apic.h>
-+#include <mach_mpparse.h>
-+#endif                                /* CONFIG_X86_LOCAL_APIC */
-+
-+static inline int gsi_irq_sharing(int gsi) { return gsi; }
-+
-+#endif                                /* X86 */
-+
-+#define BAD_MADT_ENTRY(entry, end) (                                      \
-+              (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
-+              ((acpi_table_entry_header *)entry)->length != sizeof(*entry))
-+
-+#define PREFIX                        "ACPI: "
-+
-+int acpi_noirq __initdata;    /* skip ACPI IRQ initialization */
-+int acpi_pci_disabled __initdata;     /* skip ACPI PCI scan and IRQ initialization */
-+int acpi_ht __initdata = 1;   /* enable HT */
-+
-+int acpi_lapic;
-+int acpi_ioapic;
-+int acpi_strict;
-+EXPORT_SYMBOL(acpi_strict);
-+
-+acpi_interrupt_flags acpi_sci_flags __initdata;
-+int acpi_sci_override_gsi __initdata;
-+int acpi_skip_timer_override __initdata;
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
-+#endif
-+
-+#ifndef __HAVE_ARCH_CMPXCHG
-+#warning ACPI uses CMPXCHG, i486 and later hardware
-+#endif
-+
-+#define MAX_MADT_ENTRIES      256
-+u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
-+    {[0 ... MAX_MADT_ENTRIES - 1] = 0xff };
-+EXPORT_SYMBOL(x86_acpiid_to_apicid);
-+
-+/* --------------------------------------------------------------------------
-+                              Boot-time Configuration
-+   -------------------------------------------------------------------------- */
-+
-+/*
-+ * The default interrupt routing model is PIC (8259).  This gets
-+ * overriden if IOAPICs are enumerated (below).
-+ */
-+enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
-+
-+#if defined(CONFIG_X86_64) && !defined(CONFIG_XEN)
-+
-+/* rely on all ACPI tables being in the direct mapping */
-+char *__acpi_map_table(unsigned long phys_addr, unsigned long size)
-+{
-+      if (!phys_addr || !size)
-+              return NULL;
-+
-+      if (phys_addr+size <= (end_pfn_map << PAGE_SHIFT) + PAGE_SIZE)
-+              return __va(phys_addr);
-+
-+      return NULL;
-+}
-+
-+#else
-+
-+/*
-+ * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
-+ * to map the target physical address. The problem is that set_fixmap()
-+ * provides a single page, and it is possible that the page is not
-+ * sufficient.
-+ * By using this area, we can map up to MAX_IO_APICS pages temporarily,
-+ * i.e. until the next __va_range() call.
-+ *
-+ * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
-+ * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
-+ * count idx down while incrementing the phys address.
-+ */
-+char *__acpi_map_table(unsigned long phys, unsigned long size)
-+{
-+      unsigned long base, offset, mapped_size;
-+      int idx;
-+
-+#ifndef CONFIG_XEN
-+      if (phys + size < 8 * 1024 * 1024)
-+              return __va(phys);
-+#endif
-+
-+      offset = phys & (PAGE_SIZE - 1);
-+      mapped_size = PAGE_SIZE - offset;
-+      set_fixmap(FIX_ACPI_END, phys);
-+      base = fix_to_virt(FIX_ACPI_END);
-+
-+      /*
-+       * Most cases can be covered by the below.
-+       */
-+      idx = FIX_ACPI_END;
-+      while (mapped_size < size) {
-+              if (--idx < FIX_ACPI_BEGIN)
-+                      return NULL;    /* cannot handle this */
-+              phys += PAGE_SIZE;
-+              set_fixmap(idx, phys);
-+              mapped_size += PAGE_SIZE;
-+      }
-+
-+      return ((unsigned char *)base + offset);
-+}
-+#endif
-+
-+#ifdef CONFIG_PCI_MMCONFIG
-+/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-+struct acpi_table_mcfg_config *pci_mmcfg_config;
-+int pci_mmcfg_config_num;
-+
-+int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
-+{
-+      struct acpi_table_mcfg *mcfg;
-+      unsigned long i;
-+      int config_size;
-+
-+      if (!phys_addr || !size)
-+              return -EINVAL;
-+
-+      mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size);
-+      if (!mcfg) {
-+              printk(KERN_WARNING PREFIX "Unable to map MCFG\n");
-+              return -ENODEV;
-+      }
-+
-+      /* how many config structures do we have */
-+      pci_mmcfg_config_num = 0;
-+      i = size - sizeof(struct acpi_table_mcfg);
-+      while (i >= sizeof(struct acpi_table_mcfg_config)) {
-+              ++pci_mmcfg_config_num;
-+              i -= sizeof(struct acpi_table_mcfg_config);
-+      };
-+      if (pci_mmcfg_config_num == 0) {
-+              printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
-+              return -ENODEV;
-+      }
-+
-+      config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
-+      pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
-+      if (!pci_mmcfg_config) {
-+              printk(KERN_WARNING PREFIX
-+                     "No memory for MCFG config tables\n");
-+              return -ENOMEM;
-+      }
-+
-+      memcpy(pci_mmcfg_config, &mcfg->config, config_size);
-+      for (i = 0; i < pci_mmcfg_config_num; ++i) {
-+              if (mcfg->config[i].base_reserved) {
-+                      printk(KERN_ERR PREFIX
-+                             "MMCONFIG not in low 4GB of memory\n");
-+                      return -ENODEV;
-+              }
-+      }
-+
-+      return 0;
-+}
-+#endif                                /* CONFIG_PCI_MMCONFIG */
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size)
-+{
-+      struct acpi_table_madt *madt = NULL;
-+
-+      if (!phys_addr || !size)
-+              return -EINVAL;
-+
-+      madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size);
-+      if (!madt) {
-+              printk(KERN_WARNING PREFIX "Unable to map MADT\n");
-+              return -ENODEV;
-+      }
-+
-+      if (madt->lapic_address) {
-+              acpi_lapic_addr = (u64) madt->lapic_address;
-+
-+              printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n",
-+                     madt->lapic_address);
-+      }
-+
-+      acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
-+
-+      return 0;
-+}
-+
-+static int __init
-+acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
-+{
-+      struct acpi_table_lapic *processor = NULL;
-+
-+      processor = (struct acpi_table_lapic *)header;
-+
-+      if (BAD_MADT_ENTRY(processor, end))
-+              return -EINVAL;
-+
-+      acpi_table_print_madt_entry(header);
-+
-+      /* Record local apic id only when enabled */
-+      if (processor->flags.enabled)
-+              x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
-+
-+      /*
-+       * We need to register disabled CPU as well to permit
-+       * counting disabled CPUs. This allows us to size
-+       * cpus_possible_map more accurately, to permit
-+       * to not preallocating memory for all NR_CPUS
-+       * when we use CPU hotplug.
-+       */
-+      mp_register_lapic(processor->id,        /* APIC ID */
-+                        processor->flags.enabled);    /* Enabled? */
-+
-+      return 0;
-+}
-+
-+static int __init
-+acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header,
-+                        const unsigned long end)
-+{
-+      struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
-+
-+      lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header;
-+
-+      if (BAD_MADT_ENTRY(lapic_addr_ovr, end))
-+              return -EINVAL;
-+
-+      acpi_lapic_addr = lapic_addr_ovr->address;
-+
-+      return 0;
-+}
-+
-+static int __init
-+acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end)
-+{
-+      struct acpi_table_lapic_nmi *lapic_nmi = NULL;
-+
-+      lapic_nmi = (struct acpi_table_lapic_nmi *)header;
-+
-+      if (BAD_MADT_ENTRY(lapic_nmi, end))
-+              return -EINVAL;
-+
-+      acpi_table_print_madt_entry(header);
-+
-+      if (lapic_nmi->lint != 1)
-+              printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
-+
-+      return 0;
-+}
-+
-+#endif                                /*CONFIG_X86_LOCAL_APIC */
-+
-+#ifdef CONFIG_X86_IO_APIC
-+
-+static int __init
-+acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end)
-+{
-+      struct acpi_table_ioapic *ioapic = NULL;
-+
-+      ioapic = (struct acpi_table_ioapic *)header;
-+
-+      if (BAD_MADT_ENTRY(ioapic, end))
-+              return -EINVAL;
-+
-+      acpi_table_print_madt_entry(header);
-+
-+      mp_register_ioapic(ioapic->id,
-+                         ioapic->address, ioapic->global_irq_base);
-+
-+      return 0;
-+}
-+
-+/*
-+ * Parse Interrupt Source Override for the ACPI SCI
-+ */
-+static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
-+{
-+      if (trigger == 0)       /* compatible SCI trigger is level */
-+              trigger = 3;
-+
-+      if (polarity == 0)      /* compatible SCI polarity is low */
-+              polarity = 3;
-+
-+      /* Command-line over-ride via acpi_sci= */
-+      if (acpi_sci_flags.trigger)
-+              trigger = acpi_sci_flags.trigger;
-+
-+      if (acpi_sci_flags.polarity)
-+              polarity = acpi_sci_flags.polarity;
-+
-+      /*
-+       * mp_config_acpi_legacy_irqs() already setup IRQs < 16
-+       * If GSI is < 16, this will update its flags,
-+       * else it will create a new mp_irqs[] entry.
-+       */
-+      mp_override_legacy_irq(gsi, polarity, trigger, gsi);
-+
-+      /*
-+       * stash over-ride to indicate we've been here
-+       * and for later update of acpi_fadt
-+       */
-+      acpi_sci_override_gsi = gsi;
-+      return;
-+}
-+
-+static int __init
-+acpi_parse_int_src_ovr(acpi_table_entry_header * header,
-+                     const unsigned long end)
-+{
-+      struct acpi_table_int_src_ovr *intsrc = NULL;
-+
-+      intsrc = (struct acpi_table_int_src_ovr *)header;
-+
-+      if (BAD_MADT_ENTRY(intsrc, end))
-+              return -EINVAL;
-+
-+      acpi_table_print_madt_entry(header);
-+
-+      if (intsrc->bus_irq == acpi_fadt.sci_int) {
-+              acpi_sci_ioapic_setup(intsrc->global_irq,
-+                                    intsrc->flags.polarity,
-+                                    intsrc->flags.trigger);
-+              return 0;
-+      }
-+
-+      if (acpi_skip_timer_override &&
-+          intsrc->bus_irq == 0 && intsrc->global_irq == 2) {
-+              printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
-+              return 0;
-+      }
-+
-+      mp_override_legacy_irq(intsrc->bus_irq,
-+                             intsrc->flags.polarity,
-+                             intsrc->flags.trigger, intsrc->global_irq);
-+
-+      return 0;
-+}
-+
-+static int __init
-+acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end)
-+{
-+      struct acpi_table_nmi_src *nmi_src = NULL;
-+
-+      nmi_src = (struct acpi_table_nmi_src *)header;
-+
-+      if (BAD_MADT_ENTRY(nmi_src, end))
-+              return -EINVAL;
-+
-+      acpi_table_print_madt_entry(header);
-+
-+      /* TBD: Support nimsrc entries? */
-+
-+      return 0;
-+}
-+
-+#endif                                /* CONFIG_X86_IO_APIC */
-+
-+/*
-+ * acpi_pic_sci_set_trigger()
-+ * 
-+ * use ELCR to set PIC-mode trigger type for SCI
-+ *
-+ * If a PIC-mode SCI is not recognized or gives spurious IRQ7's
-+ * it may require Edge Trigger -- use "acpi_sci=edge"
-+ *
-+ * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
-+ * for the 8259 PIC.  bit[n] = 1 means irq[n] is Level, otherwise Edge.
-+ * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0)
-+ * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
-+ */
-+
-+void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
-+{
-+      unsigned int mask = 1 << irq;
-+      unsigned int old, new;
-+
-+      /* Real old ELCR mask */
-+      old = inb(0x4d0) | (inb(0x4d1) << 8);
-+
-+      /*
-+       * If we use ACPI to set PCI irq's, then we should clear ELCR
-+       * since we will set it correctly as we enable the PCI irq
-+       * routing.
-+       */
-+      new = acpi_noirq ? old : 0;
-+
-+      /*
-+       * Update SCI information in the ELCR, it isn't in the PCI
-+       * routing tables..
-+       */
-+      switch (trigger) {
-+      case 1:         /* Edge - clear */
-+              new &= ~mask;
-+              break;
-+      case 3:         /* Level - set */
-+              new |= mask;
-+              break;
-+      }
-+
-+      if (old == new)
-+              return;
-+
-+      printk(PREFIX "setting ELCR to %04x (from %04x)\n", new, old);
-+      outb(new, 0x4d0);
-+      outb(new >> 8, 0x4d1);
-+}
-+
-+int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
-+{
-+#ifdef CONFIG_X86_IO_APIC
-+      if (use_pci_vector() && !platform_legacy_irq(gsi))
-+              *irq = IO_APIC_VECTOR(gsi);
-+      else
-+#endif
-+              *irq = gsi_irq_sharing(gsi);
-+      return 0;
-+}
-+
-+/*
-+ * success: return IRQ number (>=0)
-+ * failure: return < 0
-+ */
-+int acpi_register_gsi(u32 gsi, int triggering, int polarity)
-+{
-+      unsigned int irq;
-+      unsigned int plat_gsi = gsi;
-+
-+#ifdef CONFIG_PCI
-+      /*
-+       * Make sure all (legacy) PCI IRQs are set as level-triggered.
-+       */
-+      if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
-+              extern void eisa_set_level_irq(unsigned int irq);
-+
-+              if (triggering == ACPI_LEVEL_SENSITIVE)
-+                      eisa_set_level_irq(gsi);
-+      }
-+#endif
-+
-+#ifdef CONFIG_X86_IO_APIC
-+      if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
-+              plat_gsi = mp_register_gsi(gsi, triggering, polarity);
-+      }
-+#endif
-+      acpi_gsi_to_irq(plat_gsi, &irq);
-+      return irq;
-+}
-+
-+EXPORT_SYMBOL(acpi_register_gsi);
-+
-+/*
-+ *  ACPI based hotplug support for CPU
-+ */
-+#ifdef CONFIG_ACPI_HOTPLUG_CPU
-+int acpi_map_lsapic(acpi_handle handle, int *pcpu)
-+{
-+      /* TBD */
-+      return -EINVAL;
-+}
-+
-+EXPORT_SYMBOL(acpi_map_lsapic);
-+
-+int acpi_unmap_lsapic(int cpu)
-+{
-+      /* TBD */
-+      return -EINVAL;
-+}
-+
-+EXPORT_SYMBOL(acpi_unmap_lsapic);
-+#endif                                /* CONFIG_ACPI_HOTPLUG_CPU */
-+
-+int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
-+{
-+      /* TBD */
-+      return -EINVAL;
-+}
-+
-+EXPORT_SYMBOL(acpi_register_ioapic);
-+
-+int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
-+{
-+      /* TBD */
-+      return -EINVAL;
-+}
-+
-+EXPORT_SYMBOL(acpi_unregister_ioapic);
-+
-+static unsigned long __init
-+acpi_scan_rsdp(unsigned long start, unsigned long length)
-+{
-+      unsigned long offset = 0;
-+      unsigned long sig_len = sizeof("RSD PTR ") - 1;
-+      unsigned long vstart = (unsigned long)isa_bus_to_virt(start);
-+
-+      /*
-+       * Scan all 16-byte boundaries of the physical memory region for the
-+       * RSDP signature.
-+       */
-+      for (offset = 0; offset < length; offset += 16) {
-+              if (strncmp((char *)(vstart + offset), "RSD PTR ", sig_len))
-+                      continue;
-+              return (start + offset);
-+      }
-+
-+      return 0;
-+}
-+
-+static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size)
-+{
-+      struct acpi_table_sbf *sb;
-+
-+      if (!phys_addr || !size)
-+              return -EINVAL;
-+
-+      sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size);
-+      if (!sb) {
-+              printk(KERN_WARNING PREFIX "Unable to map SBF\n");
-+              return -ENODEV;
-+      }
-+
-+      sbf_port = sb->sbf_cmos;        /* Save CMOS port */
-+
-+      return 0;
-+}
-+
-+#ifdef CONFIG_HPET_TIMER
-+
-+static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
-+{
-+      struct acpi_table_hpet *hpet_tbl;
-+
-+      if (!phys || !size)
-+              return -EINVAL;
-+
-+      hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size);
-+      if (!hpet_tbl) {
-+              printk(KERN_WARNING PREFIX "Unable to map HPET\n");
-+              return -ENODEV;
-+      }
-+
-+      if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) {
-+              printk(KERN_WARNING PREFIX "HPET timers must be located in "
-+                     "memory.\n");
-+              return -1;
-+      }
-+#ifdef        CONFIG_X86_64
-+      vxtime.hpet_address = hpet_tbl->addr.addrl |
-+          ((long)hpet_tbl->addr.addrh << 32);
-+
-+      printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
-+             hpet_tbl->id, vxtime.hpet_address);
-+#else                         /* X86 */
-+      {
-+              extern unsigned long hpet_address;
-+
-+              hpet_address = hpet_tbl->addr.addrl;
-+              printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
-+                     hpet_tbl->id, hpet_address);
-+      }
-+#endif                                /* X86 */
-+
-+      return 0;
-+}
-+#else
-+#define       acpi_parse_hpet NULL
-+#endif
-+
-+#ifdef CONFIG_X86_PM_TIMER
-+extern u32 pmtmr_ioport;
-+#endif
-+
-+static int __init acpi_parse_fadt(unsigned long phys, unsigned long size)
-+{
-+      struct fadt_descriptor_rev2 *fadt = NULL;
-+
-+      fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size);
-+      if (!fadt) {
-+              printk(KERN_WARNING PREFIX "Unable to map FADT\n");
-+              return 0;
-+      }
-+      /* initialize sci_int early for INT_SRC_OVR MADT parsing */
-+      acpi_fadt.sci_int = fadt->sci_int;
-+
-+      /* initialize rev and apic_phys_dest_mode for x86_64 genapic */
-+      acpi_fadt.revision = fadt->revision;
-+      acpi_fadt.force_apic_physical_destination_mode =
-+          fadt->force_apic_physical_destination_mode;
-+
-+#if defined(CONFIG_X86_PM_TIMER) && !defined(CONFIG_XEN)
-+      /* detect the location of the ACPI PM Timer */
-+      if (fadt->revision >= FADT2_REVISION_ID) {
-+              /* FADT rev. 2 */
-+              if (fadt->xpm_tmr_blk.address_space_id !=
-+                  ACPI_ADR_SPACE_SYSTEM_IO)
-+                      return 0;
-+
-+              pmtmr_ioport = fadt->xpm_tmr_blk.address;
-+              /*
-+               * "X" fields are optional extensions to the original V1.0
-+               * fields, so we must selectively expand V1.0 fields if the
-+               * corresponding X field is zero.
-+               */
-+              if (!pmtmr_ioport)
-+                      pmtmr_ioport = fadt->V1_pm_tmr_blk;
-+      } else {
-+              /* FADT rev. 1 */
-+              pmtmr_ioport = fadt->V1_pm_tmr_blk;
-+      }
-+      if (pmtmr_ioport)
-+              printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n",
-+                     pmtmr_ioport);
-+#endif
-+      return 0;
-+}
-+
-+unsigned long __init acpi_find_rsdp(void)
-+{
-+      unsigned long rsdp_phys = 0;
-+
-+      if (efi_enabled) {
-+              if (efi.acpi20)
-+                      return __pa(efi.acpi20);
-+              else if (efi.acpi)
-+                      return __pa(efi.acpi);
-+      }
-+      /*
-+       * Scan memory looking for the RSDP signature. First search EBDA (low
-+       * memory) paragraphs and then search upper memory (E0000-FFFFF).
-+       */
-+      rsdp_phys = acpi_scan_rsdp(0, 0x400);
-+      if (!rsdp_phys)
-+              rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000);
-+
-+      return rsdp_phys;
-+}
-+
-+#ifdef        CONFIG_X86_LOCAL_APIC
-+/*
-+ * Parse LAPIC entries in MADT
-+ * returns 0 on success, < 0 on error
-+ */
-+static int __init acpi_parse_madt_lapic_entries(void)
-+{
-+      int count;
-+
-+      /* 
-+       * Note that the LAPIC address is obtained from the MADT (32-bit value)
-+       * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
-+       */
-+
-+      count =
-+          acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
-+                                acpi_parse_lapic_addr_ovr, 0);
-+      if (count < 0) {
-+              printk(KERN_ERR PREFIX
-+                     "Error parsing LAPIC address override entry\n");
-+              return count;
-+      }
-+
-+      mp_register_lapic_address(acpi_lapic_addr);
-+
-+      count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
-+                                    MAX_APICS);
-+      if (!count) {
-+              printk(KERN_ERR PREFIX "No LAPIC entries present\n");
-+              /* TBD: Cleanup to allow fallback to MPS */
-+              return -ENODEV;
-+      } else if (count < 0) {
-+              printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
-+              /* TBD: Cleanup to allow fallback to MPS */
-+              return count;
-+      }
-+
-+      count =
-+          acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
-+      if (count < 0) {
-+              printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
-+              /* TBD: Cleanup to allow fallback to MPS */
-+              return count;
-+      }
-+      return 0;
-+}
-+#endif                                /* CONFIG_X86_LOCAL_APIC */
-+
-+#ifdef        CONFIG_X86_IO_APIC
-+/*
-+ * Parse IOAPIC related entries in MADT
-+ * returns 0 on success, < 0 on error
-+ */
-+static int __init acpi_parse_madt_ioapic_entries(void)
-+{
-+      int count;
-+
-+      /*
-+       * ACPI interpreter is required to complete interrupt setup,
-+       * so if it is off, don't enumerate the io-apics with ACPI.
-+       * If MPS is present, it will handle them,
-+       * otherwise the system will stay in PIC mode
-+       */
-+      if (acpi_disabled || acpi_noirq) {
-+              return -ENODEV;
-+      }
-+
-+      /*
-+       * if "noapic" boot option, don't look for IO-APICs
-+       */
-+      if (skip_ioapic_setup) {
-+              printk(KERN_INFO PREFIX "Skipping IOAPIC probe "
-+                     "due to 'noapic' option.\n");
-+              return -ENODEV;
-+      }
-+
-+      count =
-+          acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic,
-+                                MAX_IO_APICS);
-+      if (!count) {
-+              printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
-+              return -ENODEV;
-+      } else if (count < 0) {
-+              printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
-+              return count;
-+      }
-+
-+      count =
-+          acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr,
-+                                NR_IRQ_VECTORS);
-+      if (count < 0) {
-+              printk(KERN_ERR PREFIX
-+                     "Error parsing interrupt source overrides entry\n");
-+              /* TBD: Cleanup to allow fallback to MPS */
-+              return count;
-+      }
-+
-+      /*
-+       * If BIOS did not supply an INT_SRC_OVR for the SCI
-+       * pretend we got one so we can set the SCI flags.
-+       */
-+      if (!acpi_sci_override_gsi)
-+              acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0);
-+
-+      /* Fill in identity legacy mapings where no override */
-+      mp_config_acpi_legacy_irqs();
-+
-+      count =
-+          acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src,
-+                                NR_IRQ_VECTORS);
-+      if (count < 0) {
-+              printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
-+              /* TBD: Cleanup to allow fallback to MPS */
-+              return count;
-+      }
-+
-+      return 0;
-+}
-+#else
-+static inline int acpi_parse_madt_ioapic_entries(void)
-+{
-+      return -1;
-+}
-+#endif        /* !CONFIG_X86_IO_APIC */
-+
-+static void __init acpi_process_madt(void)
-+{
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      int count, error;
-+
-+      count = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
-+      if (count >= 1) {
-+
-+              /*
-+               * Parse MADT LAPIC entries
-+               */
-+              error = acpi_parse_madt_lapic_entries();
-+              if (!error) {
-+                      acpi_lapic = 1;
-+
-+#ifdef CONFIG_X86_GENERICARCH
-+                      generic_bigsmp_probe();
-+#endif
-+                      /*
-+                       * Parse MADT IO-APIC entries
-+                       */
-+                      error = acpi_parse_madt_ioapic_entries();
-+                      if (!error) {
-+                              acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
-+                              acpi_irq_balance_set(NULL);
-+                              acpi_ioapic = 1;
-+
-+                              smp_found_config = 1;
-+                              clustered_apic_check();
-+                      }
-+              }
-+              if (error == -EINVAL) {
-+                      /*
-+                       * Dell Precision Workstation 410, 610 come here.
-+                       */
-+                      printk(KERN_ERR PREFIX
-+                             "Invalid BIOS MADT, disabling ACPI\n");
-+                      disable_acpi();
-+              }
-+      }
-+#endif
-+      return;
-+}
-+
-+extern int acpi_force;
-+
-+#ifdef __i386__
-+
-+static int __init disable_acpi_irq(struct dmi_system_id *d)
-+{
-+      if (!acpi_force) {
-+              printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
-+                     d->ident);
-+              acpi_noirq_set();
-+      }
-+      return 0;
-+}
-+
-+static int __init disable_acpi_pci(struct dmi_system_id *d)
-+{
-+      if (!acpi_force) {
-+              printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
-+                     d->ident);
-+              acpi_disable_pci();
-+      }
-+      return 0;
-+}
-+
-+static int __init dmi_disable_acpi(struct dmi_system_id *d)
-+{
-+      if (!acpi_force) {
-+              printk(KERN_NOTICE "%s detected: acpi off\n", d->ident);
-+              disable_acpi();
-+      } else {
-+              printk(KERN_NOTICE
-+                     "Warning: DMI blacklist says broken, but acpi forced\n");
-+      }
-+      return 0;
-+}
-+
-+/*
-+ * Limit ACPI to CPU enumeration for HT
-+ */
-+static int __init force_acpi_ht(struct dmi_system_id *d)
-+{
-+      if (!acpi_force) {
-+              printk(KERN_NOTICE "%s detected: force use of acpi=ht\n",
-+                     d->ident);
-+              disable_acpi();
-+              acpi_ht = 1;
-+      } else {
-+              printk(KERN_NOTICE
-+                     "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
-+      }
-+      return 0;
-+}
-+
-+/*
-+ * If your system is blacklisted here, but you find that acpi=force
-+ * works for you, please contact acpi-devel@sourceforge.net
-+ */
-+static struct dmi_system_id __initdata acpi_dmi_table[] = {
-+      /*
-+       * Boxes that need ACPI disabled
-+       */
-+      {
-+       .callback = dmi_disable_acpi,
-+       .ident = "IBM Thinkpad",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-+                   DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
-+                   },
-+       },
-+
-+      /*
-+       * Boxes that need acpi=ht
-+       */
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "FSC Primergy T850",
-+       .matches = {
-+                   DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-+                   DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "DELL GX240",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
-+                   DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "HP VISUALIZE NT Workstation",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-+                   DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "Compaq Workstation W8000",
-+       .matches = {
-+                   DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
-+                   DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "ASUS P4B266",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-+                   DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "ASUS P2B-DS",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-+                   DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "ASUS CUR-DLS",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-+                   DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "ABIT i440BX-W83977",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
-+                   DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "IBM Bladecenter",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-+                   DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "IBM eServer xSeries 360",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-+                   DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "IBM eserver xSeries 330",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-+                   DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
-+                   },
-+       },
-+      {
-+       .callback = force_acpi_ht,
-+       .ident = "IBM eserver xSeries 440",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
-+                   DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
-+                   },
-+       },
-+
-+      /*
-+       * Boxes that need ACPI PCI IRQ routing disabled
-+       */
-+      {
-+       .callback = disable_acpi_irq,
-+       .ident = "ASUS A7V",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
-+                   DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
-+                   /* newer BIOS, Revision 1011, does work */
-+                   DMI_MATCH(DMI_BIOS_VERSION,
-+                             "ASUS A7V ACPI BIOS Revision 1007"),
-+                   },
-+       },
-+
-+      /*
-+       * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
-+       */
-+      {                       /* _BBN 0 bug */
-+       .callback = disable_acpi_pci,
-+       .ident = "ASUS PR-DLS",
-+       .matches = {
-+                   DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-+                   DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
-+                   DMI_MATCH(DMI_BIOS_VERSION,
-+                             "ASUS PR-DLS ACPI BIOS Revision 1010"),
-+                   DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
-+                   },
-+       },
-+      {
-+       .callback = disable_acpi_pci,
-+       .ident = "Acer TravelMate 36x Laptop",
-+       .matches = {
-+                   DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-+                   DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
-+                   },
-+       },
-+      {}
-+};
-+
-+#endif                                /* __i386__ */
-+
-+/*
-+ * acpi_boot_table_init() and acpi_boot_init()
-+ *  called from setup_arch(), always.
-+ *    1. checksums all tables
-+ *    2. enumerates lapics
-+ *    3. enumerates io-apics
-+ *
-+ * acpi_table_init() is separate to allow reading SRAT without
-+ * other side effects.
-+ *
-+ * side effects of acpi_boot_init:
-+ *    acpi_lapic = 1 if LAPIC found
-+ *    acpi_ioapic = 1 if IOAPIC found
-+ *    if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
-+ *    if acpi_blacklisted() acpi_disabled = 1;
-+ *    acpi_irq_model=...
-+ *    ...
-+ *
-+ * return value: (currently ignored)
-+ *    0: success
-+ *    !0: failure
-+ */
-+
-+int __init acpi_boot_table_init(void)
-+{
-+      int error;
-+
-+#ifdef __i386__
-+      dmi_check_system(acpi_dmi_table);
-+#endif
-+
-+      /*
-+       * If acpi_disabled, bail out
-+       * One exception: acpi=ht continues far enough to enumerate LAPICs
-+       */
-+      if (acpi_disabled && !acpi_ht)
-+              return 1;
-+
-+      /* 
-+       * Initialize the ACPI boot-time table parser.
-+       */
-+      error = acpi_table_init();
-+      if (error) {
-+              disable_acpi();
-+              return error;
-+      }
-+
-+      acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
-+
-+      /*
-+       * blacklist may disable ACPI entirely
-+       */
-+      error = acpi_blacklisted();
-+      if (error) {
-+              if (acpi_force) {
-+                      printk(KERN_WARNING PREFIX "acpi=force override\n");
-+              } else {
-+                      printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
-+                      disable_acpi();
-+                      return error;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+int __init acpi_boot_init(void)
-+{
-+      /*
-+       * If acpi_disabled, bail out
-+       * One exception: acpi=ht continues far enough to enumerate LAPICs
-+       */
-+      if (acpi_disabled && !acpi_ht)
-+              return 1;
-+
-+      acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
-+
-+      /*
-+       * set sci_int and PM timer address
-+       */
-+      acpi_table_parse(ACPI_FADT, acpi_parse_fadt);
-+
-+      /*
-+       * Process the Multiple APIC Description Table (MADT), if present
-+       */
-+      acpi_process_madt();
-+
-+      acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
-+
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/apic-xen.c linux-2.6.16.33/arch/i386/kernel/apic-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/apic-xen.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/apic-xen.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,140 @@
-+/*
-+ *    Local APIC handling, local APIC timers
-+ *
-+ *    (c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
-+ *
-+ *    Fixes
-+ *    Maciej W. Rozycki       :       Bits for genuine 82489DX APICs;
-+ *                                    thanks to Eric Gilmore
-+ *                                    and Rolf G. Tews
-+ *                                    for testing these extensively.
-+ *    Maciej W. Rozycki       :       Various updates and fixes.
-+ *    Mikael Pettersson       :       Power Management for UP-APIC.
-+ *    Pavel Machek and
-+ *    Mikael Pettersson       :       PM converted to driver model.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+
-+#include <linux/mm.h>
-+#include <linux/delay.h>
-+#include <linux/bootmem.h>
-+#include <linux/smp_lock.h>
-+#include <linux/interrupt.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/sysdev.h>
-+#include <linux/cpu.h>
-+#include <linux/module.h>
-+
-+#include <asm/atomic.h>
-+#include <asm/smp.h>
-+#include <asm/mtrr.h>
-+#include <asm/mpspec.h>
-+#include <asm/desc.h>
-+#include <asm/arch_hooks.h>
-+#include <asm/hpet.h>
-+#include <asm/i8253.h>
-+
-+#include <mach_apic.h>
-+#include <mach_ipi.h>
-+
-+#include "io_ports.h"
-+
-+#ifndef CONFIG_XEN
-+/*
-+ * cpu_mask that denotes the CPUs that needs timer interrupt coming in as
-+ * IPIs in place of local APIC timers
-+ */
-+static cpumask_t timer_bcast_ipi;
-+#endif
-+
-+/*
-+ * Knob to control our willingness to enable the local APIC.
-+ */
-+int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
-+
-+/*
-+ * Debug level
-+ */
-+int apic_verbosity;
-+
-+/*
-+ * 'what should we do if we get a hw irq event on an illegal vector'.
-+ * each architecture has to answer this themselves.
-+ */
-+void ack_bad_irq(unsigned int irq)
-+{
-+      printk("unexpected IRQ trap at vector %02x\n", irq);
-+      /*
-+       * Currently unexpected vectors happen only on SMP and APIC.
-+       * We _must_ ack these because every local APIC has only N
-+       * irq slots per priority level, and a 'hanging, unacked' IRQ
-+       * holds up an irq slot - in excessive cases (when multiple
-+       * unexpected vectors occur) that might lock up the APIC
-+       * completely.
-+       * But only ack when the APIC is enabled -AK
-+       */
-+      if (cpu_has_apic)
-+              ack_APIC_irq();
-+}
-+
-+int get_physical_broadcast(void)
-+{
-+        return 0xff;
-+}
-+
-+#ifndef CONFIG_XEN
-+#ifndef CONFIG_SMP
-+static void up_apic_timer_interrupt_call(struct pt_regs *regs)
-+{
-+      int cpu = smp_processor_id();
-+
-+      /*
-+       * the NMI deadlock-detector uses this.
-+       */
-+      per_cpu(irq_stat, cpu).apic_timer_irqs++;
-+
-+      smp_local_timer_interrupt(regs);
-+}
-+#endif
-+
-+void smp_send_timer_broadcast_ipi(struct pt_regs *regs)
-+{
-+      cpumask_t mask;
-+
-+      cpus_and(mask, cpu_online_map, timer_bcast_ipi);
-+      if (!cpus_empty(mask)) {
-+#ifdef CONFIG_SMP
-+              send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
-+#else
-+              /*
-+               * We can directly call the apic timer interrupt handler
-+               * in UP case. Minus all irq related functions
-+               */
-+              up_apic_timer_interrupt_call(regs);
-+#endif
-+      }
-+}
-+#endif
-+
-+int setup_profiling_timer(unsigned int multiplier)
-+{
-+      return -EINVAL;
-+}
-+
-+/*
-+ * This initializes the IO-APIC and APIC hardware if this is
-+ * a UP kernel.
-+ */
-+int __init APIC_init_uniprocessor (void)
-+{
-+#ifdef CONFIG_X86_IO_APIC
-+      if (smp_found_config)
-+              if (!skip_ioapic_setup && nr_ioapics)
-+                      setup_IO_APIC();
-+#endif
-+
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/asm-offsets.c linux-2.6.16.33/arch/i386/kernel/asm-offsets.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/asm-offsets.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/asm-offsets.c     2007-01-08 15:00:45.000000000 +0000
-@@ -13,6 +13,7 @@
- #include <asm/fixmap.h>
- #include <asm/processor.h>
- #include <asm/thread_info.h>
-+#include <asm/elf.h>
- #define DEFINE(sym, val) \
-         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-@@ -63,10 +64,15 @@
-       OFFSET(pbe_orig_address, pbe, orig_address);
-       OFFSET(pbe_next, pbe, next);
-+#ifndef CONFIG_X86_NO_TSS
-       /* Offset from the sysenter stack to tss.esp0 */
--      DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) -
-+      DEFINE(SYSENTER_stack_esp0, offsetof(struct tss_struct, esp0) -
-                sizeof(struct tss_struct));
-+#else
-+      /* sysenter stack points directly to esp0 */
-+      DEFINE(SYSENTER_stack_esp0, 0);
-+#endif
-       DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
--      DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
-+      DEFINE(VSYSCALL_BASE, VSYSCALL_BASE);
- }
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/cpu/Makefile linux-2.6.16.33/arch/i386/kernel/cpu/Makefile
---- linux-2.6.16.33-noxen/arch/i386/kernel/cpu/Makefile        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/cpu/Makefile      2007-01-08 15:00:45.000000000 +0000
-@@ -17,3 +17,8 @@
- obj-$(CONFIG_MTRR)    +=      mtrr/
- obj-$(CONFIG_CPU_FREQ)        +=      cpufreq/
-+
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+obj-y := $(call cherrypickxen, $(obj-y), $(src))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/cpu/common-xen.c linux-2.6.16.33/arch/i386/kernel/cpu/common-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/cpu/common-xen.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/cpu/common-xen.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,715 @@
-+#include <linux/init.h>
-+#include <linux/string.h>
-+#include <linux/delay.h>
-+#include <linux/smp.h>
-+#include <linux/module.h>
-+#include <linux/percpu.h>
-+#include <linux/bootmem.h>
-+#include <asm/semaphore.h>
-+#include <asm/processor.h>
-+#include <asm/i387.h>
-+#include <asm/msr.h>
-+#include <asm/io.h>
-+#include <asm/mmu_context.h>
-+#ifdef CONFIG_X86_LOCAL_APIC
-+#include <asm/mpspec.h>
-+#include <asm/apic.h>
-+#include <mach_apic.h>
-+#endif
-+#include <asm/hypervisor.h>
-+
-+#include "cpu.h"
-+
-+DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
-+EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
-+
-+#ifndef CONFIG_XEN
-+DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
-+EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
-+#endif
-+
-+static int cachesize_override __devinitdata = -1;
-+static int disable_x86_fxsr __devinitdata = 0;
-+static int disable_x86_serial_nr __devinitdata = 1;
-+
-+struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
-+
-+extern int disable_pse;
-+
-+static void default_init(struct cpuinfo_x86 * c)
-+{
-+      /* Not much we can do here... */
-+      /* Check if at least it has cpuid */
-+      if (c->cpuid_level == -1) {
-+              /* No cpuid. It must be an ancient CPU */
-+              if (c->x86 == 4)
-+                      strcpy(c->x86_model_id, "486");
-+              else if (c->x86 == 3)
-+                      strcpy(c->x86_model_id, "386");
-+      }
-+}
-+
-+static struct cpu_dev default_cpu = {
-+      .c_init = default_init,
-+      .c_vendor = "Unknown",
-+};
-+static struct cpu_dev * this_cpu = &default_cpu;
-+
-+static int __init cachesize_setup(char *str)
-+{
-+      get_option (&str, &cachesize_override);
-+      return 1;
-+}
-+__setup("cachesize=", cachesize_setup);
-+
-+int __devinit get_model_name(struct cpuinfo_x86 *c)
-+{
-+      unsigned int *v;
-+      char *p, *q;
-+
-+      if (cpuid_eax(0x80000000) < 0x80000004)
-+              return 0;
-+
-+      v = (unsigned int *) c->x86_model_id;
-+      cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
-+      cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
-+      cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
-+      c->x86_model_id[48] = 0;
-+
-+      /* Intel chips right-justify this string for some dumb reason;
-+         undo that brain damage */
-+      p = q = &c->x86_model_id[0];
-+      while ( *p == ' ' )
-+           p++;
-+      if ( p != q ) {
-+           while ( *p )
-+                *q++ = *p++;
-+           while ( q <= &c->x86_model_id[48] )
-+                *q++ = '\0';  /* Zero-pad the rest */
-+      }
-+
-+      return 1;
-+}
-+
-+
-+void __devinit display_cacheinfo(struct cpuinfo_x86 *c)
-+{
-+      unsigned int n, dummy, ecx, edx, l2size;
-+
-+      n = cpuid_eax(0x80000000);
-+
-+      if (n >= 0x80000005) {
-+              cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
-+              printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
-+                      edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
-+              c->x86_cache_size=(ecx>>24)+(edx>>24);  
-+      }
-+
-+      if (n < 0x80000006)     /* Some chips just has a large L1. */
-+              return;
-+
-+      ecx = cpuid_ecx(0x80000006);
-+      l2size = ecx >> 16;
-+      
-+      /* do processor-specific cache resizing */
-+      if (this_cpu->c_size_cache)
-+              l2size = this_cpu->c_size_cache(c,l2size);
-+
-+      /* Allow user to override all this if necessary. */
-+      if (cachesize_override != -1)
-+              l2size = cachesize_override;
-+
-+      if ( l2size == 0 )
-+              return;         /* Again, no L2 cache is possible */
-+
-+      c->x86_cache_size = l2size;
-+
-+      printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
-+             l2size, ecx & 0xFF);
-+}
-+
-+/* Naming convention should be: <Name> [(<Codename>)] */
-+/* This table only is used unless init_<vendor>() below doesn't set it; */
-+/* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */
-+
-+/* Look up CPU names by table lookup. */
-+static char __devinit *table_lookup_model(struct cpuinfo_x86 *c)
-+{
-+      struct cpu_model_info *info;
-+
-+      if ( c->x86_model >= 16 )
-+              return NULL;    /* Range check */
-+
-+      if (!this_cpu)
-+              return NULL;
-+
-+      info = this_cpu->c_models;
-+
-+      while (info && info->family) {
-+              if (info->family == c->x86)
-+                      return info->model_names[c->x86_model];
-+              info++;
-+      }
-+      return NULL;            /* Not found */
-+}
-+
-+
-+static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
-+{
-+      char *v = c->x86_vendor_id;
-+      int i;
-+      static int printed;
-+
-+      for (i = 0; i < X86_VENDOR_NUM; i++) {
-+              if (cpu_devs[i]) {
-+                      if (!strcmp(v,cpu_devs[i]->c_ident[0]) ||
-+                          (cpu_devs[i]->c_ident[1] && 
-+                           !strcmp(v,cpu_devs[i]->c_ident[1]))) {
-+                              c->x86_vendor = i;
-+                              if (!early)
-+                                      this_cpu = cpu_devs[i];
-+                              return;
-+                      }
-+              }
-+      }
-+      if (!printed) {
-+              printed++;
-+              printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n");
-+              printk(KERN_ERR "CPU: Your system may be unstable.\n");
-+      }
-+      c->x86_vendor = X86_VENDOR_UNKNOWN;
-+      this_cpu = &default_cpu;
-+}
-+
-+
-+static int __init x86_fxsr_setup(char * s)
-+{
-+      disable_x86_fxsr = 1;
-+      return 1;
-+}
-+__setup("nofxsr", x86_fxsr_setup);
-+
-+
-+/* Standard macro to see if a specific flag is changeable */
-+static inline int flag_is_changeable_p(u32 flag)
-+{
-+      u32 f1, f2;
-+
-+      asm("pushfl\n\t"
-+          "pushfl\n\t"
-+          "popl %0\n\t"
-+          "movl %0,%1\n\t"
-+          "xorl %2,%0\n\t"
-+          "pushl %0\n\t"
-+          "popfl\n\t"
-+          "pushfl\n\t"
-+          "popl %0\n\t"
-+          "popfl\n\t"
-+          : "=&r" (f1), "=&r" (f2)
-+          : "ir" (flag));
-+
-+      return ((f1^f2) & flag) != 0;
-+}
-+
-+
-+/* Probe for the CPUID instruction */
-+static int __devinit have_cpuid_p(void)
-+{
-+      return flag_is_changeable_p(X86_EFLAGS_ID);
-+}
-+
-+/* Do minimum CPU detection early.
-+   Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment.
-+   The others are not touched to avoid unwanted side effects.
-+
-+   WARNING: this function is only called on the BP.  Don't add code here
-+   that is supposed to run on all CPUs. */
-+static void __init early_cpu_detect(void)
-+{
-+      struct cpuinfo_x86 *c = &boot_cpu_data;
-+
-+      c->x86_cache_alignment = 32;
-+
-+      if (!have_cpuid_p())
-+              return;
-+
-+      /* Get vendor name */
-+      cpuid(0x00000000, &c->cpuid_level,
-+            (int *)&c->x86_vendor_id[0],
-+            (int *)&c->x86_vendor_id[8],
-+            (int *)&c->x86_vendor_id[4]);
-+
-+      get_cpu_vendor(c, 1);
-+
-+      c->x86 = 4;
-+      if (c->cpuid_level >= 0x00000001) {
-+              u32 junk, tfms, cap0, misc;
-+              cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
-+              c->x86 = (tfms >> 8) & 15;
-+              c->x86_model = (tfms >> 4) & 15;
-+              if (c->x86 == 0xf)
-+                      c->x86 += (tfms >> 20) & 0xff;
-+              if (c->x86 >= 0x6)
-+                      c->x86_model += ((tfms >> 16) & 0xF) << 4;
-+              c->x86_mask = tfms & 15;
-+              if (cap0 & (1<<19))
-+                      c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;
-+      }
-+}
-+
-+void __devinit generic_identify(struct cpuinfo_x86 * c)
-+{
-+      u32 tfms, xlvl;
-+      int junk;
-+
-+      if (have_cpuid_p()) {
-+              /* Get vendor name */
-+              cpuid(0x00000000, &c->cpuid_level,
-+                    (int *)&c->x86_vendor_id[0],
-+                    (int *)&c->x86_vendor_id[8],
-+                    (int *)&c->x86_vendor_id[4]);
-+              
-+              get_cpu_vendor(c, 0);
-+              /* Initialize the standard set of capabilities */
-+              /* Note that the vendor-specific code below might override */
-+      
-+              /* Intel-defined flags: level 0x00000001 */
-+              if ( c->cpuid_level >= 0x00000001 ) {
-+                      u32 capability, excap;
-+                      cpuid(0x00000001, &tfms, &junk, &excap, &capability);
-+                      c->x86_capability[0] = capability;
-+                      c->x86_capability[4] = excap;
-+                      c->x86 = (tfms >> 8) & 15;
-+                      c->x86_model = (tfms >> 4) & 15;
-+                      if (c->x86 == 0xf)
-+                              c->x86 += (tfms >> 20) & 0xff;
-+                      if (c->x86 >= 0x6)
-+                              c->x86_model += ((tfms >> 16) & 0xF) << 4;
-+                      c->x86_mask = tfms & 15;
-+              } else {
-+                      /* Have CPUID level 0 only - unheard of */
-+                      c->x86 = 4;
-+              }
-+
-+              /* AMD-defined flags: level 0x80000001 */
-+              xlvl = cpuid_eax(0x80000000);
-+              if ( (xlvl & 0xffff0000) == 0x80000000 ) {
-+                      if ( xlvl >= 0x80000001 ) {
-+                              c->x86_capability[1] = cpuid_edx(0x80000001);
-+                              c->x86_capability[6] = cpuid_ecx(0x80000001);
-+                      }
-+                      if ( xlvl >= 0x80000004 )
-+                              get_model_name(c); /* Default name */
-+              }
-+      }
-+
-+      early_intel_workaround(c);
-+
-+#ifdef CONFIG_X86_HT
-+      phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
-+#endif
-+}
-+
-+static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
-+{
-+      if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) {
-+              /* Disable processor serial number */
-+              unsigned long lo,hi;
-+              rdmsr(MSR_IA32_BBL_CR_CTL,lo,hi);
-+              lo |= 0x200000;
-+              wrmsr(MSR_IA32_BBL_CR_CTL,lo,hi);
-+              printk(KERN_NOTICE "CPU serial number disabled.\n");
-+              clear_bit(X86_FEATURE_PN, c->x86_capability);
-+
-+              /* Disabling the serial number may affect the cpuid level */
-+              c->cpuid_level = cpuid_eax(0);
-+      }
-+}
-+
-+static int __init x86_serial_nr_setup(char *s)
-+{
-+      disable_x86_serial_nr = 0;
-+      return 1;
-+}
-+__setup("serialnumber", x86_serial_nr_setup);
-+
-+
-+
-+/*
-+ * This does the hard work of actually picking apart the CPU stuff...
-+ */
-+void __devinit identify_cpu(struct cpuinfo_x86 *c)
-+{
-+      int i;
-+
-+      c->loops_per_jiffy = loops_per_jiffy;
-+      c->x86_cache_size = -1;
-+      c->x86_vendor = X86_VENDOR_UNKNOWN;
-+      c->cpuid_level = -1;    /* CPUID not detected */
-+      c->x86_model = c->x86_mask = 0; /* So far unknown... */
-+      c->x86_vendor_id[0] = '\0'; /* Unset */
-+      c->x86_model_id[0] = '\0';  /* Unset */
-+      c->x86_max_cores = 1;
-+      memset(&c->x86_capability, 0, sizeof c->x86_capability);
-+
-+      if (!have_cpuid_p()) {
-+              /* First of all, decide if this is a 486 or higher */
-+              /* It's a 486 if we can modify the AC flag */
-+              if ( flag_is_changeable_p(X86_EFLAGS_AC) )
-+                      c->x86 = 4;
-+              else
-+                      c->x86 = 3;
-+      }
-+
-+      generic_identify(c);
-+
-+      printk(KERN_DEBUG "CPU: After generic identify, caps:");
-+      for (i = 0; i < NCAPINTS; i++)
-+              printk(" %08lx", c->x86_capability[i]);
-+      printk("\n");
-+
-+      if (this_cpu->c_identify) {
-+              this_cpu->c_identify(c);
-+
-+              printk(KERN_DEBUG "CPU: After vendor identify, caps:");
-+              for (i = 0; i < NCAPINTS; i++)
-+                      printk(" %08lx", c->x86_capability[i]);
-+              printk("\n");
-+      }
-+
-+      /*
-+       * Vendor-specific initialization.  In this section we
-+       * canonicalize the feature flags, meaning if there are
-+       * features a certain CPU supports which CPUID doesn't
-+       * tell us, CPUID claiming incorrect flags, or other bugs,
-+       * we handle them here.
-+       *
-+       * At the end of this section, c->x86_capability better
-+       * indicate the features this CPU genuinely supports!
-+       */
-+      if (this_cpu->c_init)
-+              this_cpu->c_init(c);
-+
-+      /* Disable the PN if appropriate */
-+      squash_the_stupid_serial_number(c);
-+
-+      /*
-+       * The vendor-specific functions might have changed features.  Now
-+       * we do "generic changes."
-+       */
-+
-+      /* TSC disabled? */
-+      if ( tsc_disable )
-+              clear_bit(X86_FEATURE_TSC, c->x86_capability);
-+
-+      /* FXSR disabled? */
-+      if (disable_x86_fxsr) {
-+              clear_bit(X86_FEATURE_FXSR, c->x86_capability);
-+              clear_bit(X86_FEATURE_XMM, c->x86_capability);
-+      }
-+
-+      if (disable_pse)
-+              clear_bit(X86_FEATURE_PSE, c->x86_capability);
-+
-+      /* If the model name is still unset, do table lookup. */
-+      if ( !c->x86_model_id[0] ) {
-+              char *p;
-+              p = table_lookup_model(c);
-+              if ( p )
-+                      strcpy(c->x86_model_id, p);
-+              else
-+                      /* Last resort... */
-+                      sprintf(c->x86_model_id, "%02x/%02x",
-+                              c->x86_vendor, c->x86_model);
-+      }
-+
-+      /* Now the feature flags better reflect actual CPU features! */
-+
-+      printk(KERN_DEBUG "CPU: After all inits, caps:");
-+      for (i = 0; i < NCAPINTS; i++)
-+              printk(" %08lx", c->x86_capability[i]);
-+      printk("\n");
-+
-+      /*
-+       * On SMP, boot_cpu_data holds the common feature set between
-+       * all CPUs; so make sure that we indicate which features are
-+       * common between the CPUs.  The first time this routine gets
-+       * executed, c == &boot_cpu_data.
-+       */
-+      if ( c != &boot_cpu_data ) {
-+              /* AND the already accumulated flags with these */
-+              for ( i = 0 ; i < NCAPINTS ; i++ )
-+                      boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
-+      }
-+
-+      /* Init Machine Check Exception if available. */
-+      mcheck_init(c);
-+
-+      if (c == &boot_cpu_data)
-+              sysenter_setup();
-+      enable_sep_cpu();
-+
-+      if (c == &boot_cpu_data)
-+              mtrr_bp_init();
-+      else
-+              mtrr_ap_init();
-+}
-+
-+#ifdef CONFIG_X86_HT
-+void __devinit detect_ht(struct cpuinfo_x86 *c)
-+{
-+      u32     eax, ebx, ecx, edx;
-+      int     index_msb, core_bits;
-+      int     cpu = smp_processor_id();
-+
-+      cpuid(1, &eax, &ebx, &ecx, &edx);
-+
-+      c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
-+
-+      if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
-+              return;
-+
-+      smp_num_siblings = (ebx & 0xff0000) >> 16;
-+
-+      if (smp_num_siblings == 1) {
-+              printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
-+      } else if (smp_num_siblings > 1 ) {
-+
-+              if (smp_num_siblings > NR_CPUS) {
-+                      printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
-+                      smp_num_siblings = 1;
-+                      return;
-+              }
-+
-+              index_msb = get_count_order(smp_num_siblings);
-+              phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
-+
-+              printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
-+                     phys_proc_id[cpu]);
-+
-+              smp_num_siblings = smp_num_siblings / c->x86_max_cores;
-+
-+              index_msb = get_count_order(smp_num_siblings) ;
-+
-+              core_bits = get_count_order(c->x86_max_cores);
-+
-+              cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) &
-+                                             ((1 << core_bits) - 1);
-+
-+              if (c->x86_max_cores > 1)
-+                      printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
-+                             cpu_core_id[cpu]);
-+      }
-+}
-+#endif
-+
-+void __devinit print_cpu_info(struct cpuinfo_x86 *c)
-+{
-+      char *vendor = NULL;
-+
-+      if (c->x86_vendor < X86_VENDOR_NUM)
-+              vendor = this_cpu->c_vendor;
-+      else if (c->cpuid_level >= 0)
-+              vendor = c->x86_vendor_id;
-+
-+      if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor)))
-+              printk("%s ", vendor);
-+
-+      if (!c->x86_model_id[0])
-+              printk("%d86", c->x86);
-+      else
-+              printk("%s", c->x86_model_id);
-+
-+      if (c->x86_mask || c->cpuid_level >= 0) 
-+              printk(" stepping %02x\n", c->x86_mask);
-+      else
-+              printk("\n");
-+}
-+
-+cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
-+
-+/* This is hacky. :)
-+ * We're emulating future behavior.
-+ * In the future, the cpu-specific init functions will be called implicitly
-+ * via the magic of initcalls.
-+ * They will insert themselves into the cpu_devs structure.
-+ * Then, when cpu_init() is called, we can just iterate over that array.
-+ */
-+
-+extern int intel_cpu_init(void);
-+extern int cyrix_init_cpu(void);
-+extern int nsc_init_cpu(void);
-+extern int amd_init_cpu(void);
-+extern int centaur_init_cpu(void);
-+extern int transmeta_init_cpu(void);
-+extern int rise_init_cpu(void);
-+extern int nexgen_init_cpu(void);
-+extern int umc_init_cpu(void);
-+
-+void __init early_cpu_init(void)
-+{
-+      intel_cpu_init();
-+      cyrix_init_cpu();
-+      nsc_init_cpu();
-+      amd_init_cpu();
-+      centaur_init_cpu();
-+      transmeta_init_cpu();
-+      rise_init_cpu();
-+      nexgen_init_cpu();
-+      umc_init_cpu();
-+      early_cpu_detect();
-+
-+#ifdef CONFIG_DEBUG_PAGEALLOC
-+      /* pse is not compatible with on-the-fly unmapping,
-+       * disable it even if the cpus claim to support it.
-+       */
-+      clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
-+      disable_pse = 1;
-+#endif
-+}
-+
-+void __cpuinit cpu_gdt_init(struct Xgt_desc_struct *gdt_descr)
-+{
-+      unsigned long frames[16];
-+      unsigned long va;
-+      int f;
-+
-+      for (va = gdt_descr->address, f = 0;
-+           va < gdt_descr->address + gdt_descr->size;
-+           va += PAGE_SIZE, f++) {
-+              frames[f] = virt_to_mfn(va);
-+              make_lowmem_page_readonly(
-+                      (void *)va, XENFEAT_writable_descriptor_tables);
-+      }
-+      if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8))
-+              BUG();
-+}
-+
-+/*
-+ * cpu_init() initializes state that is per-CPU. Some data is already
-+ * initialized (naturally) in the bootstrap process, such as the GDT
-+ * and IDT. We reload them nevertheless, this function acts as a
-+ * 'CPU state barrier', nothing should get across.
-+ */
-+void __cpuinit cpu_init(void)
-+{
-+      int cpu = smp_processor_id();
-+#ifndef CONFIG_X86_NO_TSS
-+      struct tss_struct * t = &per_cpu(init_tss, cpu);
-+#endif
-+      struct thread_struct *thread = &current->thread;
-+      struct desc_struct *gdt;
-+      struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
-+
-+      if (cpu_test_and_set(cpu, cpu_initialized)) {
-+              printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
-+              for (;;) local_irq_enable();
-+      }
-+      printk(KERN_INFO "Initializing CPU#%d\n", cpu);
-+
-+      if (cpu_has_vme || cpu_has_de)
-+              clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
-+      if (tsc_disable && cpu_has_tsc) {
-+              printk(KERN_NOTICE "Disabling TSC...\n");
-+              /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
-+              clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
-+              set_in_cr4(X86_CR4_TSD);
-+      }
-+
-+#ifndef CONFIG_XEN
-+      /*
-+       * This is a horrible hack to allocate the GDT.  The problem
-+       * is that cpu_init() is called really early for the boot CPU
-+       * (and hence needs bootmem) but much later for the secondary
-+       * CPUs, when bootmem will have gone away
-+       */
-+      if (NODE_DATA(0)->bdata->node_bootmem_map) {
-+              gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
-+              /* alloc_bootmem_pages panics on failure, so no check */
-+              memset(gdt, 0, PAGE_SIZE);
-+      } else {
-+              gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
-+              if (unlikely(!gdt)) {
-+                      printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
-+                      for (;;)
-+                              local_irq_enable();
-+              }
-+      }
-+
-+      /*
-+       * Initialize the per-CPU GDT with the boot GDT,
-+       * and set up the GDT descriptor:
-+       */
-+      memcpy(gdt, cpu_gdt_table, GDT_SIZE);
-+
-+      /* Set up GDT entry for 16bit stack */
-+      *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
-+              ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
-+              ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
-+              (CPU_16BIT_STACK_SIZE - 1);
-+
-+      cpu_gdt_descr->size = GDT_SIZE - 1;
-+      cpu_gdt_descr->address = (unsigned long)gdt;
-+#else
-+      if (cpu == 0 && cpu_gdt_descr->address == 0) {
-+              gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
-+              /* alloc_bootmem_pages panics on failure, so no check */
-+              memset(gdt, 0, PAGE_SIZE);
-+
-+              memcpy(gdt, cpu_gdt_table, GDT_SIZE);
-+              
-+              cpu_gdt_descr->size = GDT_SIZE;
-+              cpu_gdt_descr->address = (unsigned long)gdt;
-+      }
-+#endif
-+
-+      cpu_gdt_init(cpu_gdt_descr);
-+
-+      /*
-+       * Set up and load the per-CPU TSS and LDT
-+       */
-+      atomic_inc(&init_mm.mm_count);
-+      current->active_mm = &init_mm;
-+      if (current->mm)
-+              BUG();
-+      enter_lazy_tlb(&init_mm, current);
-+
-+      load_esp0(t, thread);
-+
-+      load_LDT(&init_mm.context);
-+
-+#ifdef CONFIG_DOUBLEFAULT
-+      /* Set up doublefault TSS pointer in the GDT */
-+      __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
-+#endif
-+
-+      /* Clear %fs and %gs. */
-+      asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
-+
-+      /* Clear all 6 debug registers: */
-+      set_debugreg(0, 0);
-+      set_debugreg(0, 1);
-+      set_debugreg(0, 2);
-+      set_debugreg(0, 3);
-+      set_debugreg(0, 6);
-+      set_debugreg(0, 7);
-+
-+      /*
-+       * Force FPU initialization:
-+       */
-+      current_thread_info()->status = 0;
-+      clear_used_math();
-+      mxcsr_feature_mask_init();
-+}
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+void __devinit cpu_uninit(void)
-+{
-+      int cpu = raw_smp_processor_id();
-+      cpu_clear(cpu, cpu_initialized);
-+
-+      /* lazy TLB state */
-+      per_cpu(cpu_tlbstate, cpu).state = 0;
-+      per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;
-+}
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/cpu/mtrr/Makefile linux-2.6.16.33/arch/i386/kernel/cpu/mtrr/Makefile
---- linux-2.6.16.33-noxen/arch/i386/kernel/cpu/mtrr/Makefile   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/cpu/mtrr/Makefile 2007-01-08 15:00:45.000000000 +0000
-@@ -3,3 +3,10 @@
- obj-y         += cyrix.o
- obj-y         += centaur.o
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+n-obj-xen := generic.o state.o amd.o cyrix.o centaur.o
-+
-+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/cpu/mtrr/main-xen.c linux-2.6.16.33/arch/i386/kernel/cpu/mtrr/main-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/cpu/mtrr/main-xen.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/cpu/mtrr/main-xen.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,196 @@
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/ctype.h>
-+#include <linux/module.h>
-+#include <linux/seq_file.h>
-+#include <asm/uaccess.h>
-+
-+#include <asm/mtrr.h>
-+#include "mtrr.h"
-+
-+static DECLARE_MUTEX(mtrr_sem);
-+
-+void generic_get_mtrr(unsigned int reg, unsigned long *base,
-+                    unsigned int *size, mtrr_type * type)
-+{
-+      dom0_op_t op;
-+
-+      op.cmd = DOM0_READ_MEMTYPE;
-+      op.u.read_memtype.reg = reg;
-+      (void)HYPERVISOR_dom0_op(&op);
-+
-+      *size = op.u.read_memtype.nr_mfns;
-+      *base = op.u.read_memtype.mfn;
-+      *type = op.u.read_memtype.type;
-+}
-+
-+struct mtrr_ops generic_mtrr_ops = {
-+      .use_intel_if      = 1,
-+      .get               = generic_get_mtrr,
-+};
-+
-+struct mtrr_ops *mtrr_if = &generic_mtrr_ops;
-+unsigned int num_var_ranges;
-+unsigned int *usage_table;
-+
-+static void __init set_num_var_ranges(void)
-+{
-+      dom0_op_t op;
-+
-+      for (num_var_ranges = 0; ; num_var_ranges++) {
-+              op.cmd = DOM0_READ_MEMTYPE;
-+              op.u.read_memtype.reg = num_var_ranges;
-+              if (HYPERVISOR_dom0_op(&op) != 0)
-+                      break;
-+      }
-+}
-+
-+static void __init init_table(void)
-+{
-+      int i, max;
-+
-+      max = num_var_ranges;
-+      if ((usage_table = kmalloc(max * sizeof *usage_table, GFP_KERNEL))
-+          == NULL) {
-+              printk(KERN_ERR "mtrr: could not allocate\n");
-+              return;
-+      }
-+      for (i = 0; i < max; i++)
-+              usage_table[i] = 0;
-+}
-+
-+int mtrr_add_page(unsigned long base, unsigned long size, 
-+                unsigned int type, char increment)
-+{
-+      int error;
-+      dom0_op_t op;
-+
-+      down(&mtrr_sem);
-+
-+      op.cmd = DOM0_ADD_MEMTYPE;
-+      op.u.add_memtype.mfn     = base;
-+      op.u.add_memtype.nr_mfns = size;
-+      op.u.add_memtype.type    = type;
-+      error = HYPERVISOR_dom0_op(&op);
-+      if (error) {
-+              up(&mtrr_sem);
-+              BUG_ON(error > 0);
-+              return error;
-+      }
-+
-+      if (increment)
-+              ++usage_table[op.u.add_memtype.reg];
-+
-+      up(&mtrr_sem);
-+
-+      return op.u.add_memtype.reg;
-+}
-+
-+static int mtrr_check(unsigned long base, unsigned long size)
-+{
-+      if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
-+              printk(KERN_WARNING
-+                      "mtrr: size and base must be multiples of 4 kiB\n");
-+              printk(KERN_DEBUG
-+                      "mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
-+              dump_stack();
-+              return -1;
-+      }
-+      return 0;
-+}
-+
-+int
-+mtrr_add(unsigned long base, unsigned long size, unsigned int type,
-+       char increment)
-+{
-+      if (mtrr_check(base, size))
-+              return -EINVAL;
-+      return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
-+                           increment);
-+}
-+
-+int mtrr_del_page(int reg, unsigned long base, unsigned long size)
-+{
-+      unsigned i;
-+      mtrr_type ltype;
-+      unsigned long lbase;
-+      unsigned int lsize;
-+      int error = -EINVAL;
-+      dom0_op_t op;
-+
-+      down(&mtrr_sem);
-+
-+      if (reg < 0) {
-+              /*  Search for existing MTRR  */
-+              for (i = 0; i < num_var_ranges; ++i) {
-+                      mtrr_if->get(i, &lbase, &lsize, &ltype);
-+                      if (lbase == base && lsize == size) {
-+                              reg = i;
-+                              break;
-+                      }
-+              }
-+              if (reg < 0) {
-+                      printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base,
-+                             size);
-+                      goto out;
-+              }
-+      }
-+      if (usage_table[reg] < 1) {
-+              printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg);
-+              goto out;
-+      }
-+      if (--usage_table[reg] < 1) {
-+              op.cmd = DOM0_DEL_MEMTYPE;
-+              op.u.del_memtype.handle = 0;
-+              op.u.del_memtype.reg    = reg;
-+              error = HYPERVISOR_dom0_op(&op);
-+              if (error) {
-+                      BUG_ON(error > 0);
-+                      goto out;
-+              }
-+      }
-+      error = reg;
-+ out:
-+      up(&mtrr_sem);
-+      return error;
-+}
-+
-+int
-+mtrr_del(int reg, unsigned long base, unsigned long size)
-+{
-+      if (mtrr_check(base, size))
-+              return -EINVAL;
-+      return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
-+}
-+
-+EXPORT_SYMBOL(mtrr_add);
-+EXPORT_SYMBOL(mtrr_del);
-+
-+void __init mtrr_bp_init(void)
-+{
-+}
-+
-+void mtrr_ap_init(void)
-+{
-+}
-+
-+static int __init mtrr_init(void)
-+{
-+      struct cpuinfo_x86 *c = &boot_cpu_data;
-+
-+      if (!is_initial_xendomain())
-+              return -ENODEV;
-+
-+      if ((!cpu_has(c, X86_FEATURE_MTRR)) &&
-+          (!cpu_has(c, X86_FEATURE_K6_MTRR)) &&
-+          (!cpu_has(c, X86_FEATURE_CYRIX_ARR)) &&
-+          (!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
-+              return -ENODEV;
-+
-+      set_num_var_ranges();
-+      init_table();
-+
-+      return 0;
-+}
-+
-+subsys_initcall(mtrr_init);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/crash.c linux-2.6.16.33/arch/i386/kernel/crash.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/crash.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/crash.c   2007-01-08 15:00:45.000000000 +0000
-@@ -90,6 +90,7 @@
-       crash_save_this_cpu(regs, cpu);
- }
-+#ifndef CONFIG_XEN
- #ifdef CONFIG_SMP
- static atomic_t waiting_for_crash_ipi;
-@@ -158,6 +159,7 @@
-       /* There are no cpus to shootdown */
- }
- #endif
-+#endif /* CONFIG_XEN */
- void machine_crash_shutdown(struct pt_regs *regs)
- {
-@@ -174,10 +176,12 @@
-       /* Make a note of crashing cpu. Will be used in NMI callback.*/
-       crashing_cpu = smp_processor_id();
-+#ifndef CONFIG_XEN
-       nmi_shootdown_cpus();
-       lapic_shutdown();
- #if defined(CONFIG_X86_IO_APIC)
-       disable_IO_APIC();
- #endif
-+#endif /* CONFIG_XEN */
-       crash_save_self(regs);
- }
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/early_printk-xen.c linux-2.6.16.33/arch/i386/kernel/early_printk-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/early_printk-xen.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/early_printk-xen.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2 @@
-+
-+#include "../../x86_64/kernel/early_printk-xen.c"
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/entry-xen.S linux-2.6.16.33/arch/i386/kernel/entry-xen.S
---- linux-2.6.16.33-noxen/arch/i386/kernel/entry-xen.S 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/entry-xen.S       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,899 @@
-+/*
-+ *  linux/arch/i386/entry.S
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ */
-+
-+/*
-+ * entry.S contains the system-call and fault low-level handling routines.
-+ * This also contains the timer-interrupt handler, as well as all interrupts
-+ * and faults that can result in a task-switch.
-+ *
-+ * NOTE: This code handles signal-recognition, which happens every time
-+ * after a timer-interrupt and after each system call.
-+ *
-+ * I changed all the .align's to 4 (16 byte alignment), as that's faster
-+ * on a 486.
-+ *
-+ * Stack layout in 'ret_from_system_call':
-+ *    ptrace needs to have all regs on the stack.
-+ *    if the order here is changed, it needs to be
-+ *    updated in fork.c:copy_process, signal.c:do_signal,
-+ *    ptrace.c and ptrace.h
-+ *
-+ *     0(%esp) - %ebx
-+ *     4(%esp) - %ecx
-+ *     8(%esp) - %edx
-+ *       C(%esp) - %esi
-+ *    10(%esp) - %edi
-+ *    14(%esp) - %ebp
-+ *    18(%esp) - %eax
-+ *    1C(%esp) - %ds
-+ *    20(%esp) - %es
-+ *    24(%esp) - orig_eax
-+ *    28(%esp) - %eip
-+ *    2C(%esp) - %cs
-+ *    30(%esp) - %eflags
-+ *    34(%esp) - %oldesp
-+ *    38(%esp) - %oldss
-+ *
-+ * "current" is in register %ebx during any slow entries.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/linkage.h>
-+#include <asm/thread_info.h>
-+#include <asm/errno.h>
-+#include <asm/segment.h>
-+#include <asm/smp.h>
-+#include <asm/page.h>
-+#include <asm/desc.h>
-+#include "irq_vectors.h"
-+#include <xen/interface/xen.h>
-+
-+#define nr_syscalls ((syscall_table_size)/4)
-+
-+EBX           = 0x00
-+ECX           = 0x04
-+EDX           = 0x08
-+ESI           = 0x0C
-+EDI           = 0x10
-+EBP           = 0x14
-+EAX           = 0x18
-+DS            = 0x1C
-+ES            = 0x20
-+ORIG_EAX      = 0x24
-+EIP           = 0x28
-+CS            = 0x2C
-+EFLAGS                = 0x30
-+OLDESP                = 0x34
-+OLDSS         = 0x38
-+
-+CF_MASK               = 0x00000001
-+TF_MASK               = 0x00000100
-+IF_MASK               = 0x00000200
-+DF_MASK               = 0x00000400 
-+NT_MASK               = 0x00004000
-+VM_MASK               = 0x00020000
-+/* Pseudo-eflags. */
-+NMI_MASK      = 0x80000000
-+
-+#ifndef CONFIG_XEN
-+#define DISABLE_INTERRUPTS    cli
-+#define ENABLE_INTERRUPTS     sti
-+#else
-+/* Offsets into shared_info_t. */
-+#define evtchn_upcall_pending         /* 0 */
-+#define evtchn_upcall_mask            1
-+
-+#define sizeof_vcpu_shift             6
-+
-+#ifdef CONFIG_SMP
-+#define GET_VCPU_INFO         movl TI_cpu(%ebp),%esi                  ; \
-+                              shl  $sizeof_vcpu_shift,%esi            ; \
-+                              addl HYPERVISOR_shared_info,%esi
-+#else
-+#define GET_VCPU_INFO         movl HYPERVISOR_shared_info,%esi
-+#endif
-+
-+#define __DISABLE_INTERRUPTS  movb $1,evtchn_upcall_mask(%esi)
-+#define __ENABLE_INTERRUPTS   movb $0,evtchn_upcall_mask(%esi)
-+#define DISABLE_INTERRUPTS    GET_VCPU_INFO                           ; \
-+                              __DISABLE_INTERRUPTS
-+#define ENABLE_INTERRUPTS     GET_VCPU_INFO                           ; \
-+                              __ENABLE_INTERRUPTS
-+#define __TEST_PENDING                testb $0xFF,evtchn_upcall_pending(%esi)
-+#endif
-+
-+#ifdef CONFIG_PREEMPT
-+#define preempt_stop          cli
-+#else
-+#define preempt_stop
-+#define resume_kernel         restore_nocheck
-+#endif
-+
-+#define SAVE_ALL \
-+      cld; \
-+      pushl %es; \
-+      pushl %ds; \
-+      pushl %eax; \
-+      pushl %ebp; \
-+      pushl %edi; \
-+      pushl %esi; \
-+      pushl %edx; \
-+      pushl %ecx; \
-+      pushl %ebx; \
-+      movl $(__USER_DS), %edx; \
-+      movl %edx, %ds; \
-+      movl %edx, %es;
-+
-+#define RESTORE_INT_REGS \
-+      popl %ebx;      \
-+      popl %ecx;      \
-+      popl %edx;      \
-+      popl %esi;      \
-+      popl %edi;      \
-+      popl %ebp;      \
-+      popl %eax
-+
-+#define RESTORE_REGS  \
-+      RESTORE_INT_REGS; \
-+1:    popl %ds;       \
-+2:    popl %es;       \
-+.section .fixup,"ax"; \
-+3:    movl $0,(%esp); \
-+      jmp 1b;         \
-+4:    movl $0,(%esp); \
-+      jmp 2b;         \
-+.previous;            \
-+.section __ex_table,"a";\
-+      .align 4;       \
-+      .long 1b,3b;    \
-+      .long 2b,4b;    \
-+.previous
-+
-+
-+ENTRY(ret_from_fork)
-+      pushl %eax
-+      call schedule_tail
-+      GET_THREAD_INFO(%ebp)
-+      popl %eax
-+      jmp syscall_exit
-+
-+/*
-+ * Return to user mode is not as complex as all this looks,
-+ * but we want the default path for a system call return to
-+ * go as quickly as possible which is why some of this is
-+ * less clear than it otherwise should be.
-+ */
-+
-+      # userspace resumption stub bypassing syscall exit tracing
-+      ALIGN
-+ret_from_exception:
-+      preempt_stop
-+ret_from_intr:
-+      GET_THREAD_INFO(%ebp)
-+      movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
-+      movb CS(%esp), %al
-+      testl $(VM_MASK | 2), %eax
-+      jz resume_kernel
-+ENTRY(resume_userspace)
-+      DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
-+                                      # setting need_resched or sigpending
-+                                      # between sampling and the iret
-+      movl TI_flags(%ebp), %ecx
-+      andl $_TIF_WORK_MASK, %ecx      # is there any work to be done on
-+                                      # int/exception return?
-+      jne work_pending
-+      jmp restore_all
-+
-+#ifdef CONFIG_PREEMPT
-+ENTRY(resume_kernel)
-+      cli
-+      cmpl $0,TI_preempt_count(%ebp)  # non-zero preempt_count ?
-+      jnz restore_nocheck
-+need_resched:
-+      movl TI_flags(%ebp), %ecx       # need_resched set ?
-+      testb $_TIF_NEED_RESCHED, %cl
-+      jz restore_all
-+      testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
-+      jz restore_all
-+      call preempt_schedule_irq
-+      jmp need_resched
-+#endif
-+
-+/* SYSENTER_RETURN points to after the "sysenter" instruction in
-+   the vsyscall page.  See vsyscall-sysentry.S, which defines the symbol.  */
-+
-+      # sysenter call handler stub
-+ENTRY(sysenter_entry)
-+      movl SYSENTER_stack_esp0(%esp),%esp
-+sysenter_past_esp:
-+      sti
-+      pushl $(__USER_DS)
-+      pushl %ebp
-+      pushfl
-+      pushl $(__USER_CS)
-+      pushl $SYSENTER_RETURN
-+
-+/*
-+ * Load the potential sixth argument from user stack.
-+ * Careful about security.
-+ */
-+      cmpl $__PAGE_OFFSET-3,%ebp
-+      jae syscall_fault
-+1:    movl (%ebp),%ebp
-+.section __ex_table,"a"
-+      .align 4
-+      .long 1b,syscall_fault
-+.previous
-+
-+      pushl %eax
-+      SAVE_ALL
-+      GET_THREAD_INFO(%ebp)
-+
-+      /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-+      testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+      jnz syscall_trace_entry
-+      cmpl $(nr_syscalls), %eax
-+      jae syscall_badsys
-+      call *sys_call_table(,%eax,4)
-+      movl %eax,EAX(%esp)
-+      DISABLE_INTERRUPTS
-+      movl TI_flags(%ebp), %ecx
-+      testw $_TIF_ALLWORK_MASK, %cx
-+      jne syscall_exit_work
-+/* if something modifies registers it must also disable sysexit */
-+      movl EIP(%esp), %edx
-+      movl OLDESP(%esp), %ecx
-+      xorl %ebp,%ebp
-+#ifdef CONFIG_XEN
-+      __ENABLE_INTERRUPTS
-+sysexit_scrit:        /**** START OF SYSEXIT CRITICAL REGION ****/
-+      __TEST_PENDING
-+      jnz  14f                        # process more events if necessary...
-+      movl ESI(%esp), %esi
-+      sysexit
-+14:   __DISABLE_INTERRUPTS
-+sysexit_ecrit:        /**** END OF SYSEXIT CRITICAL REGION ****/
-+      push %esp
-+      call evtchn_do_upcall
-+      add  $4,%esp
-+      jmp  ret_from_intr
-+#else
-+      sti
-+      sysexit
-+#endif /* !CONFIG_XEN */
-+
-+
-+      # system call handler stub
-+ENTRY(system_call)
-+      pushl %eax                      # save orig_eax
-+      SAVE_ALL
-+      GET_THREAD_INFO(%ebp)
-+                                      # system call tracing in operation / emulation
-+      /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-+      testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+      jnz syscall_trace_entry
-+      cmpl $(nr_syscalls), %eax
-+      jae syscall_badsys
-+syscall_call:
-+      call *sys_call_table(,%eax,4)
-+      movl %eax,EAX(%esp)             # store the return value
-+syscall_exit:
-+      DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
-+                                      # setting need_resched or sigpending
-+                                      # between sampling and the iret
-+      movl TI_flags(%ebp), %ecx
-+      testw $_TIF_ALLWORK_MASK, %cx   # current->work
-+      jne syscall_exit_work
-+
-+restore_all:
-+#ifndef CONFIG_XEN
-+      movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
-+      # Warning: OLDSS(%esp) contains the wrong/random values if we
-+      # are returning to the kernel.
-+      # See comments in process.c:copy_thread() for details.
-+      movb OLDSS(%esp), %ah
-+      movb CS(%esp), %al
-+      andl $(VM_MASK | (4 << 8) | 3), %eax
-+      cmpl $((4 << 8) | 3), %eax
-+      je ldt_ss                       # returning to user-space with LDT SS
-+restore_nocheck:
-+#else
-+restore_nocheck:
-+      movl EFLAGS(%esp), %eax
-+      testl $(VM_MASK|NMI_MASK), %eax
-+      jnz hypervisor_iret
-+      shr $9, %eax                    # EAX[0] == IRET_EFLAGS.IF
-+      GET_VCPU_INFO
-+      andb evtchn_upcall_mask(%esi),%al
-+      andb $1,%al                     # EAX[0] == IRET_EFLAGS.IF & event_mask
-+      jnz restore_all_enable_events   #        != 0 => enable event delivery
-+#endif
-+      RESTORE_REGS
-+      addl $4, %esp
-+1:    iret
-+.section .fixup,"ax"
-+iret_exc:
-+#ifndef CONFIG_XEN
-+      sti
-+#endif
-+      pushl $0                        # no error code
-+      pushl $do_iret_error
-+      jmp error_code
-+.previous
-+.section __ex_table,"a"
-+      .align 4
-+      .long 1b,iret_exc
-+.previous
-+
-+#ifndef CONFIG_XEN
-+ldt_ss:
-+      larl OLDSS(%esp), %eax
-+      jnz restore_nocheck
-+      testl $0x00400000, %eax         # returning to 32bit stack?
-+      jnz restore_nocheck             # allright, normal return
-+      /* If returning to userspace with 16bit stack,
-+       * try to fix the higher word of ESP, as the CPU
-+       * won't restore it.
-+       * This is an "official" bug of all the x86-compatible
-+       * CPUs, which we can try to work around to make
-+       * dosemu and wine happy. */
-+      subl $8, %esp           # reserve space for switch16 pointer
-+      cli
-+      movl %esp, %eax
-+      /* Set up the 16bit stack frame with switch32 pointer on top,
-+       * and a switch16 pointer on top of the current frame. */
-+      call setup_x86_bogus_stack
-+      RESTORE_REGS
-+      lss 20+4(%esp), %esp    # switch to 16bit stack
-+1:    iret
-+.section __ex_table,"a"
-+      .align 4
-+      .long 1b,iret_exc
-+.previous
-+#else
-+hypervisor_iret:
-+      andl $~NMI_MASK, EFLAGS(%esp)
-+      RESTORE_REGS
-+      addl $4, %esp
-+      jmp  hypercall_page + (__HYPERVISOR_iret * 32)
-+#endif
-+
-+      # perform work that needs to be done immediately before resumption
-+      ALIGN
-+work_pending:
-+      testb $_TIF_NEED_RESCHED, %cl
-+      jz work_notifysig
-+work_resched:
-+      call schedule
-+      DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
-+                                      # setting need_resched or sigpending
-+                                      # between sampling and the iret
-+      movl TI_flags(%ebp), %ecx
-+      andl $_TIF_WORK_MASK, %ecx      # is there any work to be done other
-+                                      # than syscall tracing?
-+      jz restore_all
-+      testb $_TIF_NEED_RESCHED, %cl
-+      jnz work_resched
-+
-+work_notifysig:                               # deal with pending signals and
-+                                      # notify-resume requests
-+      testl $VM_MASK, EFLAGS(%esp)
-+      movl %esp, %eax
-+      jne work_notifysig_v86          # returning to kernel-space or
-+                                      # vm86-space
-+      xorl %edx, %edx
-+      call do_notify_resume
-+      jmp resume_userspace
-+
-+      ALIGN
-+work_notifysig_v86:
-+#ifdef CONFIG_VM86
-+      pushl %ecx                      # save ti_flags for do_notify_resume
-+      call save_v86_state             # %eax contains pt_regs pointer
-+      popl %ecx
-+      movl %eax, %esp
-+      xorl %edx, %edx
-+      call do_notify_resume
-+      jmp resume_userspace
-+#endif
-+
-+      # perform syscall exit tracing
-+      ALIGN
-+syscall_trace_entry:
-+      movl $-ENOSYS,EAX(%esp)
-+      movl %esp, %eax
-+      xorl %edx,%edx
-+      call do_syscall_trace
-+      cmpl $0, %eax
-+      jne resume_userspace            # ret != 0 -> running under PTRACE_SYSEMU,
-+                                      # so must skip actual syscall
-+      movl ORIG_EAX(%esp), %eax
-+      cmpl $(nr_syscalls), %eax
-+      jnae syscall_call
-+      jmp syscall_exit
-+
-+      # perform syscall exit tracing
-+      ALIGN
-+syscall_exit_work:
-+      testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
-+      jz work_pending
-+      ENABLE_INTERRUPTS               # could let do_syscall_trace() call
-+                                      # schedule() instead
-+      movl %esp, %eax
-+      movl $1, %edx
-+      call do_syscall_trace
-+      jmp resume_userspace
-+
-+      ALIGN
-+syscall_fault:
-+      pushl %eax                      # save orig_eax
-+      SAVE_ALL
-+      GET_THREAD_INFO(%ebp)
-+      movl $-EFAULT,EAX(%esp)
-+      jmp resume_userspace
-+
-+      ALIGN
-+syscall_badsys:
-+      movl $-ENOSYS,EAX(%esp)
-+      jmp resume_userspace
-+
-+#ifndef CONFIG_XEN
-+#define FIXUP_ESPFIX_STACK \
-+      movl %esp, %eax; \
-+      /* switch to 32bit stack using the pointer on top of 16bit stack */ \
-+      lss %ss:CPU_16BIT_STACK_SIZE-8, %esp; \
-+      /* copy data from 16bit stack to 32bit stack */ \
-+      call fixup_x86_bogus_stack; \
-+      /* put ESP to the proper location */ \
-+      movl %eax, %esp;
-+#define UNWIND_ESPFIX_STACK \
-+      pushl %eax; \
-+      movl %ss, %eax; \
-+      /* see if on 16bit stack */ \
-+      cmpw $__ESPFIX_SS, %ax; \
-+      jne 28f; \
-+      movl $__KERNEL_DS, %edx; \
-+      movl %edx, %ds; \
-+      movl %edx, %es; \
-+      /* switch to 32bit stack */ \
-+      FIXUP_ESPFIX_STACK \
-+28:   popl %eax;
-+
-+/*
-+ * Build the entry stubs and pointer table with
-+ * some assembler magic.
-+ */
-+.data
-+ENTRY(interrupt)
-+.text
-+
-+vector=0
-+ENTRY(irq_entries_start)
-+.rept NR_IRQS
-+      ALIGN
-+1:    pushl $~(vector)
-+      jmp common_interrupt
-+.data
-+      .long 1b
-+.text
-+vector=vector+1
-+.endr
-+
-+      ALIGN
-+common_interrupt:
-+      SAVE_ALL
-+      movl %esp,%eax
-+      call do_IRQ
-+      jmp ret_from_intr
-+
-+#define BUILD_INTERRUPT(name, nr)     \
-+ENTRY(name)                           \
-+      pushl $~(nr);                   \
-+      SAVE_ALL                        \
-+      movl %esp,%eax;                 \
-+      call smp_/**/name;              \
-+      jmp ret_from_intr;
-+
-+/* The include is where all of the SMP etc. interrupts come from */
-+#include "entry_arch.h"
-+#else
-+#define UNWIND_ESPFIX_STACK
-+#endif
-+
-+ENTRY(divide_error)
-+      pushl $0                        # no error code
-+      pushl $do_divide_error
-+      ALIGN
-+error_code:
-+      pushl %ds
-+      pushl %eax
-+      xorl %eax, %eax
-+      pushl %ebp
-+      pushl %edi
-+      pushl %esi
-+      pushl %edx
-+      decl %eax                       # eax = -1
-+      pushl %ecx
-+      pushl %ebx
-+      cld
-+      pushl %es
-+      UNWIND_ESPFIX_STACK
-+      popl %ecx
-+      movl ES(%esp), %edi             # get the function address
-+      movl ORIG_EAX(%esp), %edx       # get the error code
-+      movl %eax, ORIG_EAX(%esp)
-+      movl %ecx, ES(%esp)
-+      movl $(__USER_DS), %ecx
-+      movl %ecx, %ds
-+      movl %ecx, %es
-+      movl %esp,%eax                  # pt_regs pointer
-+      call *%edi
-+      jmp ret_from_exception
-+
-+#ifdef CONFIG_XEN
-+# A note on the "critical region" in our callback handler.
-+# We want to avoid stacking callback handlers due to events occurring
-+# during handling of the last event. To do this, we keep events disabled
-+# until we've done all processing. HOWEVER, we must enable events before
-+# popping the stack frame (can't be done atomically) and so it would still
-+# be possible to get enough handler activations to overflow the stack.
-+# Although unlikely, bugs of that kind are hard to track down, so we'd
-+# like to avoid the possibility.
-+# So, on entry to the handler we detect whether we interrupted an
-+# existing activation in its critical region -- if so, we pop the current
-+# activation and restart the handler using the previous one.
-+#
-+# The sysexit critical region is slightly different. sysexit
-+# atomically removes the entire stack frame. If we interrupt in the
-+# critical region we know that the entire frame is present and correct
-+# so we can simply throw away the new one.
-+ENTRY(hypervisor_callback)
-+      pushl %eax
-+      SAVE_ALL
-+      movl EIP(%esp),%eax
-+      cmpl $scrit,%eax
-+      jb   11f
-+      cmpl $ecrit,%eax
-+      jb   critical_region_fixup
-+      cmpl $sysexit_scrit,%eax
-+      jb   11f
-+      cmpl $sysexit_ecrit,%eax
-+      ja   11f
-+      addl $0x34,%esp                 # Remove cs...ebx from stack frame.
-+11:   push %esp
-+      call evtchn_do_upcall
-+      add  $4,%esp
-+      jmp  ret_from_intr
-+
-+        ALIGN
-+restore_all_enable_events:
-+      __ENABLE_INTERRUPTS
-+scrit:        /**** START OF CRITICAL REGION ****/
-+      __TEST_PENDING
-+      jnz  14f                        # process more events if necessary...
-+      RESTORE_REGS
-+      addl $4, %esp
-+1:    iret
-+.section __ex_table,"a"
-+      .align 4
-+      .long 1b,iret_exc
-+.previous
-+14:   __DISABLE_INTERRUPTS
-+      jmp  11b
-+ecrit:  /**** END OF CRITICAL REGION ****/
-+# [How we do the fixup]. We want to merge the current stack frame with the
-+# just-interrupted frame. How we do this depends on where in the critical
-+# region the interrupted handler was executing, and so how many saved
-+# registers are in each frame. We do this quickly using the lookup table
-+# 'critical_fixup_table'. For each byte offset in the critical region, it
-+# provides the number of bytes which have already been popped from the
-+# interrupted stack frame.
-+critical_region_fixup:
-+      addl $critical_fixup_table-scrit,%eax
-+      movzbl (%eax),%eax              # %eax contains num bytes popped
-+      cmpb $0xff,%al                  # 0xff => vcpu_info critical region
-+      jne  15f
-+      GET_THREAD_INFO(%ebp)
-+        xorl %eax,%eax
-+15:   mov  %esp,%esi
-+      add  %eax,%esi                  # %esi points at end of src region
-+      mov  %esp,%edi
-+      add  $0x34,%edi                 # %edi points at end of dst region
-+      mov  %eax,%ecx
-+      shr  $2,%ecx                    # convert words to bytes
-+      je   17f                        # skip loop if nothing to copy
-+16:   subl $4,%esi                    # pre-decrementing copy loop
-+      subl $4,%edi
-+      movl (%esi),%eax
-+      movl %eax,(%edi)
-+      loop 16b
-+17:   movl %edi,%esp                  # final %edi is top of merged stack
-+      jmp  11b
-+
-+critical_fixup_table:
-+      .byte 0xff,0xff,0xff            # testb $0xff,(%esi) = __TEST_PENDING
-+      .byte 0xff,0xff                 # jnz  14f
-+      .byte 0x00                      # pop  %ebx
-+      .byte 0x04                      # pop  %ecx
-+      .byte 0x08                      # pop  %edx
-+      .byte 0x0c                      # pop  %esi
-+      .byte 0x10                      # pop  %edi
-+      .byte 0x14                      # pop  %ebp
-+      .byte 0x18                      # pop  %eax
-+      .byte 0x1c                      # pop  %ds
-+      .byte 0x20                      # pop  %es
-+      .byte 0x24,0x24,0x24            # add  $4,%esp
-+      .byte 0x28                      # iret
-+      .byte 0xff,0xff,0xff,0xff       # movb $1,1(%esi)
-+      .byte 0x00,0x00                 # jmp  11b
-+
-+# Hypervisor uses this for application faults while it executes.
-+# We get here for two reasons:
-+#  1. Fault while reloading DS, ES, FS or GS
-+#  2. Fault while executing IRET
-+# Category 1 we fix up by reattempting the load, and zeroing the segment
-+# register if the load fails.
-+# Category 2 we fix up by jumping to do_iret_error. We cannot use the
-+# normal Linux return path in this case because if we use the IRET hypercall
-+# to pop the stack frame we end up in an infinite loop of failsafe callbacks.
-+# We distinguish between categories by maintaining a status value in EAX.
-+ENTRY(failsafe_callback)
-+      pushl %eax
-+      movl $1,%eax
-+1:    mov 4(%esp),%ds
-+2:    mov 8(%esp),%es
-+3:    mov 12(%esp),%fs
-+4:    mov 16(%esp),%gs
-+      testl %eax,%eax
-+      popl %eax
-+      jz 5f
-+      addl $16,%esp           # EAX != 0 => Category 2 (Bad IRET)
-+      jmp iret_exc
-+5:    addl $16,%esp           # EAX == 0 => Category 1 (Bad segment)
-+      pushl $0
-+      SAVE_ALL
-+      jmp ret_from_exception
-+.section .fixup,"ax";         \
-+6:    xorl %eax,%eax;         \
-+      movl %eax,4(%esp);      \
-+      jmp 1b;                 \
-+7:    xorl %eax,%eax;         \
-+      movl %eax,8(%esp);      \
-+      jmp 2b;                 \
-+8:    xorl %eax,%eax;         \
-+      movl %eax,12(%esp);     \
-+      jmp 3b;                 \
-+9:    xorl %eax,%eax;         \
-+      movl %eax,16(%esp);     \
-+      jmp 4b;                 \
-+.previous;                    \
-+.section __ex_table,"a";      \
-+      .align 4;               \
-+      .long 1b,6b;            \
-+      .long 2b,7b;            \
-+      .long 3b,8b;            \
-+      .long 4b,9b;            \
-+.previous
-+#endif
-+
-+ENTRY(coprocessor_error)
-+      pushl $0
-+      pushl $do_coprocessor_error
-+      jmp error_code
-+
-+ENTRY(simd_coprocessor_error)
-+      pushl $0
-+      pushl $do_simd_coprocessor_error
-+      jmp error_code
-+
-+ENTRY(device_not_available)
-+      pushl $-1                       # mark this as an int
-+      SAVE_ALL
-+#ifndef CONFIG_XEN
-+      movl %cr0, %eax
-+      testl $0x4, %eax                # EM (math emulation bit)
-+      je device_available_emulate
-+      pushl $0                        # temporary storage for ORIG_EIP
-+      call math_emulate
-+      addl $4, %esp
-+      jmp ret_from_exception
-+device_available_emulate:
-+#endif
-+      preempt_stop
-+      call math_state_restore
-+      jmp ret_from_exception
-+
-+#ifndef CONFIG_XEN
-+/*
-+ * Debug traps and NMI can happen at the one SYSENTER instruction
-+ * that sets up the real kernel stack. Check here, since we can't
-+ * allow the wrong stack to be used.
-+ *
-+ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
-+ * already pushed 3 words if it hits on the sysenter instruction:
-+ * eflags, cs and eip.
-+ *
-+ * We just load the right stack, and push the three (known) values
-+ * by hand onto the new stack - while updating the return eip past
-+ * the instruction that would have done it for sysenter.
-+ */
-+#define FIX_STACK(offset, ok, label)          \
-+      cmpw $__KERNEL_CS,4(%esp);              \
-+      jne ok;                                 \
-+label:                                                \
-+      movl SYSENTER_stack_esp0+offset(%esp),%esp;     \
-+      pushfl;                                 \
-+      pushl $__KERNEL_CS;                     \
-+      pushl $sysenter_past_esp
-+#endif /* CONFIG_XEN */
-+
-+KPROBE_ENTRY(debug)
-+#ifndef CONFIG_XEN
-+      cmpl $sysenter_entry,(%esp)
-+      jne debug_stack_correct
-+      FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
-+debug_stack_correct:
-+#endif /* !CONFIG_XEN */
-+      pushl $-1                       # mark this as an int
-+      SAVE_ALL
-+      xorl %edx,%edx                  # error code 0
-+      movl %esp,%eax                  # pt_regs pointer
-+      call do_debug
-+      jmp ret_from_exception
-+      .previous .text
-+
-+#ifndef CONFIG_XEN
-+/*
-+ * NMI is doubly nasty. It can happen _while_ we're handling
-+ * a debug fault, and the debug fault hasn't yet been able to
-+ * clear up the stack. So we first check whether we got  an
-+ * NMI on the sysenter entry path, but after that we need to
-+ * check whether we got an NMI on the debug path where the debug
-+ * fault happened on the sysenter path.
-+ */
-+ENTRY(nmi)
-+      pushl %eax
-+      movl %ss, %eax
-+      cmpw $__ESPFIX_SS, %ax
-+      popl %eax
-+      je nmi_16bit_stack
-+      cmpl $sysenter_entry,(%esp)
-+      je nmi_stack_fixup
-+      pushl %eax
-+      movl %esp,%eax
-+      /* Do not access memory above the end of our stack page,
-+       * it might not exist.
-+       */
-+      andl $(THREAD_SIZE-1),%eax
-+      cmpl $(THREAD_SIZE-20),%eax
-+      popl %eax
-+      jae nmi_stack_correct
-+      cmpl $sysenter_entry,12(%esp)
-+      je nmi_debug_stack_check
-+nmi_stack_correct:
-+      pushl %eax
-+      SAVE_ALL
-+      xorl %edx,%edx          # zero error code
-+      movl %esp,%eax          # pt_regs pointer
-+      call do_nmi
-+      jmp restore_all
-+
-+nmi_stack_fixup:
-+      FIX_STACK(12,nmi_stack_correct, 1)
-+      jmp nmi_stack_correct
-+nmi_debug_stack_check:
-+      cmpw $__KERNEL_CS,16(%esp)
-+      jne nmi_stack_correct
-+      cmpl $debug,(%esp)
-+      jb nmi_stack_correct
-+      cmpl $debug_esp_fix_insn,(%esp)
-+      ja nmi_stack_correct
-+      FIX_STACK(24,nmi_stack_correct, 1)
-+      jmp nmi_stack_correct
-+
-+nmi_16bit_stack:
-+      /* create the pointer to lss back */
-+      pushl %ss
-+      pushl %esp
-+      movzwl %sp, %esp
-+      addw $4, (%esp)
-+      /* copy the iret frame of 12 bytes */
-+      .rept 3
-+      pushl 16(%esp)
-+      .endr
-+      pushl %eax
-+      SAVE_ALL
-+      FIXUP_ESPFIX_STACK              # %eax == %esp
-+      xorl %edx,%edx                  # zero error code
-+      call do_nmi
-+      RESTORE_REGS
-+      lss 12+4(%esp), %esp            # back to 16bit stack
-+1:    iret
-+.section __ex_table,"a"
-+      .align 4
-+      .long 1b,iret_exc
-+.previous
-+#else
-+ENTRY(nmi)
-+      pushl %eax
-+      SAVE_ALL
-+      xorl %edx,%edx          # zero error code
-+      movl %esp,%eax          # pt_regs pointer
-+      call do_nmi
-+      orl  $NMI_MASK, EFLAGS(%esp)
-+      jmp restore_all
-+#endif
-+
-+KPROBE_ENTRY(int3)
-+      pushl $-1                       # mark this as an int
-+      SAVE_ALL
-+      xorl %edx,%edx          # zero error code
-+      movl %esp,%eax          # pt_regs pointer
-+      call do_int3
-+      jmp ret_from_exception
-+      .previous .text
-+
-+ENTRY(overflow)
-+      pushl $0
-+      pushl $do_overflow
-+      jmp error_code
-+
-+ENTRY(bounds)
-+      pushl $0
-+      pushl $do_bounds
-+      jmp error_code
-+
-+ENTRY(invalid_op)
-+      pushl $0
-+      pushl $do_invalid_op
-+      jmp error_code
-+
-+ENTRY(coprocessor_segment_overrun)
-+      pushl $0
-+      pushl $do_coprocessor_segment_overrun
-+      jmp error_code
-+
-+ENTRY(invalid_TSS)
-+      pushl $do_invalid_TSS
-+      jmp error_code
-+
-+ENTRY(segment_not_present)
-+      pushl $do_segment_not_present
-+      jmp error_code
-+
-+ENTRY(stack_segment)
-+      pushl $do_stack_segment
-+      jmp error_code
-+
-+KPROBE_ENTRY(general_protection)
-+      pushl $do_general_protection
-+      jmp error_code
-+      .previous .text
-+
-+ENTRY(alignment_check)
-+      pushl $do_alignment_check
-+      jmp error_code
-+
-+KPROBE_ENTRY(page_fault)
-+      pushl $do_page_fault
-+      jmp error_code
-+      .previous .text
-+
-+#ifdef CONFIG_X86_MCE
-+ENTRY(machine_check)
-+      pushl $0
-+      pushl machine_check_vector
-+      jmp error_code
-+#endif
-+
-+ENTRY(fixup_4gb_segment)
-+      pushl $do_fixup_4gb_segment
-+      jmp error_code
-+
-+.section .rodata,"a"
-+#include "syscall_table.S"
-+
-+syscall_table_size=(.-sys_call_table)
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/entry.S linux-2.6.16.33/arch/i386/kernel/entry.S
---- linux-2.6.16.33-noxen/arch/i386/kernel/entry.S     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/entry.S   2007-05-23 21:00:01.000000000 +0000
-@@ -177,7 +177,7 @@
-       # sysenter call handler stub
- ENTRY(sysenter_entry)
--      movl TSS_sysenter_esp0(%esp),%esp
-+      movl SYSENTER_stack_esp0(%esp),%esp
- sysenter_past_esp:
-       sti
-       pushl $(__USER_DS)
-@@ -406,7 +406,7 @@
- ENTRY(irq_entries_start)
- .rept NR_IRQS
-       ALIGN
--1:    pushl $vector-256
-+1:    pushl $~(vector)
-       jmp common_interrupt
- .data
-       .long 1b
-@@ -423,7 +423,7 @@
- #define BUILD_INTERRUPT(name, nr)     \
- ENTRY(name)                           \
--      pushl $nr-256;                  \
-+      pushl $~(nr);                   \
-       SAVE_ALL                        \
-       movl %esp,%eax;                 \
-       call smp_/**/name;              \
-@@ -492,7 +492,7 @@
-  * that sets up the real kernel stack. Check here, since we can't
-  * allow the wrong stack to be used.
-  *
-- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
-+ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
-  * already pushed 3 words if it hits on the sysenter instruction:
-  * eflags, cs and eip.
-  *
-@@ -504,7 +504,7 @@
-       cmpw $__KERNEL_CS,4(%esp);              \
-       jne ok;                                 \
- label:                                                \
--      movl TSS_sysenter_esp0+offset(%esp),%esp;       \
-+      movl SYSENTER_stack_esp0+offset(%esp),%esp;     \
-       pushfl;                                 \
-       pushl $__KERNEL_CS;                     \
-       pushl $sysenter_past_esp
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/fixup.c linux-2.6.16.33/arch/i386/kernel/fixup.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/fixup.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/fixup.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,89 @@
-+/******************************************************************************
-+ * fixup.c
-+ * 
-+ * Binary-rewriting of certain IA32 instructions, on notification by Xen.
-+ * Used to avoid repeated slow emulation of common instructions used by the
-+ * user-space TLS (Thread-Local Storage) libraries.
-+ * 
-+ * **** NOTE ****
-+ *  Issues with the binary rewriting have caused it to be removed. Instead
-+ *  we rely on Xen's emulator to boot the kernel, and then print a banner
-+ *  message recommending that the user disables /lib/tls.
-+ * 
-+ * Copyright (c) 2004, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ * 
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ * 
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/version.h>
-+
-+#define DP(_f, _args...) printk(KERN_ALERT "  " _f "\n" , ## _args )
-+
-+fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
-+{
-+      static unsigned long printed = 0;
-+      char info[100];
-+      int i;
-+
-+      /* Ignore statically-linked init. */
-+      if (current->tgid == 1)
-+              return;
-+            
-+      HYPERVISOR_vm_assist(
-+              VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
-+
-+      if (test_and_set_bit(0, &printed))
-+              return;
-+
-+      sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
-+
-+      DP("");
-+      DP("***************************************************************");
-+      DP("***************************************************************");
-+      DP("** WARNING: Currently emulating unsupported memory accesses  **");
-+      DP("**          in /lib/tls glibc libraries. The emulation is    **");
-+      DP("**          slow. To ensure full performance you should      **");
-+      DP("**          install a 'xen-friendly' (nosegneg) version of   **");
-+      DP("**          the library, or disable tls support by executing **");
-+      DP("**          the following as root:                           **");
-+      DP("**          mv /lib/tls /lib/tls.disabled                    **");
-+      DP("** Offending process: %-38.38s **", info);
-+      DP("***************************************************************");
-+      DP("***************************************************************");
-+      DP("");
-+
-+      for (i = 5; i > 0; i--) {
-+              touch_softlockup_watchdog();
-+              printk("Pausing... %d", i);
-+              mdelay(1000);
-+              printk("\b\b\b\b\b\b\b\b\b\b\b\b");
-+      }
-+
-+      printk("Continuing...\n\n");
-+}
-+
-+static int __init fixup_init(void)
-+{
-+      HYPERVISOR_vm_assist(
-+              VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
-+      return 0;
-+}
-+__initcall(fixup_init);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/head-xen.S linux-2.6.16.33/arch/i386/kernel/head-xen.S
---- linux-2.6.16.33-noxen/arch/i386/kernel/head-xen.S  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/head-xen.S        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,202 @@
-+
-+
-+.text
-+#include <linux/config.h>
-+#include <linux/elfnote.h>
-+#include <linux/threads.h>
-+#include <linux/linkage.h>
-+#include <asm/segment.h>
-+#include <asm/page.h>
-+#include <asm/thread_info.h>
-+#include <asm/asm-offsets.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/elfnote.h>
-+
-+/*
-+ * References to members of the new_cpu_data structure.
-+ */
-+
-+#define X86           new_cpu_data+CPUINFO_x86
-+#define X86_VENDOR    new_cpu_data+CPUINFO_x86_vendor
-+#define X86_MODEL     new_cpu_data+CPUINFO_x86_model
-+#define X86_MASK      new_cpu_data+CPUINFO_x86_mask
-+#define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math
-+#define X86_CPUID     new_cpu_data+CPUINFO_cpuid_level
-+#define X86_CAPABILITY        new_cpu_data+CPUINFO_x86_capability
-+#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id
-+
-+#define VIRT_ENTRY_OFFSET 0x0
-+.org VIRT_ENTRY_OFFSET
-+ENTRY(startup_32)
-+      movl %esi,xen_start_info
-+      cld
-+
-+      /* Set up the stack pointer */
-+      movl $(init_thread_union+THREAD_SIZE),%esp
-+
-+      /* get vendor info */
-+      xorl %eax,%eax                  # call CPUID with 0 -> return vendor ID
-+      XEN_CPUID
-+      movl %eax,X86_CPUID             # save CPUID level
-+      movl %ebx,X86_VENDOR_ID         # lo 4 chars
-+      movl %edx,X86_VENDOR_ID+4       # next 4 chars
-+      movl %ecx,X86_VENDOR_ID+8       # last 4 chars
-+
-+      movl $1,%eax            # Use the CPUID instruction to get CPU type
-+      XEN_CPUID
-+      movb %al,%cl            # save reg for future use
-+      andb $0x0f,%ah          # mask processor family
-+      movb %ah,X86
-+      andb $0xf0,%al          # mask model
-+      shrb $4,%al
-+      movb %al,X86_MODEL
-+      andb $0x0f,%cl          # mask mask revision
-+      movb %cl,X86_MASK
-+      movl %edx,X86_CAPABILITY
-+
-+      movb $1,X86_HARD_MATH
-+
-+      xorl %eax,%eax                  # Clear FS/GS and LDT
-+      movl %eax,%fs
-+      movl %eax,%gs
-+      cld                     # gcc2 wants the direction flag cleared at all times
-+
-+      call start_kernel
-+L6:
-+      jmp L6                  # main should never return here, but
-+                              # just in case, we know what happens.
-+
-+#define HYPERCALL_PAGE_OFFSET 0x1000
-+.org HYPERCALL_PAGE_OFFSET
-+ENTRY(hypercall_page)
-+.skip 0x1000
-+
-+/*
-+ * Real beginning of normal "text" segment
-+ */
-+ENTRY(stext)
-+ENTRY(_stext)
-+
-+/*
-+ * BSS section
-+ */
-+.section ".bss.page_aligned","w"
-+ENTRY(empty_zero_page)
-+      .fill 4096,1,0
-+
-+/*
-+ * This starts the data section.
-+ */
-+.data
-+
-+/*
-+ * The Global Descriptor Table contains 28 quadwords, per-CPU.
-+ */
-+ENTRY(cpu_gdt_table)
-+      .quad 0x0000000000000000        /* NULL descriptor */
-+      .quad 0x0000000000000000        /* 0x0b reserved */
-+      .quad 0x0000000000000000        /* 0x13 reserved */
-+      .quad 0x0000000000000000        /* 0x1b reserved */
-+      .quad 0x0000000000000000        /* 0x20 unused */
-+      .quad 0x0000000000000000        /* 0x28 unused */
-+      .quad 0x0000000000000000        /* 0x33 TLS entry 1 */
-+      .quad 0x0000000000000000        /* 0x3b TLS entry 2 */
-+      .quad 0x0000000000000000        /* 0x43 TLS entry 3 */
-+      .quad 0x0000000000000000        /* 0x4b reserved */
-+      .quad 0x0000000000000000        /* 0x53 reserved */
-+      .quad 0x0000000000000000        /* 0x5b reserved */
-+
-+      .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
-+      .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
-+      .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
-+      .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
-+
-+      .quad 0x0000000000000000        /* 0x80 TSS descriptor */
-+      .quad 0x0000000000000000        /* 0x88 LDT descriptor */
-+
-+      /*
-+       * Segments used for calling PnP BIOS have byte granularity.
-+       * They code segments and data segments have fixed 64k limits,
-+       * the transfer segment sizes are set at run time.
-+       */
-+      .quad 0x0000000000000000        /* 0x90 32-bit code */
-+      .quad 0x0000000000000000        /* 0x98 16-bit code */
-+      .quad 0x0000000000000000        /* 0xa0 16-bit data */
-+      .quad 0x0000000000000000        /* 0xa8 16-bit data */
-+      .quad 0x0000000000000000        /* 0xb0 16-bit data */
-+
-+      /*
-+       * The APM segments have byte granularity and their bases
-+       * are set at run time.  All have 64k limits.
-+       */
-+      .quad 0x0000000000000000        /* 0xb8 APM CS    code */
-+      .quad 0x0000000000000000        /* 0xc0 APM CS 16 code (16 bit) */
-+      .quad 0x0000000000000000        /* 0xc8 APM DS    data */
-+
-+      .quad 0x0000000000000000        /* 0xd0 - ESPFIX 16-bit SS */
-+      .quad 0x0000000000000000        /* 0xd8 - unused */
-+      .quad 0x0000000000000000        /* 0xe0 - unused */
-+      .quad 0x0000000000000000        /* 0xe8 - unused */
-+      .quad 0x0000000000000000        /* 0xf0 - unused */
-+      .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+/*
-+ * __xen_guest information
-+ */
-+.macro utoa value
-+ .if (\value) < 0 || (\value) >= 0x10
-+      utoa (((\value)>>4)&0x0fffffff)
-+ .endif
-+ .if ((\value) & 0xf) < 10
-+  .byte '0' + ((\value) & 0xf)
-+ .else
-+  .byte 'A' + ((\value) & 0xf) - 10
-+ .endif
-+.endm
-+
-+.section __xen_guest
-+      .ascii  "GUEST_OS=linux,GUEST_VER=2.6"
-+      .ascii  ",XEN_VER=xen-3.0"
-+      .ascii  ",VIRT_BASE=0x"
-+              utoa __PAGE_OFFSET
-+      .ascii  ",ELF_PADDR_OFFSET=0x"
-+              utoa __PAGE_OFFSET
-+      .ascii  ",VIRT_ENTRY=0x"
-+              utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
-+      .ascii  ",HYPERCALL_PAGE=0x"
-+              utoa ((__PHYSICAL_START+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT)
-+      .ascii  ",FEATURES=writable_page_tables"
-+      .ascii           "|writable_descriptor_tables"
-+      .ascii           "|auto_translated_physmap"
-+      .ascii           "|pae_pgdir_above_4gb"
-+      .ascii           "|supervisor_mode_kernel"
-+#ifdef CONFIG_X86_PAE
-+      .ascii  ",PAE=yes[extended-cr3]"
-+#else
-+      .ascii  ",PAE=no"
-+#endif
-+      .ascii  ",LOADER=generic"
-+      .byte   0
-+#endif /* CONFIG_XEN_COMPAT_030002 */
-+
-+
-+      ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "linux")       
-+      ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "2.6")
-+      ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
-+      ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long,  __PAGE_OFFSET)
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  __PAGE_OFFSET)
-+#else
-+      ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .long,  0)
-+#endif /* !CONFIG_XEN_COMPAT_030002 */
-+      ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long,  startup_32)
-+      ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long,  hypercall_page)
-+      ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .long,  HYPERVISOR_VIRT_START)
-+      ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
-+#ifdef CONFIG_X86_PAE
-+      ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "yes")
-+#else
-+      ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz, "no")
-+#endif
-+      ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/init_task-xen.c linux-2.6.16.33/arch/i386/kernel/init_task-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/init_task-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/init_task-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,51 @@
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/init_task.h>
-+#include <linux/fs.h>
-+#include <linux/mqueue.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/pgtable.h>
-+#include <asm/desc.h>
-+
-+static struct fs_struct init_fs = INIT_FS;
-+static struct files_struct init_files = INIT_FILES;
-+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-+
-+#define swapper_pg_dir ((pgd_t *)NULL)
-+struct mm_struct init_mm = INIT_MM(init_mm);
-+#undef swapper_pg_dir
-+
-+EXPORT_SYMBOL(init_mm);
-+
-+/*
-+ * Initial thread structure.
-+ *
-+ * We need to make sure that this is THREAD_SIZE aligned due to the
-+ * way process stacks are handled. This is done by having a special
-+ * "init_task" linker map entry..
-+ */
-+union thread_union init_thread_union 
-+      __attribute__((__section__(".data.init_task"))) =
-+              { INIT_THREAD_INFO(init_task) };
-+
-+/*
-+ * Initial task structure.
-+ *
-+ * All other task structs will be allocated on slabs in fork.c
-+ */
-+struct task_struct init_task = INIT_TASK(init_task);
-+
-+EXPORT_SYMBOL(init_task);
-+
-+#ifndef CONFIG_X86_NO_TSS
-+/*
-+ * per-CPU TSS segments. Threads are completely 'soft' on Linux,
-+ * no more per-task TSS's.
-+ */ 
-+DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
-+#endif
-+
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/io_apic-xen.c linux-2.6.16.33/arch/i386/kernel/io_apic-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/io_apic-xen.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/io_apic-xen.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2748 @@
-+/*
-+ *    Intel IO-APIC support for multi-Pentium hosts.
-+ *
-+ *    Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo
-+ *
-+ *    Many thanks to Stig Venaas for trying out countless experimental
-+ *    patches and reporting/debugging problems patiently!
-+ *
-+ *    (c) 1999, Multiple IO-APIC support, developed by
-+ *    Ken-ichi Yaku <yaku@css1.kbnes.nec.co.jp> and
-+ *      Hidemi Kishimoto <kisimoto@css1.kbnes.nec.co.jp>,
-+ *    further tested and cleaned up by Zach Brown <zab@redhat.com>
-+ *    and Ingo Molnar <mingo@redhat.com>
-+ *
-+ *    Fixes
-+ *    Maciej W. Rozycki       :       Bits for genuine 82489DX APICs;
-+ *                                    thanks to Eric Gilmore
-+ *                                    and Rolf G. Tews
-+ *                                    for testing these extensively
-+ *    Paul Diefenbaugh        :       Added full ACPI support
-+ */
-+
-+#include <linux/mm.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/config.h>
-+#include <linux/smp_lock.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/compiler.h>
-+#include <linux/acpi.h>
-+#include <linux/module.h>
-+#include <linux/sysdev.h>
-+
-+#include <asm/io.h>
-+#include <asm/smp.h>
-+#include <asm/desc.h>
-+#include <asm/timer.h>
-+#include <asm/i8259.h>
-+
-+#include <mach_apic.h>
-+
-+#include "io_ports.h"
-+
-+#ifdef CONFIG_XEN
-+
-+#include <xen/interface/xen.h>
-+#include <xen/interface/physdev.h>
-+
-+/* Fake i8259 */
-+#define make_8259A_irq(_irq)     (io_apic_irqs &= ~(1UL<<(_irq)))
-+#define disable_8259A_irq(_irq)  ((void)0)
-+#define i8259A_irq_pending(_irq) (0)
-+
-+unsigned long io_apic_irqs;
-+
-+static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
-+{
-+      struct physdev_apic apic_op;
-+      int ret;
-+
-+      apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
-+      apic_op.reg = reg;
-+      ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
-+      if (ret)
-+              return ret;
-+      return apic_op.value;
-+}
-+
-+static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-+{
-+      struct physdev_apic apic_op;
-+
-+      apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
-+      apic_op.reg = reg;
-+      apic_op.value = value;
-+      HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
-+}
-+
-+#define io_apic_read(a,r)    xen_io_apic_read(a,r)
-+#define io_apic_write(a,r,v) xen_io_apic_write(a,r,v)
-+
-+#endif /* CONFIG_XEN */
-+
-+int (*ioapic_renumber_irq)(int ioapic, int irq);
-+atomic_t irq_mis_count;
-+
-+/* Where if anywhere is the i8259 connect in external int mode */
-+static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
-+
-+static DEFINE_SPINLOCK(ioapic_lock);
-+
-+int timer_over_8254 __initdata = 1;
-+
-+/*
-+ *    Is the SiS APIC rmw bug present ?
-+ *    -1 = don't know, 0 = no, 1 = yes
-+ */
-+int sis_apic_bug = -1;
-+
-+/*
-+ * # of IRQ routing registers
-+ */
-+int nr_ioapic_registers[MAX_IO_APICS];
-+
-+int disable_timer_pin_1 __initdata;
-+
-+/*
-+ * Rough estimation of how many shared IRQs there are, can
-+ * be changed anytime.
-+ */
-+#define MAX_PLUS_SHARED_IRQS NR_IRQS
-+#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
-+
-+/*
-+ * This is performance-critical, we want to do it O(1)
-+ *
-+ * the indexing order of this array favors 1:1 mappings
-+ * between pins and IRQs.
-+ */
-+
-+static struct irq_pin_list {
-+      int apic, pin, next;
-+} irq_2_pin[PIN_MAP_SIZE];
-+
-+int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
-+#ifdef CONFIG_PCI_MSI
-+#define vector_to_irq(vector)         \
-+      (platform_legacy_irq(vector) ? vector : vector_irq[vector])
-+#else
-+#define vector_to_irq(vector) (vector)
-+#endif
-+
-+/*
-+ * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
-+ * shared ISA-space IRQs, so we have to support them. We are super
-+ * fast in the common case, and fast for shared ISA-space IRQs.
-+ */
-+static void add_pin_to_irq(unsigned int irq, int apic, int pin)
-+{
-+      static int first_free_entry = NR_IRQS;
-+      struct irq_pin_list *entry = irq_2_pin + irq;
-+
-+      while (entry->next)
-+              entry = irq_2_pin + entry->next;
-+
-+      if (entry->pin != -1) {
-+              entry->next = first_free_entry;
-+              entry = irq_2_pin + entry->next;
-+              if (++first_free_entry >= PIN_MAP_SIZE)
-+                      panic("io_apic.c: whoops");
-+      }
-+      entry->apic = apic;
-+      entry->pin = pin;
-+}
-+
-+#ifdef CONFIG_XEN
-+#define clear_IO_APIC() ((void)0)
-+#else
-+/*
-+ * Reroute an IRQ to a different pin.
-+ */
-+static void __init replace_pin_at_irq(unsigned int irq,
-+                                    int oldapic, int oldpin,
-+                                    int newapic, int newpin)
-+{
-+      struct irq_pin_list *entry = irq_2_pin + irq;
-+
-+      while (1) {
-+              if (entry->apic == oldapic && entry->pin == oldpin) {
-+                      entry->apic = newapic;
-+                      entry->pin = newpin;
-+              }
-+              if (!entry->next)
-+                      break;
-+              entry = irq_2_pin + entry->next;
-+      }
-+}
-+
-+static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable)
-+{
-+      struct irq_pin_list *entry = irq_2_pin + irq;
-+      unsigned int pin, reg;
-+
-+      for (;;) {
-+              pin = entry->pin;
-+              if (pin == -1)
-+                      break;
-+              reg = io_apic_read(entry->apic, 0x10 + pin*2);
-+              reg &= ~disable;
-+              reg |= enable;
-+              io_apic_modify(entry->apic, 0x10 + pin*2, reg);
-+              if (!entry->next)
-+                      break;
-+              entry = irq_2_pin + entry->next;
-+      }
-+}
-+
-+/* mask = 1 */
-+static void __mask_IO_APIC_irq (unsigned int irq)
-+{
-+      __modify_IO_APIC_irq(irq, 0x00010000, 0);
-+}
-+
-+/* mask = 0 */
-+static void __unmask_IO_APIC_irq (unsigned int irq)
-+{
-+      __modify_IO_APIC_irq(irq, 0, 0x00010000);
-+}
-+
-+/* mask = 1, trigger = 0 */
-+static void __mask_and_edge_IO_APIC_irq (unsigned int irq)
-+{
-+      __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000);
-+}
-+
-+/* mask = 0, trigger = 1 */
-+static void __unmask_and_level_IO_APIC_irq (unsigned int irq)
-+{
-+      __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000);
-+}
-+
-+static void mask_IO_APIC_irq (unsigned int irq)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      __mask_IO_APIC_irq(irq);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+static void unmask_IO_APIC_irq (unsigned int irq)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      __unmask_IO_APIC_irq(irq);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
-+{
-+      struct IO_APIC_route_entry entry;
-+      unsigned long flags;
-+      
-+      /* Check delivery_mode to be sure we're not clearing an SMI pin */
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
-+      *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+      if (entry.delivery_mode == dest_SMI)
-+              return;
-+
-+      /*
-+       * Disable it in the IO-APIC irq-routing table:
-+       */
-+      memset(&entry, 0, sizeof(entry));
-+      entry.mask = 1;
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0));
-+      io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+static void clear_IO_APIC (void)
-+{
-+      int apic, pin;
-+
-+      for (apic = 0; apic < nr_ioapics; apic++)
-+              for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
-+                      clear_IO_APIC_pin(apic, pin);
-+}
-+
-+#ifdef CONFIG_SMP
-+static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
-+{
-+      unsigned long flags;
-+      int pin;
-+      struct irq_pin_list *entry = irq_2_pin + irq;
-+      unsigned int apicid_value;
-+      cpumask_t tmp;
-+      
-+      cpus_and(tmp, cpumask, cpu_online_map);
-+      if (cpus_empty(tmp))
-+              tmp = TARGET_CPUS;
-+
-+      cpus_and(cpumask, tmp, CPU_MASK_ALL);
-+
-+      apicid_value = cpu_mask_to_apicid(cpumask);
-+      /* Prepare to do the io_apic_write */
-+      apicid_value = apicid_value << 24;
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      for (;;) {
-+              pin = entry->pin;
-+              if (pin == -1)
-+                      break;
-+              io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value);
-+              if (!entry->next)
-+                      break;
-+              entry = irq_2_pin + entry->next;
-+      }
-+      set_irq_info(irq, cpumask);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+#if defined(CONFIG_IRQBALANCE)
-+# include <asm/processor.h>   /* kernel_thread() */
-+# include <linux/kernel_stat.h>       /* kstat */
-+# include <linux/slab.h>              /* kmalloc() */
-+# include <linux/timer.h>     /* time_after() */
-+ 
-+# ifdef CONFIG_BALANCED_IRQ_DEBUG
-+#  define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
-+#  define Dprintk(x...) do { TDprintk(x); } while (0)
-+# else
-+#  define TDprintk(x...) 
-+#  define Dprintk(x...) 
-+# endif
-+
-+
-+#define IRQBALANCE_CHECK_ARCH -999
-+static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH;
-+static int physical_balance = 0;
-+
-+static struct irq_cpu_info {
-+      unsigned long * last_irq;
-+      unsigned long * irq_delta;
-+      unsigned long irq;
-+} irq_cpu_data[NR_CPUS];
-+
-+#define CPU_IRQ(cpu)          (irq_cpu_data[cpu].irq)
-+#define LAST_CPU_IRQ(cpu,irq)   (irq_cpu_data[cpu].last_irq[irq])
-+#define IRQ_DELTA(cpu,irq)    (irq_cpu_data[cpu].irq_delta[irq])
-+
-+#define IDLE_ENOUGH(cpu,now) \
-+      (idle_cpu(cpu) && ((now) - per_cpu(irq_stat, (cpu)).idle_timestamp > 1))
-+
-+#define IRQ_ALLOWED(cpu, allowed_mask)        cpu_isset(cpu, allowed_mask)
-+
-+#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i]))
-+
-+#define MAX_BALANCED_IRQ_INTERVAL     (5*HZ)
-+#define MIN_BALANCED_IRQ_INTERVAL     (HZ/2)
-+#define BALANCED_IRQ_MORE_DELTA               (HZ/10)
-+#define BALANCED_IRQ_LESS_DELTA               (HZ)
-+
-+static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL;
-+
-+static unsigned long move(int curr_cpu, cpumask_t allowed_mask,
-+                      unsigned long now, int direction)
-+{
-+      int search_idle = 1;
-+      int cpu = curr_cpu;
-+
-+      goto inside;
-+
-+      do {
-+              if (unlikely(cpu == curr_cpu))
-+                      search_idle = 0;
-+inside:
-+              if (direction == 1) {
-+                      cpu++;
-+                      if (cpu >= NR_CPUS)
-+                              cpu = 0;
-+              } else {
-+                      cpu--;
-+                      if (cpu == -1)
-+                              cpu = NR_CPUS-1;
-+              }
-+      } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu,allowed_mask) ||
-+                      (search_idle && !IDLE_ENOUGH(cpu,now)));
-+
-+      return cpu;
-+}
-+
-+static inline void balance_irq(int cpu, int irq)
-+{
-+      unsigned long now = jiffies;
-+      cpumask_t allowed_mask;
-+      unsigned int new_cpu;
-+              
-+      if (irqbalance_disabled)
-+              return; 
-+
-+      cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]);
-+      new_cpu = move(cpu, allowed_mask, now, 1);
-+      if (cpu != new_cpu) {
-+              set_pending_irq(irq, cpumask_of_cpu(new_cpu));
-+      }
-+}
-+
-+static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold)
-+{
-+      int i, j;
-+      Dprintk("Rotating IRQs among CPUs.\n");
-+      for (i = 0; i < NR_CPUS; i++) {
-+              for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) {
-+                      if (!irq_desc[j].action)
-+                              continue;
-+                      /* Is it a significant load ?  */
-+                      if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i),j) <
-+                                              useful_load_threshold)
-+                              continue;
-+                      balance_irq(i, j);
-+              }
-+      }
-+      balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL,
-+              balanced_irq_interval - BALANCED_IRQ_LESS_DELTA);       
-+      return;
-+}
-+
-+static void do_irq_balance(void)
-+{
-+      int i, j;
-+      unsigned long max_cpu_irq = 0, min_cpu_irq = (~0);
-+      unsigned long move_this_load = 0;
-+      int max_loaded = 0, min_loaded = 0;
-+      int load;
-+      unsigned long useful_load_threshold = balanced_irq_interval + 10;
-+      int selected_irq;
-+      int tmp_loaded, first_attempt = 1;
-+      unsigned long tmp_cpu_irq;
-+      unsigned long imbalance = 0;
-+      cpumask_t allowed_mask, target_cpu_mask, tmp;
-+
-+      for (i = 0; i < NR_CPUS; i++) {
-+              int package_index;
-+              CPU_IRQ(i) = 0;
-+              if (!cpu_online(i))
-+                      continue;
-+              package_index = CPU_TO_PACKAGEINDEX(i);
-+              for (j = 0; j < NR_IRQS; j++) {
-+                      unsigned long value_now, delta;
-+                      /* Is this an active IRQ? */
-+                      if (!irq_desc[j].action)
-+                              continue;
-+                      if ( package_index == i )
-+                              IRQ_DELTA(package_index,j) = 0;
-+                      /* Determine the total count per processor per IRQ */
-+                      value_now = (unsigned long) kstat_cpu(i).irqs[j];
-+
-+                      /* Determine the activity per processor per IRQ */
-+                      delta = value_now - LAST_CPU_IRQ(i,j);
-+
-+                      /* Update last_cpu_irq[][] for the next time */
-+                      LAST_CPU_IRQ(i,j) = value_now;
-+
-+                      /* Ignore IRQs whose rate is less than the clock */
-+                      if (delta < useful_load_threshold)
-+                              continue;
-+                      /* update the load for the processor or package total */
-+                      IRQ_DELTA(package_index,j) += delta;
-+
-+                      /* Keep track of the higher numbered sibling as well */
-+                      if (i != package_index)
-+                              CPU_IRQ(i) += delta;
-+                      /*
-+                       * We have sibling A and sibling B in the package
-+                       *
-+                       * cpu_irq[A] = load for cpu A + load for cpu B
-+                       * cpu_irq[B] = load for cpu B
-+                       */
-+                      CPU_IRQ(package_index) += delta;
-+              }
-+      }
-+      /* Find the least loaded processor package */
-+      for (i = 0; i < NR_CPUS; i++) {
-+              if (!cpu_online(i))
-+                      continue;
-+              if (i != CPU_TO_PACKAGEINDEX(i))
-+                      continue;
-+              if (min_cpu_irq > CPU_IRQ(i)) {
-+                      min_cpu_irq = CPU_IRQ(i);
-+                      min_loaded = i;
-+              }
-+      }
-+      max_cpu_irq = ULONG_MAX;
-+
-+tryanothercpu:
-+      /* Look for heaviest loaded processor.
-+       * We may come back to get the next heaviest loaded processor.
-+       * Skip processors with trivial loads.
-+       */
-+      tmp_cpu_irq = 0;
-+      tmp_loaded = -1;
-+      for (i = 0; i < NR_CPUS; i++) {
-+              if (!cpu_online(i))
-+                      continue;
-+              if (i != CPU_TO_PACKAGEINDEX(i))
-+                      continue;
-+              if (max_cpu_irq <= CPU_IRQ(i)) 
-+                      continue;
-+              if (tmp_cpu_irq < CPU_IRQ(i)) {
-+                      tmp_cpu_irq = CPU_IRQ(i);
-+                      tmp_loaded = i;
-+              }
-+      }
-+
-+      if (tmp_loaded == -1) {
-+       /* In the case of small number of heavy interrupt sources, 
-+        * loading some of the cpus too much. We use Ingo's original 
-+        * approach to rotate them around.
-+        */
-+              if (!first_attempt && imbalance >= useful_load_threshold) {
-+                      rotate_irqs_among_cpus(useful_load_threshold);
-+                      return;
-+              }
-+              goto not_worth_the_effort;
-+      }
-+      
-+      first_attempt = 0;              /* heaviest search */
-+      max_cpu_irq = tmp_cpu_irq;      /* load */
-+      max_loaded = tmp_loaded;        /* processor */
-+      imbalance = (max_cpu_irq - min_cpu_irq) / 2;
-+      
-+      Dprintk("max_loaded cpu = %d\n", max_loaded);
-+      Dprintk("min_loaded cpu = %d\n", min_loaded);
-+      Dprintk("max_cpu_irq load = %ld\n", max_cpu_irq);
-+      Dprintk("min_cpu_irq load = %ld\n", min_cpu_irq);
-+      Dprintk("load imbalance = %lu\n", imbalance);
-+
-+      /* if imbalance is less than approx 10% of max load, then
-+       * observe diminishing returns action. - quit
-+       */
-+      if (imbalance < (max_cpu_irq >> 3)) {
-+              Dprintk("Imbalance too trivial\n");
-+              goto not_worth_the_effort;
-+      }
-+
-+tryanotherirq:
-+      /* if we select an IRQ to move that can't go where we want, then
-+       * see if there is another one to try.
-+       */
-+      move_this_load = 0;
-+      selected_irq = -1;
-+      for (j = 0; j < NR_IRQS; j++) {
-+              /* Is this an active IRQ? */
-+              if (!irq_desc[j].action)
-+                      continue;
-+              if (imbalance <= IRQ_DELTA(max_loaded,j))
-+                      continue;
-+              /* Try to find the IRQ that is closest to the imbalance
-+               * without going over.
-+               */
-+              if (move_this_load < IRQ_DELTA(max_loaded,j)) {
-+                      move_this_load = IRQ_DELTA(max_loaded,j);
-+                      selected_irq = j;
-+              }
-+      }
-+      if (selected_irq == -1) {
-+              goto tryanothercpu;
-+      }
-+
-+      imbalance = move_this_load;
-+      
-+      /* For physical_balance case, we accumlated both load
-+       * values in the one of the siblings cpu_irq[],
-+       * to use the same code for physical and logical processors
-+       * as much as possible. 
-+       *
-+       * NOTE: the cpu_irq[] array holds the sum of the load for
-+       * sibling A and sibling B in the slot for the lowest numbered
-+       * sibling (A), _AND_ the load for sibling B in the slot for
-+       * the higher numbered sibling.
-+       *
-+       * We seek the least loaded sibling by making the comparison
-+       * (A+B)/2 vs B
-+       */
-+      load = CPU_IRQ(min_loaded) >> 1;
-+      for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) {
-+              if (load > CPU_IRQ(j)) {
-+                      /* This won't change cpu_sibling_map[min_loaded] */
-+                      load = CPU_IRQ(j);
-+                      min_loaded = j;
-+              }
-+      }
-+
-+      cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]);
-+      target_cpu_mask = cpumask_of_cpu(min_loaded);
-+      cpus_and(tmp, target_cpu_mask, allowed_mask);
-+
-+      if (!cpus_empty(tmp)) {
-+
-+              Dprintk("irq = %d moved to cpu = %d\n",
-+                              selected_irq, min_loaded);
-+              /* mark for change destination */
-+              set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded));
-+
-+              /* Since we made a change, come back sooner to 
-+               * check for more variation.
-+               */
-+              balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL,
-+                      balanced_irq_interval - BALANCED_IRQ_LESS_DELTA);       
-+              return;
-+      }
-+      goto tryanotherirq;
-+
-+not_worth_the_effort:
-+      /*
-+       * if we did not find an IRQ to move, then adjust the time interval
-+       * upward
-+       */
-+      balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL,
-+              balanced_irq_interval + BALANCED_IRQ_MORE_DELTA);       
-+      Dprintk("IRQ worth rotating not found\n");
-+      return;
-+}
-+
-+static int balanced_irq(void *unused)
-+{
-+      int i;
-+      unsigned long prev_balance_time = jiffies;
-+      long time_remaining = balanced_irq_interval;
-+
-+      daemonize("kirqd");
-+      
-+      /* push everything to CPU 0 to give us a starting point.  */
-+      for (i = 0 ; i < NR_IRQS ; i++) {
-+              pending_irq_cpumask[i] = cpumask_of_cpu(0);
-+              set_pending_irq(i, cpumask_of_cpu(0));
-+      }
-+
-+      for ( ; ; ) {
-+              time_remaining = schedule_timeout_interruptible(time_remaining);
-+              try_to_freeze();
-+              if (time_after(jiffies,
-+                              prev_balance_time+balanced_irq_interval)) {
-+                      preempt_disable();
-+                      do_irq_balance();
-+                      prev_balance_time = jiffies;
-+                      time_remaining = balanced_irq_interval;
-+                      preempt_enable();
-+              }
-+      }
-+      return 0;
-+}
-+
-+static int __init balanced_irq_init(void)
-+{
-+      int i;
-+      struct cpuinfo_x86 *c;
-+      cpumask_t tmp;
-+
-+      cpus_shift_right(tmp, cpu_online_map, 2);
-+        c = &boot_cpu_data;
-+      /* When not overwritten by the command line ask subarchitecture. */
-+      if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH)
-+              irqbalance_disabled = NO_BALANCE_IRQ;
-+      if (irqbalance_disabled)
-+              return 0;
-+      
-+       /* disable irqbalance completely if there is only one processor online */
-+      if (num_online_cpus() < 2) {
-+              irqbalance_disabled = 1;
-+              return 0;
-+      }
-+      /*
-+       * Enable physical balance only if more than 1 physical processor
-+       * is present
-+       */
-+      if (smp_num_siblings > 1 && !cpus_empty(tmp))
-+              physical_balance = 1;
-+
-+      for (i = 0; i < NR_CPUS; i++) {
-+              if (!cpu_online(i))
-+                      continue;
-+              irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
-+              irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
-+              if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) {
-+                      printk(KERN_ERR "balanced_irq_init: out of memory");
-+                      goto failed;
-+              }
-+              memset(irq_cpu_data[i].irq_delta,0,sizeof(unsigned long) * NR_IRQS);
-+              memset(irq_cpu_data[i].last_irq,0,sizeof(unsigned long) * NR_IRQS);
-+      }
-+      
-+      printk(KERN_INFO "Starting balanced_irq\n");
-+      if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) 
-+              return 0;
-+      else 
-+              printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
-+failed:
-+      for (i = 0; i < NR_CPUS; i++) {
-+              kfree(irq_cpu_data[i].irq_delta);
-+              kfree(irq_cpu_data[i].last_irq);
-+      }
-+      return 0;
-+}
-+
-+int __init irqbalance_disable(char *str)
-+{
-+      irqbalance_disabled = 1;
-+      return 0;
-+}
-+
-+__setup("noirqbalance", irqbalance_disable);
-+
-+late_initcall(balanced_irq_init);
-+#endif /* CONFIG_IRQBALANCE */
-+#endif /* CONFIG_SMP */
-+#endif
-+
-+#ifndef CONFIG_SMP
-+void fastcall send_IPI_self(int vector)
-+{
-+#ifndef CONFIG_XEN
-+      unsigned int cfg;
-+
-+      /*
-+       * Wait for idle.
-+       */
-+      apic_wait_icr_idle();
-+      cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
-+      /*
-+       * Send the IPI. The write to APIC_ICR fires this off.
-+       */
-+      apic_write_around(APIC_ICR, cfg);
-+#endif
-+}
-+#endif /* !CONFIG_SMP */
-+
-+
-+/*
-+ * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
-+ * specific CPU-side IRQs.
-+ */
-+
-+#define MAX_PIRQS 8
-+static int pirq_entries [MAX_PIRQS];
-+static int pirqs_enabled;
-+int skip_ioapic_setup;
-+
-+static int __init ioapic_setup(char *str)
-+{
-+      skip_ioapic_setup = 1;
-+      return 1;
-+}
-+
-+__setup("noapic", ioapic_setup);
-+
-+static int __init ioapic_pirq_setup(char *str)
-+{
-+      int i, max;
-+      int ints[MAX_PIRQS+1];
-+
-+      get_options(str, ARRAY_SIZE(ints), ints);
-+
-+      for (i = 0; i < MAX_PIRQS; i++)
-+              pirq_entries[i] = -1;
-+
-+      pirqs_enabled = 1;
-+      apic_printk(APIC_VERBOSE, KERN_INFO
-+                      "PIRQ redirection, working around broken MP-BIOS.\n");
-+      max = MAX_PIRQS;
-+      if (ints[0] < MAX_PIRQS)
-+              max = ints[0];
-+
-+      for (i = 0; i < max; i++) {
-+              apic_printk(APIC_VERBOSE, KERN_DEBUG
-+                              "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
-+              /*
-+               * PIRQs are mapped upside down, usually.
-+               */
-+              pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
-+      }
-+      return 1;
-+}
-+
-+__setup("pirq=", ioapic_pirq_setup);
-+
-+/*
-+ * Find the IRQ entry number of a certain pin.
-+ */
-+static int find_irq_entry(int apic, int pin, int type)
-+{
-+      int i;
-+
-+      for (i = 0; i < mp_irq_entries; i++)
-+              if (mp_irqs[i].mpc_irqtype == type &&
-+                  (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid ||
-+                   mp_irqs[i].mpc_dstapic == MP_APIC_ALL) &&
-+                  mp_irqs[i].mpc_dstirq == pin)
-+                      return i;
-+
-+      return -1;
-+}
-+
-+/*
-+ * Find the pin to which IRQ[irq] (ISA) is connected
-+ */
-+static int __init find_isa_irq_pin(int irq, int type)
-+{
-+      int i;
-+
-+      for (i = 0; i < mp_irq_entries; i++) {
-+              int lbus = mp_irqs[i].mpc_srcbus;
-+
-+              if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_NEC98
-+                  ) &&
-+                  (mp_irqs[i].mpc_irqtype == type) &&
-+                  (mp_irqs[i].mpc_srcbusirq == irq))
-+
-+                      return mp_irqs[i].mpc_dstirq;
-+      }
-+      return -1;
-+}
-+
-+static int __init find_isa_irq_apic(int irq, int type)
-+{
-+      int i;
-+
-+      for (i = 0; i < mp_irq_entries; i++) {
-+              int lbus = mp_irqs[i].mpc_srcbus;
-+
-+              if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_NEC98
-+                  ) &&
-+                  (mp_irqs[i].mpc_irqtype == type) &&
-+                  (mp_irqs[i].mpc_srcbusirq == irq))
-+                      break;
-+      }
-+      if (i < mp_irq_entries) {
-+              int apic;
-+              for(apic = 0; apic < nr_ioapics; apic++) {
-+                      if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
-+                              return apic;
-+              }
-+      }
-+
-+      return -1;
-+}
-+
-+/*
-+ * Find a specific PCI IRQ entry.
-+ * Not an __init, possibly needed by modules
-+ */
-+static int pin_2_irq(int idx, int apic, int pin);
-+
-+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
-+{
-+      int apic, i, best_guess = -1;
-+
-+      apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, "
-+              "slot:%d, pin:%d.\n", bus, slot, pin);
-+      if (mp_bus_id_to_pci_bus[bus] == -1) {
-+              printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
-+              return -1;
-+      }
-+      for (i = 0; i < mp_irq_entries; i++) {
-+              int lbus = mp_irqs[i].mpc_srcbus;
-+
-+              for (apic = 0; apic < nr_ioapics; apic++)
-+                      if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic ||
-+                          mp_irqs[i].mpc_dstapic == MP_APIC_ALL)
-+                              break;
-+
-+              if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
-+                  !mp_irqs[i].mpc_irqtype &&
-+                  (bus == lbus) &&
-+                  (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
-+                      int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
-+
-+                      if (!(apic || IO_APIC_IRQ(irq)))
-+                              continue;
-+
-+                      if (pin == (mp_irqs[i].mpc_srcbusirq & 3))
-+                              return irq;
-+                      /*
-+                       * Use the first all-but-pin matching entry as a
-+                       * best-guess fuzzy result for broken mptables.
-+                       */
-+                      if (best_guess < 0)
-+                              best_guess = irq;
-+              }
-+      }
-+      return best_guess;
-+}
-+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-+
-+/*
-+ * This function currently is only a helper for the i386 smp boot process where 
-+ * we need to reprogram the ioredtbls to cater for the cpus which have come online
-+ * so mask in all cases should simply be TARGET_CPUS
-+ */
-+#ifdef CONFIG_SMP
-+#ifndef CONFIG_XEN
-+void __init setup_ioapic_dest(void)
-+{
-+      int pin, ioapic, irq, irq_entry;
-+
-+      if (skip_ioapic_setup == 1)
-+              return;
-+
-+      for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
-+              for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
-+                      irq_entry = find_irq_entry(ioapic, pin, mp_INT);
-+                      if (irq_entry == -1)
-+                              continue;
-+                      irq = pin_2_irq(irq_entry, ioapic, pin);
-+                      set_ioapic_affinity_irq(irq, TARGET_CPUS);
-+              }
-+
-+      }
-+}
-+#endif /* !CONFIG_XEN */
-+#endif
-+
-+/*
-+ * EISA Edge/Level control register, ELCR
-+ */
-+static int EISA_ELCR(unsigned int irq)
-+{
-+      if (irq < 16) {
-+              unsigned int port = 0x4d0 + (irq >> 3);
-+              return (inb(port) >> (irq & 7)) & 1;
-+      }
-+      apic_printk(APIC_VERBOSE, KERN_INFO
-+                      "Broken MPtable reports ISA irq %d\n", irq);
-+      return 0;
-+}
-+
-+/* EISA interrupts are always polarity zero and can be edge or level
-+ * trigger depending on the ELCR value.  If an interrupt is listed as
-+ * EISA conforming in the MP table, that means its trigger type must
-+ * be read in from the ELCR */
-+
-+#define default_EISA_trigger(idx)     (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq))
-+#define default_EISA_polarity(idx)    (0)
-+
-+/* ISA interrupts are always polarity zero edge triggered,
-+ * when listed as conforming in the MP table. */
-+
-+#define default_ISA_trigger(idx)      (0)
-+#define default_ISA_polarity(idx)     (0)
-+
-+/* PCI interrupts are always polarity one level triggered,
-+ * when listed as conforming in the MP table. */
-+
-+#define default_PCI_trigger(idx)      (1)
-+#define default_PCI_polarity(idx)     (1)
-+
-+/* MCA interrupts are always polarity zero level triggered,
-+ * when listed as conforming in the MP table. */
-+
-+#define default_MCA_trigger(idx)      (1)
-+#define default_MCA_polarity(idx)     (0)
-+
-+/* NEC98 interrupts are always polarity zero edge triggered,
-+ * when listed as conforming in the MP table. */
-+
-+#define default_NEC98_trigger(idx)     (0)
-+#define default_NEC98_polarity(idx)    (0)
-+
-+static int __init MPBIOS_polarity(int idx)
-+{
-+      int bus = mp_irqs[idx].mpc_srcbus;
-+      int polarity;
-+
-+      /*
-+       * Determine IRQ line polarity (high active or low active):
-+       */
-+      switch (mp_irqs[idx].mpc_irqflag & 3)
-+      {
-+              case 0: /* conforms, ie. bus-type dependent polarity */
-+              {
-+                      switch (mp_bus_id_to_type[bus])
-+                      {
-+                              case MP_BUS_ISA: /* ISA pin */
-+                              {
-+                                      polarity = default_ISA_polarity(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_EISA: /* EISA pin */
-+                              {
-+                                      polarity = default_EISA_polarity(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_PCI: /* PCI pin */
-+                              {
-+                                      polarity = default_PCI_polarity(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_MCA: /* MCA pin */
-+                              {
-+                                      polarity = default_MCA_polarity(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_NEC98: /* NEC 98 pin */
-+                              {
-+                                      polarity = default_NEC98_polarity(idx);
-+                                      break;
-+                              }
-+                              default:
-+                              {
-+                                      printk(KERN_WARNING "broken BIOS!!\n");
-+                                      polarity = 1;
-+                                      break;
-+                              }
-+                      }
-+                      break;
-+              }
-+              case 1: /* high active */
-+              {
-+                      polarity = 0;
-+                      break;
-+              }
-+              case 2: /* reserved */
-+              {
-+                      printk(KERN_WARNING "broken BIOS!!\n");
-+                      polarity = 1;
-+                      break;
-+              }
-+              case 3: /* low active */
-+              {
-+                      polarity = 1;
-+                      break;
-+              }
-+              default: /* invalid */
-+              {
-+                      printk(KERN_WARNING "broken BIOS!!\n");
-+                      polarity = 1;
-+                      break;
-+              }
-+      }
-+      return polarity;
-+}
-+
-+static int MPBIOS_trigger(int idx)
-+{
-+      int bus = mp_irqs[idx].mpc_srcbus;
-+      int trigger;
-+
-+      /*
-+       * Determine IRQ trigger mode (edge or level sensitive):
-+       */
-+      switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
-+      {
-+              case 0: /* conforms, ie. bus-type dependent */
-+              {
-+                      switch (mp_bus_id_to_type[bus])
-+                      {
-+                              case MP_BUS_ISA: /* ISA pin */
-+                              {
-+                                      trigger = default_ISA_trigger(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_EISA: /* EISA pin */
-+                              {
-+                                      trigger = default_EISA_trigger(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_PCI: /* PCI pin */
-+                              {
-+                                      trigger = default_PCI_trigger(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_MCA: /* MCA pin */
-+                              {
-+                                      trigger = default_MCA_trigger(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_NEC98: /* NEC 98 pin */
-+                              {
-+                                      trigger = default_NEC98_trigger(idx);
-+                                      break;
-+                              }
-+                              default:
-+                              {
-+                                      printk(KERN_WARNING "broken BIOS!!\n");
-+                                      trigger = 1;
-+                                      break;
-+                              }
-+                      }
-+                      break;
-+              }
-+              case 1: /* edge */
-+              {
-+                      trigger = 0;
-+                      break;
-+              }
-+              case 2: /* reserved */
-+              {
-+                      printk(KERN_WARNING "broken BIOS!!\n");
-+                      trigger = 1;
-+                      break;
-+              }
-+              case 3: /* level */
-+              {
-+                      trigger = 1;
-+                      break;
-+              }
-+              default: /* invalid */
-+              {
-+                      printk(KERN_WARNING "broken BIOS!!\n");
-+                      trigger = 0;
-+                      break;
-+              }
-+      }
-+      return trigger;
-+}
-+
-+static inline int irq_polarity(int idx)
-+{
-+      return MPBIOS_polarity(idx);
-+}
-+
-+static inline int irq_trigger(int idx)
-+{
-+      return MPBIOS_trigger(idx);
-+}
-+
-+static int pin_2_irq(int idx, int apic, int pin)
-+{
-+      int irq, i;
-+      int bus = mp_irqs[idx].mpc_srcbus;
-+
-+      /*
-+       * Debugging check, we are in big trouble if this message pops up!
-+       */
-+      if (mp_irqs[idx].mpc_dstirq != pin)
-+              printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
-+
-+      switch (mp_bus_id_to_type[bus])
-+      {
-+              case MP_BUS_ISA: /* ISA pin */
-+              case MP_BUS_EISA:
-+              case MP_BUS_MCA:
-+              case MP_BUS_NEC98:
-+              {
-+                      irq = mp_irqs[idx].mpc_srcbusirq;
-+                      break;
-+              }
-+              case MP_BUS_PCI: /* PCI pin */
-+              {
-+                      /*
-+                       * PCI IRQs are mapped in order
-+                       */
-+                      i = irq = 0;
-+                      while (i < apic)
-+                              irq += nr_ioapic_registers[i++];
-+                      irq += pin;
-+
-+                      /*
-+                       * For MPS mode, so far only needed by ES7000 platform
-+                       */
-+                      if (ioapic_renumber_irq)
-+                              irq = ioapic_renumber_irq(apic, irq);
-+
-+                      break;
-+              }
-+              default:
-+              {
-+                      printk(KERN_ERR "unknown bus type %d.\n",bus); 
-+                      irq = 0;
-+                      break;
-+              }
-+      }
-+
-+      /*
-+       * PCI IRQ command line redirection. Yes, limits are hardcoded.
-+       */
-+      if ((pin >= 16) && (pin <= 23)) {
-+              if (pirq_entries[pin-16] != -1) {
-+                      if (!pirq_entries[pin-16]) {
-+                              apic_printk(APIC_VERBOSE, KERN_DEBUG
-+                                              "disabling PIRQ%d\n", pin-16);
-+                      } else {
-+                              irq = pirq_entries[pin-16];
-+                              apic_printk(APIC_VERBOSE, KERN_DEBUG
-+                                              "using PIRQ%d -> IRQ %d\n",
-+                                              pin-16, irq);
-+                      }
-+              }
-+      }
-+      return irq;
-+}
-+
-+static inline int IO_APIC_irq_trigger(int irq)
-+{
-+      int apic, idx, pin;
-+
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+              for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-+                      idx = find_irq_entry(apic,pin,mp_INT);
-+                      if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin)))
-+                              return irq_trigger(idx);
-+              }
-+      }
-+      /*
-+       * nonexistent IRQs are edge default
-+       */
-+      return 0;
-+}
-+
-+/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-+u8 irq_vector[NR_IRQ_VECTORS] __read_mostly; /* = { FIRST_DEVICE_VECTOR , 0 }; */
-+
-+int assign_irq_vector(int irq)
-+{
-+      struct physdev_irq irq_op;
-+
-+      BUG_ON(irq >= NR_IRQ_VECTORS);
-+      if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
-+              return IO_APIC_VECTOR(irq);
-+
-+      irq_op.irq = irq;
-+      if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
-+              return -ENOSPC;
-+
-+      vector_irq[irq_op.vector] = irq;
-+      if (irq != AUTO_ASSIGN)
-+              IO_APIC_VECTOR(irq) = irq_op.vector;
-+
-+      return irq_op.vector;
-+}
-+
-+#ifndef CONFIG_XEN
-+static struct hw_interrupt_type ioapic_level_type;
-+static struct hw_interrupt_type ioapic_edge_type;
-+
-+#define IOAPIC_AUTO   -1
-+#define IOAPIC_EDGE   0
-+#define IOAPIC_LEVEL  1
-+
-+static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger)
-+{
-+      if (use_pci_vector() && !platform_legacy_irq(irq)) {
-+              if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
-+                              trigger == IOAPIC_LEVEL)
-+                      irq_desc[vector].handler = &ioapic_level_type;
-+              else
-+                      irq_desc[vector].handler = &ioapic_edge_type;
-+              set_intr_gate(vector, interrupt[vector]);
-+      } else  {
-+              if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
-+                              trigger == IOAPIC_LEVEL)
-+                      irq_desc[irq].handler = &ioapic_level_type;
-+              else
-+                      irq_desc[irq].handler = &ioapic_edge_type;
-+              set_intr_gate(vector, interrupt[irq]);
-+      }
-+}
-+#else
-+#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0)
-+#endif
-+
-+static void __init setup_IO_APIC_irqs(void)
-+{
-+      struct IO_APIC_route_entry entry;
-+      int apic, pin, idx, irq, first_notcon = 1, vector;
-+      unsigned long flags;
-+
-+      apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
-+
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+      for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-+
-+              /*
-+               * add it to the IO-APIC irq-routing table:
-+               */
-+              memset(&entry,0,sizeof(entry));
-+
-+              entry.delivery_mode = INT_DELIVERY_MODE;
-+              entry.dest_mode = INT_DEST_MODE;
-+              entry.mask = 0;                         /* enable IRQ */
-+              entry.dest.logical.logical_dest = 
-+                                      cpu_mask_to_apicid(TARGET_CPUS);
-+
-+              idx = find_irq_entry(apic,pin,mp_INT);
-+              if (idx == -1) {
-+                      if (first_notcon) {
-+                              apic_printk(APIC_VERBOSE, KERN_DEBUG
-+                                              " IO-APIC (apicid-pin) %d-%d",
-+                                              mp_ioapics[apic].mpc_apicid,
-+                                              pin);
-+                              first_notcon = 0;
-+                      } else
-+                              apic_printk(APIC_VERBOSE, ", %d-%d",
-+                                      mp_ioapics[apic].mpc_apicid, pin);
-+                      continue;
-+              }
-+
-+              entry.trigger = irq_trigger(idx);
-+              entry.polarity = irq_polarity(idx);
-+
-+              if (irq_trigger(idx)) {
-+                      entry.trigger = 1;
-+                      entry.mask = 1;
-+              }
-+
-+              irq = pin_2_irq(idx, apic, pin);
-+              /*
-+               * skip adding the timer int on secondary nodes, which causes
-+               * a small but painful rift in the time-space continuum
-+               */
-+              if (multi_timer_check(apic, irq))
-+                      continue;
-+              else
-+                      add_pin_to_irq(irq, apic, pin);
-+
-+              if (/*!apic &&*/ !IO_APIC_IRQ(irq))
-+                      continue;
-+
-+              if (IO_APIC_IRQ(irq)) {
-+                      vector = assign_irq_vector(irq);
-+                      entry.vector = vector;
-+                      ioapic_register_intr(irq, vector, IOAPIC_AUTO);
-+              
-+                      if (!apic && (irq < 16))
-+                              disable_8259A_irq(irq);
-+              }
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
-+              io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
-+              set_native_irq_info(irq, TARGET_CPUS);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+      }
-+      }
-+
-+      if (!first_notcon)
-+              apic_printk(APIC_VERBOSE, " not connected.\n");
-+}
-+
-+/*
-+ * Set up the 8259A-master output pin:
-+ */
-+#ifndef CONFIG_XEN
-+static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
-+{
-+      struct IO_APIC_route_entry entry;
-+      unsigned long flags;
-+
-+      memset(&entry,0,sizeof(entry));
-+
-+      disable_8259A_irq(0);
-+
-+      /* mask LVT0 */
-+      apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
-+
-+      /*
-+       * We use logical delivery to get the timer IRQ
-+       * to the first CPU.
-+       */
-+      entry.dest_mode = INT_DEST_MODE;
-+      entry.mask = 0;                                 /* unmask IRQ now */
-+      entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-+      entry.delivery_mode = INT_DELIVERY_MODE;
-+      entry.polarity = 0;
-+      entry.trigger = 0;
-+      entry.vector = vector;
-+
-+      /*
-+       * The timer IRQ doesn't have to know that behind the
-+       * scene we have a 8259A-master in AEOI mode ...
-+       */
-+      irq_desc[0].handler = &ioapic_edge_type;
-+
-+      /*
-+       * Add it to the IO-APIC irq-routing table:
-+       */
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
-+      io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      enable_8259A_irq(0);
-+}
-+
-+static inline void UNEXPECTED_IO_APIC(void)
-+{
-+}
-+
-+void __init print_IO_APIC(void)
-+{
-+      int apic, i;
-+      union IO_APIC_reg_00 reg_00;
-+      union IO_APIC_reg_01 reg_01;
-+      union IO_APIC_reg_02 reg_02;
-+      union IO_APIC_reg_03 reg_03;
-+      unsigned long flags;
-+
-+      if (apic_verbosity == APIC_QUIET)
-+              return;
-+
-+      printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
-+      for (i = 0; i < nr_ioapics; i++)
-+              printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
-+                     mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]);
-+
-+      /*
-+       * We are a bit conservative about what we expect.  We have to
-+       * know about every hardware change ASAP.
-+       */
-+      printk(KERN_INFO "testing the IO APIC.......................\n");
-+
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_00.raw = io_apic_read(apic, 0);
-+      reg_01.raw = io_apic_read(apic, 1);
-+      if (reg_01.bits.version >= 0x10)
-+              reg_02.raw = io_apic_read(apic, 2);
-+      if (reg_01.bits.version >= 0x20)
-+              reg_03.raw = io_apic_read(apic, 3);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
-+      printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
-+      printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
-+      printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
-+      printk(KERN_DEBUG ".......    : LTS          : %X\n", reg_00.bits.LTS);
-+      if (reg_00.bits.ID >= get_physical_broadcast())
-+              UNEXPECTED_IO_APIC();
-+      if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2)
-+              UNEXPECTED_IO_APIC();
-+
-+      printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw);
-+      printk(KERN_DEBUG ".......     : max redirection entries: %04X\n", reg_01.bits.entries);
-+      if (    (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */
-+              (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */
-+              (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */
-+              (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */
-+              (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */
-+              (reg_01.bits.entries != 0x2E) &&
-+              (reg_01.bits.entries != 0x3F)
-+      )
-+              UNEXPECTED_IO_APIC();
-+
-+      printk(KERN_DEBUG ".......     : PRQ implemented: %X\n", reg_01.bits.PRQ);
-+      printk(KERN_DEBUG ".......     : IO APIC version: %04X\n", reg_01.bits.version);
-+      if (    (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */
-+              (reg_01.bits.version != 0x10) && /* oldest IO-APICs */
-+              (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */
-+              (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */
-+              (reg_01.bits.version != 0x20)    /* Intel P64H (82806 AA) */
-+      )
-+              UNEXPECTED_IO_APIC();
-+      if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2)
-+              UNEXPECTED_IO_APIC();
-+
-+      /*
-+       * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
-+       * but the value of reg_02 is read as the previous read register
-+       * value, so ignore it if reg_02 == reg_01.
-+       */
-+      if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) {
-+              printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
-+              printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.bits.arbitration);
-+              if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2)
-+                      UNEXPECTED_IO_APIC();
-+      }
-+
-+      /*
-+       * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
-+       * or reg_03, but the value of reg_0[23] is read as the previous read
-+       * register value, so ignore it if reg_03 == reg_0[12].
-+       */
-+      if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw &&
-+          reg_03.raw != reg_01.raw) {
-+              printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw);
-+              printk(KERN_DEBUG ".......     : Boot DT    : %X\n", reg_03.bits.boot_DT);
-+              if (reg_03.bits.__reserved_1)
-+                      UNEXPECTED_IO_APIC();
-+      }
-+
-+      printk(KERN_DEBUG ".... IRQ redirection table:\n");
-+
-+      printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
-+                        " Stat Dest Deli Vect:   \n");
-+
-+      for (i = 0; i <= reg_01.bits.entries; i++) {
-+              struct IO_APIC_route_entry entry;
-+
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2);
-+              *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+              printk(KERN_DEBUG " %02x %03X %02X  ",
-+                      i,
-+                      entry.dest.logical.logical_dest,
-+                      entry.dest.physical.physical_dest
-+              );
-+
-+              printk("%1d    %1d    %1d   %1d   %1d    %1d    %1d    %02X\n",
-+                      entry.mask,
-+                      entry.trigger,
-+                      entry.irr,
-+                      entry.polarity,
-+                      entry.delivery_status,
-+                      entry.dest_mode,
-+                      entry.delivery_mode,
-+                      entry.vector
-+              );
-+      }
-+      }
-+      if (use_pci_vector())
-+              printk(KERN_INFO "Using vector-based indexing\n");
-+      printk(KERN_DEBUG "IRQ to pin mappings:\n");
-+      for (i = 0; i < NR_IRQS; i++) {
-+              struct irq_pin_list *entry = irq_2_pin + i;
-+              if (entry->pin < 0)
-+                      continue;
-+              if (use_pci_vector() && !platform_legacy_irq(i))
-+                      printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
-+              else
-+                      printk(KERN_DEBUG "IRQ%d ", i);
-+              for (;;) {
-+                      printk("-> %d:%d", entry->apic, entry->pin);
-+                      if (!entry->next)
-+                              break;
-+                      entry = irq_2_pin + entry->next;
-+              }
-+              printk("\n");
-+      }
-+
-+      printk(KERN_INFO ".................................... done.\n");
-+
-+      return;
-+}
-+
-+#if 0
-+
-+static void print_APIC_bitfield (int base)
-+{
-+      unsigned int v;
-+      int i, j;
-+
-+      if (apic_verbosity == APIC_QUIET)
-+              return;
-+
-+      printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
-+      for (i = 0; i < 8; i++) {
-+              v = apic_read(base + i*0x10);
-+              for (j = 0; j < 32; j++) {
-+                      if (v & (1<<j))
-+                              printk("1");
-+                      else
-+                              printk("0");
-+              }
-+              printk("\n");
-+      }
-+}
-+
-+void /*__init*/ print_local_APIC(void * dummy)
-+{
-+      unsigned int v, ver, maxlvt;
-+
-+      if (apic_verbosity == APIC_QUIET)
-+              return;
-+
-+      printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
-+              smp_processor_id(), hard_smp_processor_id());
-+      v = apic_read(APIC_ID);
-+      printk(KERN_INFO "... APIC ID:      %08x (%01x)\n", v, GET_APIC_ID(v));
-+      v = apic_read(APIC_LVR);
-+      printk(KERN_INFO "... APIC VERSION: %08x\n", v);
-+      ver = GET_APIC_VERSION(v);
-+      maxlvt = get_maxlvt();
-+
-+      v = apic_read(APIC_TASKPRI);
-+      printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
-+
-+      if (APIC_INTEGRATED(ver)) {                     /* !82489DX */
-+              v = apic_read(APIC_ARBPRI);
-+              printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
-+                      v & APIC_ARBPRI_MASK);
-+              v = apic_read(APIC_PROCPRI);
-+              printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
-+      }
-+
-+      v = apic_read(APIC_EOI);
-+      printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
-+      v = apic_read(APIC_RRR);
-+      printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
-+      v = apic_read(APIC_LDR);
-+      printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
-+      v = apic_read(APIC_DFR);
-+      printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
-+      v = apic_read(APIC_SPIV);
-+      printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
-+
-+      printk(KERN_DEBUG "... APIC ISR field:\n");
-+      print_APIC_bitfield(APIC_ISR);
-+      printk(KERN_DEBUG "... APIC TMR field:\n");
-+      print_APIC_bitfield(APIC_TMR);
-+      printk(KERN_DEBUG "... APIC IRR field:\n");
-+      print_APIC_bitfield(APIC_IRR);
-+
-+      if (APIC_INTEGRATED(ver)) {             /* !82489DX */
-+              if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
-+                      apic_write(APIC_ESR, 0);
-+              v = apic_read(APIC_ESR);
-+              printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
-+      }
-+
-+      v = apic_read(APIC_ICR);
-+      printk(KERN_DEBUG "... APIC ICR: %08x\n", v);
-+      v = apic_read(APIC_ICR2);
-+      printk(KERN_DEBUG "... APIC ICR2: %08x\n", v);
-+
-+      v = apic_read(APIC_LVTT);
-+      printk(KERN_DEBUG "... APIC LVTT: %08x\n", v);
-+
-+      if (maxlvt > 3) {                       /* PC is LVT#4. */
-+              v = apic_read(APIC_LVTPC);
-+              printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v);
-+      }
-+      v = apic_read(APIC_LVT0);
-+      printk(KERN_DEBUG "... APIC LVT0: %08x\n", v);
-+      v = apic_read(APIC_LVT1);
-+      printk(KERN_DEBUG "... APIC LVT1: %08x\n", v);
-+
-+      if (maxlvt > 2) {                       /* ERR is LVT#3. */
-+              v = apic_read(APIC_LVTERR);
-+              printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v);
-+      }
-+
-+      v = apic_read(APIC_TMICT);
-+      printk(KERN_DEBUG "... APIC TMICT: %08x\n", v);
-+      v = apic_read(APIC_TMCCT);
-+      printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
-+      v = apic_read(APIC_TDCR);
-+      printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
-+      printk("\n");
-+}
-+
-+void print_all_local_APICs (void)
-+{
-+      on_each_cpu(print_local_APIC, NULL, 1, 1);
-+}
-+
-+void /*__init*/ print_PIC(void)
-+{
-+      unsigned int v;
-+      unsigned long flags;
-+
-+      if (apic_verbosity == APIC_QUIET)
-+              return;
-+
-+      printk(KERN_DEBUG "\nprinting PIC contents\n");
-+
-+      spin_lock_irqsave(&i8259A_lock, flags);
-+
-+      v = inb(0xa1) << 8 | inb(0x21);
-+      printk(KERN_DEBUG "... PIC  IMR: %04x\n", v);
-+
-+      v = inb(0xa0) << 8 | inb(0x20);
-+      printk(KERN_DEBUG "... PIC  IRR: %04x\n", v);
-+
-+      outb(0x0b,0xa0);
-+      outb(0x0b,0x20);
-+      v = inb(0xa0) << 8 | inb(0x20);
-+      outb(0x0a,0xa0);
-+      outb(0x0a,0x20);
-+
-+      spin_unlock_irqrestore(&i8259A_lock, flags);
-+
-+      printk(KERN_DEBUG "... PIC  ISR: %04x\n", v);
-+
-+      v = inb(0x4d1) << 8 | inb(0x4d0);
-+      printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
-+}
-+
-+#endif  /*  0  */
-+
-+#else
-+void __init print_IO_APIC(void) { }
-+#endif /* !CONFIG_XEN */
-+
-+static void __init enable_IO_APIC(void)
-+{
-+      union IO_APIC_reg_01 reg_01;
-+      int i8259_apic, i8259_pin;
-+      int i, apic;
-+      unsigned long flags;
-+
-+      for (i = 0; i < PIN_MAP_SIZE; i++) {
-+              irq_2_pin[i].pin = -1;
-+              irq_2_pin[i].next = 0;
-+      }
-+      if (!pirqs_enabled)
-+              for (i = 0; i < MAX_PIRQS; i++)
-+                      pirq_entries[i] = -1;
-+
-+      /*
-+       * The number of IO-APIC IRQ registers (== #pins):
-+       */
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              reg_01.raw = io_apic_read(apic, 1);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+              nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-+      }
-+      for(apic = 0; apic < nr_ioapics; apic++) {
-+              int pin;
-+              /* See if any of the pins is in ExtINT mode */
-+              for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-+                      struct IO_APIC_route_entry entry;
-+                      spin_lock_irqsave(&ioapic_lock, flags);
-+                      *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
-+                      *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
-+                      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+
-+                      /* If the interrupt line is enabled and in ExtInt mode
-+                       * I have found the pin where the i8259 is connected.
-+                       */
-+                      if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
-+                              ioapic_i8259.apic = apic;
-+                              ioapic_i8259.pin  = pin;
-+                              goto found_i8259;
-+                      }
-+              }
-+      }
-+ found_i8259:
-+      /* Look to see what if the MP table has reported the ExtINT */
-+      /* If we could not find the appropriate pin by looking at the ioapic
-+       * the i8259 probably is not connected the ioapic but give the
-+       * mptable a chance anyway.
-+       */
-+      i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
-+      i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
-+      /* Trust the MP table if nothing is setup in the hardware */
-+      if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
-+              printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
-+              ioapic_i8259.pin  = i8259_pin;
-+              ioapic_i8259.apic = i8259_apic;
-+      }
-+      /* Complain if the MP table and the hardware disagree */
-+      if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
-+              (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
-+      {
-+              printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
-+      }
-+
-+      /*
-+       * Do not trust the IO-APIC being empty at bootup
-+       */
-+      clear_IO_APIC();
-+}
-+
-+/*
-+ * Not an __init, needed by the reboot code
-+ */
-+void disable_IO_APIC(void)
-+{
-+      /*
-+       * Clear the IO-APIC before rebooting:
-+       */
-+      clear_IO_APIC();
-+
-+#ifndef CONFIG_XEN
-+      /*
-+       * If the i8259 is routed through an IOAPIC
-+       * Put that IOAPIC in virtual wire mode
-+       * so legacy interrupts can be delivered.
-+       */
-+      if (ioapic_i8259.pin != -1) {
-+              struct IO_APIC_route_entry entry;
-+              unsigned long flags;
-+
-+              memset(&entry, 0, sizeof(entry));
-+              entry.mask            = 0; /* Enabled */
-+              entry.trigger         = 0; /* Edge */
-+              entry.irr             = 0;
-+              entry.polarity        = 0; /* High */
-+              entry.delivery_status = 0;
-+              entry.dest_mode       = 0; /* Physical */
-+              entry.delivery_mode   = dest_ExtINT; /* ExtInt */
-+              entry.vector          = 0;
-+              entry.dest.physical.physical_dest =
-+                                      GET_APIC_ID(apic_read(APIC_ID));
-+
-+              /*
-+               * Add it to the IO-APIC irq-routing table:
-+               */
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
-+                      *(((int *)&entry)+1));
-+              io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
-+                      *(((int *)&entry)+0));
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+      }
-+      disconnect_bsp_APIC(ioapic_i8259.pin != -1);
-+#endif
-+}
-+
-+/*
-+ * function to set the IO-APIC physical IDs based on the
-+ * values stored in the MPC table.
-+ *
-+ * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
-+ */
-+
-+#if !defined(CONFIG_XEN) && !defined(CONFIG_X86_NUMAQ)
-+static void __init setup_ioapic_ids_from_mpc(void)
-+{
-+      union IO_APIC_reg_00 reg_00;
-+      physid_mask_t phys_id_present_map;
-+      int apic;
-+      int i;
-+      unsigned char old_id;
-+      unsigned long flags;
-+
-+      /*
-+       * Don't check I/O APIC IDs for xAPIC systems.  They have
-+       * no meaning without the serial APIC bus.
-+       */
-+      if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15))
-+              return;
-+      /*
-+       * This is broken; anything with a real cpu count has to
-+       * circumvent this idiocy regardless.
-+       */
-+      phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
-+
-+      /*
-+       * Set the IOAPIC ID to the value stored in the MPC table.
-+       */
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+
-+              /* Read the register 0 value */
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              reg_00.raw = io_apic_read(apic, 0);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+              
-+              old_id = mp_ioapics[apic].mpc_apicid;
-+
-+              if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) {
-+                      printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
-+                              apic, mp_ioapics[apic].mpc_apicid);
-+                      printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
-+                              reg_00.bits.ID);
-+                      mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
-+              }
-+
-+              /*
-+               * Sanity check, is the ID really free? Every APIC in a
-+               * system must have a unique ID or we get lots of nice
-+               * 'stuck on smp_invalidate_needed IPI wait' messages.
-+               */
-+              if (check_apicid_used(phys_id_present_map,
-+                                      mp_ioapics[apic].mpc_apicid)) {
-+                      printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
-+                              apic, mp_ioapics[apic].mpc_apicid);
-+                      for (i = 0; i < get_physical_broadcast(); i++)
-+                              if (!physid_isset(i, phys_id_present_map))
-+                                      break;
-+                      if (i >= get_physical_broadcast())
-+                              panic("Max APIC ID exceeded!\n");
-+                      printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
-+                              i);
-+                      physid_set(i, phys_id_present_map);
-+                      mp_ioapics[apic].mpc_apicid = i;
-+              } else {
-+                      physid_mask_t tmp;
-+                      tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid);
-+                      apic_printk(APIC_VERBOSE, "Setting %d in the "
-+                                      "phys_id_present_map\n",
-+                                      mp_ioapics[apic].mpc_apicid);
-+                      physids_or(phys_id_present_map, phys_id_present_map, tmp);
-+              }
-+
-+
-+              /*
-+               * We need to adjust the IRQ routing table
-+               * if the ID changed.
-+               */
-+              if (old_id != mp_ioapics[apic].mpc_apicid)
-+                      for (i = 0; i < mp_irq_entries; i++)
-+                              if (mp_irqs[i].mpc_dstapic == old_id)
-+                                      mp_irqs[i].mpc_dstapic
-+                                              = mp_ioapics[apic].mpc_apicid;
-+
-+              /*
-+               * Read the right value from the MPC table and
-+               * write it into the ID register.
-+               */
-+              apic_printk(APIC_VERBOSE, KERN_INFO
-+                      "...changing IO-APIC physical APIC ID to %d ...",
-+                      mp_ioapics[apic].mpc_apicid);
-+
-+              reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              io_apic_write(apic, 0, reg_00.raw);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+              /*
-+               * Sanity check
-+               */
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              reg_00.raw = io_apic_read(apic, 0);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+              if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid)
-+                      printk("could not set ID!\n");
-+              else
-+                      apic_printk(APIC_VERBOSE, " ok.\n");
-+      }
-+}
-+#else
-+static void __init setup_ioapic_ids_from_mpc(void) { }
-+#endif
-+
-+#ifndef CONFIG_XEN
-+/*
-+ * There is a nasty bug in some older SMP boards, their mptable lies
-+ * about the timer IRQ. We do the following to work around the situation:
-+ *
-+ *    - timer IRQ defaults to IO-APIC IRQ
-+ *    - if this function detects that timer IRQs are defunct, then we fall
-+ *      back to ISA timer IRQs
-+ */
-+static int __init timer_irq_works(void)
-+{
-+      unsigned long t1 = jiffies;
-+
-+      local_irq_enable();
-+      /* Let ten ticks pass... */
-+      mdelay((10 * 1000) / HZ);
-+
-+      /*
-+       * Expect a few ticks at least, to be sure some possible
-+       * glue logic does not lock up after one or two first
-+       * ticks in a non-ExtINT mode.  Also the local APIC
-+       * might have cached one ExtINT interrupt.  Finally, at
-+       * least one tick may be lost due to delays.
-+       */
-+      if (jiffies - t1 > 4)
-+              return 1;
-+
-+      return 0;
-+}
-+
-+/*
-+ * In the SMP+IOAPIC case it might happen that there are an unspecified
-+ * number of pending IRQ events unhandled. These cases are very rare,
-+ * so we 'resend' these IRQs via IPIs, to the same CPU. It's much
-+ * better to do it this way as thus we do not have to be aware of
-+ * 'pending' interrupts in the IRQ path, except at this point.
-+ */
-+/*
-+ * Edge triggered needs to resend any interrupt
-+ * that was delayed but this is now handled in the device
-+ * independent code.
-+ */
-+
-+/*
-+ * Starting up a edge-triggered IO-APIC interrupt is
-+ * nasty - we need to make sure that we get the edge.
-+ * If it is already asserted for some reason, we need
-+ * return 1 to indicate that is was pending.
-+ *
-+ * This is not complete - we should be able to fake
-+ * an edge even if it isn't on the 8259A...
-+ */
-+static unsigned int startup_edge_ioapic_irq(unsigned int irq)
-+{
-+      int was_pending = 0;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      if (irq < 16) {
-+              disable_8259A_irq(irq);
-+              if (i8259A_irq_pending(irq))
-+                      was_pending = 1;
-+      }
-+      __unmask_IO_APIC_irq(irq);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return was_pending;
-+}
-+
-+/*
-+ * Once we have recorded IRQ_PENDING already, we can mask the
-+ * interrupt for real. This prevents IRQ storms from unhandled
-+ * devices.
-+ */
-+static void ack_edge_ioapic_irq(unsigned int irq)
-+{
-+      move_irq(irq);
-+      if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
-+                                      == (IRQ_PENDING | IRQ_DISABLED))
-+              mask_IO_APIC_irq(irq);
-+      ack_APIC_irq();
-+}
-+
-+/*
-+ * Level triggered interrupts can just be masked,
-+ * and shutting down and starting up the interrupt
-+ * is the same as enabling and disabling them -- except
-+ * with a startup need to return a "was pending" value.
-+ *
-+ * Level triggered interrupts are special because we
-+ * do not touch any IO-APIC register while handling
-+ * them. We ack the APIC in the end-IRQ handler, not
-+ * in the start-IRQ-handler. Protection against reentrance
-+ * from the same interrupt is still provided, both by the
-+ * generic IRQ layer and by the fact that an unacked local
-+ * APIC does not accept IRQs.
-+ */
-+static unsigned int startup_level_ioapic_irq (unsigned int irq)
-+{
-+      unmask_IO_APIC_irq(irq);
-+
-+      return 0; /* don't check for pending */
-+}
-+
-+static void end_level_ioapic_irq (unsigned int irq)
-+{
-+      unsigned long v;
-+      int i;
-+
-+      move_irq(irq);
-+/*
-+ * It appears there is an erratum which affects at least version 0x11
-+ * of I/O APIC (that's the 82093AA and cores integrated into various
-+ * chipsets).  Under certain conditions a level-triggered interrupt is
-+ * erroneously delivered as edge-triggered one but the respective IRR
-+ * bit gets set nevertheless.  As a result the I/O unit expects an EOI
-+ * message but it will never arrive and further interrupts are blocked
-+ * from the source.  The exact reason is so far unknown, but the
-+ * phenomenon was observed when two consecutive interrupt requests
-+ * from a given source get delivered to the same CPU and the source is
-+ * temporarily disabled in between.
-+ *
-+ * A workaround is to simulate an EOI message manually.  We achieve it
-+ * by setting the trigger mode to edge and then to level when the edge
-+ * trigger mode gets detected in the TMR of a local APIC for a
-+ * level-triggered interrupt.  We mask the source for the time of the
-+ * operation to prevent an edge-triggered interrupt escaping meanwhile.
-+ * The idea is from Manfred Spraul.  --macro
-+ */
-+      i = IO_APIC_VECTOR(irq);
-+
-+      v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
-+
-+      ack_APIC_irq();
-+
-+      if (!(v & (1 << (i & 0x1f)))) {
-+              atomic_inc(&irq_mis_count);
-+              spin_lock(&ioapic_lock);
-+              __mask_and_edge_IO_APIC_irq(irq);
-+              __unmask_and_level_IO_APIC_irq(irq);
-+              spin_unlock(&ioapic_lock);
-+      }
-+}
-+
-+#ifdef CONFIG_PCI_MSI
-+static unsigned int startup_edge_ioapic_vector(unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      return startup_edge_ioapic_irq(irq);
-+}
-+
-+static void ack_edge_ioapic_vector(unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      move_native_irq(vector);
-+      ack_edge_ioapic_irq(irq);
-+}
-+
-+static unsigned int startup_level_ioapic_vector (unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      return startup_level_ioapic_irq (irq);
-+}
-+
-+static void end_level_ioapic_vector (unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      move_native_irq(vector);
-+      end_level_ioapic_irq(irq);
-+}
-+
-+static void mask_IO_APIC_vector (unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      mask_IO_APIC_irq(irq);
-+}
-+
-+static void unmask_IO_APIC_vector (unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      unmask_IO_APIC_irq(irq);
-+}
-+
-+#ifdef CONFIG_SMP
-+static void set_ioapic_affinity_vector (unsigned int vector,
-+                                      cpumask_t cpu_mask)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      set_native_irq_info(vector, cpu_mask);
-+      set_ioapic_affinity_irq(irq, cpu_mask);
-+}
-+#endif
-+#endif
-+
-+/*
-+ * Level and edge triggered IO-APIC interrupts need different handling,
-+ * so we use two separate IRQ descriptors. Edge triggered IRQs can be
-+ * handled with the level-triggered descriptor, but that one has slightly
-+ * more overhead. Level-triggered interrupts cannot be handled with the
-+ * edge-triggered handler, without risking IRQ storms and other ugly
-+ * races.
-+ */
-+static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
-+      .typename       = "IO-APIC-edge",
-+      .startup        = startup_edge_ioapic,
-+      .shutdown       = shutdown_edge_ioapic,
-+      .enable         = enable_edge_ioapic,
-+      .disable        = disable_edge_ioapic,
-+      .ack            = ack_edge_ioapic,
-+      .end            = end_edge_ioapic,
-+#ifdef CONFIG_SMP
-+      .set_affinity   = set_ioapic_affinity,
-+#endif
-+};
-+
-+static struct hw_interrupt_type ioapic_level_type __read_mostly = {
-+      .typename       = "IO-APIC-level",
-+      .startup        = startup_level_ioapic,
-+      .shutdown       = shutdown_level_ioapic,
-+      .enable         = enable_level_ioapic,
-+      .disable        = disable_level_ioapic,
-+      .ack            = mask_and_ack_level_ioapic,
-+      .end            = end_level_ioapic,
-+#ifdef CONFIG_SMP
-+      .set_affinity   = set_ioapic_affinity,
-+#endif
-+};
-+#endif /* !CONFIG_XEN */
-+
-+static inline void init_IO_APIC_traps(void)
-+{
-+      int irq;
-+
-+      /*
-+       * NOTE! The local APIC isn't very good at handling
-+       * multiple interrupts at the same interrupt level.
-+       * As the interrupt level is determined by taking the
-+       * vector number and shifting that right by 4, we
-+       * want to spread these out a bit so that they don't
-+       * all fall in the same interrupt level.
-+       *
-+       * Also, we've got to be careful not to trash gate
-+       * 0x80, because int 0x80 is hm, kind of importantish. ;)
-+       */
-+      for (irq = 0; irq < NR_IRQS ; irq++) {
-+              int tmp = irq;
-+              if (use_pci_vector()) {
-+                      if (!platform_legacy_irq(tmp))
-+                              if ((tmp = vector_to_irq(tmp)) == -1)
-+                                      continue;
-+              }
-+              if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
-+                      /*
-+                       * Hmm.. We don't have an entry for this,
-+                       * so default to an old-fashioned 8259
-+                       * interrupt if we can..
-+                       */
-+                      if (irq < 16)
-+                              make_8259A_irq(irq);
-+#ifndef CONFIG_XEN
-+                      else
-+                              /* Strange. Oh, well.. */
-+                              irq_desc[irq].handler = &no_irq_type;
-+#endif
-+              }
-+      }
-+}
-+
-+#ifndef CONFIG_XEN
-+static void enable_lapic_irq (unsigned int irq)
-+{
-+      unsigned long v;
-+
-+      v = apic_read(APIC_LVT0);
-+      apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
-+}
-+
-+static void disable_lapic_irq (unsigned int irq)
-+{
-+      unsigned long v;
-+
-+      v = apic_read(APIC_LVT0);
-+      apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
-+}
-+
-+static void ack_lapic_irq (unsigned int irq)
-+{
-+      ack_APIC_irq();
-+}
-+
-+static void end_lapic_irq (unsigned int i) { /* nothing */ }
-+
-+static struct hw_interrupt_type lapic_irq_type __read_mostly = {
-+      .typename       = "local-APIC-edge",
-+      .startup        = NULL, /* startup_irq() not used for IRQ0 */
-+      .shutdown       = NULL, /* shutdown_irq() not used for IRQ0 */
-+      .enable         = enable_lapic_irq,
-+      .disable        = disable_lapic_irq,
-+      .ack            = ack_lapic_irq,
-+      .end            = end_lapic_irq
-+};
-+
-+static void setup_nmi (void)
-+{
-+      /*
-+       * Dirty trick to enable the NMI watchdog ...
-+       * We put the 8259A master into AEOI mode and
-+       * unmask on all local APICs LVT0 as NMI.
-+       *
-+       * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
-+       * is from Maciej W. Rozycki - so we do not have to EOI from
-+       * the NMI handler or the timer interrupt.
-+       */ 
-+      apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
-+
-+      on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1);
-+
-+      apic_printk(APIC_VERBOSE, " done.\n");
-+}
-+
-+/*
-+ * This looks a bit hackish but it's about the only one way of sending
-+ * a few INTA cycles to 8259As and any associated glue logic.  ICR does
-+ * not support the ExtINT mode, unfortunately.  We need to send these
-+ * cycles as some i82489DX-based boards have glue logic that keeps the
-+ * 8259A interrupt line asserted until INTA.  --macro
-+ */
-+static inline void unlock_ExtINT_logic(void)
-+{
-+      int apic, pin, i;
-+      struct IO_APIC_route_entry entry0, entry1;
-+      unsigned char save_control, save_freq_select;
-+      unsigned long flags;
-+
-+      pin  = find_isa_irq_pin(8, mp_INT);
-+      apic = find_isa_irq_apic(8, mp_INT);
-+      if (pin == -1)
-+              return;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
-+      *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+      clear_IO_APIC_pin(apic, pin);
-+
-+      memset(&entry1, 0, sizeof(entry1));
-+
-+      entry1.dest_mode = 0;                   /* physical delivery */
-+      entry1.mask = 0;                        /* unmask IRQ now */
-+      entry1.dest.physical.physical_dest = hard_smp_processor_id();
-+      entry1.delivery_mode = dest_ExtINT;
-+      entry1.polarity = entry0.polarity;
-+      entry1.trigger = 0;
-+      entry1.vector = 0;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
-+      io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      save_control = CMOS_READ(RTC_CONTROL);
-+      save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
-+      CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6,
-+                 RTC_FREQ_SELECT);
-+      CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL);
-+
-+      i = 100;
-+      while (i-- > 0) {
-+              mdelay(10);
-+              if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF)
-+                      i -= 10;
-+      }
-+
-+      CMOS_WRITE(save_control, RTC_CONTROL);
-+      CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-+      clear_IO_APIC_pin(apic, pin);
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
-+      io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+/*
-+ * This code may look a bit paranoid, but it's supposed to cooperate with
-+ * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
-+ * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
-+ * fanatically on his truly buggy board.
-+ */
-+static inline void check_timer(void)
-+{
-+      int apic1, pin1, apic2, pin2;
-+      int vector;
-+
-+      /*
-+       * get/set the timer IRQ vector:
-+       */
-+      disable_8259A_irq(0);
-+      vector = assign_irq_vector(0);
-+      set_intr_gate(vector, interrupt[0]);
-+
-+      /*
-+       * Subtle, code in do_timer_interrupt() expects an AEOI
-+       * mode for the 8259A whenever interrupts are routed
-+       * through I/O APICs.  Also IRQ0 has to be enabled in
-+       * the 8259A which implies the virtual wire has to be
-+       * disabled in the local APIC.
-+       */
-+      apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
-+      init_8259A(1);
-+      timer_ack = 1;
-+      if (timer_over_8254 > 0)
-+              enable_8259A_irq(0);
-+
-+      pin1  = find_isa_irq_pin(0, mp_INT);
-+      apic1 = find_isa_irq_apic(0, mp_INT);
-+      pin2  = ioapic_i8259.pin;
-+      apic2 = ioapic_i8259.apic;
-+
-+      printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
-+              vector, apic1, pin1, apic2, pin2);
-+
-+      if (pin1 != -1) {
-+              /*
-+               * Ok, does IRQ0 through the IOAPIC work?
-+               */
-+              unmask_IO_APIC_irq(0);
-+              if (timer_irq_works()) {
-+                      if (nmi_watchdog == NMI_IO_APIC) {
-+                              disable_8259A_irq(0);
-+                              setup_nmi();
-+                              enable_8259A_irq(0);
-+                      }
-+                      if (disable_timer_pin_1 > 0)
-+                              clear_IO_APIC_pin(0, pin1);
-+                      return;
-+              }
-+              clear_IO_APIC_pin(apic1, pin1);
-+              printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
-+                              "IO-APIC\n");
-+      }
-+
-+      printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
-+      if (pin2 != -1) {
-+              printk("\n..... (found pin %d) ...", pin2);
-+              /*
-+               * legacy devices should be connected to IO APIC #0
-+               */
-+              setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
-+              if (timer_irq_works()) {
-+                      printk("works.\n");
-+                      if (pin1 != -1)
-+                              replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
-+                      else
-+                              add_pin_to_irq(0, apic2, pin2);
-+                      if (nmi_watchdog == NMI_IO_APIC) {
-+                              setup_nmi();
-+                      }
-+                      return;
-+              }
-+              /*
-+               * Cleanup, just in case ...
-+               */
-+              clear_IO_APIC_pin(apic2, pin2);
-+      }
-+      printk(" failed.\n");
-+
-+      if (nmi_watchdog == NMI_IO_APIC) {
-+              printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
-+              nmi_watchdog = 0;
-+      }
-+
-+      printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
-+
-+      disable_8259A_irq(0);
-+      irq_desc[0].handler = &lapic_irq_type;
-+      apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector);   /* Fixed mode */
-+      enable_8259A_irq(0);
-+
-+      if (timer_irq_works()) {
-+              printk(" works.\n");
-+              return;
-+      }
-+      apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
-+      printk(" failed.\n");
-+
-+      printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");
-+
-+      timer_ack = 0;
-+      init_8259A(0);
-+      make_8259A_irq(0);
-+      apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
-+
-+      unlock_ExtINT_logic();
-+
-+      if (timer_irq_works()) {
-+              printk(" works.\n");
-+              return;
-+      }
-+      printk(" failed :(.\n");
-+      panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
-+              "report.  Then try booting with the 'noapic' option");
-+}
-+#else
-+#define check_timer() ((void)0)
-+#endif
-+
-+/*
-+ *
-+ * IRQ's that are handled by the PIC in the MPS IOAPIC case.
-+ * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
-+ *   Linux doesn't really care, as it's not actually used
-+ *   for any interrupt handling anyway.
-+ */
-+#define PIC_IRQS      (1 << PIC_CASCADE_IR)
-+
-+void __init setup_IO_APIC(void)
-+{
-+      enable_IO_APIC();
-+
-+      if (acpi_ioapic)
-+              io_apic_irqs = ~0;      /* all IRQs go through IOAPIC */
-+      else
-+              io_apic_irqs = ~PIC_IRQS;
-+
-+      printk("ENABLING IO-APIC IRQs\n");
-+
-+      /*
-+       * Set up IO-APIC IRQ routing.
-+       */
-+      if (!acpi_ioapic)
-+              setup_ioapic_ids_from_mpc();
-+#ifndef CONFIG_XEN
-+      sync_Arb_IDs();
-+#endif
-+      setup_IO_APIC_irqs();
-+      init_IO_APIC_traps();
-+      check_timer();
-+      if (!acpi_ioapic)
-+              print_IO_APIC();
-+}
-+
-+static int __init setup_disable_8254_timer(char *s)
-+{
-+      timer_over_8254 = -1;
-+      return 1;
-+}
-+static int __init setup_enable_8254_timer(char *s)
-+{
-+      timer_over_8254 = 2;
-+      return 1;
-+}
-+
-+__setup("disable_8254_timer", setup_disable_8254_timer);
-+__setup("enable_8254_timer", setup_enable_8254_timer);
-+
-+/*
-+ *    Called after all the initialization is done. If we didnt find any
-+ *    APIC bugs then we can allow the modify fast path
-+ */
-+ 
-+static int __init io_apic_bug_finalize(void)
-+{
-+      if(sis_apic_bug == -1)
-+              sis_apic_bug = 0;
-+      if (is_initial_xendomain()) {
-+              dom0_op_t op = { .cmd = DOM0_PLATFORM_QUIRK };
-+              op.u.platform_quirk.quirk_id = sis_apic_bug ?
-+                      QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL;
-+              HYPERVISOR_dom0_op(&op);
-+      }
-+      return 0;
-+}
-+
-+late_initcall(io_apic_bug_finalize);
-+
-+struct sysfs_ioapic_data {
-+      struct sys_device dev;
-+      struct IO_APIC_route_entry entry[0];
-+};
-+static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
-+
-+static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
-+{
-+      struct IO_APIC_route_entry *entry;
-+      struct sysfs_ioapic_data *data;
-+      unsigned long flags;
-+      int i;
-+      
-+      data = container_of(dev, struct sysfs_ioapic_data, dev);
-+      entry = data->entry;
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
-+              *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i);
-+              *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i);
-+      }
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int ioapic_resume(struct sys_device *dev)
-+{
-+      struct IO_APIC_route_entry *entry;
-+      struct sysfs_ioapic_data *data;
-+      unsigned long flags;
-+      union IO_APIC_reg_00 reg_00;
-+      int i;
-+      
-+      data = container_of(dev, struct sysfs_ioapic_data, dev);
-+      entry = data->entry;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_00.raw = io_apic_read(dev->id, 0);
-+      if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) {
-+              reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
-+              io_apic_write(dev->id, 0, reg_00.raw);
-+      }
-+      for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
-+              io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1));
-+              io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0));
-+      }
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return 0;
-+}
-+
-+static struct sysdev_class ioapic_sysdev_class = {
-+      set_kset_name("ioapic"),
-+      .suspend = ioapic_suspend,
-+      .resume = ioapic_resume,
-+};
-+
-+static int __init ioapic_init_sysfs(void)
-+{
-+      struct sys_device * dev;
-+      int i, size, error = 0;
-+
-+      error = sysdev_class_register(&ioapic_sysdev_class);
-+      if (error)
-+              return error;
-+
-+      for (i = 0; i < nr_ioapics; i++ ) {
-+              size = sizeof(struct sys_device) + nr_ioapic_registers[i] 
-+                      * sizeof(struct IO_APIC_route_entry);
-+              mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL);
-+              if (!mp_ioapic_data[i]) {
-+                      printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
-+                      continue;
-+              }
-+              memset(mp_ioapic_data[i], 0, size);
-+              dev = &mp_ioapic_data[i]->dev;
-+              dev->id = i; 
-+              dev->cls = &ioapic_sysdev_class;
-+              error = sysdev_register(dev);
-+              if (error) {
-+                      kfree(mp_ioapic_data[i]);
-+                      mp_ioapic_data[i] = NULL;
-+                      printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
-+                      continue;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+device_initcall(ioapic_init_sysfs);
-+
-+/* --------------------------------------------------------------------------
-+                          ACPI-based IOAPIC Configuration
-+   -------------------------------------------------------------------------- */
-+
-+#ifdef CONFIG_ACPI
-+
-+int __init io_apic_get_unique_id (int ioapic, int apic_id)
-+{
-+#ifndef CONFIG_XEN
-+      union IO_APIC_reg_00 reg_00;
-+      static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
-+      physid_mask_t tmp;
-+      unsigned long flags;
-+      int i = 0;
-+
-+      /*
-+       * The P4 platform supports up to 256 APIC IDs on two separate APIC 
-+       * buses (one for LAPICs, one for IOAPICs), where predecessors only 
-+       * supports up to 16 on one shared APIC bus.
-+       * 
-+       * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
-+       *      advantage of new APIC bus architecture.
-+       */
-+
-+      if (physids_empty(apic_id_map))
-+              apic_id_map = ioapic_phys_id_map(phys_cpu_present_map);
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_00.raw = io_apic_read(ioapic, 0);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      if (apic_id >= get_physical_broadcast()) {
-+              printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
-+                      "%d\n", ioapic, apic_id, reg_00.bits.ID);
-+              apic_id = reg_00.bits.ID;
-+      }
-+
-+      /*
-+       * Every APIC in a system must have a unique ID or we get lots of nice 
-+       * 'stuck on smp_invalidate_needed IPI wait' messages.
-+       */
-+      if (check_apicid_used(apic_id_map, apic_id)) {
-+
-+              for (i = 0; i < get_physical_broadcast(); i++) {
-+                      if (!check_apicid_used(apic_id_map, i))
-+                              break;
-+              }
-+
-+              if (i == get_physical_broadcast())
-+                      panic("Max apic_id exceeded!\n");
-+
-+              printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
-+                      "trying %d\n", ioapic, apic_id, i);
-+
-+              apic_id = i;
-+      } 
-+
-+      tmp = apicid_to_cpu_present(apic_id);
-+      physids_or(apic_id_map, apic_id_map, tmp);
-+
-+      if (reg_00.bits.ID != apic_id) {
-+              reg_00.bits.ID = apic_id;
-+
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              io_apic_write(ioapic, 0, reg_00.raw);
-+              reg_00.raw = io_apic_read(ioapic, 0);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+              /* Sanity check */
-+              if (reg_00.bits.ID != apic_id) {
-+                      printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic);
-+                      return -1;
-+              }
-+      }
-+
-+      apic_printk(APIC_VERBOSE, KERN_INFO
-+                      "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
-+#endif /* !CONFIG_XEN */
-+
-+      return apic_id;
-+}
-+
-+
-+int __init io_apic_get_version (int ioapic)
-+{
-+      union IO_APIC_reg_01    reg_01;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_01.raw = io_apic_read(ioapic, 1);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return reg_01.bits.version;
-+}
-+
-+
-+int __init io_apic_get_redir_entries (int ioapic)
-+{
-+      union IO_APIC_reg_01    reg_01;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_01.raw = io_apic_read(ioapic, 1);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return reg_01.bits.entries;
-+}
-+
-+
-+int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low)
-+{
-+      struct IO_APIC_route_entry entry;
-+      unsigned long flags;
-+
-+      if (!IO_APIC_IRQ(irq)) {
-+              printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
-+                      ioapic);
-+              return -EINVAL;
-+      }
-+
-+      /*
-+       * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
-+       * Note that we mask (disable) IRQs now -- these get enabled when the
-+       * corresponding device driver registers for this IRQ.
-+       */
-+
-+      memset(&entry,0,sizeof(entry));
-+
-+      entry.delivery_mode = INT_DELIVERY_MODE;
-+      entry.dest_mode = INT_DEST_MODE;
-+      entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-+      entry.trigger = edge_level;
-+      entry.polarity = active_high_low;
-+      entry.mask  = 1;
-+
-+      /*
-+       * IRQs < 16 are already in the irq_2_pin[] map
-+       */
-+      if (irq >= 16)
-+              add_pin_to_irq(irq, ioapic, pin);
-+
-+      entry.vector = assign_irq_vector(irq);
-+
-+      apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry "
-+              "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic,
-+              mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
-+              edge_level, active_high_low);
-+
-+      ioapic_register_intr(irq, entry.vector, edge_level);
-+
-+      if (!ioapic && (irq < 16))
-+              disable_8259A_irq(irq);
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
-+      io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
-+      set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return 0;
-+}
-+
-+#endif /* CONFIG_ACPI */
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/ioport-xen.c linux-2.6.16.33/arch/i386/kernel/ioport-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/ioport-xen.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/ioport-xen.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,121 @@
-+/*
-+ *    linux/arch/i386/kernel/ioport.c
-+ *
-+ * This contains the io-permission bitmap code - written by obz, with changes
-+ * by Linus.
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/capability.h>
-+#include <linux/errno.h>
-+#include <linux/types.h>
-+#include <linux/ioport.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/stddef.h>
-+#include <linux/slab.h>
-+#include <linux/thread_info.h>
-+#include <xen/interface/physdev.h>
-+
-+/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
-+static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
-+{
-+      unsigned long mask;
-+      unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG);
-+      unsigned int low_index = base & (BITS_PER_LONG-1);
-+      int length = low_index + extent;
-+
-+      if (low_index != 0) {
-+              mask = (~0UL << low_index);
-+              if (length < BITS_PER_LONG)
-+                      mask &= ~(~0UL << length);
-+              if (new_value)
-+                      *bitmap_base++ |= mask;
-+              else
-+                      *bitmap_base++ &= ~mask;
-+              length -= BITS_PER_LONG;
-+      }
-+
-+      mask = (new_value ? ~0UL : 0UL);
-+      while (length >= BITS_PER_LONG) {
-+              *bitmap_base++ = mask;
-+              length -= BITS_PER_LONG;
-+      }
-+
-+      if (length > 0) {
-+              mask = ~(~0UL << length);
-+              if (new_value)
-+                      *bitmap_base++ |= mask;
-+              else
-+                      *bitmap_base++ &= ~mask;
-+      }
-+}
-+
-+
-+/*
-+ * this changes the io permissions bitmap in the current task.
-+ */
-+asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
-+{
-+      struct thread_struct * t = &current->thread;
-+      unsigned long *bitmap;
-+      struct physdev_set_iobitmap set_iobitmap;
-+
-+      if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
-+              return -EINVAL;
-+      if (turn_on && !capable(CAP_SYS_RAWIO))
-+              return -EPERM;
-+
-+      /*
-+       * If it's the first ioperm() call in this thread's lifetime, set the
-+       * IO bitmap up. ioperm() is much less timing critical than clone(),
-+       * this is why we delay this operation until now:
-+       */
-+      if (!t->io_bitmap_ptr) {
-+              bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
-+              if (!bitmap)
-+                      return -ENOMEM;
-+
-+              memset(bitmap, 0xff, IO_BITMAP_BYTES);
-+              t->io_bitmap_ptr = bitmap;
-+
-+              set_iobitmap.bitmap   = (char *)bitmap;
-+              set_iobitmap.nr_ports = IO_BITMAP_BITS;
-+              HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
-+      }
-+
-+      set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
-+
-+      return 0;
-+}
-+
-+/*
-+ * sys_iopl has to be used when you want to access the IO ports
-+ * beyond the 0x3ff range: to get the full 65536 ports bitmapped
-+ * you'd need 8kB of bitmaps/process, which is a bit excessive.
-+ *
-+ * Here we just change the eflags value on the stack: we allow
-+ * only the super-user to do it. This depends on the stack-layout
-+ * on system-call entry - see also fork() and the signal handling
-+ * code.
-+ */
-+
-+asmlinkage long sys_iopl(unsigned long unused)
-+{
-+      volatile struct pt_regs * regs = (struct pt_regs *) &unused;
-+      unsigned int level = regs->ebx;
-+      struct thread_struct *t = &current->thread;
-+      unsigned int old = (t->iopl >> 12) & 3;
-+
-+      if (level > 3)
-+              return -EINVAL;
-+      /* Trying to gain more privileges? */
-+      if (level > old) {
-+              if (!capable(CAP_SYS_RAWIO))
-+                      return -EPERM;
-+      }
-+      t->iopl = level << 12;
-+      set_iopl_mask(t->iopl);
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/irq-xen.c linux-2.6.16.33/arch/i386/kernel/irq-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/irq-xen.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/irq-xen.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,306 @@
-+/*
-+ *    linux/arch/i386/kernel/irq.c
-+ *
-+ *    Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
-+ *
-+ * This file contains the lowest level x86-specific interrupt
-+ * entry, irq-stacks and irq statistics code. All the remaining
-+ * irq logic is done by the generic kernel/irq/ code and
-+ * by the x86-specific irq controller code. (e.g. i8259.c and
-+ * io_apic.c.)
-+ */
-+
-+#include <asm/uaccess.h>
-+#include <linux/module.h>
-+#include <linux/seq_file.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/notifier.h>
-+#include <linux/cpu.h>
-+#include <linux/delay.h>
-+
-+DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp;
-+EXPORT_PER_CPU_SYMBOL(irq_stat);
-+
-+#ifndef CONFIG_X86_LOCAL_APIC
-+/*
-+ * 'what should we do if we get a hw irq event on an illegal vector'.
-+ * each architecture has to answer this themselves.
-+ */
-+void ack_bad_irq(unsigned int irq)
-+{
-+      printk("unexpected IRQ trap at vector %02x\n", irq);
-+}
-+#endif
-+
-+#ifdef CONFIG_4KSTACKS
-+/*
-+ * per-CPU IRQ handling contexts (thread information and stack)
-+ */
-+union irq_ctx {
-+      struct thread_info      tinfo;
-+      u32                     stack[THREAD_SIZE/sizeof(u32)];
-+};
-+
-+static union irq_ctx *hardirq_ctx[NR_CPUS];
-+static union irq_ctx *softirq_ctx[NR_CPUS];
-+#endif
-+
-+/*
-+ * do_IRQ handles all normal device IRQ's (the special
-+ * SMP cross-CPU interrupts have their own specific
-+ * handlers).
-+ */
-+fastcall unsigned int do_IRQ(struct pt_regs *regs)
-+{     
-+      /* high bit used in ret_from_ code */
-+      int irq = ~regs->orig_eax;
-+#ifdef CONFIG_4KSTACKS
-+      union irq_ctx *curctx, *irqctx;
-+      u32 *isp;
-+#endif
-+
-+      irq_enter();
-+#ifdef CONFIG_DEBUG_STACKOVERFLOW
-+      /* Debugging check for stack overflow: is there less than 1KB free? */
-+      {
-+              long esp;
-+
-+              __asm__ __volatile__("andl %%esp,%0" :
-+                                      "=r" (esp) : "0" (THREAD_SIZE - 1));
-+              if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) {
-+                      printk("do_IRQ: stack overflow: %ld\n",
-+                              esp - sizeof(struct thread_info));
-+                      dump_stack();
-+              }
-+      }
-+#endif
-+
-+#ifdef CONFIG_4KSTACKS
-+
-+      curctx = (union irq_ctx *) current_thread_info();
-+      irqctx = hardirq_ctx[smp_processor_id()];
-+
-+      /*
-+       * this is where we switch to the IRQ stack. However, if we are
-+       * already using the IRQ stack (because we interrupted a hardirq
-+       * handler) we can't do that and just have to keep using the
-+       * current stack (which is the irq stack already after all)
-+       */
-+      if (curctx != irqctx) {
-+              int arg1, arg2, ebx;
-+
-+              /* build the stack frame on the IRQ stack */
-+              isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
-+              irqctx->tinfo.task = curctx->tinfo.task;
-+              irqctx->tinfo.previous_esp = current_stack_pointer;
-+
-+              asm volatile(
-+                      "       xchgl   %%ebx,%%esp      \n"
-+                      "       call    __do_IRQ         \n"
-+                      "       movl   %%ebx,%%esp      \n"
-+                      : "=a" (arg1), "=d" (arg2), "=b" (ebx)
-+                      :  "0" (irq),   "1" (regs),  "2" (isp)
-+                      : "memory", "cc", "ecx"
-+              );
-+      } else
-+#endif
-+              __do_IRQ(irq, regs);
-+
-+      irq_exit();
-+
-+      return 1;
-+}
-+
-+#ifdef CONFIG_4KSTACKS
-+
-+/*
-+ * These should really be __section__(".bss.page_aligned") as well, but
-+ * gcc's 3.0 and earlier don't handle that correctly.
-+ */
-+static char softirq_stack[NR_CPUS * THREAD_SIZE]
-+              __attribute__((__aligned__(THREAD_SIZE)));
-+
-+static char hardirq_stack[NR_CPUS * THREAD_SIZE]
-+              __attribute__((__aligned__(THREAD_SIZE)));
-+
-+/*
-+ * allocate per-cpu stacks for hardirq and for softirq processing
-+ */
-+void irq_ctx_init(int cpu)
-+{
-+      union irq_ctx *irqctx;
-+
-+      if (hardirq_ctx[cpu])
-+              return;
-+
-+      irqctx = (union irq_ctx*) &hardirq_stack[cpu*THREAD_SIZE];
-+      irqctx->tinfo.task              = NULL;
-+      irqctx->tinfo.exec_domain       = NULL;
-+      irqctx->tinfo.cpu               = cpu;
-+      irqctx->tinfo.preempt_count     = HARDIRQ_OFFSET;
-+      irqctx->tinfo.addr_limit        = MAKE_MM_SEG(0);
-+
-+      hardirq_ctx[cpu] = irqctx;
-+
-+      irqctx = (union irq_ctx*) &softirq_stack[cpu*THREAD_SIZE];
-+      irqctx->tinfo.task              = NULL;
-+      irqctx->tinfo.exec_domain       = NULL;
-+      irqctx->tinfo.cpu               = cpu;
-+      irqctx->tinfo.preempt_count     = SOFTIRQ_OFFSET;
-+      irqctx->tinfo.addr_limit        = MAKE_MM_SEG(0);
-+
-+      softirq_ctx[cpu] = irqctx;
-+
-+      printk("CPU %u irqstacks, hard=%p soft=%p\n",
-+              cpu,hardirq_ctx[cpu],softirq_ctx[cpu]);
-+}
-+
-+void irq_ctx_exit(int cpu)
-+{
-+      hardirq_ctx[cpu] = NULL;
-+}
-+
-+extern asmlinkage void __do_softirq(void);
-+
-+asmlinkage void do_softirq(void)
-+{
-+      unsigned long flags;
-+      struct thread_info *curctx;
-+      union irq_ctx *irqctx;
-+      u32 *isp;
-+
-+      if (in_interrupt())
-+              return;
-+
-+      local_irq_save(flags);
-+
-+      if (local_softirq_pending()) {
-+              curctx = current_thread_info();
-+              irqctx = softirq_ctx[smp_processor_id()];
-+              irqctx->tinfo.task = curctx->task;
-+              irqctx->tinfo.previous_esp = current_stack_pointer;
-+
-+              /* build the stack frame on the softirq stack */
-+              isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
-+
-+              asm volatile(
-+                      "       xchgl   %%ebx,%%esp     \n"
-+                      "       call    __do_softirq    \n"
-+                      "       movl    %%ebx,%%esp     \n"
-+                      : "=b"(isp)
-+                      : "0"(isp)
-+                      : "memory", "cc", "edx", "ecx", "eax"
-+              );
-+      }
-+
-+      local_irq_restore(flags);
-+}
-+
-+EXPORT_SYMBOL(do_softirq);
-+#endif
-+
-+/*
-+ * Interrupt statistics:
-+ */
-+
-+atomic_t irq_err_count;
-+
-+/*
-+ * /proc/interrupts printing:
-+ */
-+
-+int show_interrupts(struct seq_file *p, void *v)
-+{
-+      int i = *(loff_t *) v, j;
-+      struct irqaction * action;
-+      unsigned long flags;
-+
-+      if (i == 0) {
-+              seq_printf(p, "           ");
-+              for_each_online_cpu(j)
-+                      seq_printf(p, "CPU%d       ",j);
-+              seq_putc(p, '\n');
-+      }
-+
-+      if (i < NR_IRQS) {
-+              spin_lock_irqsave(&irq_desc[i].lock, flags);
-+              action = irq_desc[i].action;
-+              if (!action)
-+                      goto skip;
-+              seq_printf(p, "%3d: ",i);
-+#ifndef CONFIG_SMP
-+              seq_printf(p, "%10u ", kstat_irqs(i));
-+#else
-+              for_each_online_cpu(j)
-+                      seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
-+#endif
-+              seq_printf(p, " %14s", irq_desc[i].handler->typename);
-+              seq_printf(p, "  %s", action->name);
-+
-+              for (action=action->next; action; action = action->next)
-+                      seq_printf(p, ", %s", action->name);
-+
-+              seq_putc(p, '\n');
-+skip:
-+              spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-+      } else if (i == NR_IRQS) {
-+              seq_printf(p, "NMI: ");
-+              for_each_online_cpu(j)
-+                      seq_printf(p, "%10u ", nmi_count(j));
-+              seq_putc(p, '\n');
-+#ifdef CONFIG_X86_LOCAL_APIC
-+              seq_printf(p, "LOC: ");
-+              for_each_online_cpu(j)
-+                      seq_printf(p, "%10u ",
-+                              per_cpu(irq_stat,j).apic_timer_irqs);
-+              seq_putc(p, '\n');
-+#endif
-+              seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-+#if defined(CONFIG_X86_IO_APIC)
-+              seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
-+#endif
-+      }
-+      return 0;
-+}
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+
-+void fixup_irqs(cpumask_t map)
-+{
-+      unsigned int irq;
-+      static int warned;
-+
-+      for (irq = 0; irq < NR_IRQS; irq++) {
-+              cpumask_t mask;
-+              if (irq == 2)
-+                      continue;
-+
-+              cpus_and(mask, irq_affinity[irq], map);
-+              if (any_online_cpu(mask) == NR_CPUS) {
-+                      /*printk("Breaking affinity for irq %i\n", irq);*/
-+                      mask = map;
-+              }
-+              if (irq_desc[irq].handler->set_affinity)
-+                      irq_desc[irq].handler->set_affinity(irq, mask);
-+              else if (irq_desc[irq].action && !(warned++))
-+                      printk("Cannot set affinity for irq %i\n", irq);
-+      }
-+
-+#if 0
-+      barrier();
-+      /* Ingo Molnar says: "after the IO-APIC masks have been redirected
-+         [note the nop - the interrupt-enable boundary on x86 is two
-+         instructions from sti] - to flush out pending hardirqs and
-+         IPIs. After this point nothing is supposed to reach this CPU." */
-+      __asm__ __volatile__("sti; nop; cli");
-+      barrier();
-+#else
-+      /* That doesn't seem sufficient.  Give it 1ms. */
-+      local_irq_enable();
-+      mdelay(1);
-+      local_irq_disable();
-+#endif
-+}
-+#endif
-+
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/irq.c linux-2.6.16.33/arch/i386/kernel/irq.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/irq.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/irq.c     2007-05-23 21:00:01.000000000 +0000
-@@ -53,8 +53,8 @@
-  */
- fastcall unsigned int do_IRQ(struct pt_regs *regs)
- {     
--      /* high bits used in ret_from_ code */
--      int irq = regs->orig_eax & 0xff;
-+      /* high bit used in ret_from_ code */
-+      int irq = ~regs->orig_eax;
- #ifdef CONFIG_4KSTACKS
-       union irq_ctx *curctx, *irqctx;
-       u32 *isp;
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/ldt-xen.c linux-2.6.16.33/arch/i386/kernel/ldt-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/ldt-xen.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/ldt-xen.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,270 @@
-+/*
-+ * linux/kernel/ldt.c
-+ *
-+ * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
-+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
-+ */
-+
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/vmalloc.h>
-+#include <linux/slab.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <asm/ldt.h>
-+#include <asm/desc.h>
-+#include <asm/mmu_context.h>
-+
-+#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
-+static void flush_ldt(void *null)
-+{
-+      if (current->active_mm)
-+              load_LDT(&current->active_mm->context);
-+}
-+#endif
-+
-+static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+{
-+      void *oldldt;
-+      void *newldt;
-+      int oldsize;
-+
-+      if (mincount <= pc->size)
-+              return 0;
-+      oldsize = pc->size;
-+      mincount = (mincount+511)&(~511);
-+      if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
-+              newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
-+      else
-+              newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
-+
-+      if (!newldt)
-+              return -ENOMEM;
-+
-+      if (oldsize)
-+              memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
-+      oldldt = pc->ldt;
-+      memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
-+      pc->ldt = newldt;
-+      wmb();
-+      pc->size = mincount;
-+      wmb();
-+
-+      if (reload) {
-+#ifdef CONFIG_SMP
-+              cpumask_t mask;
-+              preempt_disable();
-+#endif
-+              make_pages_readonly(
-+                      pc->ldt,
-+                      (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                      XENFEAT_writable_descriptor_tables);
-+              load_LDT(pc);
-+#ifdef CONFIG_SMP
-+              mask = cpumask_of_cpu(smp_processor_id());
-+              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+                      smp_call_function(flush_ldt, NULL, 1, 1);
-+              preempt_enable();
-+#endif
-+      }
-+      if (oldsize) {
-+              make_pages_writable(
-+                      oldldt,
-+                      (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                      XENFEAT_writable_descriptor_tables);
-+              if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
-+                      vfree(oldldt);
-+              else
-+                      kfree(oldldt);
-+      }
-+      return 0;
-+}
-+
-+static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+{
-+      int err = alloc_ldt(new, old->size, 0);
-+      if (err < 0)
-+              return err;
-+      memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+      make_pages_readonly(
-+              new->ldt,
-+              (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+              XENFEAT_writable_descriptor_tables);
-+      return 0;
-+}
-+
-+/*
-+ * we do not have to muck with descriptors here, that is
-+ * done in switch_mm() as needed.
-+ */
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+      struct mm_struct * old_mm;
-+      int retval = 0;
-+
-+      init_MUTEX(&mm->context.sem);
-+      mm->context.size = 0;
-+      mm->context.has_foreign_mappings = 0;
-+      old_mm = current->mm;
-+      if (old_mm && old_mm->context.size > 0) {
-+              down(&old_mm->context.sem);
-+              retval = copy_ldt(&mm->context, &old_mm->context);
-+              up(&old_mm->context.sem);
-+      }
-+      return retval;
-+}
-+
-+/*
-+ * No need to lock the MM as we are the last user
-+ */
-+void destroy_context(struct mm_struct *mm)
-+{
-+      if (mm->context.size) {
-+              if (mm == current->active_mm)
-+                      clear_LDT();
-+              make_pages_writable(
-+                      mm->context.ldt,
-+                      (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                      XENFEAT_writable_descriptor_tables);
-+              if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
-+                      vfree(mm->context.ldt);
-+              else
-+                      kfree(mm->context.ldt);
-+              mm->context.size = 0;
-+      }
-+}
-+
-+static int read_ldt(void __user * ptr, unsigned long bytecount)
-+{
-+      int err;
-+      unsigned long size;
-+      struct mm_struct * mm = current->mm;
-+
-+      if (!mm->context.size)
-+              return 0;
-+      if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
-+              bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
-+
-+      down(&mm->context.sem);
-+      size = mm->context.size*LDT_ENTRY_SIZE;
-+      if (size > bytecount)
-+              size = bytecount;
-+
-+      err = 0;
-+      if (copy_to_user(ptr, mm->context.ldt, size))
-+              err = -EFAULT;
-+      up(&mm->context.sem);
-+      if (err < 0)
-+              goto error_return;
-+      if (size != bytecount) {
-+              /* zero-fill the rest */
-+              if (clear_user(ptr+size, bytecount-size) != 0) {
-+                      err = -EFAULT;
-+                      goto error_return;
-+              }
-+      }
-+      return bytecount;
-+error_return:
-+      return err;
-+}
-+
-+static int read_default_ldt(void __user * ptr, unsigned long bytecount)
-+{
-+      int err;
-+      unsigned long size;
-+      void *address;
-+
-+      err = 0;
-+      address = &default_ldt[0];
-+      size = 5*sizeof(struct desc_struct);
-+      if (size > bytecount)
-+              size = bytecount;
-+
-+      err = size;
-+      if (copy_to_user(ptr, address, size))
-+              err = -EFAULT;
-+
-+      return err;
-+}
-+
-+static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+{
-+      struct mm_struct * mm = current->mm;
-+      __u32 entry_1, entry_2;
-+      int error;
-+      struct user_desc ldt_info;
-+
-+      error = -EINVAL;
-+      if (bytecount != sizeof(ldt_info))
-+              goto out;
-+      error = -EFAULT;        
-+      if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
-+              goto out;
-+
-+      error = -EINVAL;
-+      if (ldt_info.entry_number >= LDT_ENTRIES)
-+              goto out;
-+      if (ldt_info.contents == 3) {
-+              if (oldmode)
-+                      goto out;
-+              if (ldt_info.seg_not_present == 0)
-+                      goto out;
-+      }
-+
-+      down(&mm->context.sem);
-+      if (ldt_info.entry_number >= mm->context.size) {
-+              error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+              if (error < 0)
-+                      goto out_unlock;
-+      }
-+
-+      /* Allow LDTs to be cleared by the user. */
-+      if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
-+              if (oldmode || LDT_empty(&ldt_info)) {
-+                      entry_1 = 0;
-+                      entry_2 = 0;
-+                      goto install;
-+              }
-+      }
-+
-+      entry_1 = LDT_entry_a(&ldt_info);
-+      entry_2 = LDT_entry_b(&ldt_info);
-+      if (oldmode)
-+              entry_2 &= ~(1 << 20);
-+
-+      /* Install the new entry ...  */
-+install:
-+      error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number,
-+                              entry_1, entry_2);
-+
-+out_unlock:
-+      up(&mm->context.sem);
-+out:
-+      return error;
-+}
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+      int ret = -ENOSYS;
-+
-+      switch (func) {
-+      case 0:
-+              ret = read_ldt(ptr, bytecount);
-+              break;
-+      case 1:
-+              ret = write_ldt(ptr, bytecount, 1);
-+              break;
-+      case 2:
-+              ret = read_default_ldt(ptr, bytecount);
-+              break;
-+      case 0x11:
-+              ret = write_ldt(ptr, bytecount, 0);
-+              break;
-+      }
-+      return ret;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/machine_kexec.c linux-2.6.16.33/arch/i386/kernel/machine_kexec.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/machine_kexec.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/machine_kexec.c   2007-01-08 15:00:45.000000000 +0000
-@@ -19,123 +19,52 @@
- #include <asm/desc.h>
- #include <asm/system.h>
--#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
--
--#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
--#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
--#define L2_ATTR (_PAGE_PRESENT)
--
--#define LEVEL0_SIZE (1UL << 12UL)
--
--#ifndef CONFIG_X86_PAE
--#define LEVEL1_SIZE (1UL << 22UL)
--static u32 pgtable_level1[1024] PAGE_ALIGNED;
--
--static void identity_map_page(unsigned long address)
--{
--      unsigned long level1_index, level2_index;
--      u32 *pgtable_level2;
--
--      /* Find the current page table */
--      pgtable_level2 = __va(read_cr3());
--
--      /* Find the indexes of the physical address to identity map */
--      level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
--      level2_index = address / LEVEL1_SIZE;
--
--      /* Identity map the page table entry */
--      pgtable_level1[level1_index] = address | L0_ATTR;
--      pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
--
--      /* Flush the tlb so the new mapping takes effect.
--       * Global tlb entries are not flushed but that is not an issue.
--       */
--      load_cr3(pgtable_level2);
--}
--
--#else
--#define LEVEL1_SIZE (1UL << 21UL)
--#define LEVEL2_SIZE (1UL << 30UL)
--static u64 pgtable_level1[512] PAGE_ALIGNED;
--static u64 pgtable_level2[512] PAGE_ALIGNED;
--
--static void identity_map_page(unsigned long address)
--{
--      unsigned long level1_index, level2_index, level3_index;
--      u64 *pgtable_level3;
--
--      /* Find the current page table */
--      pgtable_level3 = __va(read_cr3());
-+#ifdef CONFIG_XEN
-+#include <xen/interface/kexec.h>
-+#endif
--      /* Find the indexes of the physical address to identity map */
--      level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
--      level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
--      level3_index = address / LEVEL2_SIZE;
--
--      /* Identity map the page table entry */
--      pgtable_level1[level1_index] = address | L0_ATTR;
--      pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
--      set_64bit(&pgtable_level3[level3_index],
--                                             __pa(pgtable_level2) | L2_ATTR);
--
--      /* Flush the tlb so the new mapping takes effect.
--       * Global tlb entries are not flushed but that is not an issue.
--       */
--      load_cr3(pgtable_level3);
--}
-+#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
-+static u32 kexec_pgd[1024] PAGE_ALIGNED;
-+#ifdef CONFIG_X86_PAE
-+static u32 kexec_pmd0[1024] PAGE_ALIGNED;
-+static u32 kexec_pmd1[1024] PAGE_ALIGNED;
- #endif
-+static u32 kexec_pte0[1024] PAGE_ALIGNED;
-+static u32 kexec_pte1[1024] PAGE_ALIGNED;
--static void set_idt(void *newidt, __u16 limit)
--{
--      struct Xgt_desc_struct curidt;
-+#ifdef CONFIG_XEN
--      /* ia32 supports unaliged loads & stores */
--      curidt.size    = limit;
--      curidt.address = (unsigned long)newidt;
-+#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT)
--      load_idt(&curidt);
--};
-+#if PAGES_NR > KEXEC_XEN_NO_PAGES
-+#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break
-+#endif
-+#if PA_CONTROL_PAGE != 0
-+#error PA_CONTROL_PAGE is non zero - Xen support will break
-+#endif
--static void set_gdt(void *newgdt, __u16 limit)
-+void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
- {
--      struct Xgt_desc_struct curgdt;
-+      void *control_page;
--      /* ia32 supports unaligned loads & stores */
--      curgdt.size    = limit;
--      curgdt.address = (unsigned long)newgdt;
-+      memset(xki->page_list, 0, sizeof(xki->page_list));
--      load_gdt(&curgdt);
--};
-+      control_page = page_address(image->control_code_page);
-+      memcpy(control_page, relocate_kernel, PAGE_SIZE);
--static void load_segments(void)
--{
--#define __STR(X) #X
--#define STR(X) __STR(X)
-+      xki->page_list[PA_CONTROL_PAGE] = __ma(control_page);
-+      xki->page_list[PA_PGD] = __ma(kexec_pgd);
-+#ifdef CONFIG_X86_PAE
-+      xki->page_list[PA_PMD_0] = __ma(kexec_pmd0);
-+      xki->page_list[PA_PMD_1] = __ma(kexec_pmd1);
-+#endif
-+      xki->page_list[PA_PTE_0] = __ma(kexec_pte0);
-+      xki->page_list[PA_PTE_1] = __ma(kexec_pte1);
--      __asm__ __volatile__ (
--              "\tljmp $"STR(__KERNEL_CS)",$1f\n"
--              "\t1:\n"
--              "\tmovl $"STR(__KERNEL_DS)",%%eax\n"
--              "\tmovl %%eax,%%ds\n"
--              "\tmovl %%eax,%%es\n"
--              "\tmovl %%eax,%%fs\n"
--              "\tmovl %%eax,%%gs\n"
--              "\tmovl %%eax,%%ss\n"
--              ::: "eax", "memory");
--#undef STR
--#undef __STR
- }
--typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
--                                      unsigned long indirection_page,
--                                      unsigned long reboot_code_buffer,
--                                      unsigned long start_address,
--                                      unsigned int has_pae) ATTRIB_NORET;
--
--const extern unsigned char relocate_new_kernel[];
--extern void relocate_new_kernel_end(void);
--const extern unsigned int relocate_new_kernel_size;
-+#endif /* CONFIG_XEN */
- /*
-  * A architecture hook called to validate the
-@@ -163,52 +92,38 @@
- {
- }
-+#ifndef CONFIG_XEN
- /*
-  * Do not allocate memory (or fail in any way) in machine_kexec().
-  * We are past the point of no return, committed to rebooting now.
-  */
- NORET_TYPE void machine_kexec(struct kimage *image)
- {
--      unsigned long page_list;
--      unsigned long reboot_code_buffer;
--
--      relocate_new_kernel_t rnk;
-+      unsigned long page_list[PAGES_NR];
-+      void *control_page;
-       /* Interrupts aren't acceptable while we reboot */
-       local_irq_disable();
--      /* Compute some offsets */
--      reboot_code_buffer = page_to_pfn(image->control_code_page)
--                                                              << PAGE_SHIFT;
--      page_list = image->head;
--
--      /* Set up an identity mapping for the reboot_code_buffer */
--      identity_map_page(reboot_code_buffer);
--
--      /* copy it out */
--      memcpy((void *)reboot_code_buffer, relocate_new_kernel,
--                                              relocate_new_kernel_size);
--
--      /* The segment registers are funny things, they are
--       * automatically loaded from a table, in memory wherever you
--       * set them to a specific selector, but this table is never
--       * accessed again you set the segment to a different selector.
--       *
--       * The more common model is are caches where the behide
--       * the scenes work is done, but is also dropped at arbitrary
--       * times.
--       *
--       * I take advantage of this here by force loading the
--       * segments, before I zap the gdt with an invalid value.
--       */
--      load_segments();
--      /* The gdt & idt are now invalid.
--       * If you want to load them you must set up your own idt & gdt.
--       */
--      set_gdt(phys_to_virt(0),0);
--      set_idt(phys_to_virt(0),0);
--
--      /* now call it */
--      rnk = (relocate_new_kernel_t) reboot_code_buffer;
--      (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
-+      control_page = page_address(image->control_code_page);
-+      memcpy(control_page, relocate_kernel, PAGE_SIZE);
-+
-+      page_list[PA_CONTROL_PAGE] = __pa(control_page);
-+      page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
-+      page_list[PA_PGD] = __pa(kexec_pgd);
-+      page_list[VA_PGD] = (unsigned long)kexec_pgd;
-+#ifdef CONFIG_X86_PAE
-+      page_list[PA_PMD_0] = __pa(kexec_pmd0);
-+      page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
-+      page_list[PA_PMD_1] = __pa(kexec_pmd1);
-+      page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
-+#endif
-+      page_list[PA_PTE_0] = __pa(kexec_pte0);
-+      page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
-+      page_list[PA_PTE_1] = __pa(kexec_pte1);
-+      page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
-+
-+      relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
-+                      image->start, cpu_has_pae);
- }
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/machine_kexec.c~ linux-2.6.16.33/arch/i386/kernel/machine_kexec.c~
---- linux-2.6.16.33-noxen/arch/i386/kernel/machine_kexec.c~    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/machine_kexec.c~  2007-05-23 21:00:01.000000000 +0000
-@@ -0,0 +1,148 @@
-+/*
-+ * machine_kexec.c - handle transition of Linux booting another kernel
-+ * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
-+ *
-+ * This source code is licensed under the GNU General Public License,
-+ * Version 2.  See the file COPYING for more details.
-+ */
-+
-+#include <linux/mm.h>
-+#include <linux/kexec.h>
-+#include <linux/delay.h>
-+#include <asm/pgtable.h>
-+#include <asm/pgalloc.h>
-+#include <asm/tlbflush.h>
-+#include <asm/mmu_context.h>
-+#include <asm/io.h>
-+#include <asm/apic.h>
-+#include <asm/cpufeature.h>
-+#include <asm/desc.h>
-+#include <asm/system.h>
-+
-+#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
-+static u32 kexec_pgd[1024] PAGE_ALIGNED;
-+#ifdef CONFIG_X86_PAE
-+static u32 kexec_pmd0[1024] PAGE_ALIGNED;
-+static u32 kexec_pmd1[1024] PAGE_ALIGNED;
-+#endif
-+static u32 kexec_pte0[1024] PAGE_ALIGNED;
-+static u32 kexec_pte1[1024] PAGE_ALIGNED;
-+
-+static void set_idt(void *newidt, __u16 limit)
-+{
-+      struct Xgt_desc_struct curidt;
-+
-+      /* ia32 supports unaliged loads & stores */
-+      curidt.size    = limit;
-+      curidt.address = (unsigned long)newidt;
-+
-+      load_idt(&curidt);
-+};
-+
-+
-+static void set_gdt(void *newgdt, __u16 limit)
-+{
-+      struct Xgt_desc_struct curgdt;
-+
-+      /* ia32 supports unaligned loads & stores */
-+      curgdt.size    = limit;
-+      curgdt.address = (unsigned long)newgdt;
-+
-+      load_gdt(&curgdt);
-+};
-+
-+static void load_segments(void)
-+{
-+#define __STR(X) #X
-+#define STR(X) __STR(X)
-+
-+      __asm__ __volatile__ (
-+              "\tljmp $"STR(__KERNEL_CS)",$1f\n"
-+              "\t1:\n"
-+              "\tmovl $"STR(__KERNEL_DS)",%%eax\n"
-+              "\tmovl %%eax,%%ds\n"
-+              "\tmovl %%eax,%%es\n"
-+              "\tmovl %%eax,%%fs\n"
-+              "\tmovl %%eax,%%gs\n"
-+              "\tmovl %%eax,%%ss\n"
-+              ::: "eax", "memory");
-+#undef STR
-+#undef __STR
-+}
-+
-+/*
-+ * A architecture hook called to validate the
-+ * proposed image and prepare the control pages
-+ * as needed.  The pages for KEXEC_CONTROL_CODE_SIZE
-+ * have been allocated, but the segments have yet
-+ * been copied into the kernel.
-+ *
-+ * Do what every setup is needed on image and the
-+ * reboot code buffer to allow us to avoid allocations
-+ * later.
-+ *
-+ * Currently nothing.
-+ */
-+int machine_kexec_prepare(struct kimage *image)
-+{
-+      return 0;
-+}
-+
-+/*
-+ * Undo anything leftover by machine_kexec_prepare
-+ * when an image is freed.
-+ */
-+void machine_kexec_cleanup(struct kimage *image)
-+{
-+}
-+
-+/*
-+ * Do not allocate memory (or fail in any way) in machine_kexec().
-+ * We are past the point of no return, committed to rebooting now.
-+ */
-+NORET_TYPE void machine_kexec(struct kimage *image)
-+{
-+      unsigned long page_list[PAGES_NR];
-+      void *control_page;
-+
-+      /* Interrupts aren't acceptable while we reboot */
-+      local_irq_disable();
-+
-+      control_page = page_address(image->control_code_page);
-+      memcpy(control_page, relocate_kernel, PAGE_SIZE);
-+
-+      page_list[PA_CONTROL_PAGE] = __pa(control_page);
-+      page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
-+      page_list[PA_PGD] = __pa(kexec_pgd);
-+      page_list[VA_PGD] = (unsigned long)kexec_pgd;
-+#ifdef CONFIG_X86_PAE
-+      page_list[PA_PMD_0] = __pa(kexec_pmd0);
-+      page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
-+      page_list[PA_PMD_1] = __pa(kexec_pmd1);
-+      page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
-+#endif
-+      page_list[PA_PTE_0] = __pa(kexec_pte0);
-+      page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
-+      page_list[PA_PTE_1] = __pa(kexec_pte1);
-+      page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
-+
-+      /* The segment registers are funny things, they have both a
-+       * visible and an invisible part.  Whenever the visible part is
-+       * set to a specific selector, the invisible part is loaded
-+       * with from a table in memory.  At no other time is the
-+       * descriptor table in memory accessed.
-+       *
-+       * I take advantage of this here by force loading the
-+       * segments, before I zap the gdt with an invalid value.
-+       */
-+      load_segments();
-+      /* The gdt & idt are now invalid.
-+       * If you want to load them you must set up your own idt & gdt.
-+       */
-+      set_gdt(phys_to_virt(0),0);
-+      set_idt(phys_to_virt(0),0);
-+
-+      /* now call it */
-+      relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
-+                      image->start, cpu_has_pae);
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/microcode-xen.c linux-2.6.16.33/arch/i386/kernel/microcode-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/microcode-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/microcode-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,159 @@
-+/*
-+ *    Intel CPU Microcode Update Driver for Linux
-+ *
-+ *    Copyright (C) 2000-2004 Tigran Aivazian
-+ *
-+ *    This driver allows to upgrade microcode on Intel processors
-+ *    belonging to IA-32 family - PentiumPro, Pentium II, 
-+ *    Pentium III, Xeon, Pentium 4, etc.
-+ *
-+ *    Reference: Section 8.10 of Volume III, Intel Pentium 4 Manual, 
-+ *    Order Number 245472 or free download from:
-+ *            
-+ *    http://developer.intel.com/design/pentium4/manuals/245472.htm
-+ *
-+ *    For more information, go to http://www.urbanmyth.org/microcode
-+ *
-+ *    This program is free software; you can redistribute it and/or
-+ *    modify it under the terms of the GNU General Public License
-+ *    as published by the Free Software Foundation; either version
-+ *    2 of the License, or (at your option) any later version.
-+ */
-+
-+//#define DEBUG /* pr_debug */
-+#include <linux/capability.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/cpumask.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/miscdevice.h>
-+#include <linux/spinlock.h>
-+#include <linux/mm.h>
-+#include <linux/syscalls.h>
-+
-+#include <asm/msr.h>
-+#include <asm/uaccess.h>
-+#include <asm/processor.h>
-+
-+MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver");
-+MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
-+MODULE_LICENSE("GPL");
-+
-+#define MICROCODE_VERSION     "1.14-xen"
-+
-+#define DEFAULT_UCODE_DATASIZE        (2000)    /* 2000 bytes */
-+#define MC_HEADER_SIZE                (sizeof (microcode_header_t))     /* 48 bytes */
-+#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */
-+
-+/* no concurrent ->write()s are allowed on /dev/cpu/microcode */
-+static DECLARE_MUTEX(microcode_sem);
-+                              
-+static int microcode_open (struct inode *unused1, struct file *unused2)
-+{
-+      return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
-+}
-+
-+
-+static int do_microcode_update (const void __user *ubuf, size_t len)
-+{
-+      int err;
-+      void *kbuf;
-+
-+      kbuf = vmalloc(len);
-+      if (!kbuf)
-+              return -ENOMEM;
-+
-+      if (copy_from_user(kbuf, ubuf, len) == 0) {
-+              dom0_op_t op;
-+
-+              op.cmd = DOM0_MICROCODE;
-+              set_xen_guest_handle(op.u.microcode.data, kbuf);
-+              op.u.microcode.length = len;
-+              err = HYPERVISOR_dom0_op(&op);
-+      } else
-+              err = -EFAULT;
-+
-+      vfree(kbuf);
-+
-+      return err;
-+}
-+
-+static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
-+{
-+      ssize_t ret;
-+
-+      if (len < DEFAULT_UCODE_TOTALSIZE) {
-+              printk(KERN_ERR "microcode: not enough data\n"); 
-+              return -EINVAL;
-+      }
-+
-+      down(&microcode_sem);
-+
-+      ret = do_microcode_update(buf, len);
-+      if (!ret)
-+              ret = (ssize_t)len;
-+
-+      up(&microcode_sem);
-+
-+      return ret;
-+}
-+
-+static int microcode_ioctl (struct inode *inode, struct file *file, 
-+              unsigned int cmd, unsigned long arg)
-+{
-+      switch (cmd) {
-+              /* 
-+               *  XXX: will be removed after microcode_ctl 
-+               *  is updated to ignore failure of this ioctl()
-+               */
-+              case MICROCODE_IOCFREE:
-+                      return 0;
-+              default:
-+                      return -EINVAL;
-+      }
-+      return -EINVAL;
-+}
-+
-+static struct file_operations microcode_fops = {
-+      .owner          = THIS_MODULE,
-+      .write          = microcode_write,
-+      .ioctl          = microcode_ioctl,
-+      .open           = microcode_open,
-+};
-+
-+static struct miscdevice microcode_dev = {
-+      .minor          = MICROCODE_MINOR,
-+      .name           = "microcode",
-+      .devfs_name     = "cpu/microcode",
-+      .fops           = &microcode_fops,
-+};
-+
-+static int __init microcode_init (void)
-+{
-+      int error;
-+
-+      error = misc_register(&microcode_dev);
-+      if (error) {
-+              printk(KERN_ERR
-+                      "microcode: can't misc_register on minor=%d\n",
-+                      MICROCODE_MINOR);
-+              return error;
-+      }
-+
-+      printk(KERN_INFO 
-+              "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@veritas.com>\n");
-+      return 0;
-+}
-+
-+static void __exit microcode_exit (void)
-+{
-+      misc_deregister(&microcode_dev);
-+      printk(KERN_INFO "IA-32 Microcode Update Driver v" MICROCODE_VERSION " unregistered\n");
-+}
-+
-+module_init(microcode_init)
-+module_exit(microcode_exit)
-+MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/mpparse-xen.c linux-2.6.16.33/arch/i386/kernel/mpparse-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/mpparse-xen.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/mpparse-xen.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1188 @@
-+/*
-+ *    Intel Multiprocessor Specification 1.1 and 1.4
-+ *    compliant MP-table parsing routines.
-+ *
-+ *    (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
-+ *    (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
-+ *
-+ *    Fixes
-+ *            Erich Boleyn    :       MP v1.4 and additional changes.
-+ *            Alan Cox        :       Added EBDA scanning
-+ *            Ingo Molnar     :       various cleanups and rewrites
-+ *            Maciej W. Rozycki:      Bits for default MP configurations
-+ *            Paul Diefenbaugh:       Added full ACPI support
-+ */
-+
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/acpi.h>
-+#include <linux/delay.h>
-+#include <linux/config.h>
-+#include <linux/bootmem.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/bitops.h>
-+
-+#include <asm/smp.h>
-+#include <asm/acpi.h>
-+#include <asm/mtrr.h>
-+#include <asm/mpspec.h>
-+#include <asm/io_apic.h>
-+
-+#include <mach_apic.h>
-+#include <mach_mpparse.h>
-+#include <bios_ebda.h>
-+
-+/* Have we found an MP table */
-+int smp_found_config;
-+unsigned int __initdata maxcpus = NR_CPUS;
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+#define CPU_HOTPLUG_ENABLED   (1)
-+#else
-+#define CPU_HOTPLUG_ENABLED   (0)
-+#endif
-+
-+/*
-+ * Various Linux-internal data structures created from the
-+ * MP-table.
-+ */
-+int apic_version [MAX_APICS];
-+int mp_bus_id_to_type [MAX_MP_BUSSES];
-+int mp_bus_id_to_node [MAX_MP_BUSSES];
-+int mp_bus_id_to_local [MAX_MP_BUSSES];
-+int quad_local_to_mp_bus_id [NR_CPUS/4][4];
-+int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
-+static int mp_current_pci_id;
-+
-+/* I/O APIC entries */
-+struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
-+
-+/* # of MP IRQ source entries */
-+struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
-+
-+/* MP IRQ source entries */
-+int mp_irq_entries;
-+
-+int nr_ioapics;
-+
-+int pic_mode;
-+unsigned long mp_lapic_addr;
-+
-+unsigned int def_to_bigsmp = 0;
-+
-+/* Processor that is doing the boot up */
-+unsigned int boot_cpu_physical_apicid = -1U;
-+/* Internal processor count */
-+static unsigned int __devinitdata num_processors;
-+
-+/* Bitmask of physically existing CPUs */
-+physid_mask_t phys_cpu_present_map;
-+
-+u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-+
-+/*
-+ * Intel MP BIOS table parsing routines:
-+ */
-+
-+
-+/*
-+ * Checksum an MP configuration block.
-+ */
-+
-+static int __init mpf_checksum(unsigned char *mp, int len)
-+{
-+      int sum = 0;
-+
-+      while (len--)
-+              sum += *mp++;
-+
-+      return sum & 0xFF;
-+}
-+
-+/*
-+ * Have to match translation table entries to main table entries by counter
-+ * hence the mpc_record variable .... can't see a less disgusting way of
-+ * doing this ....
-+ */
-+
-+static int mpc_record; 
-+static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata;
-+
-+#ifdef CONFIG_X86_NUMAQ
-+static int MP_valid_apicid(int apicid, int version)
-+{
-+      return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf;
-+}
-+#elif !defined(CONFIG_XEN)
-+static int MP_valid_apicid(int apicid, int version)
-+{
-+      if (version >= 0x14)
-+              return apicid < 0xff;
-+      else
-+              return apicid < 0xf;
-+}
-+#endif
-+
-+#ifndef CONFIG_XEN
-+static void __devinit MP_processor_info (struct mpc_config_processor *m)
-+{
-+      int ver, apicid;
-+      physid_mask_t phys_cpu;
-+      
-+      if (!(m->mpc_cpuflag & CPU_ENABLED))
-+              return;
-+
-+      apicid = mpc_apic_id(m, translation_table[mpc_record]);
-+
-+      if (m->mpc_featureflag&(1<<0))
-+              Dprintk("    Floating point unit present.\n");
-+      if (m->mpc_featureflag&(1<<7))
-+              Dprintk("    Machine Exception supported.\n");
-+      if (m->mpc_featureflag&(1<<8))
-+              Dprintk("    64 bit compare & exchange supported.\n");
-+      if (m->mpc_featureflag&(1<<9))
-+              Dprintk("    Internal APIC present.\n");
-+      if (m->mpc_featureflag&(1<<11))
-+              Dprintk("    SEP present.\n");
-+      if (m->mpc_featureflag&(1<<12))
-+              Dprintk("    MTRR  present.\n");
-+      if (m->mpc_featureflag&(1<<13))
-+              Dprintk("    PGE  present.\n");
-+      if (m->mpc_featureflag&(1<<14))
-+              Dprintk("    MCA  present.\n");
-+      if (m->mpc_featureflag&(1<<15))
-+              Dprintk("    CMOV  present.\n");
-+      if (m->mpc_featureflag&(1<<16))
-+              Dprintk("    PAT  present.\n");
-+      if (m->mpc_featureflag&(1<<17))
-+              Dprintk("    PSE  present.\n");
-+      if (m->mpc_featureflag&(1<<18))
-+              Dprintk("    PSN  present.\n");
-+      if (m->mpc_featureflag&(1<<19))
-+              Dprintk("    Cache Line Flush Instruction present.\n");
-+      /* 20 Reserved */
-+      if (m->mpc_featureflag&(1<<21))
-+              Dprintk("    Debug Trace and EMON Store present.\n");
-+      if (m->mpc_featureflag&(1<<22))
-+              Dprintk("    ACPI Thermal Throttle Registers  present.\n");
-+      if (m->mpc_featureflag&(1<<23))
-+              Dprintk("    MMX  present.\n");
-+      if (m->mpc_featureflag&(1<<24))
-+              Dprintk("    FXSR  present.\n");
-+      if (m->mpc_featureflag&(1<<25))
-+              Dprintk("    XMM  present.\n");
-+      if (m->mpc_featureflag&(1<<26))
-+              Dprintk("    Willamette New Instructions  present.\n");
-+      if (m->mpc_featureflag&(1<<27))
-+              Dprintk("    Self Snoop  present.\n");
-+      if (m->mpc_featureflag&(1<<28))
-+              Dprintk("    HT  present.\n");
-+      if (m->mpc_featureflag&(1<<29))
-+              Dprintk("    Thermal Monitor present.\n");
-+      /* 30, 31 Reserved */
-+
-+
-+      if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
-+              Dprintk("    Bootup CPU\n");
-+              boot_cpu_physical_apicid = m->mpc_apicid;
-+      }
-+
-+      ver = m->mpc_apicver;
-+
-+      if (!MP_valid_apicid(apicid, ver)) {
-+              printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n",
-+                      m->mpc_apicid, MAX_APICS);
-+              return;
-+      }
-+
-+      /*
-+       * Validate version
-+       */
-+      if (ver == 0x0) {
-+              printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! "
-+                              "fixing up to 0x10. (tell your hw vendor)\n",
-+                              m->mpc_apicid);
-+              ver = 0x10;
-+      }
-+      apic_version[m->mpc_apicid] = ver;
-+
-+      phys_cpu = apicid_to_cpu_present(apicid);
-+      physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
-+
-+      if (num_processors >= NR_CPUS) {
-+              printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
-+                      "  Processor ignored.\n", NR_CPUS);
-+              return;
-+      }
-+
-+      if (num_processors >= maxcpus) {
-+              printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
-+                      " Processor ignored.\n", maxcpus);
-+              return;
-+      }
-+
-+      cpu_set(num_processors, cpu_possible_map);
-+      num_processors++;
-+
-+      if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) {
-+              switch (boot_cpu_data.x86_vendor) {
-+              case X86_VENDOR_INTEL:
-+                      if (!APIC_XAPIC(ver)) {
-+                              def_to_bigsmp = 0;
-+                              break;
-+                      }
-+                      /* If P4 and above fall through */
-+              case X86_VENDOR_AMD:
-+                      def_to_bigsmp = 1;
-+              }
-+      }
-+      bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
-+}
-+#else
-+void __init MP_processor_info (struct mpc_config_processor *m)
-+{
-+      num_processors++;
-+}
-+#endif /* CONFIG_XEN */
-+
-+static void __init MP_bus_info (struct mpc_config_bus *m)
-+{
-+      char str[7];
-+
-+      memcpy(str, m->mpc_bustype, 6);
-+      str[6] = 0;
-+
-+      mpc_oem_bus_info(m, str, translation_table[mpc_record]);
-+
-+      if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
-+      } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
-+      } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) {
-+              mpc_oem_pci_bus(m, translation_table[mpc_record]);
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
-+              mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
-+              mp_current_pci_id++;
-+      } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) {
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
-+      } else if (strncmp(str, BUSTYPE_NEC98, sizeof(BUSTYPE_NEC98)-1) == 0) {
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_NEC98;
-+      } else {
-+              printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
-+      }
-+}
-+
-+static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
-+{
-+      if (!(m->mpc_flags & MPC_APIC_USABLE))
-+              return;
-+
-+      printk(KERN_INFO "I/O APIC #%d Version %d at 0x%lX.\n",
-+              m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
-+      if (nr_ioapics >= MAX_IO_APICS) {
-+              printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n",
-+                      MAX_IO_APICS, nr_ioapics);
-+              panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
-+      }
-+      if (!m->mpc_apicaddr) {
-+              printk(KERN_ERR "WARNING: bogus zero I/O APIC address"
-+                      " found in MP table, skipping!\n");
-+              return;
-+      }
-+      mp_ioapics[nr_ioapics] = *m;
-+      nr_ioapics++;
-+}
-+
-+static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
-+{
-+      mp_irqs [mp_irq_entries] = *m;
-+      Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
-+              " IRQ %02x, APIC ID %x, APIC INT %02x\n",
-+                      m->mpc_irqtype, m->mpc_irqflag & 3,
-+                      (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
-+                      m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
-+      if (++mp_irq_entries == MAX_IRQ_SOURCES)
-+              panic("Max # of irq sources exceeded!!\n");
-+}
-+
-+static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
-+{
-+      Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
-+              " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
-+                      m->mpc_irqtype, m->mpc_irqflag & 3,
-+                      (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
-+                      m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
-+      /*
-+       * Well it seems all SMP boards in existence
-+       * use ExtINT/LVT1 == LINT0 and
-+       * NMI/LVT2 == LINT1 - the following check
-+       * will show us if this assumptions is false.
-+       * Until then we do not have to add baggage.
-+       */
-+      if ((m->mpc_irqtype == mp_ExtINT) &&
-+              (m->mpc_destapiclint != 0))
-+                      BUG();
-+      if ((m->mpc_irqtype == mp_NMI) &&
-+              (m->mpc_destapiclint != 1))
-+                      BUG();
-+}
-+
-+#ifdef CONFIG_X86_NUMAQ
-+static void __init MP_translation_info (struct mpc_config_translation *m)
-+{
-+      printk(KERN_INFO "Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local);
-+
-+      if (mpc_record >= MAX_MPC_ENTRY) 
-+              printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
-+      else
-+              translation_table[mpc_record] = m; /* stash this for later */
-+      if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
-+              node_set_online(m->trans_quad);
-+}
-+
-+/*
-+ * Read/parse the MPC oem tables
-+ */
-+
-+static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \
-+      unsigned short oemsize)
-+{
-+      int count = sizeof (*oemtable); /* the header size */
-+      unsigned char *oemptr = ((unsigned char *)oemtable)+count;
-+      
-+      mpc_record = 0;
-+      printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
-+      if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4))
-+      {
-+              printk(KERN_WARNING "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
-+                      oemtable->oem_signature[0],
-+                      oemtable->oem_signature[1],
-+                      oemtable->oem_signature[2],
-+                      oemtable->oem_signature[3]);
-+              return;
-+      }
-+      if (mpf_checksum((unsigned char *)oemtable,oemtable->oem_length))
-+      {
-+              printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
-+              return;
-+      }
-+      while (count < oemtable->oem_length) {
-+              switch (*oemptr) {
-+                      case MP_TRANSLATION:
-+                      {
-+                              struct mpc_config_translation *m=
-+                                      (struct mpc_config_translation *)oemptr;
-+                              MP_translation_info(m);
-+                              oemptr += sizeof(*m);
-+                              count += sizeof(*m);
-+                              ++mpc_record;
-+                              break;
-+                      }
-+                      default:
-+                      {
-+                              printk(KERN_WARNING "Unrecognised OEM table entry type! - %d\n", (int) *oemptr);
-+                              return;
-+                      }
-+              }
-+       }
-+}
-+
-+static inline void mps_oem_check(struct mp_config_table *mpc, char *oem,
-+              char *productid)
-+{
-+      if (strncmp(oem, "IBM NUMA", 8))
-+              printk("Warning!  May not be a NUMA-Q system!\n");
-+      if (mpc->mpc_oemptr)
-+              smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr,
-+                              mpc->mpc_oemsize);
-+}
-+#endif        /* CONFIG_X86_NUMAQ */
-+
-+/*
-+ * Read/parse the MPC
-+ */
-+
-+static int __init smp_read_mpc(struct mp_config_table *mpc)
-+{
-+      char str[16];
-+      char oem[10];
-+      int count=sizeof(*mpc);
-+      unsigned char *mpt=((unsigned char *)mpc)+count;
-+
-+      if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
-+              printk(KERN_ERR "SMP mptable: bad signature [0x%x]!\n",
-+                      *(u32 *)mpc->mpc_signature);
-+              return 0;
-+      }
-+      if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
-+              printk(KERN_ERR "SMP mptable: checksum error!\n");
-+              return 0;
-+      }
-+      if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
-+              printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n",
-+                      mpc->mpc_spec);
-+              return 0;
-+      }
-+      if (!mpc->mpc_lapic) {
-+              printk(KERN_ERR "SMP mptable: null local APIC address!\n");
-+              return 0;
-+      }
-+      memcpy(oem,mpc->mpc_oem,8);
-+      oem[8]=0;
-+      printk(KERN_INFO "OEM ID: %s ",oem);
-+
-+      memcpy(str,mpc->mpc_productid,12);
-+      str[12]=0;
-+      printk("Product ID: %s ",str);
-+
-+      mps_oem_check(mpc, oem, str);
-+
-+      printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
-+
-+      /* 
-+       * Save the local APIC address (it might be non-default) -- but only
-+       * if we're not using ACPI.
-+       */
-+      if (!acpi_lapic)
-+              mp_lapic_addr = mpc->mpc_lapic;
-+
-+      /*
-+       *      Now process the configuration blocks.
-+       */
-+      mpc_record = 0;
-+      while (count < mpc->mpc_length) {
-+              switch(*mpt) {
-+                      case MP_PROCESSOR:
-+                      {
-+                              struct mpc_config_processor *m=
-+                                      (struct mpc_config_processor *)mpt;
-+                              /* ACPI may have already provided this data */
-+                              if (!acpi_lapic)
-+                                      MP_processor_info(m);
-+                              mpt += sizeof(*m);
-+                              count += sizeof(*m);
-+                              break;
-+                      }
-+                      case MP_BUS:
-+                      {
-+                              struct mpc_config_bus *m=
-+                                      (struct mpc_config_bus *)mpt;
-+                              MP_bus_info(m);
-+                              mpt += sizeof(*m);
-+                              count += sizeof(*m);
-+                              break;
-+                      }
-+                      case MP_IOAPIC:
-+                      {
-+                              struct mpc_config_ioapic *m=
-+                                      (struct mpc_config_ioapic *)mpt;
-+                              MP_ioapic_info(m);
-+                              mpt+=sizeof(*m);
-+                              count+=sizeof(*m);
-+                              break;
-+                      }
-+                      case MP_INTSRC:
-+                      {
-+                              struct mpc_config_intsrc *m=
-+                                      (struct mpc_config_intsrc *)mpt;
-+
-+                              MP_intsrc_info(m);
-+                              mpt+=sizeof(*m);
-+                              count+=sizeof(*m);
-+                              break;
-+                      }
-+                      case MP_LINTSRC:
-+                      {
-+                              struct mpc_config_lintsrc *m=
-+                                      (struct mpc_config_lintsrc *)mpt;
-+                              MP_lintsrc_info(m);
-+                              mpt+=sizeof(*m);
-+                              count+=sizeof(*m);
-+                              break;
-+                      }
-+                      default:
-+                      {
-+                              count = mpc->mpc_length;
-+                              break;
-+                      }
-+              }
-+              ++mpc_record;
-+      }
-+      clustered_apic_check();
-+      if (!num_processors)
-+              printk(KERN_ERR "SMP mptable: no processors registered!\n");
-+      return num_processors;
-+}
-+
-+static int __init ELCR_trigger(unsigned int irq)
-+{
-+      unsigned int port;
-+
-+      port = 0x4d0 + (irq >> 3);
-+      return (inb(port) >> (irq & 7)) & 1;
-+}
-+
-+static void __init construct_default_ioirq_mptable(int mpc_default_type)
-+{
-+      struct mpc_config_intsrc intsrc;
-+      int i;
-+      int ELCR_fallback = 0;
-+
-+      intsrc.mpc_type = MP_INTSRC;
-+      intsrc.mpc_irqflag = 0;                 /* conforming */
-+      intsrc.mpc_srcbus = 0;
-+      intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
-+
-+      intsrc.mpc_irqtype = mp_INT;
-+
-+      /*
-+       *  If true, we have an ISA/PCI system with no IRQ entries
-+       *  in the MP table. To prevent the PCI interrupts from being set up
-+       *  incorrectly, we try to use the ELCR. The sanity check to see if
-+       *  there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
-+       *  never be level sensitive, so we simply see if the ELCR agrees.
-+       *  If it does, we assume it's valid.
-+       */
-+      if (mpc_default_type == 5) {
-+              printk(KERN_INFO "ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
-+
-+              if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
-+                      printk(KERN_WARNING "ELCR contains invalid data... not using ELCR\n");
-+              else {
-+                      printk(KERN_INFO "Using ELCR to identify PCI interrupts\n");
-+                      ELCR_fallback = 1;
-+              }
-+      }
-+
-+      for (i = 0; i < 16; i++) {
-+              switch (mpc_default_type) {
-+              case 2:
-+                      if (i == 0 || i == 13)
-+                              continue;       /* IRQ0 & IRQ13 not connected */
-+                      /* fall through */
-+              default:
-+                      if (i == 2)
-+                              continue;       /* IRQ2 is never connected */
-+              }
-+
-+              if (ELCR_fallback) {
-+                      /*
-+                       *  If the ELCR indicates a level-sensitive interrupt, we
-+                       *  copy that information over to the MP table in the
-+                       *  irqflag field (level sensitive, active high polarity).
-+                       */
-+                      if (ELCR_trigger(i))
-+                              intsrc.mpc_irqflag = 13;
-+                      else
-+                              intsrc.mpc_irqflag = 0;
-+              }
-+
-+              intsrc.mpc_srcbusirq = i;
-+              intsrc.mpc_dstirq = i ? i : 2;          /* IRQ0 to INTIN2 */
-+              MP_intsrc_info(&intsrc);
-+      }
-+
-+      intsrc.mpc_irqtype = mp_ExtINT;
-+      intsrc.mpc_srcbusirq = 0;
-+      intsrc.mpc_dstirq = 0;                          /* 8259A to INTIN0 */
-+      MP_intsrc_info(&intsrc);
-+}
-+
-+static inline void __init construct_default_ISA_mptable(int mpc_default_type)
-+{
-+      struct mpc_config_processor processor;
-+      struct mpc_config_bus bus;
-+      struct mpc_config_ioapic ioapic;
-+      struct mpc_config_lintsrc lintsrc;
-+      int linttypes[2] = { mp_ExtINT, mp_NMI };
-+      int i;
-+
-+      /*
-+       * local APIC has default address
-+       */
-+      mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-+
-+      /*
-+       * 2 CPUs, numbered 0 & 1.
-+       */
-+      processor.mpc_type = MP_PROCESSOR;
-+      /* Either an integrated APIC or a discrete 82489DX. */
-+      processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
-+      processor.mpc_cpuflag = CPU_ENABLED;
-+      processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
-+                                 (boot_cpu_data.x86_model << 4) |
-+                                 boot_cpu_data.x86_mask;
-+      processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
-+      processor.mpc_reserved[0] = 0;
-+      processor.mpc_reserved[1] = 0;
-+      for (i = 0; i < 2; i++) {
-+              processor.mpc_apicid = i;
-+              MP_processor_info(&processor);
-+      }
-+
-+      bus.mpc_type = MP_BUS;
-+      bus.mpc_busid = 0;
-+      switch (mpc_default_type) {
-+              default:
-+                      printk("???\n");
-+                      printk(KERN_ERR "Unknown standard configuration %d\n",
-+                              mpc_default_type);
-+                      /* fall through */
-+              case 1:
-+              case 5:
-+                      memcpy(bus.mpc_bustype, "ISA   ", 6);
-+                      break;
-+              case 2:
-+              case 6:
-+              case 3:
-+                      memcpy(bus.mpc_bustype, "EISA  ", 6);
-+                      break;
-+              case 4:
-+              case 7:
-+                      memcpy(bus.mpc_bustype, "MCA   ", 6);
-+      }
-+      MP_bus_info(&bus);
-+      if (mpc_default_type > 4) {
-+              bus.mpc_busid = 1;
-+              memcpy(bus.mpc_bustype, "PCI   ", 6);
-+              MP_bus_info(&bus);
-+      }
-+
-+      ioapic.mpc_type = MP_IOAPIC;
-+      ioapic.mpc_apicid = 2;
-+      ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
-+      ioapic.mpc_flags = MPC_APIC_USABLE;
-+      ioapic.mpc_apicaddr = 0xFEC00000;
-+      MP_ioapic_info(&ioapic);
-+
-+      /*
-+       * We set up most of the low 16 IO-APIC pins according to MPS rules.
-+       */
-+      construct_default_ioirq_mptable(mpc_default_type);
-+
-+      lintsrc.mpc_type = MP_LINTSRC;
-+      lintsrc.mpc_irqflag = 0;                /* conforming */
-+      lintsrc.mpc_srcbusid = 0;
-+      lintsrc.mpc_srcbusirq = 0;
-+      lintsrc.mpc_destapic = MP_APIC_ALL;
-+      for (i = 0; i < 2; i++) {
-+              lintsrc.mpc_irqtype = linttypes[i];
-+              lintsrc.mpc_destapiclint = i;
-+              MP_lintsrc_info(&lintsrc);
-+      }
-+}
-+
-+static struct intel_mp_floating *mpf_found;
-+
-+/*
-+ * Scan the memory blocks for an SMP configuration block.
-+ */
-+void __init get_smp_config (void)
-+{
-+      struct intel_mp_floating *mpf = mpf_found;
-+
-+      /*
-+       * ACPI supports both logical (e.g. Hyper-Threading) and physical 
-+       * processors, where MPS only supports physical.
-+       */
-+      if (acpi_lapic && acpi_ioapic) {
-+              printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
-+              return;
-+      }
-+      else if (acpi_lapic)
-+              printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
-+
-+      printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
-+      if (mpf->mpf_feature2 & (1<<7)) {
-+              printk(KERN_INFO "    IMCR and PIC compatibility mode.\n");
-+              pic_mode = 1;
-+      } else {
-+              printk(KERN_INFO "    Virtual Wire compatibility mode.\n");
-+              pic_mode = 0;
-+      }
-+
-+      /*
-+       * Now see if we need to read further.
-+       */
-+      if (mpf->mpf_feature1 != 0) {
-+
-+              printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1);
-+              construct_default_ISA_mptable(mpf->mpf_feature1);
-+
-+      } else if (mpf->mpf_physptr) {
-+
-+              /*
-+               * Read the physical hardware table.  Anything here will
-+               * override the defaults.
-+               */
-+              if (!smp_read_mpc(isa_bus_to_virt(mpf->mpf_physptr))) {
-+                      smp_found_config = 0;
-+                      printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
-+                      printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
-+                      return;
-+              }
-+              /*
-+               * If there are no explicit MP IRQ entries, then we are
-+               * broken.  We set up most of the low 16 IO-APIC pins to
-+               * ISA defaults and hope it will work.
-+               */
-+              if (!mp_irq_entries) {
-+                      struct mpc_config_bus bus;
-+
-+                      printk(KERN_ERR "BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
-+
-+                      bus.mpc_type = MP_BUS;
-+                      bus.mpc_busid = 0;
-+                      memcpy(bus.mpc_bustype, "ISA   ", 6);
-+                      MP_bus_info(&bus);
-+
-+                      construct_default_ioirq_mptable(0);
-+              }
-+
-+      } else
-+              BUG();
-+
-+      printk(KERN_INFO "Processors: %d\n", num_processors);
-+      /*
-+       * Only use the first configuration found.
-+       */
-+}
-+
-+static int __init smp_scan_config (unsigned long base, unsigned long length)
-+{
-+      unsigned long *bp = isa_bus_to_virt(base);
-+      struct intel_mp_floating *mpf;
-+
-+      Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
-+      if (sizeof(*mpf) != 16)
-+              printk("Error: MPF size\n");
-+
-+      while (length > 0) {
-+              mpf = (struct intel_mp_floating *)bp;
-+              if ((*bp == SMP_MAGIC_IDENT) &&
-+                      (mpf->mpf_length == 1) &&
-+                      !mpf_checksum((unsigned char *)bp, 16) &&
-+                      ((mpf->mpf_specification == 1)
-+                              || (mpf->mpf_specification == 4)) ) {
-+
-+                      smp_found_config = 1;
-+#ifndef CONFIG_XEN
-+                      printk(KERN_INFO "found SMP MP-table at %08lx\n",
-+                                              virt_to_phys(mpf));
-+                      reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
-+                      if (mpf->mpf_physptr) {
-+                              /*
-+                               * We cannot access to MPC table to compute
-+                               * table size yet, as only few megabytes from
-+                               * the bottom is mapped now.
-+                               * PC-9800's MPC table places on the very last
-+                               * of physical memory; so that simply reserving
-+                               * PAGE_SIZE from mpg->mpf_physptr yields BUG()
-+                               * in reserve_bootmem.
-+                               */
-+                              unsigned long size = PAGE_SIZE;
-+                              unsigned long end = max_low_pfn * PAGE_SIZE;
-+                              if (mpf->mpf_physptr + size > end)
-+                                      size = end - mpf->mpf_physptr;
-+                              reserve_bootmem(mpf->mpf_physptr, size);
-+                      }
-+#else
-+                      printk(KERN_INFO "found SMP MP-table at %08lx\n",
-+                              ((unsigned long)bp - (unsigned long)isa_bus_to_virt(base)) + base);
-+#endif
-+
-+                      mpf_found = mpf;
-+                      return 1;
-+              }
-+              bp += 4;
-+              length -= 16;
-+      }
-+      return 0;
-+}
-+
-+void __init find_smp_config (void)
-+{
-+#ifndef CONFIG_XEN
-+      unsigned int address;
-+#endif
-+
-+      /*
-+       * FIXME: Linux assumes you have 640K of base ram..
-+       * this continues the error...
-+       *
-+       * 1) Scan the bottom 1K for a signature
-+       * 2) Scan the top 1K of base RAM
-+       * 3) Scan the 64K of bios
-+       */
-+      if (smp_scan_config(0x0,0x400) ||
-+              smp_scan_config(639*0x400,0x400) ||
-+                      smp_scan_config(0xF0000,0x10000))
-+              return;
-+      /*
-+       * If it is an SMP machine we should know now, unless the
-+       * configuration is in an EISA/MCA bus machine with an
-+       * extended bios data area.
-+       *
-+       * there is a real-mode segmented pointer pointing to the
-+       * 4K EBDA area at 0x40E, calculate and scan it here.
-+       *
-+       * NOTE! There are Linux loaders that will corrupt the EBDA
-+       * area, and as such this kind of SMP config may be less
-+       * trustworthy, simply because the SMP table may have been
-+       * stomped on during early boot. These loaders are buggy and
-+       * should be fixed.
-+       *
-+       * MP1.4 SPEC states to only scan first 1K of 4K EBDA.
-+       */
-+
-+#ifndef CONFIG_XEN
-+      address = get_bios_ebda();
-+      if (address)
-+              smp_scan_config(address, 0x400);
-+#endif
-+}
-+
-+/* --------------------------------------------------------------------------
-+                            ACPI-based MP Configuration
-+   -------------------------------------------------------------------------- */
-+
-+#ifdef CONFIG_ACPI
-+
-+void __init mp_register_lapic_address (
-+      u64                     address)
-+{
-+#ifndef CONFIG_XEN
-+      mp_lapic_addr = (unsigned long) address;
-+
-+      set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
-+
-+      if (boot_cpu_physical_apicid == -1U)
-+              boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
-+
-+      Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid);
-+#endif
-+}
-+
-+
-+void __devinit mp_register_lapic (
-+      u8                      id, 
-+      u8                      enabled)
-+{
-+      struct mpc_config_processor processor;
-+      int                     boot_cpu = 0;
-+      
-+      if (MAX_APICS - id <= 0) {
-+              printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
-+                      id, MAX_APICS);
-+              return;
-+      }
-+
-+      if (id == boot_cpu_physical_apicid)
-+              boot_cpu = 1;
-+
-+#ifndef CONFIG_XEN
-+      processor.mpc_type = MP_PROCESSOR;
-+      processor.mpc_apicid = id;
-+      processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR));
-+      processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
-+      processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
-+      processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 
-+              (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
-+      processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
-+      processor.mpc_reserved[0] = 0;
-+      processor.mpc_reserved[1] = 0;
-+#endif
-+
-+      MP_processor_info(&processor);
-+}
-+
-+#ifdef        CONFIG_X86_IO_APIC
-+
-+#define MP_ISA_BUS            0
-+#define MP_MAX_IOAPIC_PIN     127
-+
-+static struct mp_ioapic_routing {
-+      int                     apic_id;
-+      int                     gsi_base;
-+      int                     gsi_end;
-+      u32                     pin_programmed[4];
-+} mp_ioapic_routing[MAX_IO_APICS];
-+
-+
-+static int mp_find_ioapic (
-+      int                     gsi)
-+{
-+      int                     i = 0;
-+
-+      /* Find the IOAPIC that manages this GSI. */
-+      for (i = 0; i < nr_ioapics; i++) {
-+              if ((gsi >= mp_ioapic_routing[i].gsi_base)
-+                      && (gsi <= mp_ioapic_routing[i].gsi_end))
-+                      return i;
-+      }
-+
-+      printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
-+
-+      return -1;
-+}
-+      
-+
-+void __init mp_register_ioapic (
-+      u8                      id, 
-+      u32                     address,
-+      u32                     gsi_base)
-+{
-+      int                     idx = 0;
-+      int                     tmpid;
-+
-+      if (nr_ioapics >= MAX_IO_APICS) {
-+              printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
-+                      "(found %d)\n", MAX_IO_APICS, nr_ioapics);
-+              panic("Recompile kernel with bigger MAX_IO_APICS!\n");
-+      }
-+      if (!address) {
-+              printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
-+                      " found in MADT table, skipping!\n");
-+              return;
-+      }
-+
-+      idx = nr_ioapics++;
-+
-+      mp_ioapics[idx].mpc_type = MP_IOAPIC;
-+      mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE;
-+      mp_ioapics[idx].mpc_apicaddr = address;
-+
-+#ifndef CONFIG_XEN
-+      set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-+#endif
-+      if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
-+              tmpid = io_apic_get_unique_id(idx, id);
-+      else
-+              tmpid = id;
-+      if (tmpid == -1) {
-+              nr_ioapics--;
-+              return;
-+      }
-+      mp_ioapics[idx].mpc_apicid = tmpid;
-+      mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
-+      
-+      /* 
-+       * Build basic GSI lookup table to facilitate gsi->io_apic lookups
-+       * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
-+       */
-+      mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
-+      mp_ioapic_routing[idx].gsi_base = gsi_base;
-+      mp_ioapic_routing[idx].gsi_end = gsi_base + 
-+              io_apic_get_redir_entries(idx);
-+
-+      printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
-+              "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 
-+              mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
-+              mp_ioapic_routing[idx].gsi_base,
-+              mp_ioapic_routing[idx].gsi_end);
-+
-+      return;
-+}
-+
-+
-+void __init mp_override_legacy_irq (
-+      u8                      bus_irq,
-+      u8                      polarity, 
-+      u8                      trigger, 
-+      u32                     gsi)
-+{
-+      struct mpc_config_intsrc intsrc;
-+      int                     ioapic = -1;
-+      int                     pin = -1;
-+
-+      /* 
-+       * Convert 'gsi' to 'ioapic.pin'.
-+       */
-+      ioapic = mp_find_ioapic(gsi);
-+      if (ioapic < 0)
-+              return;
-+      pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
-+
-+      /*
-+       * TBD: This check is for faulty timer entries, where the override
-+       *      erroneously sets the trigger to level, resulting in a HUGE 
-+       *      increase of timer interrupts!
-+       */
-+      if ((bus_irq == 0) && (trigger == 3))
-+              trigger = 1;
-+
-+      intsrc.mpc_type = MP_INTSRC;
-+      intsrc.mpc_irqtype = mp_INT;
-+      intsrc.mpc_irqflag = (trigger << 2) | polarity;
-+      intsrc.mpc_srcbus = MP_ISA_BUS;
-+      intsrc.mpc_srcbusirq = bus_irq;                                /* IRQ */
-+      intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;        /* APIC ID */
-+      intsrc.mpc_dstirq = pin;                                    /* INTIN# */
-+
-+      Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n",
-+              intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 
-+              (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
-+              intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
-+
-+      mp_irqs[mp_irq_entries] = intsrc;
-+      if (++mp_irq_entries == MAX_IRQ_SOURCES)
-+              panic("Max # of irq sources exceeded!\n");
-+
-+      return;
-+}
-+
-+int es7000_plat;
-+
-+void __init mp_config_acpi_legacy_irqs (void)
-+{
-+      struct mpc_config_intsrc intsrc;
-+      int                     i = 0;
-+      int                     ioapic = -1;
-+
-+      /* 
-+       * Fabricate the legacy ISA bus (bus #31).
-+       */
-+      mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA;
-+      Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
-+
-+      /*
-+       * Older generations of ES7000 have no legacy identity mappings
-+       */
-+      if (es7000_plat == 1)
-+              return;
-+
-+      /* 
-+       * Locate the IOAPIC that manages the ISA IRQs (0-15). 
-+       */
-+      ioapic = mp_find_ioapic(0);
-+      if (ioapic < 0)
-+              return;
-+
-+      intsrc.mpc_type = MP_INTSRC;
-+      intsrc.mpc_irqflag = 0;                                 /* Conforming */
-+      intsrc.mpc_srcbus = MP_ISA_BUS;
-+      intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;
-+
-+      /* 
-+       * Use the default configuration for the IRQs 0-15.  Unless
-+       * overriden by (MADT) interrupt source override entries.
-+       */
-+      for (i = 0; i < 16; i++) {
-+              int idx;
-+
-+              for (idx = 0; idx < mp_irq_entries; idx++) {
-+                      struct mpc_config_intsrc *irq = mp_irqs + idx;
-+
-+                      /* Do we already have a mapping for this ISA IRQ? */
-+                      if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i)
-+                              break;
-+
-+                      /* Do we already have a mapping for this IOAPIC pin */
-+                      if ((irq->mpc_dstapic == intsrc.mpc_dstapic) &&
-+                              (irq->mpc_dstirq == i))
-+                              break;
-+              }
-+
-+              if (idx != mp_irq_entries) {
-+                      printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i);
-+                      continue;                       /* IRQ already used */
-+              }
-+
-+              intsrc.mpc_irqtype = mp_INT;
-+              intsrc.mpc_srcbusirq = i;                  /* Identity mapped */
-+              intsrc.mpc_dstirq = i;
-+
-+              Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, "
-+                      "%d-%d\n", intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 
-+                      (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
-+                      intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, 
-+                      intsrc.mpc_dstirq);
-+
-+              mp_irqs[mp_irq_entries] = intsrc;
-+              if (++mp_irq_entries == MAX_IRQ_SOURCES)
-+                      panic("Max # of irq sources exceeded!\n");
-+      }
-+}
-+
-+#define MAX_GSI_NUM   4096
-+
-+int mp_register_gsi (u32 gsi, int triggering, int polarity)
-+{
-+      int                     ioapic = -1;
-+      int                     ioapic_pin = 0;
-+      int                     idx, bit = 0;
-+      static int              pci_irq = 16;
-+      /*
-+       * Mapping between Global System Interrups, which
-+       * represent all possible interrupts, and IRQs
-+       * assigned to actual devices.
-+       */
-+      static int              gsi_to_irq[MAX_GSI_NUM];
-+
-+      /* Don't set up the ACPI SCI because it's already set up */
-+      if (acpi_fadt.sci_int == gsi)
-+              return gsi;
-+
-+      ioapic = mp_find_ioapic(gsi);
-+      if (ioapic < 0) {
-+              printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
-+              return gsi;
-+      }
-+
-+      ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
-+
-+      if (ioapic_renumber_irq)
-+              gsi = ioapic_renumber_irq(ioapic, gsi);
-+
-+      /* 
-+       * Avoid pin reprogramming.  PRTs typically include entries  
-+       * with redundant pin->gsi mappings (but unique PCI devices);
-+       * we only program the IOAPIC on the first.
-+       */
-+      bit = ioapic_pin % 32;
-+      idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
-+      if (idx > 3) {
-+              printk(KERN_ERR "Invalid reference to IOAPIC pin "
-+                      "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
-+                      ioapic_pin);
-+              return gsi;
-+      }
-+      if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
-+              Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
-+                      mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-+              return gsi_to_irq[gsi];
-+      }
-+
-+      mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
-+
-+      if (triggering == ACPI_LEVEL_SENSITIVE) {
-+              /*
-+               * For PCI devices assign IRQs in order, avoiding gaps
-+               * due to unused I/O APIC pins.
-+               */
-+              int irq = gsi;
-+              if (gsi < MAX_GSI_NUM) {
-+                      if (gsi > 15)
-+                              gsi = pci_irq++;
-+                      /*
-+                       * Don't assign IRQ used by ACPI SCI
-+                       */
-+                      if (gsi == acpi_fadt.sci_int)
-+                              gsi = pci_irq++;
-+                      gsi_to_irq[irq] = gsi;
-+              } else {
-+                      printk(KERN_ERR "GSI %u is too high\n", gsi);
-+                      return gsi;
-+              }
-+      }
-+
-+      io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
-+                  triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
-+                  polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-+      return gsi;
-+}
-+
-+#endif /* CONFIG_X86_IO_APIC */
-+#endif /* CONFIG_ACPI */
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/pci-dma-xen.c linux-2.6.16.33/arch/i386/kernel/pci-dma-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/pci-dma-xen.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/pci-dma-xen.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,345 @@
-+/*
-+ * Dynamic DMA mapping support.
-+ *
-+ * On i386 there is no hardware dynamic DMA address translation,
-+ * so consistent alloc/free are merely page allocation/freeing.
-+ * The rest of the dynamic DMA mapping interface is implemented
-+ * in asm/pci.h.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/mm.h>
-+#include <linux/string.h>
-+#include <linux/pci.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <asm/io.h>
-+#include <xen/balloon.h>
-+#include <asm/swiotlb.h>
-+#include <asm/tlbflush.h>
-+#include <asm-i386/mach-xen/asm/swiotlb.h>
-+#include <asm/bug.h>
-+
-+#ifdef __x86_64__
-+int iommu_merge __read_mostly = 0;
-+EXPORT_SYMBOL(iommu_merge);
-+
-+dma_addr_t bad_dma_address __read_mostly;
-+EXPORT_SYMBOL(bad_dma_address);
-+
-+/* This tells the BIO block layer to assume merging. Default to off
-+   because we cannot guarantee merging later. */
-+int iommu_bio_merge __read_mostly = 0;
-+EXPORT_SYMBOL(iommu_bio_merge);
-+
-+__init int iommu_setup(char *p)
-+{
-+    return 1;
-+}
-+#endif
-+
-+struct dma_coherent_mem {
-+      void            *virt_base;
-+      u32             device_base;
-+      int             size;
-+      int             flags;
-+      unsigned long   *bitmap;
-+};
-+
-+#define IOMMU_BUG_ON(test)                            \
-+do {                                                  \
-+      if (unlikely(test)) {                           \
-+              printk(KERN_ALERT "Fatal DMA error! "   \
-+                     "Please use 'swiotlb=force'\n"); \
-+              BUG();                                  \
-+      }                                               \
-+} while (0)
-+
-+int
-+dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-+         enum dma_data_direction direction)
-+{
-+      int i, rc;
-+
-+      if (direction == DMA_NONE)
-+              BUG();
-+      WARN_ON(nents == 0 || sg[0].length == 0);
-+
-+      if (swiotlb) {
-+              rc = swiotlb_map_sg(hwdev, sg, nents, direction);
-+      } else {
-+              for (i = 0; i < nents; i++ ) {
-+                      sg[i].dma_address =
-+                              page_to_bus(sg[i].page) + sg[i].offset;
-+                      sg[i].dma_length  = sg[i].length;
-+                      BUG_ON(!sg[i].page);
-+                      IOMMU_BUG_ON(address_needs_mapping(
-+                              hwdev, sg[i].dma_address));
-+              }
-+              rc = nents;
-+      }
-+
-+      flush_write_buffers();
-+      return rc;
-+}
-+EXPORT_SYMBOL(dma_map_sg);
-+
-+void
-+dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-+           enum dma_data_direction direction)
-+{
-+      BUG_ON(direction == DMA_NONE);
-+      if (swiotlb)
-+              swiotlb_unmap_sg(hwdev, sg, nents, direction);
-+}
-+EXPORT_SYMBOL(dma_unmap_sg);
-+
-+/*
-+ * XXX This file is also used by xenLinux/ia64. 
-+ * "defined(__i386__) || defined (__x86_64__)" means "!defined(__ia64__)".
-+ * This #if work around should be removed once this file is merbed back into
-+ * i386' pci-dma or is moved to drivers/xen/core.
-+ */
-+#if defined(__i386__) || defined(__x86_64__)
-+dma_addr_t
-+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-+           size_t size, enum dma_data_direction direction)
-+{
-+      dma_addr_t dma_addr;
-+
-+      BUG_ON(direction == DMA_NONE);
-+
-+      if (swiotlb) {
-+              dma_addr = swiotlb_map_page(
-+                      dev, page, offset, size, direction);
-+      } else {
-+              dma_addr = page_to_bus(page) + offset;
-+              IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr));
-+      }
-+
-+      return dma_addr;
-+}
-+EXPORT_SYMBOL(dma_map_page);
-+
-+void
-+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-+             enum dma_data_direction direction)
-+{
-+      BUG_ON(direction == DMA_NONE);
-+      if (swiotlb)
-+              swiotlb_unmap_page(dev, dma_address, size, direction);
-+}
-+EXPORT_SYMBOL(dma_unmap_page);
-+#endif /* defined(__i386__) || defined(__x86_64__) */
-+
-+int
-+dma_mapping_error(dma_addr_t dma_addr)
-+{
-+      if (swiotlb)
-+              return swiotlb_dma_mapping_error(dma_addr);
-+      return 0;
-+}
-+EXPORT_SYMBOL(dma_mapping_error);
-+
-+int
-+dma_supported(struct device *dev, u64 mask)
-+{
-+      if (swiotlb)
-+              return swiotlb_dma_supported(dev, mask);
-+      /*
-+       * By default we'll BUG when an infeasible DMA is requested, and
-+       * request swiotlb=force (see IOMMU_BUG_ON).
-+       */
-+      return 1;
-+}
-+EXPORT_SYMBOL(dma_supported);
-+
-+void *dma_alloc_coherent(struct device *dev, size_t size,
-+                         dma_addr_t *dma_handle, gfp_t gfp)
-+{
-+      void *ret;
-+      struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
-+      unsigned int order = get_order(size);
-+      unsigned long vstart;
-+      /* ignore region specifiers */
-+      gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-+
-+      if (mem) {
-+              int page = bitmap_find_free_region(mem->bitmap, mem->size,
-+                                                   order);
-+              if (page >= 0) {
-+                      *dma_handle = mem->device_base + (page << PAGE_SHIFT);
-+                      ret = mem->virt_base + (page << PAGE_SHIFT);
-+                      memset(ret, 0, size);
-+                      return ret;
-+              }
-+              if (mem->flags & DMA_MEMORY_EXCLUSIVE)
-+                      return NULL;
-+      }
-+
-+      if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
-+              gfp |= GFP_DMA;
-+
-+      vstart = __get_free_pages(gfp, order);
-+      ret = (void *)vstart;
-+
-+      if (ret != NULL) {
-+              if (xen_create_contiguous_region(vstart, order,
-+                                               dma_bits) != 0) {
-+                      free_pages(vstart, order);
-+                      return NULL;
-+              }
-+              memset(ret, 0, size);
-+              *dma_handle = virt_to_bus(ret);
-+      }
-+      return ret;
-+}
-+EXPORT_SYMBOL(dma_alloc_coherent);
-+
-+void dma_free_coherent(struct device *dev, size_t size,
-+                       void *vaddr, dma_addr_t dma_handle)
-+{
-+      struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
-+      int order = get_order(size);
-+      
-+      if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
-+              int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
-+
-+              bitmap_release_region(mem->bitmap, page, order);
-+      } else {
-+              xen_destroy_contiguous_region((unsigned long)vaddr, order);
-+              free_pages((unsigned long)vaddr, order);
-+      }
-+}
-+EXPORT_SYMBOL(dma_free_coherent);
-+
-+#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-+int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-+                              dma_addr_t device_addr, size_t size, int flags)
-+{
-+      void __iomem *mem_base;
-+      int pages = size >> PAGE_SHIFT;
-+      int bitmap_size = (pages + 31)/32;
-+
-+      if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
-+              goto out;
-+      if (!size)
-+              goto out;
-+      if (dev->dma_mem)
-+              goto out;
-+
-+      /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
-+
-+      mem_base = ioremap(bus_addr, size);
-+      if (!mem_base)
-+              goto out;
-+
-+      dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
-+      if (!dev->dma_mem)
-+              goto out;
-+      memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem));
-+      dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL);
-+      if (!dev->dma_mem->bitmap)
-+              goto free1_out;
-+      memset(dev->dma_mem->bitmap, 0, bitmap_size);
-+
-+      dev->dma_mem->virt_base = mem_base;
-+      dev->dma_mem->device_base = device_addr;
-+      dev->dma_mem->size = pages;
-+      dev->dma_mem->flags = flags;
-+
-+      if (flags & DMA_MEMORY_MAP)
-+              return DMA_MEMORY_MAP;
-+
-+      return DMA_MEMORY_IO;
-+
-+ free1_out:
-+      kfree(dev->dma_mem->bitmap);
-+ out:
-+      return 0;
-+}
-+EXPORT_SYMBOL(dma_declare_coherent_memory);
-+
-+void dma_release_declared_memory(struct device *dev)
-+{
-+      struct dma_coherent_mem *mem = dev->dma_mem;
-+      
-+      if(!mem)
-+              return;
-+      dev->dma_mem = NULL;
-+      iounmap(mem->virt_base);
-+      kfree(mem->bitmap);
-+      kfree(mem);
-+}
-+EXPORT_SYMBOL(dma_release_declared_memory);
-+
-+void *dma_mark_declared_memory_occupied(struct device *dev,
-+                                      dma_addr_t device_addr, size_t size)
-+{
-+      struct dma_coherent_mem *mem = dev->dma_mem;
-+      int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+      int pos, err;
-+
-+      if (!mem)
-+              return ERR_PTR(-EINVAL);
-+
-+      pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
-+      err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
-+      if (err != 0)
-+              return ERR_PTR(err);
-+      return mem->virt_base + (pos << PAGE_SHIFT);
-+}
-+EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
-+#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */
-+
-+dma_addr_t
-+dma_map_single(struct device *dev, void *ptr, size_t size,
-+             enum dma_data_direction direction)
-+{
-+      dma_addr_t dma;
-+
-+      if (direction == DMA_NONE)
-+              BUG();
-+      WARN_ON(size == 0);
-+
-+      if (swiotlb) {
-+              dma = swiotlb_map_single(dev, ptr, size, direction);
-+      } else {
-+              dma = virt_to_bus(ptr);
-+              IOMMU_BUG_ON(range_straddles_page_boundary(ptr, size));
-+              IOMMU_BUG_ON(address_needs_mapping(dev, dma));
-+      }
-+
-+      flush_write_buffers();
-+      return dma;
-+}
-+EXPORT_SYMBOL(dma_map_single);
-+
-+void
-+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-+               enum dma_data_direction direction)
-+{
-+      if (direction == DMA_NONE)
-+              BUG();
-+      if (swiotlb)
-+              swiotlb_unmap_single(dev, dma_addr, size, direction);
-+}
-+EXPORT_SYMBOL(dma_unmap_single);
-+
-+void
-+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-+                      enum dma_data_direction direction)
-+{
-+      if (swiotlb)
-+              swiotlb_sync_single_for_cpu(dev, dma_handle, size, direction);
-+}
-+EXPORT_SYMBOL(dma_sync_single_for_cpu);
-+
-+void
-+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-+                           enum dma_data_direction direction)
-+{
-+      if (swiotlb)
-+              swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
-+}
-+EXPORT_SYMBOL(dma_sync_single_for_device);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/process-xen.c linux-2.6.16.33/arch/i386/kernel/process-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/process-xen.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/process-xen.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,821 @@
-+/*
-+ *  linux/arch/i386/kernel/process.c
-+ *
-+ *  Copyright (C) 1995  Linus Torvalds
-+ *
-+ *  Pentium III FXSR, SSE support
-+ *    Gareth Hughes <gareth@valinux.com>, May 2000
-+ */
-+
-+/*
-+ * This file handles the architecture-dependent parts of process handling..
-+ */
-+
-+#include <stdarg.h>
-+
-+#include <linux/cpu.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/elfcore.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/stddef.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/user.h>
-+#include <linux/a.out.h>
-+#include <linux/interrupt.h>
-+#include <linux/config.h>
-+#include <linux/utsname.h>
-+#include <linux/delay.h>
-+#include <linux/reboot.h>
-+#include <linux/init.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/module.h>
-+#include <linux/kallsyms.h>
-+#include <linux/ptrace.h>
-+#include <linux/random.h>
-+#include <linux/kprobes.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/pgtable.h>
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/ldt.h>
-+#include <asm/processor.h>
-+#include <asm/i387.h>
-+#include <asm/desc.h>
-+#include <asm/vm86.h>
-+#ifdef CONFIG_MATH_EMULATION
-+#include <asm/math_emu.h>
-+#endif
-+
-+#include <xen/interface/physdev.h>
-+#include <xen/interface/vcpu.h>
-+#include <xen/cpu_hotplug.h>
-+
-+#include <linux/err.h>
-+
-+#include <asm/tlbflush.h>
-+#include <asm/cpu.h>
-+
-+#include <asm/tlbflush.h>
-+#include <asm/cpu.h>
-+
-+asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
-+
-+static int hlt_counter;
-+
-+unsigned long boot_option_idle_override = 0;
-+EXPORT_SYMBOL(boot_option_idle_override);
-+
-+/*
-+ * Return saved PC of a blocked thread.
-+ */
-+unsigned long thread_saved_pc(struct task_struct *tsk)
-+{
-+      return ((unsigned long *)tsk->thread.esp)[3];
-+}
-+
-+/*
-+ * Powermanagement idle function, if any..
-+ */
-+void (*pm_idle)(void);
-+EXPORT_SYMBOL(pm_idle);
-+static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
-+
-+void disable_hlt(void)
-+{
-+      hlt_counter++;
-+}
-+
-+EXPORT_SYMBOL(disable_hlt);
-+
-+void enable_hlt(void)
-+{
-+      hlt_counter--;
-+}
-+
-+EXPORT_SYMBOL(enable_hlt);
-+
-+/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-+void xen_idle(void)
-+{
-+      local_irq_disable();
-+
-+      if (need_resched())
-+              local_irq_enable();
-+      else {
-+              clear_thread_flag(TIF_POLLING_NRFLAG);
-+              smp_mb__after_clear_bit();
-+              safe_halt();
-+              set_thread_flag(TIF_POLLING_NRFLAG);
-+      }
-+}
-+#ifdef CONFIG_APM_MODULE
-+EXPORT_SYMBOL(default_idle);
-+#endif
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+extern cpumask_t cpu_initialized;
-+static inline void play_dead(void)
-+{
-+      idle_task_exit();
-+      local_irq_disable();
-+      cpu_clear(smp_processor_id(), cpu_initialized);
-+      preempt_enable_no_resched();
-+      HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
-+      cpu_bringup();
-+}
-+#else
-+static inline void play_dead(void)
-+{
-+      BUG();
-+}
-+#endif /* CONFIG_HOTPLUG_CPU */
-+
-+/*
-+ * The idle thread. There's no useful work to be
-+ * done, so just try to conserve power and have a
-+ * low exit latency (ie sit in a loop waiting for
-+ * somebody to say that they'd like to reschedule)
-+ */
-+void cpu_idle(void)
-+{
-+      int cpu = smp_processor_id();
-+
-+      set_thread_flag(TIF_POLLING_NRFLAG);
-+
-+      /* endless idle loop with no priority at all */
-+      while (1) {
-+              while (!need_resched()) {
-+
-+                      if (__get_cpu_var(cpu_idle_state))
-+                              __get_cpu_var(cpu_idle_state) = 0;
-+
-+                      rmb();
-+
-+                      if (cpu_is_offline(cpu))
-+                              play_dead();
-+
-+                      __get_cpu_var(irq_stat).idle_timestamp = jiffies;
-+                      xen_idle();
-+              }
-+              preempt_enable_no_resched();
-+              schedule();
-+              preempt_disable();
-+      }
-+}
-+
-+void cpu_idle_wait(void)
-+{
-+      unsigned int cpu, this_cpu = get_cpu();
-+      cpumask_t map;
-+
-+      set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
-+      put_cpu();
-+
-+      cpus_clear(map);
-+      for_each_online_cpu(cpu) {
-+              per_cpu(cpu_idle_state, cpu) = 1;
-+              cpu_set(cpu, map);
-+      }
-+
-+      __get_cpu_var(cpu_idle_state) = 0;
-+
-+      wmb();
-+      do {
-+              ssleep(1);
-+              for_each_online_cpu(cpu) {
-+                      if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
-+                              cpu_clear(cpu, map);
-+              }
-+              cpus_and(map, map, cpu_online_map);
-+      } while (!cpus_empty(map));
-+}
-+EXPORT_SYMBOL_GPL(cpu_idle_wait);
-+
-+/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
-+/* Always use xen_idle() instead. */
-+void __devinit select_idle_routine(const struct cpuinfo_x86 *c) {}
-+
-+void show_regs(struct pt_regs * regs)
-+{
-+      unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
-+
-+      printk("\n");
-+      printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
-+      printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
-+      print_symbol("EIP is at %s\n", regs->eip);
-+
-+      if (user_mode(regs))
-+              printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
-+      printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
-+             regs->eflags, print_tainted(), system_utsname.release,
-+             (int)strcspn(system_utsname.version, " "),
-+             system_utsname.version);
-+      printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
-+              regs->eax,regs->ebx,regs->ecx,regs->edx);
-+      printk("ESI: %08lx EDI: %08lx EBP: %08lx",
-+              regs->esi, regs->edi, regs->ebp);
-+      printk(" DS: %04x ES: %04x\n",
-+              0xffff & regs->xds,0xffff & regs->xes);
-+
-+      cr0 = read_cr0();
-+      cr2 = read_cr2();
-+      cr3 = read_cr3();
-+      cr4 = read_cr4_safe();
-+      printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
-+      show_trace(NULL, &regs->esp);
-+}
-+
-+/*
-+ * This gets run with %ebx containing the
-+ * function to call, and %edx containing
-+ * the "args".
-+ */
-+extern void kernel_thread_helper(void);
-+__asm__(".section .text\n"
-+      ".align 4\n"
-+      "kernel_thread_helper:\n\t"
-+      "movl %edx,%eax\n\t"
-+      "pushl %edx\n\t"
-+      "call *%ebx\n\t"
-+      "pushl %eax\n\t"
-+      "call do_exit\n"
-+      ".previous");
-+
-+/*
-+ * Create a kernel thread
-+ */
-+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+{
-+      struct pt_regs regs;
-+
-+      memset(&regs, 0, sizeof(regs));
-+
-+      regs.ebx = (unsigned long) fn;
-+      regs.edx = (unsigned long) arg;
-+
-+      regs.xds = __USER_DS;
-+      regs.xes = __USER_DS;
-+      regs.orig_eax = -1;
-+      regs.eip = (unsigned long) kernel_thread_helper;
-+      regs.xcs = GET_KERNEL_CS();
-+      regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
-+
-+      /* Ok, create the new process.. */
-+      return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-+}
-+EXPORT_SYMBOL(kernel_thread);
-+
-+/*
-+ * Free current thread data structures etc..
-+ */
-+void exit_thread(void)
-+{
-+      struct task_struct *tsk = current;
-+      struct thread_struct *t = &tsk->thread;
-+
-+      /*
-+       * Remove function-return probe instances associated with this task
-+       * and put them back on the free list. Do not insert an exit probe for
-+       * this function, it will be disabled by kprobe_flush_task if you do.
-+       */
-+      kprobe_flush_task(tsk);
-+
-+      /* The process may have allocated an io port bitmap... nuke it. */
-+      if (unlikely(NULL != t->io_bitmap_ptr)) {
-+              struct physdev_set_iobitmap set_iobitmap = { 0 };
-+              HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
-+              kfree(t->io_bitmap_ptr);
-+              t->io_bitmap_ptr = NULL;
-+      }
-+}
-+
-+void flush_thread(void)
-+{
-+      struct task_struct *tsk = current;
-+
-+      memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
-+      memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
-+      /*
-+       * Forget coprocessor state..
-+       */
-+      clear_fpu(tsk);
-+      clear_used_math();
-+}
-+
-+void release_thread(struct task_struct *dead_task)
-+{
-+      BUG_ON(dead_task->mm);
-+      release_vm86_irqs(dead_task);
-+}
-+
-+/*
-+ * This gets called before we allocate a new thread and copy
-+ * the current task into it.
-+ */
-+void prepare_to_copy(struct task_struct *tsk)
-+{
-+      unlazy_fpu(tsk);
-+}
-+
-+int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
-+      unsigned long unused,
-+      struct task_struct * p, struct pt_regs * regs)
-+{
-+      struct pt_regs * childregs;
-+      struct task_struct *tsk;
-+      int err;
-+
-+      childregs = task_pt_regs(p);
-+      *childregs = *regs;
-+      childregs->eax = 0;
-+      childregs->esp = esp;
-+
-+      p->thread.esp = (unsigned long) childregs;
-+      p->thread.esp0 = (unsigned long) (childregs+1);
-+
-+      p->thread.eip = (unsigned long) ret_from_fork;
-+
-+      savesegment(fs,p->thread.fs);
-+      savesegment(gs,p->thread.gs);
-+
-+      tsk = current;
-+      if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) {
-+              p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
-+              if (!p->thread.io_bitmap_ptr) {
-+                      p->thread.io_bitmap_max = 0;
-+                      return -ENOMEM;
-+              }
-+              memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr,
-+                      IO_BITMAP_BYTES);
-+      }
-+
-+      /*
-+       * Set a new TLS for the child thread?
-+       */
-+      if (clone_flags & CLONE_SETTLS) {
-+              struct desc_struct *desc;
-+              struct user_desc info;
-+              int idx;
-+
-+              err = -EFAULT;
-+              if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info)))
-+                      goto out;
-+              err = -EINVAL;
-+              if (LDT_empty(&info))
-+                      goto out;
-+
-+              idx = info.entry_number;
-+              if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
-+                      goto out;
-+
-+              desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
-+              desc->a = LDT_entry_a(&info);
-+              desc->b = LDT_entry_b(&info);
-+      }
-+
-+      p->thread.iopl = current->thread.iopl;
-+
-+      err = 0;
-+ out:
-+      if (err && p->thread.io_bitmap_ptr) {
-+              kfree(p->thread.io_bitmap_ptr);
-+              p->thread.io_bitmap_max = 0;
-+      }
-+      return err;
-+}
-+
-+/*
-+ * fill in the user structure for a core dump..
-+ */
-+void dump_thread(struct pt_regs * regs, struct user * dump)
-+{
-+      int i;
-+
-+/* changed the size calculations - should hopefully work better. lbt */
-+      dump->magic = CMAGIC;
-+      dump->start_code = 0;
-+      dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
-+      dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
-+      dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
-+      dump->u_dsize -= dump->u_tsize;
-+      dump->u_ssize = 0;
-+      for (i = 0; i < 8; i++)
-+              dump->u_debugreg[i] = current->thread.debugreg[i];  
-+
-+      if (dump->start_stack < TASK_SIZE)
-+              dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
-+
-+      dump->regs.ebx = regs->ebx;
-+      dump->regs.ecx = regs->ecx;
-+      dump->regs.edx = regs->edx;
-+      dump->regs.esi = regs->esi;
-+      dump->regs.edi = regs->edi;
-+      dump->regs.ebp = regs->ebp;
-+      dump->regs.eax = regs->eax;
-+      dump->regs.ds = regs->xds;
-+      dump->regs.es = regs->xes;
-+      savesegment(fs,dump->regs.fs);
-+      savesegment(gs,dump->regs.gs);
-+      dump->regs.orig_eax = regs->orig_eax;
-+      dump->regs.eip = regs->eip;
-+      dump->regs.cs = regs->xcs;
-+      dump->regs.eflags = regs->eflags;
-+      dump->regs.esp = regs->esp;
-+      dump->regs.ss = regs->xss;
-+
-+      dump->u_fpvalid = dump_fpu (regs, &dump->i387);
-+}
-+EXPORT_SYMBOL(dump_thread);
-+
-+/* 
-+ * Capture the user space registers if the task is not running (in user space)
-+ */
-+int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
-+{
-+      struct pt_regs ptregs = *task_pt_regs(tsk);
-+      ptregs.xcs &= 0xffff;
-+      ptregs.xds &= 0xffff;
-+      ptregs.xes &= 0xffff;
-+      ptregs.xss &= 0xffff;
-+
-+      elf_core_copy_regs(regs, &ptregs);
-+
-+      return 1;
-+}
-+
-+/*
-+ * This function selects if the context switch from prev to next
-+ * has to tweak the TSC disable bit in the cr4.
-+ */
-+static inline void disable_tsc(struct task_struct *prev_p,
-+                             struct task_struct *next_p)
-+{
-+      struct thread_info *prev, *next;
-+
-+      /*
-+       * gcc should eliminate the ->thread_info dereference if
-+       * has_secure_computing returns 0 at compile time (SECCOMP=n).
-+       */
-+      prev = task_thread_info(prev_p);
-+      next = task_thread_info(next_p);
-+
-+      if (has_secure_computing(prev) || has_secure_computing(next)) {
-+              /* slow path here */
-+              if (has_secure_computing(prev) &&
-+                  !has_secure_computing(next)) {
-+                      write_cr4(read_cr4() & ~X86_CR4_TSD);
-+              } else if (!has_secure_computing(prev) &&
-+                         has_secure_computing(next))
-+                      write_cr4(read_cr4() | X86_CR4_TSD);
-+      }
-+}
-+
-+/*
-+ *    switch_to(x,yn) should switch tasks from x to y.
-+ *
-+ * We fsave/fwait so that an exception goes off at the right time
-+ * (as a call from the fsave or fwait in effect) rather than to
-+ * the wrong process. Lazy FP saving no longer makes any sense
-+ * with modern CPU's, and this simplifies a lot of things (SMP
-+ * and UP become the same).
-+ *
-+ * NOTE! We used to use the x86 hardware context switching. The
-+ * reason for not using it any more becomes apparent when you
-+ * try to recover gracefully from saved state that is no longer
-+ * valid (stale segment register values in particular). With the
-+ * hardware task-switch, there is no way to fix up bad state in
-+ * a reasonable manner.
-+ *
-+ * The fact that Intel documents the hardware task-switching to
-+ * be slow is a fairly red herring - this code is not noticeably
-+ * faster. However, there _is_ some room for improvement here,
-+ * so the performance issues may eventually be a valid point.
-+ * More important, however, is the fact that this allows us much
-+ * more flexibility.
-+ *
-+ * The return value (in %eax) will be the "prev" task after
-+ * the task-switch, and shows up in ret_from_fork in entry.S,
-+ * for example.
-+ */
-+struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
-+{
-+      struct thread_struct *prev = &prev_p->thread,
-+                               *next = &next_p->thread;
-+      int cpu = smp_processor_id();
-+#ifndef CONFIG_X86_NO_TSS
-+      struct tss_struct *tss = &per_cpu(init_tss, cpu);
-+#endif
-+      struct physdev_set_iopl iopl_op;
-+      struct physdev_set_iobitmap iobmp_op;
-+      multicall_entry_t _mcl[8], *mcl = _mcl;
-+
-+      /* XEN NOTE: FS/GS saved in switch_mm(), not here. */
-+
-+      /*
-+       * This is basically '__unlazy_fpu', except that we queue a
-+       * multicall to indicate FPU task switch, rather than
-+       * synchronously trapping to Xen.
-+       */
-+      if (prev_p->thread_info->status & TS_USEDFPU) {
-+              __save_init_fpu(prev_p); /* _not_ save_init_fpu() */
-+              mcl->op      = __HYPERVISOR_fpu_taskswitch;
-+              mcl->args[0] = 1;
-+              mcl++;
-+      }
-+#if 0 /* lazy fpu sanity check */
-+      else BUG_ON(!(read_cr0() & 8));
-+#endif
-+
-+      /*
-+       * Reload esp0.
-+       * This is load_esp0(tss, next) with a multicall.
-+       */
-+      mcl->op      = __HYPERVISOR_stack_switch;
-+      mcl->args[0] = __KERNEL_DS;
-+      mcl->args[1] = next->esp0;
-+      mcl++;
-+
-+      /*
-+       * Load the per-thread Thread-Local Storage descriptor.
-+       * This is load_TLS(next, cpu) with multicalls.
-+       */
-+#define C(i) do {                                                     \
-+      if (unlikely(next->tls_array[i].a != prev->tls_array[i].a ||    \
-+                   next->tls_array[i].b != prev->tls_array[i].b)) {   \
-+              mcl->op = __HYPERVISOR_update_descriptor;               \
-+              *(u64 *)&mcl->args[0] = virt_to_machine(                \
-+                      &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]);\
-+              *(u64 *)&mcl->args[2] = *(u64 *)&next->tls_array[i];    \
-+              mcl++;                                                  \
-+      }                                                               \
-+} while (0)
-+      C(0); C(1); C(2);
-+#undef C
-+
-+      if (unlikely(prev->iopl != next->iopl)) {
-+              iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3;
-+              mcl->op      = __HYPERVISOR_physdev_op;
-+              mcl->args[0] = PHYSDEVOP_set_iopl;
-+              mcl->args[1] = (unsigned long)&iopl_op;
-+              mcl++;
-+      }
-+
-+      if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
-+              iobmp_op.bitmap   = (char *)next->io_bitmap_ptr;
-+              iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
-+              mcl->op      = __HYPERVISOR_physdev_op;
-+              mcl->args[0] = PHYSDEVOP_set_iobitmap;
-+              mcl->args[1] = (unsigned long)&iobmp_op;
-+              mcl++;
-+      }
-+
-+      (void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
-+
-+      /*
-+       * Restore %fs and %gs if needed.
-+       *
-+       * Glibc normally makes %fs be zero, and %gs is one of
-+       * the TLS segments.
-+       */
-+      if (unlikely(next->fs))
-+              loadsegment(fs, next->fs);
-+
-+      if (next->gs)
-+              loadsegment(gs, next->gs);
-+
-+      /*
-+       * Now maybe reload the debug registers
-+       */
-+      if (unlikely(next->debugreg[7])) {
-+              set_debugreg(next->debugreg[0], 0);
-+              set_debugreg(next->debugreg[1], 1);
-+              set_debugreg(next->debugreg[2], 2);
-+              set_debugreg(next->debugreg[3], 3);
-+              /* no 4 and 5 */
-+              set_debugreg(next->debugreg[6], 6);
-+              set_debugreg(next->debugreg[7], 7);
-+      }
-+
-+      disable_tsc(prev_p, next_p);
-+
-+      return prev_p;
-+}
-+
-+asmlinkage int sys_fork(struct pt_regs regs)
-+{
-+      return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
-+}
-+
-+asmlinkage int sys_clone(struct pt_regs regs)
-+{
-+      unsigned long clone_flags;
-+      unsigned long newsp;
-+      int __user *parent_tidptr, *child_tidptr;
-+
-+      clone_flags = regs.ebx;
-+      newsp = regs.ecx;
-+      parent_tidptr = (int __user *)regs.edx;
-+      child_tidptr = (int __user *)regs.edi;
-+      if (!newsp)
-+              newsp = regs.esp;
-+      return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
-+}
-+
-+/*
-+ * This is trivial, and on the face of it looks like it
-+ * could equally well be done in user mode.
-+ *
-+ * Not so, for quite unobvious reasons - register pressure.
-+ * In user mode vfork() cannot have a stack frame, and if
-+ * done by calling the "clone()" system call directly, you
-+ * do not have enough call-clobbered registers to hold all
-+ * the information you need.
-+ */
-+asmlinkage int sys_vfork(struct pt_regs regs)
-+{
-+      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
-+}
-+
-+/*
-+ * sys_execve() executes a new program.
-+ */
-+asmlinkage int sys_execve(struct pt_regs regs)
-+{
-+      int error;
-+      char * filename;
-+
-+      filename = getname((char __user *) regs.ebx);
-+      error = PTR_ERR(filename);
-+      if (IS_ERR(filename))
-+              goto out;
-+      error = do_execve(filename,
-+                      (char __user * __user *) regs.ecx,
-+                      (char __user * __user *) regs.edx,
-+                      &regs);
-+      if (error == 0) {
-+              task_lock(current);
-+              current->ptrace &= ~PT_DTRACE;
-+              task_unlock(current);
-+              /* Make sure we don't return using sysenter.. */
-+              set_thread_flag(TIF_IRET);
-+      }
-+      putname(filename);
-+out:
-+      return error;
-+}
-+
-+#define top_esp                (THREAD_SIZE - sizeof(unsigned long))
-+#define top_ebp                (THREAD_SIZE - 2*sizeof(unsigned long))
-+
-+unsigned long get_wchan(struct task_struct *p)
-+{
-+      unsigned long ebp, esp, eip;
-+      unsigned long stack_page;
-+      int count = 0;
-+      if (!p || p == current || p->state == TASK_RUNNING)
-+              return 0;
-+      stack_page = (unsigned long)task_stack_page(p);
-+      esp = p->thread.esp;
-+      if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
-+              return 0;
-+      /* include/asm-i386/system.h:switch_to() pushes ebp last. */
-+      ebp = *(unsigned long *) esp;
-+      do {
-+              if (ebp < stack_page || ebp > top_ebp+stack_page)
-+                      return 0;
-+              eip = *(unsigned long *) (ebp+4);
-+              if (!in_sched_functions(eip))
-+                      return eip;
-+              ebp = *(unsigned long *) ebp;
-+      } while (count++ < 16);
-+      return 0;
-+}
-+EXPORT_SYMBOL(get_wchan);
-+
-+/*
-+ * sys_alloc_thread_area: get a yet unused TLS descriptor index.
-+ */
-+static int get_free_idx(void)
-+{
-+      struct thread_struct *t = &current->thread;
-+      int idx;
-+
-+      for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
-+              if (desc_empty(t->tls_array + idx))
-+                      return idx + GDT_ENTRY_TLS_MIN;
-+      return -ESRCH;
-+}
-+
-+/*
-+ * Set a given TLS descriptor:
-+ */
-+asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
-+{
-+      struct thread_struct *t = &current->thread;
-+      struct user_desc info;
-+      struct desc_struct *desc;
-+      int cpu, idx;
-+
-+      if (copy_from_user(&info, u_info, sizeof(info)))
-+              return -EFAULT;
-+      idx = info.entry_number;
-+
-+      /*
-+       * index -1 means the kernel should try to find and
-+       * allocate an empty descriptor:
-+       */
-+      if (idx == -1) {
-+              idx = get_free_idx();
-+              if (idx < 0)
-+                      return idx;
-+              if (put_user(idx, &u_info->entry_number))
-+                      return -EFAULT;
-+      }
-+
-+      if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
-+              return -EINVAL;
-+
-+      desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
-+
-+      /*
-+       * We must not get preempted while modifying the TLS.
-+       */
-+      cpu = get_cpu();
-+
-+      if (LDT_empty(&info)) {
-+              desc->a = 0;
-+              desc->b = 0;
-+      } else {
-+              desc->a = LDT_entry_a(&info);
-+              desc->b = LDT_entry_b(&info);
-+      }
-+      load_TLS(t, cpu);
-+
-+      put_cpu();
-+
-+      return 0;
-+}
-+
-+/*
-+ * Get the current Thread-Local Storage area:
-+ */
-+
-+#define GET_BASE(desc) ( \
-+      (((desc)->a >> 16) & 0x0000ffff) | \
-+      (((desc)->b << 16) & 0x00ff0000) | \
-+      ( (desc)->b        & 0xff000000)   )
-+
-+#define GET_LIMIT(desc) ( \
-+      ((desc)->a & 0x0ffff) | \
-+       ((desc)->b & 0xf0000) )
-+      
-+#define GET_32BIT(desc)               (((desc)->b >> 22) & 1)
-+#define GET_CONTENTS(desc)    (((desc)->b >> 10) & 3)
-+#define GET_WRITABLE(desc)    (((desc)->b >>  9) & 1)
-+#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
-+#define GET_PRESENT(desc)     (((desc)->b >> 15) & 1)
-+#define GET_USEABLE(desc)     (((desc)->b >> 20) & 1)
-+
-+asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
-+{
-+      struct user_desc info;
-+      struct desc_struct *desc;
-+      int idx;
-+
-+      if (get_user(idx, &u_info->entry_number))
-+              return -EFAULT;
-+      if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
-+              return -EINVAL;
-+
-+      memset(&info, 0, sizeof(info));
-+
-+      desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
-+
-+      info.entry_number = idx;
-+      info.base_addr = GET_BASE(desc);
-+      info.limit = GET_LIMIT(desc);
-+      info.seg_32bit = GET_32BIT(desc);
-+      info.contents = GET_CONTENTS(desc);
-+      info.read_exec_only = !GET_WRITABLE(desc);
-+      info.limit_in_pages = GET_LIMIT_PAGES(desc);
-+      info.seg_not_present = !GET_PRESENT(desc);
-+      info.useable = GET_USEABLE(desc);
-+
-+      if (copy_to_user(u_info, &info, sizeof(info)))
-+              return -EFAULT;
-+      return 0;
-+}
-+
-+unsigned long arch_align_stack(unsigned long sp)
-+{
-+      if (randomize_va_space)
-+              sp -= get_random_int() % 8192;
-+      return sp & ~0xf;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/quirks-xen.c linux-2.6.16.33/arch/i386/kernel/quirks-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/quirks-xen.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/quirks-xen.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,48 @@
-+/*
-+ * This file contains work-arounds for x86 and x86_64 platform bugs.
-+ */
-+#include <linux/config.h>
-+#include <linux/pci.h>
-+#include <linux/irq.h>
-+
-+#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_SMP) || defined(CONFIG_XEN)) && defined(CONFIG_PCI)
-+
-+static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
-+{
-+      u8 config, rev;
-+      u32 word;
-+
-+      /* BIOS may enable hardware IRQ balancing for
-+       * E7520/E7320/E7525(revision ID 0x9 and below)
-+       * based platforms.
-+       * Disable SW irqbalance/affinity on those platforms.
-+       */
-+      pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
-+      if (rev > 0x9)
-+              return;
-+
-+      printk(KERN_INFO "Intel E7520/7320/7525 detected.");
-+
-+      /* enable access to config space*/
-+      pci_read_config_byte(dev, 0xf4, &config);
-+      pci_write_config_byte(dev, 0xf4, config|0x2);
-+
-+      /* read xTPR register */
-+      raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
-+
-+      if (!(word & (1 << 13))) {
-+              dom0_op_t op;
-+              printk(KERN_INFO "Disabling irq balancing and affinity\n");
-+              op.cmd = DOM0_PLATFORM_QUIRK;
-+              op.u.platform_quirk.quirk_id = QUIRK_NOIRQBALANCING;
-+              (void)HYPERVISOR_dom0_op(&op);
-+      }
-+
-+      /* put back the original value for config space*/
-+      if (!(config & 0x2))
-+              pci_write_config_byte(dev, 0xf4, config);
-+}
-+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_E7320_MCH,  quirk_intel_irqbalance);
-+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_E7525_MCH,  quirk_intel_irqbalance);
-+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_E7520_MCH,  quirk_intel_irqbalance);
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/relocate_kernel.S linux-2.6.16.33/arch/i386/kernel/relocate_kernel.S
---- linux-2.6.16.33-noxen/arch/i386/kernel/relocate_kernel.S   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/relocate_kernel.S 2007-05-23 21:00:01.000000000 +0000
-@@ -7,16 +7,138 @@
-  */
- #include <linux/linkage.h>
-+#include <asm/page.h>
-+#include <asm/kexec.h>
-+
-+/*
-+ * Must be relocatable PIC code callable as a C function
-+ */
-+
-+#define PTR(x) (x << 2)
-+#define PAGE_ALIGNED (1 << PAGE_SHIFT)
-+#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
-+#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */
-+
-+      .text
-+      .align PAGE_ALIGNED
-+      .globl relocate_kernel
-+relocate_kernel:
-+      movl    8(%esp), %ebp /* list of pages */
-+
-+#ifdef CONFIG_X86_PAE
-+      /* map the control page at its virtual address */
-+
-+      movl    PTR(VA_PGD)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0xc0000000, %eax
-+      shrl    $27, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PMD_0)(%ebp), %edx
-+      orl     $PAE_PGD_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PMD_0)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x3fe00000, %eax
-+      shrl    $18, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PTE_0)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PTE_0)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x001ff000, %eax
-+      shrl    $9, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      /* identity map the control page at its physical address */
-+
-+      movl    PTR(VA_PGD)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0xc0000000, %eax
-+      shrl    $27, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PMD_1)(%ebp), %edx
-+      orl     $PAE_PGD_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PMD_1)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x3fe00000, %eax
-+      shrl    $18, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PTE_1)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PTE_1)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x001ff000, %eax
-+      shrl    $9, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+#else
-+      /* map the control page at its virtual address */
-+
-+      movl    PTR(VA_PGD)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0xffc00000, %eax
-+      shrl    $20, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PTE_0)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PTE_0)(%ebp), %edi
-+      movl    PTR(VA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x003ff000, %eax
-+      shrl    $10, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      /* identity map the control page at its physical address */
-+
-+      movl    PTR(VA_PGD)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0xffc00000, %eax
-+      shrl    $20, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_PTE_1)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+
-+      movl    PTR(VA_PTE_1)(%ebp), %edi
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %eax
-+      andl    $0x003ff000, %eax
-+      shrl    $10, %eax
-+      addl    %edi, %eax
-+
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edx
-+      orl     $PAGE_ATTR, %edx
-+      movl    %edx, (%eax)
-+#endif
--      /*
--       * Must be relocatable PIC code callable as a C function, that once
--       * it starts can not use the previous processes stack.
--       */
--      .globl relocate_new_kernel
- relocate_new_kernel:
-       /* read the arguments and say goodbye to the stack */
-       movl  4(%esp), %ebx /* page_list */
--      movl  8(%esp), %ebp /* reboot_code_buffer */
-+      movl  8(%esp), %ebp /* list of pages */
-       movl  12(%esp), %edx /* start address */
-       movl  16(%esp), %ecx /* cpu_has_pae */
-@@ -24,11 +146,57 @@
-       pushl $0
-       popfl
--      /* set a new stack at the bottom of our page... */
--      lea   4096(%ebp), %esp
-+      /* get physical address of control page now */
-+      /* this is impossible after page table switch */
-+      movl    PTR(PA_CONTROL_PAGE)(%ebp), %edi
--      /* store the parameters back on the stack */
--      pushl   %edx /* store the start address */
-+      /* switch to new set of page tables */
-+      movl    PTR(PA_PGD)(%ebp), %eax
-+      movl    %eax, %cr3
-+
-+      /* setup idt */
-+      movl    %edi, %eax
-+      addl    $(idt_48 - relocate_kernel), %eax
-+      lidtl   (%eax)
-+
-+      /* setup gdt */
-+      movl    %edi, %eax
-+      addl    $(gdt - relocate_kernel), %eax
-+      movl    %edi, %esi
-+      addl    $((gdt_48 - relocate_kernel) + 2), %esi
-+      movl    %eax, (%esi)
-+      
-+      movl    %edi, %eax
-+      addl    $(gdt_48 - relocate_kernel), %eax
-+      lgdtl   (%eax)
-+
-+      /* setup data segment registers */
-+      mov     $(gdt_ds - gdt), %eax
-+      mov     %eax, %ds
-+      mov     %eax, %es
-+      mov     %eax, %fs
-+      mov     %eax, %gs
-+      mov     %eax, %ss
-+      
-+      /* setup a new stack at the end of the physical control page */
-+      lea     4096(%edi), %esp
-+
-+      /* load new code segment and jump to identity mapped page */
-+      movl    %edi, %esi
-+      xorl    %eax, %eax
-+      pushl   %eax
-+      pushl   %esi
-+      pushl   %eax
-+      movl    $(gdt_cs - gdt), %eax
-+      pushl   %eax    
-+      movl    %edi, %eax
-+      addl    $(identity_mapped - relocate_kernel),%eax
-+      pushl   %eax
-+      iretl
-+
-+identity_mapped:
-+      /* store the start address on the stack */
-+      pushl   %edx
-       /* Set cr0 to a known state:
-        * 31 0 == Paging disabled
-@@ -113,8 +281,20 @@
-       xorl    %edi, %edi
-       xorl    %ebp, %ebp
-       ret
--relocate_new_kernel_end:
--      .globl relocate_new_kernel_size
--relocate_new_kernel_size:
--      .long relocate_new_kernel_end - relocate_new_kernel
-+      .align  16
-+gdt:
-+      .quad   0x0000000000000000      /* NULL descriptor */
-+gdt_cs:       
-+      .quad   0x00cf9a000000ffff      /* kernel 4GB code at 0x00000000 */
-+gdt_ds:
-+      .quad   0x00cf92000000ffff      /* kernel 4GB data at 0x00000000 */
-+gdt_end:
-+      
-+gdt_48:
-+      .word   gdt_end - gdt - 1       /* limit */
-+      .long   0                       /* base - filled in by code above */
-+
-+idt_48:
-+      .word   0                       /* limit */
-+      .long   0                       /* base */
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/setup-xen.c linux-2.6.16.33/arch/i386/kernel/setup-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/setup-xen.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/setup-xen.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1892 @@
-+/*
-+ *  linux/arch/i386/kernel/setup.c
-+ *
-+ *  Copyright (C) 1995  Linus Torvalds
-+ *
-+ *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
-+ *
-+ *  Memory region support
-+ *    David Parsons <orc@pell.chi.il.us>, July-August 1999
-+ *
-+ *  Added E820 sanitization routine (removes overlapping memory regions);
-+ *  Brian Moyle <bmoyle@mvista.com>, February 2001
-+ *
-+ * Moved CPU detection code to cpu/${cpu}.c
-+ *    Patrick Mochel <mochel@osdl.org>, March 2002
-+ *
-+ *  Provisions for empty E820 memory regions (reported by certain BIOSes).
-+ *  Alex Achenbach <xela@slit.de>, December 2002.
-+ *
-+ */
-+
-+/*
-+ * This file handles the architecture-dependent parts of initialization
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/mmzone.h>
-+#include <linux/tty.h>
-+#include <linux/ioport.h>
-+#include <linux/acpi.h>
-+#include <linux/apm_bios.h>
-+#include <linux/initrd.h>
-+#include <linux/bootmem.h>
-+#include <linux/seq_file.h>
-+#include <linux/console.h>
-+#include <linux/mca.h>
-+#include <linux/root_dev.h>
-+#include <linux/highmem.h>
-+#include <linux/module.h>
-+#include <linux/efi.h>
-+#include <linux/init.h>
-+#include <linux/edd.h>
-+#include <linux/nodemask.h>
-+#include <linux/kernel.h>
-+#include <linux/percpu.h>
-+#include <linux/notifier.h>
-+#include <linux/kexec.h>
-+#include <linux/crash_dump.h>
-+#include <linux/dmi.h>
-+
-+#include <video/edid.h>
-+
-+#include <asm/apic.h>
-+#include <asm/e820.h>
-+#include <asm/mpspec.h>
-+#include <asm/setup.h>
-+#include <asm/arch_hooks.h>
-+#include <asm/sections.h>
-+#include <asm/io_apic.h>
-+#include <asm/ist.h>
-+#include <asm/io.h>
-+#include <asm/hypervisor.h>
-+#include <xen/interface/physdev.h>
-+#include <xen/interface/memory.h>
-+#include <xen/features.h>
-+#include <xen/xencons.h>
-+#include "setup_arch_pre.h"
-+#include <bios_ebda.h>
-+
-+#ifdef CONFIG_XEN
-+#include <xen/interface/kexec.h>
-+#endif
-+
-+/* Forward Declaration. */
-+void __init find_max_pfn(void);
-+
-+static int xen_panic_event(struct notifier_block *, unsigned long, void *);
-+static struct notifier_block xen_panic_block = {
-+      xen_panic_event, NULL, 0 /* try to go last */
-+};
-+
-+extern char hypercall_page[PAGE_SIZE];
-+EXPORT_SYMBOL(hypercall_page);
-+
-+int disable_pse __devinitdata = 0;
-+
-+/*
-+ * Machine setup..
-+ */
-+
-+#ifdef CONFIG_EFI
-+int efi_enabled = 0;
-+EXPORT_SYMBOL(efi_enabled);
-+#endif
-+
-+/* cpu data as detected by the assembly code in head.S */
-+struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
-+/* common cpu data for all cpus */
-+struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
-+EXPORT_SYMBOL(boot_cpu_data);
-+
-+unsigned long mmu_cr4_features;
-+
-+#ifdef        CONFIG_ACPI
-+      int acpi_disabled = 0;
-+#else
-+      int acpi_disabled = 1;
-+#endif
-+EXPORT_SYMBOL(acpi_disabled);
-+
-+#ifdef        CONFIG_ACPI
-+int __initdata acpi_force = 0;
-+extern acpi_interrupt_flags   acpi_sci_flags;
-+#endif
-+
-+/* for MCA, but anyone else can use it if they want */
-+unsigned int machine_id;
-+#ifdef CONFIG_MCA
-+EXPORT_SYMBOL(machine_id);
-+#endif
-+unsigned int machine_submodel_id;
-+unsigned int BIOS_revision;
-+unsigned int mca_pentium_flag;
-+
-+/* For PCI or other memory-mapped resources */
-+unsigned long pci_mem_start = 0x10000000;
-+#ifdef CONFIG_PCI
-+EXPORT_SYMBOL(pci_mem_start);
-+#endif
-+
-+/* Boot loader ID as an integer, for the benefit of proc_dointvec */
-+int bootloader_type;
-+
-+/* user-defined highmem size */
-+static unsigned int highmem_pages = -1;
-+
-+/*
-+ * Setup options
-+ */
-+struct drive_info_struct { char dummy[32]; } drive_info;
-+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
-+    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-+EXPORT_SYMBOL(drive_info);
-+#endif
-+struct screen_info screen_info;
-+EXPORT_SYMBOL(screen_info);
-+struct apm_info apm_info;
-+EXPORT_SYMBOL(apm_info);
-+struct sys_desc_table_struct {
-+      unsigned short length;
-+      unsigned char table[0];
-+};
-+struct edid_info edid_info;
-+EXPORT_SYMBOL_GPL(edid_info);
-+struct ist_info ist_info;
-+#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
-+      defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
-+EXPORT_SYMBOL(ist_info);
-+#endif
-+struct e820map e820;
-+#ifdef CONFIG_XEN
-+struct e820map machine_e820;
-+#endif
-+
-+extern void early_cpu_init(void);
-+extern void generic_apic_probe(char *);
-+extern int root_mountflags;
-+
-+unsigned long saved_videomode;
-+
-+#define RAMDISK_IMAGE_START_MASK      0x07FF
-+#define RAMDISK_PROMPT_FLAG           0x8000
-+#define RAMDISK_LOAD_FLAG             0x4000  
-+
-+static char command_line[COMMAND_LINE_SIZE];
-+
-+unsigned char __initdata boot_params[PARAM_SIZE];
-+
-+static struct resource data_resource = {
-+      .name   = "Kernel data",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-+};
-+
-+static struct resource code_resource = {
-+      .name   = "Kernel code",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-+};
-+
-+static struct resource system_rom_resource = {
-+      .name   = "System ROM",
-+      .start  = 0xf0000,
-+      .end    = 0xfffff,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+};
-+
-+static struct resource extension_rom_resource = {
-+      .name   = "Extension ROM",
-+      .start  = 0xe0000,
-+      .end    = 0xeffff,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+};
-+
-+static struct resource adapter_rom_resources[] = { {
-+      .name   = "Adapter ROM",
-+      .start  = 0xc8000,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+}, {
-+      .name   = "Adapter ROM",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+}, {
-+      .name   = "Adapter ROM",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+}, {
-+      .name   = "Adapter ROM",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+}, {
-+      .name   = "Adapter ROM",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+}, {
-+      .name   = "Adapter ROM",
-+      .start  = 0,
-+      .end    = 0,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+} };
-+
-+#define ADAPTER_ROM_RESOURCES \
-+      (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
-+
-+static struct resource video_rom_resource = {
-+      .name   = "Video ROM",
-+      .start  = 0xc0000,
-+      .end    = 0xc7fff,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-+};
-+
-+static struct resource video_ram_resource = {
-+      .name   = "Video RAM area",
-+      .start  = 0xa0000,
-+      .end    = 0xbffff,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-+};
-+
-+static struct resource standard_io_resources[] = { {
-+      .name   = "dma1",
-+      .start  = 0x0000,
-+      .end    = 0x001f,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "pic1",
-+      .start  = 0x0020,
-+      .end    = 0x0021,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "timer0",
-+      .start  = 0x0040,
-+      .end    = 0x0043,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "timer1",
-+      .start  = 0x0050,
-+      .end    = 0x0053,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "keyboard",
-+      .start  = 0x0060,
-+      .end    = 0x006f,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "dma page reg",
-+      .start  = 0x0080,
-+      .end    = 0x008f,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "pic2",
-+      .start  = 0x00a0,
-+      .end    = 0x00a1,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "dma2",
-+      .start  = 0x00c0,
-+      .end    = 0x00df,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+}, {
-+      .name   = "fpu",
-+      .start  = 0x00f0,
-+      .end    = 0x00ff,
-+      .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-+} };
-+
-+#define STANDARD_IO_RESOURCES \
-+      (sizeof standard_io_resources / sizeof standard_io_resources[0])
-+
-+#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
-+
-+static int __init romchecksum(unsigned char *rom, unsigned long length)
-+{
-+      unsigned char *p, sum = 0;
-+
-+      for (p = rom; p < rom + length; p++)
-+              sum += *p;
-+      return sum == 0;
-+}
-+
-+static void __init probe_roms(void)
-+{
-+      unsigned long start, length, upper;
-+      unsigned char *rom;
-+      int           i;
-+
-+#ifdef CONFIG_XEN
-+      /* Nothing to do if not running in dom0. */
-+      if (!is_initial_xendomain())
-+              return;
-+#endif
-+
-+      /* video rom */
-+      upper = adapter_rom_resources[0].start;
-+      for (start = video_rom_resource.start; start < upper; start += 2048) {
-+              rom = isa_bus_to_virt(start);
-+              if (!romsignature(rom))
-+                      continue;
-+
-+              video_rom_resource.start = start;
-+
-+              /* 0 < length <= 0x7f * 512, historically */
-+              length = rom[2] * 512;
-+
-+              /* if checksum okay, trust length byte */
-+              if (length && romchecksum(rom, length))
-+                      video_rom_resource.end = start + length - 1;
-+
-+              request_resource(&iomem_resource, &video_rom_resource);
-+              break;
-+      }
-+
-+      start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
-+      if (start < upper)
-+              start = upper;
-+
-+      /* system rom */
-+      request_resource(&iomem_resource, &system_rom_resource);
-+      upper = system_rom_resource.start;
-+
-+      /* check for extension rom (ignore length byte!) */
-+      rom = isa_bus_to_virt(extension_rom_resource.start);
-+      if (romsignature(rom)) {
-+              length = extension_rom_resource.end - extension_rom_resource.start + 1;
-+              if (romchecksum(rom, length)) {
-+                      request_resource(&iomem_resource, &extension_rom_resource);
-+                      upper = extension_rom_resource.start;
-+              }
-+      }
-+
-+      /* check for adapter roms on 2k boundaries */
-+      for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
-+              rom = isa_bus_to_virt(start);
-+              if (!romsignature(rom))
-+                      continue;
-+
-+              /* 0 < length <= 0x7f * 512, historically */
-+              length = rom[2] * 512;
-+
-+              /* but accept any length that fits if checksum okay */
-+              if (!length || start + length > upper || !romchecksum(rom, length))
-+                      continue;
-+
-+              adapter_rom_resources[i].start = start;
-+              adapter_rom_resources[i].end = start + length - 1;
-+              request_resource(&iomem_resource, &adapter_rom_resources[i]);
-+
-+              start = adapter_rom_resources[i++].end & ~2047UL;
-+      }
-+}
-+
-+/*
-+ * Point at the empty zero page to start with. We map the real shared_info
-+ * page as soon as fixmap is up and running.
-+ */
-+shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
-+EXPORT_SYMBOL(HYPERVISOR_shared_info);
-+
-+unsigned long *phys_to_machine_mapping;
-+unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[16];
-+EXPORT_SYMBOL(phys_to_machine_mapping);
-+
-+/* Raw start-of-day parameters from the hypervisor. */
-+start_info_t *xen_start_info;
-+EXPORT_SYMBOL(xen_start_info);
-+
-+static void __init add_memory_region(unsigned long long start,
-+                                  unsigned long long size, int type)
-+{
-+      int x;
-+
-+      if (!efi_enabled) {
-+                      x = e820.nr_map;
-+
-+              if (x == E820MAX) {
-+                  printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
-+                  return;
-+              }
-+
-+              e820.map[x].addr = start;
-+              e820.map[x].size = size;
-+              e820.map[x].type = type;
-+              e820.nr_map++;
-+      }
-+} /* add_memory_region */
-+
-+static void __init limit_regions(unsigned long long size)
-+{
-+      unsigned long long current_addr = 0;
-+      int i;
-+
-+      if (efi_enabled) {
-+              efi_memory_desc_t *md;
-+              void *p;
-+
-+              for (p = memmap.map, i = 0; p < memmap.map_end;
-+                      p += memmap.desc_size, i++) {
-+                      md = p;
-+                      current_addr = md->phys_addr + (md->num_pages << 12);
-+                      if (md->type == EFI_CONVENTIONAL_MEMORY) {
-+                              if (current_addr >= size) {
-+                                      md->num_pages -=
-+                                              (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
-+                                      memmap.nr_map = i + 1;
-+                                      return;
-+                              }
-+                      }
-+              }
-+      }
-+      for (i = 0; i < e820.nr_map; i++) {
-+              current_addr = e820.map[i].addr + e820.map[i].size;
-+              if (current_addr < size)
-+                      continue;
-+
-+              if (e820.map[i].type != E820_RAM)
-+                      continue;
-+
-+              if (e820.map[i].addr >= size) {
-+                      /*
-+                       * This region starts past the end of the
-+                       * requested size, skip it completely.
-+                       */
-+                      e820.nr_map = i;
-+              } else {
-+                      e820.nr_map = i + 1;
-+                      e820.map[i].size -= current_addr - size;
-+              }
-+              return;
-+      }
-+#ifdef CONFIG_XEN
-+      if (i==e820.nr_map && current_addr < size) {
-+              /*
-+                 * The e820 map finished before our requested size so
-+                 * extend the final entry to the requested address.
-+                 */
-+              --i;
-+              if (e820.map[i].type == E820_RAM)
-+                      e820.map[i].size -= current_addr - size;
-+              else
-+                      add_memory_region(current_addr, size - current_addr, E820_RAM);
-+      }
-+#endif
-+}
-+
-+#define E820_DEBUG    1
-+
-+static void __init print_memory_map(char *who)
-+{
-+      int i;
-+
-+      for (i = 0; i < e820.nr_map; i++) {
-+              printk(" %s: %016Lx - %016Lx ", who,
-+                      e820.map[i].addr,
-+                      e820.map[i].addr + e820.map[i].size);
-+              switch (e820.map[i].type) {
-+              case E820_RAM:  printk("(usable)\n");
-+                              break;
-+              case E820_RESERVED:
-+                              printk("(reserved)\n");
-+                              break;
-+              case E820_ACPI:
-+                              printk("(ACPI data)\n");
-+                              break;
-+              case E820_NVS:
-+                              printk("(ACPI NVS)\n");
-+                              break;
-+              default:        printk("type %lu\n", e820.map[i].type);
-+                              break;
-+              }
-+      }
-+}
-+
-+/*
-+ * Sanitize the BIOS e820 map.
-+ *
-+ * Some e820 responses include overlapping entries.  The following 
-+ * replaces the original e820 map with a new one, removing overlaps.
-+ *
-+ */
-+struct change_member {
-+      struct e820entry *pbios; /* pointer to original bios entry */
-+      unsigned long long addr; /* address for this change point */
-+};
-+static struct change_member change_point_list[2*E820MAX] __initdata;
-+static struct change_member *change_point[2*E820MAX] __initdata;
-+static struct e820entry *overlap_list[E820MAX] __initdata;
-+static struct e820entry new_bios[E820MAX] __initdata;
-+
-+static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
-+{
-+      struct change_member *change_tmp;
-+      unsigned long current_type, last_type;
-+      unsigned long long last_addr;
-+      int chgidx, still_changing;
-+      int overlap_entries;
-+      int new_bios_entry;
-+      int old_nr, new_nr, chg_nr;
-+      int i;
-+
-+      /*
-+              Visually we're performing the following (1,2,3,4 = memory types)...
-+
-+              Sample memory map (w/overlaps):
-+                 ____22__________________
-+                 ______________________4_
-+                 ____1111________________
-+                 _44_____________________
-+                 11111111________________
-+                 ____________________33__
-+                 ___________44___________
-+                 __________33333_________
-+                 ______________22________
-+                 ___________________2222_
-+                 _________111111111______
-+                 _____________________11_
-+                 _________________4______
-+
-+              Sanitized equivalent (no overlap):
-+                 1_______________________
-+                 _44_____________________
-+                 ___1____________________
-+                 ____22__________________
-+                 ______11________________
-+                 _________1______________
-+                 __________3_____________
-+                 ___________44___________
-+                 _____________33_________
-+                 _______________2________
-+                 ________________1_______
-+                 _________________4______
-+                 ___________________2____
-+                 ____________________33__
-+                 ______________________4_
-+      */
-+
-+      /* if there's only one memory region, don't bother */
-+      if (*pnr_map < 2)
-+              return -1;
-+
-+      old_nr = *pnr_map;
-+
-+      /* bail out if we find any unreasonable addresses in bios map */
-+      for (i=0; i<old_nr; i++)
-+              if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
-+                      return -1;
-+
-+      /* create pointers for initial change-point information (for sorting) */
-+      for (i=0; i < 2*old_nr; i++)
-+              change_point[i] = &change_point_list[i];
-+
-+      /* record all known change-points (starting and ending addresses),
-+         omitting those that are for empty memory regions */
-+      chgidx = 0;
-+      for (i=0; i < old_nr; i++)      {
-+              if (biosmap[i].size != 0) {
-+                      change_point[chgidx]->addr = biosmap[i].addr;
-+                      change_point[chgidx++]->pbios = &biosmap[i];
-+                      change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
-+                      change_point[chgidx++]->pbios = &biosmap[i];
-+              }
-+      }
-+      chg_nr = chgidx;        /* true number of change-points */
-+
-+      /* sort change-point list by memory addresses (low -> high) */
-+      still_changing = 1;
-+      while (still_changing)  {
-+              still_changing = 0;
-+              for (i=1; i < chg_nr; i++)  {
-+                      /* if <current_addr> > <last_addr>, swap */
-+                      /* or, if current=<start_addr> & last=<end_addr>, swap */
-+                      if ((change_point[i]->addr < change_point[i-1]->addr) ||
-+                              ((change_point[i]->addr == change_point[i-1]->addr) &&
-+                               (change_point[i]->addr == change_point[i]->pbios->addr) &&
-+                               (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
-+                         )
-+                      {
-+                              change_tmp = change_point[i];
-+                              change_point[i] = change_point[i-1];
-+                              change_point[i-1] = change_tmp;
-+                              still_changing=1;
-+                      }
-+              }
-+      }
-+
-+      /* create a new bios memory map, removing overlaps */
-+      overlap_entries=0;       /* number of entries in the overlap table */
-+      new_bios_entry=0;        /* index for creating new bios map entries */
-+      last_type = 0;           /* start with undefined memory type */
-+      last_addr = 0;           /* start with 0 as last starting address */
-+      /* loop through change-points, determining affect on the new bios map */
-+      for (chgidx=0; chgidx < chg_nr; chgidx++)
-+      {
-+              /* keep track of all overlapping bios entries */
-+              if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
-+              {
-+                      /* add map entry to overlap list (> 1 entry implies an overlap) */
-+                      overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
-+              }
-+              else
-+              {
-+                      /* remove entry from list (order independent, so swap with last) */
-+                      for (i=0; i<overlap_entries; i++)
-+                      {
-+                              if (overlap_list[i] == change_point[chgidx]->pbios)
-+                                      overlap_list[i] = overlap_list[overlap_entries-1];
-+                      }
-+                      overlap_entries--;
-+              }
-+              /* if there are overlapping entries, decide which "type" to use */
-+              /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
-+              current_type = 0;
-+              for (i=0; i<overlap_entries; i++)
-+                      if (overlap_list[i]->type > current_type)
-+                              current_type = overlap_list[i]->type;
-+              /* continue building up new bios map based on this information */
-+              if (current_type != last_type)  {
-+                      if (last_type != 0)      {
-+                              new_bios[new_bios_entry].size =
-+                                      change_point[chgidx]->addr - last_addr;
-+                              /* move forward only if the new size was non-zero */
-+                              if (new_bios[new_bios_entry].size != 0)
-+                                      if (++new_bios_entry >= E820MAX)
-+                                              break;  /* no more space left for new bios entries */
-+                      }
-+                      if (current_type != 0)  {
-+                              new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
-+                              new_bios[new_bios_entry].type = current_type;
-+                              last_addr=change_point[chgidx]->addr;
-+                      }
-+                      last_type = current_type;
-+              }
-+      }
-+      new_nr = new_bios_entry;   /* retain count for new bios entries */
-+
-+      /* copy new bios mapping into original location */
-+      memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
-+      *pnr_map = new_nr;
-+
-+      return 0;
-+}
-+
-+/*
-+ * Copy the BIOS e820 map into a safe place.
-+ *
-+ * Sanity-check it while we're at it..
-+ *
-+ * If we're lucky and live on a modern system, the setup code
-+ * will have given us a memory map that we can use to properly
-+ * set up memory.  If we aren't, we'll fake a memory map.
-+ *
-+ * We check to see that the memory map contains at least 2 elements
-+ * before we'll use it, because the detection code in setup.S may
-+ * not be perfect and most every PC known to man has two memory
-+ * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
-+ * thinkpad 560x, for example, does not cooperate with the memory
-+ * detection code.)
-+ */
-+static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
-+{
-+#ifndef CONFIG_XEN
-+      /* Only one memory region (or negative)? Ignore it */
-+      if (nr_map < 2)
-+              return -1;
-+#else
-+      BUG_ON(nr_map < 1);
-+#endif
-+
-+      do {
-+              unsigned long long start = biosmap->addr;
-+              unsigned long long size = biosmap->size;
-+              unsigned long long end = start + size;
-+              unsigned long type = biosmap->type;
-+
-+              /* Overflow in 64 bits? Ignore the memory map. */
-+              if (start > end)
-+                      return -1;
-+
-+#ifndef CONFIG_XEN
-+              /*
-+               * Some BIOSes claim RAM in the 640k - 1M region.
-+               * Not right. Fix it up.
-+               */
-+              if (type == E820_RAM) {
-+                      if (start < 0x100000ULL && end > 0xA0000ULL) {
-+                              if (start < 0xA0000ULL)
-+                                      add_memory_region(start, 0xA0000ULL-start, type);
-+                              if (end <= 0x100000ULL)
-+                                      continue;
-+                              start = 0x100000ULL;
-+                              size = end - start;
-+                      }
-+              }
-+#endif
-+              add_memory_region(start, size, type);
-+      } while (biosmap++,--nr_map);
-+      return 0;
-+}
-+
-+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-+struct edd edd;
-+#ifdef CONFIG_EDD_MODULE
-+EXPORT_SYMBOL(edd);
-+#endif
-+/**
-+ * copy_edd() - Copy the BIOS EDD information
-+ *              from boot_params into a safe place.
-+ *
-+ */
-+static inline void copy_edd(void)
-+{
-+     memcpy(edd.mbr_signature, EDD_MBR_SIGNATURE, sizeof(edd.mbr_signature));
-+     memcpy(edd.edd_info, EDD_BUF, sizeof(edd.edd_info));
-+     edd.mbr_signature_nr = EDD_MBR_SIG_NR;
-+     edd.edd_info_nr = EDD_NR;
-+}
-+#else
-+static inline void copy_edd(void)
-+{
-+}
-+#endif
-+
-+/*
-+ * Do NOT EVER look at the BIOS memory size location.
-+ * It does not work on many machines.
-+ */
-+#define LOWMEMSIZE()  (0x9f000)
-+
-+static void __init parse_cmdline_early (char ** cmdline_p)
-+{
-+      char c = ' ', *to = command_line, *from = saved_command_line;
-+      int len = 0, max_cmdline;
-+      int userdef = 0;
-+
-+      if ((max_cmdline = MAX_GUEST_CMDLINE) > COMMAND_LINE_SIZE)
-+              max_cmdline = COMMAND_LINE_SIZE;
-+      memcpy(saved_command_line, xen_start_info->cmd_line, max_cmdline);
-+      /* Save unparsed command line copy for /proc/cmdline */
-+      saved_command_line[max_cmdline-1] = '\0';
-+
-+      for (;;) {
-+              if (c != ' ')
-+                      goto next_char;
-+              /*
-+               * "mem=nopentium" disables the 4MB page tables.
-+               * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
-+               * to <mem>, overriding the bios size.
-+               * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from
-+               * <start> to <start>+<mem>, overriding the bios size.
-+               *
-+               * HPA tells me bootloaders need to parse mem=, so no new
-+               * option should be mem=  [also see Documentation/i386/boot.txt]
-+               */
-+              if (!memcmp(from, "mem=", 4)) {
-+                      if (to != command_line)
-+                              to--;
-+                      if (!memcmp(from+4, "nopentium", 9)) {
-+                              from += 9+4;
-+                              clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
-+                              disable_pse = 1;
-+                      } else {
-+                              /* If the user specifies memory size, we
-+                               * limit the BIOS-provided memory map to
-+                               * that size. exactmap can be used to specify
-+                               * the exact map. mem=number can be used to
-+                               * trim the existing memory map.
-+                               */
-+                              unsigned long long mem_size;
-+ 
-+                              mem_size = memparse(from+4, &from);
-+                              limit_regions(mem_size);
-+                              userdef=1;
-+                      }
-+              }
-+
-+              else if (!memcmp(from, "memmap=", 7)) {
-+                      if (to != command_line)
-+                              to--;
-+                      if (!memcmp(from+7, "exactmap", 8)) {
-+#ifdef CONFIG_CRASH_DUMP
-+                              /* If we are doing a crash dump, we
-+                               * still need to know the real mem
-+                               * size before original memory map is
-+                               * reset.
-+                               */
-+                              find_max_pfn();
-+                              saved_max_pfn = max_pfn;
-+#endif
-+                              from += 8+7;
-+                              e820.nr_map = 0;
-+                              userdef = 1;
-+                      } else {
-+                              /* If the user specifies memory size, we
-+                               * limit the BIOS-provided memory map to
-+                               * that size. exactmap can be used to specify
-+                               * the exact map. mem=number can be used to
-+                               * trim the existing memory map.
-+                               */
-+                              unsigned long long start_at, mem_size;
-+ 
-+                              mem_size = memparse(from+7, &from);
-+                              if (*from == '@') {
-+                                      start_at = memparse(from+1, &from);
-+                                      add_memory_region(start_at, mem_size, E820_RAM);
-+                              } else if (*from == '#') {
-+                                      start_at = memparse(from+1, &from);
-+                                      add_memory_region(start_at, mem_size, E820_ACPI);
-+                              } else if (*from == '$') {
-+                                      start_at = memparse(from+1, &from);
-+                                      add_memory_region(start_at, mem_size, E820_RESERVED);
-+                              } else {
-+                                      limit_regions(mem_size);
-+                                      userdef=1;
-+                              }
-+                      }
-+              }
-+
-+              else if (!memcmp(from, "noexec=", 7))
-+                      noexec_setup(from + 7);
-+
-+
-+#ifdef  CONFIG_X86_MPPARSE
-+              /*
-+               * If the BIOS enumerates physical processors before logical,
-+               * maxcpus=N at enumeration-time can be used to disable HT.
-+               */
-+              else if (!memcmp(from, "maxcpus=", 8)) {
-+                      extern unsigned int maxcpus;
-+
-+                      maxcpus = simple_strtoul(from + 8, NULL, 0);
-+              }
-+#endif
-+
-+#ifdef CONFIG_ACPI
-+              /* "acpi=off" disables both ACPI table parsing and interpreter */
-+              else if (!memcmp(from, "acpi=off", 8)) {
-+                      disable_acpi();
-+              }
-+
-+              /* acpi=force to over-ride black-list */
-+              else if (!memcmp(from, "acpi=force", 10)) {
-+                      acpi_force = 1;
-+                      acpi_ht = 1;
-+                      acpi_disabled = 0;
-+              }
-+
-+              /* acpi=strict disables out-of-spec workarounds */
-+              else if (!memcmp(from, "acpi=strict", 11)) {
-+                      acpi_strict = 1;
-+              }
-+
-+              /* Limit ACPI just to boot-time to enable HT */
-+              else if (!memcmp(from, "acpi=ht", 7)) {
-+                      if (!acpi_force)
-+                              disable_acpi();
-+                      acpi_ht = 1;
-+              }
-+              
-+              /* "pci=noacpi" disable ACPI IRQ routing and PCI scan */
-+              else if (!memcmp(from, "pci=noacpi", 10)) {
-+                      acpi_disable_pci();
-+              }
-+              /* "acpi=noirq" disables ACPI interrupt routing */
-+              else if (!memcmp(from, "acpi=noirq", 10)) {
-+                      acpi_noirq_set();
-+              }
-+
-+              else if (!memcmp(from, "acpi_sci=edge", 13))
-+                      acpi_sci_flags.trigger =  1;
-+
-+              else if (!memcmp(from, "acpi_sci=level", 14))
-+                      acpi_sci_flags.trigger = 3;
-+
-+              else if (!memcmp(from, "acpi_sci=high", 13))
-+                      acpi_sci_flags.polarity = 1;
-+
-+              else if (!memcmp(from, "acpi_sci=low", 12))
-+                      acpi_sci_flags.polarity = 3;
-+
-+#ifdef CONFIG_X86_IO_APIC
-+              else if (!memcmp(from, "acpi_skip_timer_override", 24))
-+                      acpi_skip_timer_override = 1;
-+
-+              if (!memcmp(from, "disable_timer_pin_1", 19))
-+                      disable_timer_pin_1 = 1;
-+              if (!memcmp(from, "enable_timer_pin_1", 18))
-+                      disable_timer_pin_1 = -1;
-+
-+              /* disable IO-APIC */
-+              else if (!memcmp(from, "noapic", 6))
-+                      disable_ioapic_setup();
-+#endif /* CONFIG_X86_IO_APIC */
-+#endif /* CONFIG_ACPI */
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+              /* enable local APIC */
-+              else if (!memcmp(from, "lapic", 5))
-+                      lapic_enable();
-+
-+              /* disable local APIC */
-+              else if (!memcmp(from, "nolapic", 6))
-+                      lapic_disable();
-+#endif /* CONFIG_X86_LOCAL_APIC */
-+
-+#ifdef CONFIG_KEXEC
-+              /* crashkernel=size@addr specifies the location to reserve for
-+               * a crash kernel.  By reserving this memory we guarantee
-+               * that linux never set's it up as a DMA target.
-+               * Useful for holding code to do something appropriate
-+               * after a kernel panic.
-+               */
-+              else if (!memcmp(from, "crashkernel=", 12)) {
-+#ifndef CONFIG_XEN
-+                      unsigned long size, base;
-+                      size = memparse(from+12, &from);
-+                      if (*from == '@') {
-+                              base = memparse(from+1, &from);
-+                              /* FIXME: Do I want a sanity check
-+                               * to validate the memory range?
-+                               */
-+                              crashk_res.start = base;
-+                              crashk_res.end   = base + size - 1;
-+                      }
-+#else
-+                      printk("Ignoring crashkernel command line, "
-+                             "parameter will be supplied by xen\n");
-+#endif
-+              }
-+#endif
-+#ifdef CONFIG_PROC_VMCORE
-+              /* elfcorehdr= specifies the location of elf core header
-+               * stored by the crashed kernel.
-+               */
-+              else if (!memcmp(from, "elfcorehdr=", 11))
-+                      elfcorehdr_addr = memparse(from+11, &from);
-+#endif
-+
-+              /*
-+               * highmem=size forces highmem to be exactly 'size' bytes.
-+               * This works even on boxes that have no highmem otherwise.
-+               * This also works to reduce highmem size on bigger boxes.
-+               */
-+              else if (!memcmp(from, "highmem=", 8))
-+                      highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
-+      
-+              /*
-+               * vmalloc=size forces the vmalloc area to be exactly 'size'
-+               * bytes. This can be used to increase (or decrease) the
-+               * vmalloc area - the default is 128m.
-+               */
-+              else if (!memcmp(from, "vmalloc=", 8))
-+                      __VMALLOC_RESERVE = memparse(from+8, &from);
-+
-+      next_char:
-+              c = *(from++);
-+              if (!c)
-+                      break;
-+              if (COMMAND_LINE_SIZE <= ++len)
-+                      break;
-+              *(to++) = c;
-+      }
-+      *to = '\0';
-+      *cmdline_p = command_line;
-+      if (userdef) {
-+              printk(KERN_INFO "user-defined physical RAM map:\n");
-+              print_memory_map("user");
-+      }
-+}
-+
-+/*
-+ * Callback for efi_memory_walk.
-+ */
-+static int __init
-+efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
-+{
-+      unsigned long *max_pfn = arg, pfn;
-+
-+      if (start < end) {
-+              pfn = PFN_UP(end -1);
-+              if (pfn > *max_pfn)
-+                      *max_pfn = pfn;
-+      }
-+      return 0;
-+}
-+
-+static int __init
-+efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
-+{
-+      memory_present(0, start, end);
-+      return 0;
-+}
-+
-+/*
-+ * Find the highest page frame number we have available
-+ */
-+void __init find_max_pfn(void)
-+{
-+      int i;
-+
-+      max_pfn = 0;
-+      if (efi_enabled) {
-+              efi_memmap_walk(efi_find_max_pfn, &max_pfn);
-+              efi_memmap_walk(efi_memory_present_wrapper, NULL);
-+              return;
-+      }
-+
-+      for (i = 0; i < e820.nr_map; i++) {
-+              unsigned long start, end;
-+              /* RAM? */
-+              if (e820.map[i].type != E820_RAM)
-+                      continue;
-+              start = PFN_UP(e820.map[i].addr);
-+              end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
-+              if (start >= end)
-+                      continue;
-+              if (end > max_pfn)
-+                      max_pfn = end;
-+              memory_present(0, start, end);
-+      }
-+}
-+
-+/*
-+ * Determine low and high memory ranges:
-+ */
-+unsigned long __init find_max_low_pfn(void)
-+{
-+      unsigned long max_low_pfn;
-+
-+      max_low_pfn = max_pfn;
-+      if (max_low_pfn > MAXMEM_PFN) {
-+              if (highmem_pages == -1)
-+                      highmem_pages = max_pfn - MAXMEM_PFN;
-+              if (highmem_pages + MAXMEM_PFN < max_pfn)
-+                      max_pfn = MAXMEM_PFN + highmem_pages;
-+              if (highmem_pages + MAXMEM_PFN > max_pfn) {
-+                      printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages));
-+                      highmem_pages = 0;
-+              }
-+              max_low_pfn = MAXMEM_PFN;
-+#ifndef CONFIG_HIGHMEM
-+              /* Maximum memory usable is what is directly addressable */
-+              printk(KERN_WARNING "Warning only %ldMB will be used.\n",
-+                                      MAXMEM>>20);
-+              if (max_pfn > MAX_NONPAE_PFN)
-+                      printk(KERN_WARNING "Use a PAE enabled kernel.\n");
-+              else
-+                      printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
-+              max_pfn = MAXMEM_PFN;
-+#else /* !CONFIG_HIGHMEM */
-+#ifndef CONFIG_X86_PAE
-+              if (max_pfn > MAX_NONPAE_PFN) {
-+                      max_pfn = MAX_NONPAE_PFN;
-+                      printk(KERN_WARNING "Warning only 4GB will be used.\n");
-+                      printk(KERN_WARNING "Use a PAE enabled kernel.\n");
-+              }
-+#endif /* !CONFIG_X86_PAE */
-+#endif /* !CONFIG_HIGHMEM */
-+      } else {
-+              if (highmem_pages == -1)
-+                      highmem_pages = 0;
-+#ifdef CONFIG_HIGHMEM
-+              if (highmem_pages >= max_pfn) {
-+                      printk(KERN_ERR "highmem size specified (%uMB) is bigger than pages available (%luMB)!.\n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
-+                      highmem_pages = 0;
-+              }
-+              if (highmem_pages) {
-+                      if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
-+                              printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages));
-+                              highmem_pages = 0;
-+                      }
-+                      max_low_pfn -= highmem_pages;
-+              }
-+#else
-+              if (highmem_pages)
-+                      printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
-+#endif
-+      }
-+      return max_low_pfn;
-+}
-+
-+/*
-+ * Free all available memory for boot time allocation.  Used
-+ * as a callback function by efi_memory_walk()
-+ */
-+
-+static int __init
-+free_available_memory(unsigned long start, unsigned long end, void *arg)
-+{
-+      /* check max_low_pfn */
-+      if (start >= ((max_low_pfn + 1) << PAGE_SHIFT))
-+              return 0;
-+      if (end >= ((max_low_pfn + 1) << PAGE_SHIFT))
-+              end = (max_low_pfn + 1) << PAGE_SHIFT;
-+      if (start < end)
-+              free_bootmem(start, end - start);
-+
-+      return 0;
-+}
-+/*
-+ * Register fully available low RAM pages with the bootmem allocator.
-+ */
-+static void __init register_bootmem_low_pages(unsigned long max_low_pfn)
-+{
-+      int i;
-+
-+      if (efi_enabled) {
-+              efi_memmap_walk(free_available_memory, NULL);
-+              return;
-+      }
-+      for (i = 0; i < e820.nr_map; i++) {
-+              unsigned long curr_pfn, last_pfn, size;
-+              /*
-+               * Reserve usable low memory
-+               */
-+              if (e820.map[i].type != E820_RAM)
-+                      continue;
-+              /*
-+               * We are rounding up the start address of usable memory:
-+               */
-+              curr_pfn = PFN_UP(e820.map[i].addr);
-+              if (curr_pfn >= max_low_pfn)
-+                      continue;
-+              /*
-+               * ... and at the end of the usable range downwards:
-+               */
-+              last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
-+
-+#ifdef CONFIG_XEN
-+              /*
-+                 * Truncate to the number of actual pages currently
-+                 * present.
-+                 */
-+              if (last_pfn > xen_start_info->nr_pages)
-+                      last_pfn = xen_start_info->nr_pages;
-+#endif
-+
-+              if (last_pfn > max_low_pfn)
-+                      last_pfn = max_low_pfn;
-+
-+              /*
-+               * .. finally, did all the rounding and playing
-+               * around just make the area go away?
-+               */
-+              if (last_pfn <= curr_pfn)
-+                      continue;
-+
-+              size = last_pfn - curr_pfn;
-+              free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
-+      }
-+}
-+
-+#ifndef CONFIG_XEN
-+/*
-+ * workaround for Dell systems that neglect to reserve EBDA
-+ */
-+static void __init reserve_ebda_region(void)
-+{
-+      unsigned int addr;
-+      addr = get_bios_ebda();
-+      if (addr)
-+              reserve_bootmem(addr, PAGE_SIZE);       
-+}
-+#endif
-+
-+#ifndef CONFIG_NEED_MULTIPLE_NODES
-+void __init setup_bootmem_allocator(void);
-+static unsigned long __init setup_memory(void)
-+{
-+      /*
-+       * partially used pages are not usable - thus
-+       * we are rounding upwards:
-+       */
-+      min_low_pfn = PFN_UP(__pa(xen_start_info->pt_base)) +
-+              xen_start_info->nr_pt_frames;
-+
-+      find_max_pfn();
-+
-+      max_low_pfn = find_max_low_pfn();
-+
-+#ifdef CONFIG_HIGHMEM
-+      highstart_pfn = highend_pfn = max_pfn;
-+      if (max_pfn > max_low_pfn) {
-+              highstart_pfn = max_low_pfn;
-+      }
-+      printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
-+              pages_to_mb(highend_pfn - highstart_pfn));
-+#endif
-+      printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
-+                      pages_to_mb(max_low_pfn));
-+
-+      setup_bootmem_allocator();
-+
-+      return max_low_pfn;
-+}
-+
-+void __init zone_sizes_init(void)
-+{
-+      unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-+      unsigned int max_dma, low;
-+
-+      /*
-+       * XEN: Our notion of "DMA memory" is fake when running over Xen.
-+       * We simply put all RAM in the DMA zone so that those drivers which
-+       * needlessly specify GFP_DMA do not get starved of RAM unnecessarily.
-+       * Those drivers that *do* require lowmem are screwed anyway when
-+       * running over Xen!
-+       */
-+      max_dma = max_low_pfn;
-+      low = max_low_pfn;
-+
-+      if (low < max_dma)
-+              zones_size[ZONE_DMA] = low;
-+      else {
-+              zones_size[ZONE_DMA] = max_dma;
-+              zones_size[ZONE_NORMAL] = low - max_dma;
-+#ifdef CONFIG_HIGHMEM
-+              zones_size[ZONE_HIGHMEM] = highend_pfn - low;
-+#endif
-+      }
-+      free_area_init(zones_size);
-+}
-+#else
-+extern unsigned long __init setup_memory(void);
-+extern void zone_sizes_init(void);
-+#endif /* !CONFIG_NEED_MULTIPLE_NODES */
-+
-+void __init setup_bootmem_allocator(void)
-+{
-+      unsigned long bootmap_size;
-+      /*
-+       * Initialize the boot-time allocator (with low memory only):
-+       */
-+      bootmap_size = init_bootmem(min_low_pfn, max_low_pfn);
-+
-+      register_bootmem_low_pages(max_low_pfn);
-+
-+      /*
-+       * Reserve the bootmem bitmap itself as well. We do this in two
-+       * steps (first step was init_bootmem()) because this catches
-+       * the (very unlikely) case of us accidentally initializing the
-+       * bootmem allocator with an invalid RAM area.
-+       */
-+      reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) +
-+                       bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START));
-+
-+#ifndef CONFIG_XEN
-+      /*
-+       * reserve physical page 0 - it's a special BIOS page on many boxes,
-+       * enabling clean reboots, SMP operation, laptop functions.
-+       */
-+      reserve_bootmem(0, PAGE_SIZE);
-+
-+      /* reserve EBDA region, it's a 4K region */
-+      reserve_ebda_region();
-+
-+    /* could be an AMD 768MPX chipset. Reserve a page  before VGA to prevent
-+       PCI prefetch into it (errata #56). Usually the page is reserved anyways,
-+       unless you have no PS/2 mouse plugged in. */
-+      if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-+          boot_cpu_data.x86 == 6)
-+           reserve_bootmem(0xa0000 - 4096, 4096);
-+
-+#ifdef CONFIG_SMP
-+      /*
-+       * But first pinch a few for the stack/trampoline stuff
-+       * FIXME: Don't need the extra page at 4K, but need to fix
-+       * trampoline before removing it. (see the GDT stuff)
-+       */
-+      reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
-+#endif
-+#ifdef CONFIG_ACPI_SLEEP
-+      /*
-+       * Reserve low memory region for sleep support.
-+       */
-+      acpi_reserve_bootmem();
-+#endif
-+#endif /* !CONFIG_XEN */
-+
-+#ifdef CONFIG_BLK_DEV_INITRD
-+      if (xen_start_info->mod_start) {
-+              if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
-+                      /*reserve_bootmem(INITRD_START, INITRD_SIZE);*/
-+                      initrd_start = INITRD_START + PAGE_OFFSET;
-+                      initrd_end = initrd_start+INITRD_SIZE;
-+                      initrd_below_start_ok = 1;
-+              }
-+              else {
-+                      printk(KERN_ERR "initrd extends beyond end of memory "
-+                          "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-+                          INITRD_START + INITRD_SIZE,
-+                          max_low_pfn << PAGE_SHIFT);
-+                      initrd_start = 0;
-+              }
-+      }
-+#endif
-+#ifdef CONFIG_KEXEC
-+#ifdef CONFIG_XEN
-+      xen_machine_kexec_setup_resources();
-+#else
-+      if (crashk_res.start != crashk_res.end)
-+              reserve_bootmem(crashk_res.start,
-+                      crashk_res.end - crashk_res.start + 1);
-+#endif
-+#endif
-+
-+      if (!xen_feature(XENFEAT_auto_translated_physmap))
-+              phys_to_machine_mapping =
-+                      (unsigned long *)xen_start_info->mfn_list;
-+}
-+
-+/*
-+ * The node 0 pgdat is initialized before all of these because
-+ * it's needed for bootmem.  node>0 pgdats have their virtual
-+ * space allocated before the pagetables are in place to access
-+ * them, so they can't be cleared then.
-+ *
-+ * This should all compile down to nothing when NUMA is off.
-+ */
-+void __init remapped_pgdat_init(void)
-+{
-+      int nid;
-+
-+      for_each_online_node(nid) {
-+              if (nid != 0)
-+                      memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
-+      }
-+}
-+
-+/*
-+ * Request address space for all standard RAM and ROM resources
-+ * and also for regions reported as reserved by the e820.
-+ */
-+static void __init
-+legacy_init_iomem_resources(struct e820entry *e820, int nr_map,
-+                          struct resource *code_resource,
-+                          struct resource *data_resource)
-+{
-+      int i;
-+
-+      probe_roms();
-+
-+      for (i = 0; i < nr_map; i++) {
-+              struct resource *res;
-+              if (e820[i].addr + e820[i].size > 0x100000000ULL)
-+                      continue;
-+              res = alloc_bootmem_low(sizeof(struct resource));
-+              switch (e820[i].type) {
-+              case E820_RAM:  res->name = "System RAM"; break;
-+              case E820_ACPI: res->name = "ACPI Tables"; break;
-+              case E820_NVS:  res->name = "ACPI Non-volatile Storage"; break;
-+              default:        res->name = "reserved";
-+              }
-+              res->start = e820[i].addr;
-+              res->end = res->start + e820[i].size - 1;
-+              res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+              request_resource(&iomem_resource, res);
-+              if (e820[i].type == E820_RAM) {
-+                      /*
-+                       *  We don't know which RAM region contains kernel data,
-+                       *  so we try it repeatedly and let the resource manager
-+                       *  test it.
-+                       */
-+#ifndef CONFIG_XEN
-+                      request_resource(res, code_resource);
-+                      request_resource(res, data_resource);
-+#endif
-+#ifdef CONFIG_KEXEC
-+                      if (crashk_res.start != crashk_res.end)
-+                           request_resource(res, &crashk_res);
-+#ifdef CONFIG_XEN
-+                      xen_machine_kexec_register_resources(res);
-+#endif
-+#endif
-+              }
-+      }
-+}
-+
-+/*
-+ * Locate a unused range of the physical address space below 4G which
-+ * can be used for PCI mappings.
-+ */
-+static void __init
-+e820_setup_gap(struct e820entry *e820, int nr_map)
-+{
-+      unsigned long gapstart, gapsize, round;
-+      unsigned long long last;
-+      int i;
-+
-+      /*
-+       * Search for the bigest gap in the low 32 bits of the e820
-+       * memory space.
-+       */
-+      last = 0x100000000ull;
-+      gapstart = 0x10000000;
-+      gapsize = 0x400000;
-+      i = nr_map;
-+      while (--i >= 0) {
-+              unsigned long long start = e820[i].addr;
-+              unsigned long long end = start + e820[i].size;
-+
-+              /*
-+               * Since "last" is at most 4GB, we know we'll
-+               * fit in 32 bits if this condition is true
-+               */
-+              if (last > end) {
-+                      unsigned long gap = last - end;
-+
-+                      if (gap > gapsize) {
-+                              gapsize = gap;
-+                              gapstart = end;
-+                      }
-+              }
-+              if (start < last)
-+                      last = start;
-+      }
-+
-+      /*
-+       * See how much we want to round up: start off with
-+       * rounding to the next 1MB area.
-+       */
-+      round = 0x100000;
-+      while ((gapsize >> 4) > round)
-+              round += round;
-+      /* Fun with two's complement */
-+      pci_mem_start = (gapstart + round) & -round;
-+
-+      printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
-+              pci_mem_start, gapstart, gapsize);
-+}
-+
-+/*
-+ * Request address space for all standard resources
-+ */
-+static void __init register_memory(void)
-+{
-+#ifdef CONFIG_XEN
-+      struct xen_memory_map memmap;
-+#endif
-+      int           i;
-+
-+      /* Nothing to do if not running in dom0. */
-+      if (!is_initial_xendomain())
-+              return;
-+
-+#ifdef CONFIG_XEN
-+      memmap.nr_entries = E820MAX;
-+      set_xen_guest_handle(memmap.buffer, machine_e820.map);
-+
-+      if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
-+              BUG();
-+      machine_e820.nr_map = memmap.nr_entries;
-+
-+      legacy_init_iomem_resources(machine_e820.map, machine_e820.nr_map,
-+                                  &code_resource, &data_resource);
-+#else
-+      if (efi_enabled)
-+              efi_initialize_iomem_resources(&code_resource, &data_resource);
-+      else
-+              legacy_init_iomem_resources(e820.map, e820.nr_map,
-+                                          &code_resource, &data_resource);
-+#endif
-+
-+      /* EFI systems may still have VGA */
-+      request_resource(&iomem_resource, &video_ram_resource);
-+
-+      /* request I/O space for devices used on all i[345]86 PCs */
-+      for (i = 0; i < STANDARD_IO_RESOURCES; i++)
-+              request_resource(&ioport_resource, &standard_io_resources[i]);
-+
-+#ifdef CONFIG_XEN
-+      e820_setup_gap(machine_e820.map, machine_e820.nr_map);
-+#else
-+      e820_setup_gap(e820.map, e820.nr_map);
-+#endif
-+}
-+
-+/* Use inline assembly to define this because the nops are defined 
-+   as inline assembly strings in the include files and we cannot 
-+   get them easily into strings. */
-+asm("\t.data\nintelnops: " 
-+    GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
-+    GENERIC_NOP7 GENERIC_NOP8); 
-+asm("\t.data\nk8nops: " 
-+    K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
-+    K8_NOP7 K8_NOP8); 
-+asm("\t.data\nk7nops: " 
-+    K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
-+    K7_NOP7 K7_NOP8); 
-+    
-+extern unsigned char intelnops[], k8nops[], k7nops[];
-+static unsigned char *intel_nops[ASM_NOP_MAX+1] = { 
-+     NULL,
-+     intelnops,
-+     intelnops + 1,
-+     intelnops + 1 + 2,
-+     intelnops + 1 + 2 + 3,
-+     intelnops + 1 + 2 + 3 + 4,
-+     intelnops + 1 + 2 + 3 + 4 + 5,
-+     intelnops + 1 + 2 + 3 + 4 + 5 + 6,
-+     intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
-+}; 
-+static unsigned char *k8_nops[ASM_NOP_MAX+1] = { 
-+     NULL,
-+     k8nops,
-+     k8nops + 1,
-+     k8nops + 1 + 2,
-+     k8nops + 1 + 2 + 3,
-+     k8nops + 1 + 2 + 3 + 4,
-+     k8nops + 1 + 2 + 3 + 4 + 5,
-+     k8nops + 1 + 2 + 3 + 4 + 5 + 6,
-+     k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
-+}; 
-+static unsigned char *k7_nops[ASM_NOP_MAX+1] = { 
-+     NULL,
-+     k7nops,
-+     k7nops + 1,
-+     k7nops + 1 + 2,
-+     k7nops + 1 + 2 + 3,
-+     k7nops + 1 + 2 + 3 + 4,
-+     k7nops + 1 + 2 + 3 + 4 + 5,
-+     k7nops + 1 + 2 + 3 + 4 + 5 + 6,
-+     k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
-+}; 
-+static struct nop { 
-+     int cpuid; 
-+     unsigned char **noptable; 
-+} noptypes[] = { 
-+     { X86_FEATURE_K8, k8_nops }, 
-+     { X86_FEATURE_K7, k7_nops }, 
-+     { -1, NULL }
-+}; 
-+
-+/* Replace instructions with better alternatives for this CPU type.
-+
-+   This runs before SMP is initialized to avoid SMP problems with
-+   self modifying code. This implies that assymetric systems where
-+   APs have less capabilities than the boot processor are not handled. 
-+   Tough. Make sure you disable such features by hand. */ 
-+void apply_alternatives(void *start, void *end) 
-+{ 
-+      struct alt_instr *a; 
-+      int diff, i, k;
-+        unsigned char **noptable = intel_nops; 
-+      for (i = 0; noptypes[i].cpuid >= 0; i++) { 
-+              if (boot_cpu_has(noptypes[i].cpuid)) { 
-+                      noptable = noptypes[i].noptable;
-+                      break;
-+              }
-+      } 
-+      for (a = start; (void *)a < end; a++) { 
-+              if (!boot_cpu_has(a->cpuid))
-+                      continue;
-+              BUG_ON(a->replacementlen > a->instrlen); 
-+              memcpy(a->instr, a->replacement, a->replacementlen); 
-+              diff = a->instrlen - a->replacementlen; 
-+              /* Pad the rest with nops */
-+              for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
-+                      k = diff;
-+                      if (k > ASM_NOP_MAX)
-+                              k = ASM_NOP_MAX;
-+                      memcpy(a->instr + i, noptable[k], k); 
-+              } 
-+      }
-+} 
-+
-+void __init alternative_instructions(void)
-+{
-+      extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
-+      apply_alternatives(__alt_instructions, __alt_instructions_end);
-+}
-+
-+static char * __init machine_specific_memory_setup(void);
-+
-+#ifdef CONFIG_MCA
-+static void set_mca_bus(int x)
-+{
-+      MCA_bus = x;
-+}
-+#else
-+static void set_mca_bus(int x) { }
-+#endif
-+
-+/*
-+ * Determine if we were loaded by an EFI loader.  If so, then we have also been
-+ * passed the efi memmap, systab, etc., so we should use these data structures
-+ * for initialization.  Note, the efi init code path is determined by the
-+ * global efi_enabled. This allows the same kernel image to be used on existing
-+ * systems (with a traditional BIOS) as well as on EFI systems.
-+ */
-+void __init setup_arch(char **cmdline_p)
-+{
-+      int i, j, k, fpp;
-+      struct physdev_set_iopl set_iopl;
-+      unsigned long max_low_pfn;
-+
-+      /* Force a quick death if the kernel panics (not domain 0). */
-+      extern int panic_timeout;
-+      if (!panic_timeout && !is_initial_xendomain())
-+              panic_timeout = 1;
-+
-+      /* Register a call for panic conditions. */
-+      notifier_chain_register(&panic_notifier_list, &xen_panic_block);
-+
-+      HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
-+      HYPERVISOR_vm_assist(VMASST_CMD_enable,
-+                           VMASST_TYPE_writable_pagetables);
-+
-+      memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
-+      early_cpu_init();
-+
-+      /*
-+       * FIXME: This isn't an official loader_type right
-+       * now but does currently work with elilo.
-+       * If we were configured as an EFI kernel, check to make
-+       * sure that we were loaded correctly from elilo and that
-+       * the system table is valid.  If not, then initialize normally.
-+       */
-+#ifdef CONFIG_EFI
-+      if ((LOADER_TYPE == 0x50) && EFI_SYSTAB)
-+              efi_enabled = 1;
-+#endif
-+
-+      /* This must be initialized to UNNAMED_MAJOR for ipconfig to work
-+         properly.  Setting ROOT_DEV to default to /dev/ram0 breaks initrd.
-+      */
-+      ROOT_DEV = MKDEV(UNNAMED_MAJOR,0);
-+      drive_info = DRIVE_INFO;
-+      screen_info = SCREEN_INFO;
-+      edid_info = EDID_INFO;
-+      apm_info.bios = APM_BIOS_INFO;
-+      ist_info = IST_INFO;
-+      saved_videomode = VIDEO_MODE;
-+      if( SYS_DESC_TABLE.length != 0 ) {
-+              set_mca_bus(SYS_DESC_TABLE.table[3] & 0x2);
-+              machine_id = SYS_DESC_TABLE.table[0];
-+              machine_submodel_id = SYS_DESC_TABLE.table[1];
-+              BIOS_revision = SYS_DESC_TABLE.table[2];
-+      }
-+      bootloader_type = LOADER_TYPE;
-+
-+      if (is_initial_xendomain()) {
-+              /* This is drawn from a dump from vgacon:startup in
-+               * standard Linux. */
-+              screen_info.orig_video_mode = 3; 
-+              screen_info.orig_video_isVGA = 1;
-+              screen_info.orig_video_lines = 25;
-+              screen_info.orig_video_cols = 80;
-+              screen_info.orig_video_ega_bx = 3;
-+              screen_info.orig_video_points = 16;
-+              screen_info.orig_y = screen_info.orig_video_lines - 1;
-+              if (xen_start_info->console.dom0.info_size >=
-+                  sizeof(struct dom0_vga_console_info)) {
-+                      const struct dom0_vga_console_info *info =
-+                              (struct dom0_vga_console_info *)(
-+                                      (char *)xen_start_info +
-+                                      xen_start_info->console.dom0.info_off);
-+                      dom0_init_screen_info(info);
-+              }
-+              xen_start_info->console.domU.mfn = 0;
-+              xen_start_info->console.domU.evtchn = 0;
-+      } else
-+              screen_info.orig_video_isVGA = 0;
-+
-+#ifdef CONFIG_BLK_DEV_RAM
-+      rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-+      rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
-+      rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-+#endif
-+
-+      setup_xen_features();
-+
-+      ARCH_SETUP
-+      if (efi_enabled)
-+              efi_init();
-+      else {
-+              printk(KERN_INFO "BIOS-provided physical RAM map:\n");
-+              print_memory_map(machine_specific_memory_setup());
-+      }
-+
-+      copy_edd();
-+
-+      if (!MOUNT_ROOT_RDONLY)
-+              root_mountflags &= ~MS_RDONLY;
-+      init_mm.start_code = (unsigned long) _text;
-+      init_mm.end_code = (unsigned long) _etext;
-+      init_mm.end_data = (unsigned long) _edata;
-+      init_mm.brk = (PFN_UP(__pa(xen_start_info->pt_base)) +
-+                     xen_start_info->nr_pt_frames) << PAGE_SHIFT;
-+
-+      code_resource.start = virt_to_phys(_text);
-+      code_resource.end = virt_to_phys(_etext)-1;
-+      data_resource.start = virt_to_phys(_etext);
-+      data_resource.end = virt_to_phys(_edata)-1;
-+
-+      parse_cmdline_early(cmdline_p);
-+
-+      max_low_pfn = setup_memory();
-+
-+      /*
-+       * NOTE: before this point _nobody_ is allowed to allocate
-+       * any memory using the bootmem allocator.  Although the
-+       * alloctor is now initialised only the first 8Mb of the kernel
-+       * virtual address space has been mapped.  All allocations before
-+       * paging_init() has completed must use the alloc_bootmem_low_pages()
-+       * variant (which allocates DMA'able memory) and care must be taken
-+       * not to exceed the 8Mb limit.
-+       */
-+
-+#ifdef CONFIG_SMP
-+      smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
-+#endif
-+      paging_init();
-+      remapped_pgdat_init();
-+      sparse_init();
-+      zone_sizes_init();
-+
-+#ifdef CONFIG_X86_FIND_SMP_CONFIG
-+      /*
-+       * Find and reserve possible boot-time SMP configuration:
-+       */
-+      find_smp_config();
-+#endif
-+
-+      /* Make sure we have a correctly sized P->M table. */
-+      if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+              phys_to_machine_mapping = alloc_bootmem_low_pages(
-+                   max_pfn * sizeof(unsigned long));
-+              memset(phys_to_machine_mapping, ~0,
-+                     max_pfn * sizeof(unsigned long));
-+              memcpy(phys_to_machine_mapping,
-+                     (unsigned long *)xen_start_info->mfn_list,
-+                     xen_start_info->nr_pages * sizeof(unsigned long));
-+              free_bootmem(
-+                   __pa(xen_start_info->mfn_list),
-+                   PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
-+                                   sizeof(unsigned long))));
-+
-+              /*
-+               * Initialise the list of the frames that specify the list of
-+               * frames that make up the p2m table. Used by save/restore
-+               */
-+              pfn_to_mfn_frame_list_list = alloc_bootmem_low_pages(PAGE_SIZE);
-+              HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
-+                   virt_to_mfn(pfn_to_mfn_frame_list_list);
-+
-+              fpp = PAGE_SIZE/sizeof(unsigned long);
-+              for (i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++) {
-+                      if ((j % fpp) == 0) {
-+                              k++;
-+                              BUG_ON(k>=16);
-+                              pfn_to_mfn_frame_list[k] =
-+                                      alloc_bootmem_low_pages(PAGE_SIZE);
-+                              pfn_to_mfn_frame_list_list[k] =
-+                                      virt_to_mfn(pfn_to_mfn_frame_list[k]);
-+                              j=0;
-+                      }
-+                      pfn_to_mfn_frame_list[k][j] =
-+                              virt_to_mfn(&phys_to_machine_mapping[i]);
-+              }
-+              HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-+      }
-+
-+      /*
-+       * NOTE: at this point the bootmem allocator is fully available.
-+       */
-+
-+#ifdef CONFIG_EARLY_PRINTK
-+      {
-+              char *s = strstr(*cmdline_p, "earlyprintk=");
-+              if (s) {
-+                      extern void setup_early_printk(char *);
-+
-+                      setup_early_printk(strchr(s, '=') + 1);
-+                      printk("early console enabled\n");
-+              }
-+      }
-+#endif
-+
-+      if (is_initial_xendomain())
-+              dmi_scan_machine();
-+
-+#ifdef CONFIG_X86_GENERICARCH
-+      generic_apic_probe(*cmdline_p);
-+#endif        
-+      if (efi_enabled)
-+              efi_map_memmap();
-+
-+      set_iopl.iopl = 1;
-+      HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
-+
-+#ifdef CONFIG_X86_IO_APIC
-+      check_acpi_pci();       /* Checks more than just ACPI actually */
-+#endif
-+
-+#ifdef CONFIG_ACPI
-+      if (!is_initial_xendomain()) {
-+              printk(KERN_INFO "ACPI in unprivileged domain disabled\n");
-+              acpi_disabled = 1;
-+              acpi_ht = 0;
-+      }
-+
-+      /*
-+       * Parse the ACPI tables for possible boot-time SMP configuration.
-+       */
-+      acpi_boot_table_init();
-+      acpi_boot_init();
-+
-+#if defined(CONFIG_SMP) && defined(CONFIG_X86_PC)
-+      if (def_to_bigsmp)
-+              printk(KERN_WARNING "More than 8 CPUs detected and "
-+                      "CONFIG_X86_PC cannot handle it.\nUse "
-+                      "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n");
-+#endif
-+#endif
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      if (smp_found_config)
-+              get_smp_config();
-+#endif
-+
-+      register_memory();
-+
-+      if (is_initial_xendomain()) {
-+#ifdef CONFIG_VT
-+#if defined(CONFIG_VGA_CONSOLE)
-+              if (!efi_enabled ||
-+                  (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
-+                      conswitchp = &vga_con;
-+#elif defined(CONFIG_DUMMY_CONSOLE)
-+              conswitchp = &dummy_con;
-+#endif
-+#endif
-+      } else {
-+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
-+              conswitchp = &dummy_con;
-+#endif
-+      }
-+      xencons_early_setup();
-+}
-+
-+static int
-+xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
-+{
-+      HYPERVISOR_shutdown(SHUTDOWN_crash);
-+      /* we're never actually going to get here... */
-+      return NOTIFY_DONE;
-+}
-+
-+#include "setup_arch_post.h"
-+/*
-+ * Local Variables:
-+ * mode:c
-+ * c-file-style:"k&r"
-+ * c-basic-offset:8
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/smp-xen.c linux-2.6.16.33/arch/i386/kernel/smp-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/smp-xen.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/smp-xen.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,618 @@
-+/*
-+ *    Intel SMP support routines.
-+ *
-+ *    (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
-+ *    (c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com>
-+ *
-+ *    This code is released under the GNU General Public License version 2 or
-+ *    later.
-+ */
-+
-+#include <linux/init.h>
-+
-+#include <linux/mm.h>
-+#include <linux/delay.h>
-+#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/cache.h>
-+#include <linux/interrupt.h>
-+#include <linux/cpu.h>
-+#include <linux/module.h>
-+
-+#include <asm/mtrr.h>
-+#include <asm/tlbflush.h>
-+#if 0
-+#include <mach_apic.h>
-+#endif
-+#include <xen/evtchn.h>
-+
-+/*
-+ *    Some notes on x86 processor bugs affecting SMP operation:
-+ *
-+ *    Pentium, Pentium Pro, II, III (and all CPUs) have bugs.
-+ *    The Linux implications for SMP are handled as follows:
-+ *
-+ *    Pentium III / [Xeon]
-+ *            None of the E1AP-E3AP errata are visible to the user.
-+ *
-+ *    E1AP.   see PII A1AP
-+ *    E2AP.   see PII A2AP
-+ *    E3AP.   see PII A3AP
-+ *
-+ *    Pentium II / [Xeon]
-+ *            None of the A1AP-A3AP errata are visible to the user.
-+ *
-+ *    A1AP.   see PPro 1AP
-+ *    A2AP.   see PPro 2AP
-+ *    A3AP.   see PPro 7AP
-+ *
-+ *    Pentium Pro
-+ *            None of 1AP-9AP errata are visible to the normal user,
-+ *    except occasional delivery of 'spurious interrupt' as trap #15.
-+ *    This is very rare and a non-problem.
-+ *
-+ *    1AP.    Linux maps APIC as non-cacheable
-+ *    2AP.    worked around in hardware
-+ *    3AP.    fixed in C0 and above steppings microcode update.
-+ *            Linux does not use excessive STARTUP_IPIs.
-+ *    4AP.    worked around in hardware
-+ *    5AP.    symmetric IO mode (normal Linux operation) not affected.
-+ *            'noapic' mode has vector 0xf filled out properly.
-+ *    6AP.    'noapic' mode might be affected - fixed in later steppings
-+ *    7AP.    We do not assume writes to the LVT deassering IRQs
-+ *    8AP.    We do not enable low power mode (deep sleep) during MP bootup
-+ *    9AP.    We do not use mixed mode
-+ *
-+ *    Pentium
-+ *            There is a marginal case where REP MOVS on 100MHz SMP
-+ *    machines with B stepping processors can fail. XXX should provide
-+ *    an L1cache=Writethrough or L1cache=off option.
-+ *
-+ *            B stepping CPUs may hang. There are hardware work arounds
-+ *    for this. We warn about it in case your board doesn't have the work
-+ *    arounds. Basically thats so I can tell anyone with a B stepping
-+ *    CPU and SMP problems "tough".
-+ *
-+ *    Specific items [From Pentium Processor Specification Update]
-+ *
-+ *    1AP.    Linux doesn't use remote read
-+ *    2AP.    Linux doesn't trust APIC errors
-+ *    3AP.    We work around this
-+ *    4AP.    Linux never generated 3 interrupts of the same priority
-+ *            to cause a lost local interrupt.
-+ *    5AP.    Remote read is never used
-+ *    6AP.    not affected - worked around in hardware
-+ *    7AP.    not affected - worked around in hardware
-+ *    8AP.    worked around in hardware - we get explicit CS errors if not
-+ *    9AP.    only 'noapic' mode affected. Might generate spurious
-+ *            interrupts, we log only the first one and count the
-+ *            rest silently.
-+ *    10AP.   not affected - worked around in hardware
-+ *    11AP.   Linux reads the APIC between writes to avoid this, as per
-+ *            the documentation. Make sure you preserve this as it affects
-+ *            the C stepping chips too.
-+ *    12AP.   not affected - worked around in hardware
-+ *    13AP.   not affected - worked around in hardware
-+ *    14AP.   we always deassert INIT during bootup
-+ *    15AP.   not affected - worked around in hardware
-+ *    16AP.   not affected - worked around in hardware
-+ *    17AP.   not affected - worked around in hardware
-+ *    18AP.   not affected - worked around in hardware
-+ *    19AP.   not affected - worked around in BIOS
-+ *
-+ *    If this sounds worrying believe me these bugs are either ___RARE___,
-+ *    or are signal timing bugs worked around in hardware and there's
-+ *    about nothing of note with C stepping upwards.
-+ */
-+
-+DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
-+
-+/*
-+ * the following functions deal with sending IPIs between CPUs.
-+ *
-+ * We use 'broadcast', CPU->CPU IPIs and self-IPIs too.
-+ */
-+
-+static inline int __prepare_ICR (unsigned int shortcut, int vector)
-+{
-+      return APIC_DM_FIXED | shortcut | vector | APIC_DEST_LOGICAL;
-+}
-+
-+static inline int __prepare_ICR2 (unsigned int mask)
-+{
-+      return SET_APIC_DEST_FIELD(mask);
-+}
-+
-+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
-+
-+static inline void __send_IPI_one(unsigned int cpu, int vector)
-+{
-+      int irq = per_cpu(ipi_to_irq, cpu)[vector];
-+      BUG_ON(irq < 0);
-+      notify_remote_via_irq(irq);
-+}
-+
-+void __send_IPI_shortcut(unsigned int shortcut, int vector)
-+{
-+      int cpu;
-+
-+      switch (shortcut) {
-+      case APIC_DEST_SELF:
-+              __send_IPI_one(smp_processor_id(), vector);
-+              break;
-+      case APIC_DEST_ALLBUT:
-+              for (cpu = 0; cpu < NR_CPUS; ++cpu) {
-+                      if (cpu == smp_processor_id())
-+                              continue;
-+                      if (cpu_isset(cpu, cpu_online_map)) {
-+                              __send_IPI_one(cpu, vector);
-+                      }
-+              }
-+              break;
-+      default:
-+              printk("XXXXXX __send_IPI_shortcut %08x vector %d\n", shortcut,
-+                     vector);
-+              break;
-+      }
-+}
-+
-+void fastcall send_IPI_self(int vector)
-+{
-+      __send_IPI_shortcut(APIC_DEST_SELF, vector);
-+}
-+
-+/*
-+ * This is only used on smaller machines.
-+ */
-+void send_IPI_mask_bitmask(cpumask_t mask, int vector)
-+{
-+      unsigned long flags;
-+      unsigned int cpu;
-+
-+      local_irq_save(flags);
-+      WARN_ON(cpus_addr(mask)[0] & ~cpus_addr(cpu_online_map)[0]);
-+
-+      for (cpu = 0; cpu < NR_CPUS; ++cpu) {
-+              if (cpu_isset(cpu, mask)) {
-+                      __send_IPI_one(cpu, vector);
-+              }
-+      }
-+
-+      local_irq_restore(flags);
-+}
-+
-+void send_IPI_mask_sequence(cpumask_t mask, int vector)
-+{
-+
-+      send_IPI_mask_bitmask(mask, vector);
-+}
-+
-+#include <mach_ipi.h> /* must come after the send_IPI functions above for inlining */
-+
-+#if 0 /* XEN */
-+/*
-+ *    Smarter SMP flushing macros. 
-+ *            c/o Linus Torvalds.
-+ *
-+ *    These mean you can really definitely utterly forget about
-+ *    writing to user space from interrupts. (Its not allowed anyway).
-+ *
-+ *    Optimizations Manfred Spraul <manfred@colorfullife.com>
-+ */
-+
-+static cpumask_t flush_cpumask;
-+static struct mm_struct * flush_mm;
-+static unsigned long flush_va;
-+static DEFINE_SPINLOCK(tlbstate_lock);
-+#define FLUSH_ALL     0xffffffff
-+
-+/*
-+ * We cannot call mmdrop() because we are in interrupt context, 
-+ * instead update mm->cpu_vm_mask.
-+ *
-+ * We need to reload %cr3 since the page tables may be going
-+ * away from under us..
-+ */
-+static inline void leave_mm (unsigned long cpu)
-+{
-+      if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
-+              BUG();
-+      cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask);
-+      load_cr3(swapper_pg_dir);
-+}
-+
-+/*
-+ *
-+ * The flush IPI assumes that a thread switch happens in this order:
-+ * [cpu0: the cpu that switches]
-+ * 1) switch_mm() either 1a) or 1b)
-+ * 1a) thread switch to a different mm
-+ * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
-+ *    Stop ipi delivery for the old mm. This is not synchronized with
-+ *    the other cpus, but smp_invalidate_interrupt ignore flush ipis
-+ *    for the wrong mm, and in the worst case we perform a superflous
-+ *    tlb flush.
-+ * 1a2) set cpu_tlbstate to TLBSTATE_OK
-+ *    Now the smp_invalidate_interrupt won't call leave_mm if cpu0
-+ *    was in lazy tlb mode.
-+ * 1a3) update cpu_tlbstate[].active_mm
-+ *    Now cpu0 accepts tlb flushes for the new mm.
-+ * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask);
-+ *    Now the other cpus will send tlb flush ipis.
-+ * 1a4) change cr3.
-+ * 1b) thread switch without mm change
-+ *    cpu_tlbstate[].active_mm is correct, cpu0 already handles
-+ *    flush ipis.
-+ * 1b1) set cpu_tlbstate to TLBSTATE_OK
-+ * 1b2) test_and_set the cpu bit in cpu_vm_mask.
-+ *    Atomically set the bit [other cpus will start sending flush ipis],
-+ *    and test the bit.
-+ * 1b3) if the bit was 0: leave_mm was called, flush the tlb.
-+ * 2) switch %%esp, ie current
-+ *
-+ * The interrupt must handle 2 special cases:
-+ * - cr3 is changed before %%esp, ie. it cannot use current->{active_,}mm.
-+ * - the cpu performs speculative tlb reads, i.e. even if the cpu only
-+ *   runs in kernel space, the cpu could load tlb entries for user space
-+ *   pages.
-+ *
-+ * The good news is that cpu_tlbstate is local to each cpu, no
-+ * write/read ordering problems.
-+ */
-+
-+/*
-+ * TLB flush IPI:
-+ *
-+ * 1) Flush the tlb entries if the cpu uses the mm that's being flushed.
-+ * 2) Leave the mm if we are in the lazy tlb mode.
-+ */
-+
-+irqreturn_t smp_invalidate_interrupt(int irq, void *dev_id,
-+                                   struct pt_regs *regs)
-+{
-+      unsigned long cpu;
-+
-+      cpu = get_cpu();
-+
-+      if (!cpu_isset(cpu, flush_cpumask))
-+              goto out;
-+              /* 
-+               * This was a BUG() but until someone can quote me the
-+               * line from the intel manual that guarantees an IPI to
-+               * multiple CPUs is retried _only_ on the erroring CPUs
-+               * its staying as a return
-+               *
-+               * BUG();
-+               */
-+               
-+      if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
-+              if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
-+                      if (flush_va == FLUSH_ALL)
-+                              local_flush_tlb();
-+                      else
-+                              __flush_tlb_one(flush_va);
-+              } else
-+                      leave_mm(cpu);
-+      }
-+      smp_mb__before_clear_bit();
-+      cpu_clear(cpu, flush_cpumask);
-+      smp_mb__after_clear_bit();
-+out:
-+      put_cpu_no_resched();
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
-+                                              unsigned long va)
-+{
-+      /*
-+       * A couple of (to be removed) sanity checks:
-+       *
-+       * - current CPU must not be in mask
-+       * - mask must exist :)
-+       */
-+      BUG_ON(cpus_empty(cpumask));
-+      BUG_ON(cpu_isset(smp_processor_id(), cpumask));
-+      BUG_ON(!mm);
-+
-+      /* If a CPU which we ran on has gone down, OK. */
-+      cpus_and(cpumask, cpumask, cpu_online_map);
-+      if (cpus_empty(cpumask))
-+              return;
-+
-+      /*
-+       * i'm not happy about this global shared spinlock in the
-+       * MM hot path, but we'll see how contended it is.
-+       * Temporarily this turns IRQs off, so that lockups are
-+       * detected by the NMI watchdog.
-+       */
-+      spin_lock(&tlbstate_lock);
-+      
-+      flush_mm = mm;
-+      flush_va = va;
-+#if NR_CPUS <= BITS_PER_LONG
-+      atomic_set_mask(cpumask, &flush_cpumask);
-+#else
-+      {
-+              int k;
-+              unsigned long *flush_mask = (unsigned long *)&flush_cpumask;
-+              unsigned long *cpu_mask = (unsigned long *)&cpumask;
-+              for (k = 0; k < BITS_TO_LONGS(NR_CPUS); ++k)
-+                      atomic_set_mask(cpu_mask[k], &flush_mask[k]);
-+      }
-+#endif
-+      /*
-+       * We have to send the IPI only to
-+       * CPUs affected.
-+       */
-+      send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR);
-+
-+      while (!cpus_empty(flush_cpumask))
-+              /* nothing. lockup detection does not belong here */
-+              mb();
-+
-+      flush_mm = NULL;
-+      flush_va = 0;
-+      spin_unlock(&tlbstate_lock);
-+}
-+      
-+void flush_tlb_current_task(void)
-+{
-+      struct mm_struct *mm = current->mm;
-+      cpumask_t cpu_mask;
-+
-+      preempt_disable();
-+      cpu_mask = mm->cpu_vm_mask;
-+      cpu_clear(smp_processor_id(), cpu_mask);
-+
-+      local_flush_tlb();
-+      if (!cpus_empty(cpu_mask))
-+              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-+      preempt_enable();
-+}
-+
-+void flush_tlb_mm (struct mm_struct * mm)
-+{
-+      cpumask_t cpu_mask;
-+
-+      preempt_disable();
-+      cpu_mask = mm->cpu_vm_mask;
-+      cpu_clear(smp_processor_id(), cpu_mask);
-+
-+      if (current->active_mm == mm) {
-+              if (current->mm)
-+                      local_flush_tlb();
-+              else
-+                      leave_mm(smp_processor_id());
-+      }
-+      if (!cpus_empty(cpu_mask))
-+              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-+
-+      preempt_enable();
-+}
-+
-+void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
-+{
-+      struct mm_struct *mm = vma->vm_mm;
-+      cpumask_t cpu_mask;
-+
-+      preempt_disable();
-+      cpu_mask = mm->cpu_vm_mask;
-+      cpu_clear(smp_processor_id(), cpu_mask);
-+
-+      if (current->active_mm == mm) {
-+              if(current->mm)
-+                      __flush_tlb_one(va);
-+              else
-+                      leave_mm(smp_processor_id());
-+      }
-+
-+      if (!cpus_empty(cpu_mask))
-+              flush_tlb_others(cpu_mask, mm, va);
-+
-+      preempt_enable();
-+}
-+EXPORT_SYMBOL(flush_tlb_page);
-+
-+static void do_flush_tlb_all(void* info)
-+{
-+      unsigned long cpu = smp_processor_id();
-+
-+      __flush_tlb_all();
-+      if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY)
-+              leave_mm(cpu);
-+}
-+
-+void flush_tlb_all(void)
-+{
-+      on_each_cpu(do_flush_tlb_all, NULL, 1, 1);
-+}
-+
-+#else
-+
-+irqreturn_t smp_invalidate_interrupt(int irq, void *dev_id,
-+                                   struct pt_regs *regs)
-+{ return 0; }
-+void flush_tlb_current_task(void)
-+{ xen_tlb_flush_mask(&current->mm->cpu_vm_mask); }
-+void flush_tlb_mm(struct mm_struct * mm)
-+{ xen_tlb_flush_mask(&mm->cpu_vm_mask); }
-+void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
-+{ xen_invlpg_mask(&vma->vm_mm->cpu_vm_mask, va); }
-+EXPORT_SYMBOL(flush_tlb_page);
-+void flush_tlb_all(void)
-+{ xen_tlb_flush_all(); }
-+
-+#endif /* XEN */
-+
-+/*
-+ * this function sends a 'reschedule' IPI to another CPU.
-+ * it goes straight through and wastes no time serializing
-+ * anything. Worst case is that we lose a reschedule ...
-+ */
-+void smp_send_reschedule(int cpu)
-+{
-+      WARN_ON(cpu_is_offline(cpu));
-+      send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
-+}
-+
-+/*
-+ * Structure and data for smp_call_function(). This is designed to minimise
-+ * static memory requirements. It also looks cleaner.
-+ */
-+static DEFINE_SPINLOCK(call_lock);
-+
-+struct call_data_struct {
-+      void (*func) (void *info);
-+      void *info;
-+      atomic_t started;
-+      atomic_t finished;
-+      int wait;
-+};
-+
-+void lock_ipi_call_lock(void)
-+{
-+      spin_lock_irq(&call_lock);
-+}
-+
-+void unlock_ipi_call_lock(void)
-+{
-+      spin_unlock_irq(&call_lock);
-+}
-+
-+static struct call_data_struct * call_data;
-+
-+/*
-+ * this function sends a 'generic call function' IPI to all other CPUs
-+ * in the system.
-+ */
-+
-+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
-+                      int wait)
-+/*
-+ * [SUMMARY] Run a function on all other CPUs.
-+ * <func> The function to run. This must be fast and non-blocking.
-+ * <info> An arbitrary pointer to pass to the function.
-+ * <nonatomic> currently unused.
-+ * <wait> If true, wait (atomically) until function has completed on other CPUs.
-+ * [RETURNS] 0 on success, else a negative status code. Does not return until
-+ * remote CPUs are nearly ready to execute <<func>> or are or have executed.
-+ *
-+ * You must not call this function with disabled interrupts or from a
-+ * hardware interrupt handler or from a bottom half handler.
-+ */
-+{
-+      struct call_data_struct data;
-+      int cpus;
-+
-+      /* Holding any lock stops cpus from going down. */
-+      spin_lock(&call_lock);
-+      cpus = num_online_cpus() - 1;
-+      if (!cpus) {
-+              spin_unlock(&call_lock);
-+              return 0;
-+      }
-+
-+      /* Can deadlock when called with interrupts disabled */
-+      WARN_ON(irqs_disabled());
-+
-+      data.func = func;
-+      data.info = info;
-+      atomic_set(&data.started, 0);
-+      data.wait = wait;
-+      if (wait)
-+              atomic_set(&data.finished, 0);
-+
-+      call_data = &data;
-+      mb();
-+      
-+      /* Send a message to all other CPUs and wait for them to respond */
-+      send_IPI_allbutself(CALL_FUNCTION_VECTOR);
-+
-+      /* Wait for response */
-+      while (atomic_read(&data.started) != cpus)
-+              barrier();
-+
-+      if (wait)
-+              while (atomic_read(&data.finished) != cpus)
-+                      barrier();
-+      spin_unlock(&call_lock);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL(smp_call_function);
-+
-+static void stop_this_cpu (void * dummy)
-+{
-+      /*
-+       * Remove this CPU:
-+       */
-+      cpu_clear(smp_processor_id(), cpu_online_map);
-+      local_irq_disable();
-+#if 0
-+      disable_local_APIC();
-+#endif
-+      if (cpu_data[smp_processor_id()].hlt_works_ok)
-+              for(;;) halt();
-+      for (;;);
-+}
-+
-+/*
-+ * this function calls the 'stop' function on all other CPUs in the system.
-+ */
-+
-+void smp_send_stop(void)
-+{
-+      smp_call_function(stop_this_cpu, NULL, 1, 0);
-+
-+      local_irq_disable();
-+#if 0
-+      disable_local_APIC();
-+#endif
-+      local_irq_enable();
-+}
-+
-+/*
-+ * Reschedule call back. Nothing to do,
-+ * all the work is done automatically when
-+ * we return from the interrupt.
-+ */
-+irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id,
-+                                   struct pt_regs *regs)
-+{
-+
-+      return IRQ_HANDLED;
-+}
-+
-+#include <linux/kallsyms.h>
-+irqreturn_t smp_call_function_interrupt(int irq, void *dev_id,
-+                                      struct pt_regs *regs)
-+{
-+      void (*func) (void *info) = call_data->func;
-+      void *info = call_data->info;
-+      int wait = call_data->wait;
-+
-+      /*
-+       * Notify initiating CPU that I've grabbed the data and am
-+       * about to execute the function
-+       */
-+      mb();
-+      atomic_inc(&call_data->started);
-+      /*
-+       * At this point the info structure may be out of scope unless wait==1
-+       */
-+      irq_enter();
-+      (*func)(info);
-+      irq_exit();
-+
-+      if (wait) {
-+              mb();
-+              atomic_inc(&call_data->finished);
-+      }
-+
-+      return IRQ_HANDLED;
-+}
-+
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/smpalts.c linux-2.6.16.33/arch/i386/kernel/smpalts.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/smpalts.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/smpalts.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,85 @@
-+#include <linux/kernel.h>
-+#include <asm/system.h>
-+#include <asm/smp_alt.h>
-+#include <asm/processor.h>
-+#include <asm/string.h>
-+
-+struct smp_replacement_record {
-+      unsigned char targ_size;
-+      unsigned char smp1_size;
-+      unsigned char smp2_size;
-+      unsigned char up_size;
-+      unsigned char feature;
-+      unsigned char data[0];
-+};
-+
-+struct smp_alternative_record {
-+      void *targ_start;
-+      struct smp_replacement_record *repl;
-+};
-+
-+extern struct smp_alternative_record __start_smp_alternatives_table,
-+  __stop_smp_alternatives_table;
-+extern unsigned long __init_begin, __init_end;
-+
-+void prepare_for_smp(void)
-+{
-+      struct smp_alternative_record *r;
-+      printk(KERN_INFO "Enabling SMP...\n");
-+      for (r = &__start_smp_alternatives_table;
-+           r != &__stop_smp_alternatives_table;
-+           r++) {
-+              BUG_ON(r->repl->targ_size < r->repl->smp1_size);
-+              BUG_ON(r->repl->targ_size < r->repl->smp2_size);
-+              BUG_ON(r->repl->targ_size < r->repl->up_size);
-+               if (system_state == SYSTEM_RUNNING &&
-+                   r->targ_start >= (void *)&__init_begin &&
-+                   r->targ_start < (void *)&__init_end)
-+                       continue;
-+              if (r->repl->feature != (unsigned char)-1 &&
-+                  boot_cpu_has(r->repl->feature)) {
-+                      memcpy(r->targ_start,
-+                             r->repl->data + r->repl->smp1_size,
-+                             r->repl->smp2_size);
-+                      memset(r->targ_start + r->repl->smp2_size,
-+                             0x90,
-+                             r->repl->targ_size - r->repl->smp2_size);
-+              } else {
-+                      memcpy(r->targ_start,
-+                             r->repl->data,
-+                             r->repl->smp1_size);
-+                      memset(r->targ_start + r->repl->smp1_size,
-+                             0x90,
-+                             r->repl->targ_size - r->repl->smp1_size);
-+              }
-+      }
-+      /* Paranoia */
-+      asm volatile ("jmp 1f\n1:");
-+      mb();
-+}
-+
-+void unprepare_for_smp(void)
-+{
-+      struct smp_alternative_record *r;
-+      printk(KERN_INFO "Disabling SMP...\n");
-+      for (r = &__start_smp_alternatives_table;
-+           r != &__stop_smp_alternatives_table;
-+           r++) {
-+              BUG_ON(r->repl->targ_size < r->repl->smp1_size);
-+              BUG_ON(r->repl->targ_size < r->repl->smp2_size);
-+              BUG_ON(r->repl->targ_size < r->repl->up_size);
-+               if (system_state == SYSTEM_RUNNING &&
-+                   r->targ_start >= (void *)&__init_begin &&
-+                   r->targ_start < (void *)&__init_end)
-+                       continue;
-+              memcpy(r->targ_start,
-+                     r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
-+                     r->repl->up_size);
-+              memset(r->targ_start + r->repl->up_size,
-+                     0x90,
-+                     r->repl->targ_size - r->repl->up_size);
-+      }
-+      /* Paranoia */
-+      asm volatile ("jmp 1f\n1:");
-+      mb();
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/smpboot.c linux-2.6.16.33/arch/i386/kernel/smpboot.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/smpboot.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/smpboot.c 2007-01-08 15:00:45.000000000 +0000
-@@ -1218,6 +1218,11 @@
-               if (max_cpus <= cpucount+1)
-                       continue;
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+              if (kicked == 1)
-+                      prepare_for_smp();
-+#endif
-+
-               if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
-                       printk("CPU #%d not responding - cannot use it.\n",
-                                                               apicid);
-@@ -1396,6 +1401,11 @@
-               return -EIO;
-       }
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+      if (num_online_cpus() == 1)
-+              prepare_for_smp();
-+#endif
-+
-       local_irq_enable();
-       per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
-       /* Unleash the CPU! */
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/swiotlb.c linux-2.6.16.33/arch/i386/kernel/swiotlb.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/swiotlb.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/swiotlb.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,683 @@
-+/*
-+ * Dynamic DMA mapping support.
-+ *
-+ * This implementation is a fallback for platforms that do not support
-+ * I/O TLBs (aka DMA address translation hardware).
-+ * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com>
-+ * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com>
-+ * Copyright (C) 2000, 2003 Hewlett-Packard Co
-+ *    David Mosberger-Tang <davidm@hpl.hp.com>
-+ * Copyright (C) 2005 Keir Fraser <keir@xensource.com>
-+ */
-+
-+#include <linux/cache.h>
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/spinlock.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/ctype.h>
-+#include <linux/init.h>
-+#include <linux/bootmem.h>
-+#include <linux/highmem.h>
-+#include <asm/io.h>
-+#include <asm/pci.h>
-+#include <asm/dma.h>
-+#include <asm/uaccess.h>
-+#include <xen/interface/memory.h>
-+
-+int swiotlb;
-+EXPORT_SYMBOL(swiotlb);
-+
-+#define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
-+
-+#define SG_ENT_PHYS_ADDRESS(sg)       (page_to_bus((sg)->page) + (sg)->offset)
-+
-+/*
-+ * Maximum allowable number of contiguous slabs to map,
-+ * must be a power of 2.  What is the appropriate value ?
-+ * The complexity of {map,unmap}_single is linearly dependent on this value.
-+ */
-+#define IO_TLB_SEGSIZE        128
-+
-+/*
-+ * log of the size of each IO TLB slab.  The number of slabs is command line
-+ * controllable.
-+ */
-+#define IO_TLB_SHIFT 11
-+
-+/* Width of DMA addresses. 30 bits is a b44 limitation. */
-+#define DEFAULT_DMA_BITS 30
-+
-+static int swiotlb_force;
-+static char *iotlb_virt_start;
-+static unsigned long iotlb_nslabs;
-+
-+/*
-+ * Used to do a quick range check in swiotlb_unmap_single and
-+ * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
-+ * API.
-+ */
-+static unsigned long iotlb_pfn_start, iotlb_pfn_end;
-+
-+/* Does the given dma address reside within the swiotlb aperture? */
-+static inline int in_swiotlb_aperture(dma_addr_t dev_addr)
-+{
-+      unsigned long pfn = mfn_to_local_pfn(dev_addr >> PAGE_SHIFT);
-+      return (pfn_valid(pfn)
-+              && (pfn >= iotlb_pfn_start)
-+              && (pfn < iotlb_pfn_end));
-+}
-+
-+/*
-+ * When the IOMMU overflows we return a fallback buffer. This sets the size.
-+ */
-+static unsigned long io_tlb_overflow = 32*1024;
-+
-+void *io_tlb_overflow_buffer;
-+
-+/*
-+ * This is a free list describing the number of free entries available from
-+ * each index
-+ */
-+static unsigned int *io_tlb_list;
-+static unsigned int io_tlb_index;
-+
-+/*
-+ * We need to save away the original address corresponding to a mapped entry
-+ * for the sync operations.
-+ */
-+static struct phys_addr {
-+      struct page *page;
-+      unsigned int offset;
-+} *io_tlb_orig_addr;
-+
-+/*
-+ * Protect the above data structures in the map and unmap calls
-+ */
-+static DEFINE_SPINLOCK(io_tlb_lock);
-+
-+unsigned int dma_bits = DEFAULT_DMA_BITS;
-+static int __init
-+setup_dma_bits(char *str)
-+{
-+      dma_bits = simple_strtoul(str, NULL, 0);
-+      return 0;
-+}
-+__setup("dma_bits=", setup_dma_bits);
-+
-+static int __init
-+setup_io_tlb_npages(char *str)
-+{
-+      /* Unlike ia64, the size is aperture in megabytes, not 'slabs'! */
-+      if (isdigit(*str)) {
-+              iotlb_nslabs = simple_strtoul(str, &str, 0) <<
-+                      (20 - IO_TLB_SHIFT);
-+              iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE);
-+              /* Round up to power of two (xen_create_contiguous_region). */
-+              while (iotlb_nslabs & (iotlb_nslabs-1))
-+                      iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1);
-+      }
-+      if (*str == ',')
-+              ++str;
-+      /*
-+         * NB. 'force' enables the swiotlb, but doesn't force its use for
-+         * every DMA like it does on native Linux. 'off' forcibly disables
-+         * use of the swiotlb.
-+         */
-+      if (!strcmp(str, "force"))
-+              swiotlb_force = 1;
-+      else if (!strcmp(str, "off"))
-+              swiotlb_force = -1;
-+      return 1;
-+}
-+__setup("swiotlb=", setup_io_tlb_npages);
-+/* make io_tlb_overflow tunable too? */
-+
-+/*
-+ * Statically reserve bounce buffer space and initialize bounce buffer data
-+ * structures for the software IO TLB used to implement the PCI DMA API.
-+ */
-+void
-+swiotlb_init_with_default_size (size_t default_size)
-+{
-+      unsigned long i, bytes;
-+
-+      if (!iotlb_nslabs) {
-+              iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
-+              iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE);
-+              /* Round up to power of two (xen_create_contiguous_region). */
-+              while (iotlb_nslabs & (iotlb_nslabs-1))
-+                      iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1);
-+      }
-+
-+      bytes = iotlb_nslabs * (1UL << IO_TLB_SHIFT);
-+
-+      /*
-+       * Get IO TLB memory from the low pages
-+       */
-+      iotlb_virt_start = alloc_bootmem_low_pages(bytes);
-+      if (!iotlb_virt_start)
-+              panic("Cannot allocate SWIOTLB buffer!\n"
-+                    "Use dom0_mem Xen boot parameter to reserve\n"
-+                    "some DMA memory (e.g., dom0_mem=-128M).\n");
-+
-+      for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) {
-+              int rc = xen_create_contiguous_region(
-+                      (unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
-+                      get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
-+                      dma_bits);
-+              BUG_ON(rc);
-+      }
-+
-+      /*
-+       * Allocate and initialize the free list array.  This array is used
-+       * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE.
-+       */
-+      io_tlb_list = alloc_bootmem(iotlb_nslabs * sizeof(int));
-+      for (i = 0; i < iotlb_nslabs; i++)
-+              io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
-+      io_tlb_index = 0;
-+      io_tlb_orig_addr = alloc_bootmem(
-+              iotlb_nslabs * sizeof(*io_tlb_orig_addr));
-+
-+      /*
-+       * Get the overflow emergency buffer
-+       */
-+      io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
-+
-+      iotlb_pfn_start = __pa(iotlb_virt_start) >> PAGE_SHIFT;
-+      iotlb_pfn_end   = iotlb_pfn_start + (bytes >> PAGE_SHIFT);
-+
-+      printk(KERN_INFO "Software IO TLB enabled: \n"
-+             " Aperture:     %lu megabytes\n"
-+             " Kernel range: 0x%016lx - 0x%016lx\n"
-+             " Address size: %u bits\n",
-+             bytes >> 20,
-+             (unsigned long)iotlb_virt_start,
-+             (unsigned long)iotlb_virt_start + bytes,
-+             dma_bits);
-+}
-+
-+void
-+swiotlb_init(void)
-+{
-+      long ram_end;
-+      size_t defsz = 64 * (1 << 20); /* 64MB default size */
-+
-+      if (swiotlb_force == 1) {
-+              swiotlb = 1;
-+      } else if ((swiotlb_force != -1) &&
-+                 is_running_on_xen() &&
-+                 is_initial_xendomain()) {
-+              /* Domain 0 always has a swiotlb. */
-+              ram_end = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
-+              if (ram_end <= 0x7ffff)
-+                      defsz = 2 * (1 << 20); /* 2MB on <2GB on systems. */
-+              swiotlb = 1;
-+      }
-+
-+      if (swiotlb)
-+              swiotlb_init_with_default_size(defsz);
-+      else
-+              printk(KERN_INFO "Software IO TLB disabled\n");
-+}
-+
-+/*
-+ * We use __copy_to_user_inatomic to transfer to the host buffer because the
-+ * buffer may be mapped read-only (e.g, in blkback driver) but lower-level
-+ * drivers map the buffer for DMA_BIDIRECTIONAL access. This causes an
-+ * unnecessary copy from the aperture to the host buffer, and a page fault.
-+ */
-+static void
-+__sync_single(struct phys_addr buffer, char *dma_addr, size_t size, int dir)
-+{
-+      if (PageHighMem(buffer.page)) {
-+              size_t len, bytes;
-+              char *dev, *host, *kmp;
-+              len = size;
-+              while (len != 0) {
-+                      if (((bytes = len) + buffer.offset) > PAGE_SIZE)
-+                              bytes = PAGE_SIZE - buffer.offset;
-+                      kmp  = kmap_atomic(buffer.page, KM_SWIOTLB);
-+                      dev  = dma_addr + size - len;
-+                      host = kmp + buffer.offset;
-+                      if (dir == DMA_FROM_DEVICE) {
-+                              if (__copy_to_user_inatomic(host, dev, bytes))
-+                                      /* inaccessible */;
-+                      } else
-+                              memcpy(dev, host, bytes);
-+                      kunmap_atomic(kmp, KM_SWIOTLB);
-+                      len -= bytes;
-+                      buffer.page++;
-+                      buffer.offset = 0;
-+              }
-+      } else {
-+              char *host = (char *)phys_to_virt(
-+                      page_to_pseudophys(buffer.page)) + buffer.offset;
-+              if (dir == DMA_FROM_DEVICE) {
-+                      if (__copy_to_user_inatomic(host, dma_addr, size))
-+                              /* inaccessible */;
-+              } else if (dir == DMA_TO_DEVICE)
-+                      memcpy(dma_addr, host, size);
-+      }
-+}
-+
-+/*
-+ * Allocates bounce buffer and returns its kernel virtual address.
-+ */
-+static void *
-+map_single(struct device *hwdev, struct phys_addr buffer, size_t size, int dir)
-+{
-+      unsigned long flags;
-+      char *dma_addr;
-+      unsigned int nslots, stride, index, wrap;
-+      int i;
-+
-+      /*
-+       * For mappings greater than a page, we limit the stride (and
-+       * hence alignment) to a page size.
-+       */
-+      nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
-+      if (size > PAGE_SIZE)
-+              stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
-+      else
-+              stride = 1;
-+
-+      BUG_ON(!nslots);
-+
-+      /*
-+       * Find suitable number of IO TLB entries size that will fit this
-+       * request and allocate a buffer from that IO TLB pool.
-+       */
-+      spin_lock_irqsave(&io_tlb_lock, flags);
-+      {
-+              wrap = index = ALIGN(io_tlb_index, stride);
-+
-+              if (index >= iotlb_nslabs)
-+                      wrap = index = 0;
-+
-+              do {
-+                      /*
-+                       * If we find a slot that indicates we have 'nslots'
-+                       * number of contiguous buffers, we allocate the
-+                       * buffers from that slot and mark the entries as '0'
-+                       * indicating unavailable.
-+                       */
-+                      if (io_tlb_list[index] >= nslots) {
-+                              int count = 0;
-+
-+                              for (i = index; i < (int)(index + nslots); i++)
-+                                      io_tlb_list[i] = 0;
-+                              for (i = index - 1;
-+                                   (OFFSET(i, IO_TLB_SEGSIZE) !=
-+                                    IO_TLB_SEGSIZE -1) && io_tlb_list[i];
-+                                   i--)
-+                                      io_tlb_list[i] = ++count;
-+                              dma_addr = iotlb_virt_start +
-+                                      (index << IO_TLB_SHIFT);
-+
-+                              /*
-+                               * Update the indices to avoid searching in
-+                               * the next round.
-+                               */
-+                              io_tlb_index = 
-+                                      ((index + nslots) < iotlb_nslabs
-+                                       ? (index + nslots) : 0);
-+
-+                              goto found;
-+                      }
-+                      index += stride;
-+                      if (index >= iotlb_nslabs)
-+                              index = 0;
-+              } while (index != wrap);
-+
-+              spin_unlock_irqrestore(&io_tlb_lock, flags);
-+              return NULL;
-+      }
-+  found:
-+      spin_unlock_irqrestore(&io_tlb_lock, flags);
-+
-+      /*
-+       * Save away the mapping from the original address to the DMA address.
-+       * This is needed when we sync the memory.  Then we sync the buffer if
-+       * needed.
-+       */
-+      io_tlb_orig_addr[index] = buffer;
-+      if ((dir == DMA_TO_DEVICE) || (dir == DMA_BIDIRECTIONAL))
-+              __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE);
-+
-+      return dma_addr;
-+}
-+
-+/*
-+ * dma_addr is the kernel virtual address of the bounce buffer to unmap.
-+ */
-+static void
-+unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
-+{
-+      unsigned long flags;
-+      int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
-+      int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
-+      struct phys_addr buffer = io_tlb_orig_addr[index];
-+
-+      /*
-+       * First, sync the memory before unmapping the entry
-+       */
-+      if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))
-+              __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE);
-+
-+      /*
-+       * Return the buffer to the free list by setting the corresponding
-+       * entries to indicate the number of contigous entries available.
-+       * While returning the entries to the free list, we merge the entries
-+       * with slots below and above the pool being returned.
-+       */
-+      spin_lock_irqsave(&io_tlb_lock, flags);
-+      {
-+              count = ((index + nslots) < ALIGN(index + 1, IO_TLB_SEGSIZE) ?
-+                       io_tlb_list[index + nslots] : 0);
-+              /*
-+               * Step 1: return the slots to the free list, merging the
-+               * slots with superceeding slots
-+               */
-+              for (i = index + nslots - 1; i >= index; i--)
-+                      io_tlb_list[i] = ++count;
-+              /*
-+               * Step 2: merge the returned slots with the preceding slots,
-+               * if available (non zero)
-+               */
-+              for (i = index - 1;
-+                   (OFFSET(i, IO_TLB_SEGSIZE) !=
-+                    IO_TLB_SEGSIZE -1) && io_tlb_list[i];
-+                   i--)
-+                      io_tlb_list[i] = ++count;
-+      }
-+      spin_unlock_irqrestore(&io_tlb_lock, flags);
-+}
-+
-+static void
-+sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
-+{
-+      int index = (dma_addr - iotlb_virt_start) >> IO_TLB_SHIFT;
-+      struct phys_addr buffer = io_tlb_orig_addr[index];
-+      BUG_ON((dir != DMA_FROM_DEVICE) && (dir != DMA_TO_DEVICE));
-+      __sync_single(buffer, dma_addr, size, dir);
-+}
-+
-+static void
-+swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
-+{
-+      /*
-+       * Ran out of IOMMU space for this operation. This is very bad.
-+       * Unfortunately the drivers cannot handle this operation properly.
-+       * unless they check for pci_dma_mapping_error (most don't)
-+       * When the mapping is small enough return a static buffer to limit
-+       * the damage, or panic when the transfer is too big.
-+       */
-+      printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at "
-+             "device %s\n", (unsigned long)size, dev ? dev->bus_id : "?");
-+
-+      if (size > io_tlb_overflow && do_panic) {
-+              if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
-+                      panic("PCI-DMA: Memory would be corrupted\n");
-+              if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
-+                      panic("PCI-DMA: Random memory would be DMAed\n");
-+      }
-+}
-+
-+/*
-+ * Map a single buffer of the indicated size for DMA in streaming mode.  The
-+ * PCI address to use is returned.
-+ *
-+ * Once the device is given the dma address, the device owns this memory until
-+ * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
-+ */
-+dma_addr_t
-+swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir)
-+{
-+      dma_addr_t dev_addr = virt_to_bus(ptr);
-+      void *map;
-+      struct phys_addr buffer;
-+
-+      BUG_ON(dir == DMA_NONE);
-+
-+      /*
-+       * If the pointer passed in happens to be in the device's DMA window,
-+       * we can safely return the device addr and not worry about bounce
-+       * buffering it.
-+       */
-+      if (!range_straddles_page_boundary(ptr, size) &&
-+          !address_needs_mapping(hwdev, dev_addr))
-+              return dev_addr;
-+
-+      /*
-+       * Oh well, have to allocate and map a bounce buffer.
-+       */
-+      buffer.page   = virt_to_page(ptr);
-+      buffer.offset = (unsigned long)ptr & ~PAGE_MASK;
-+      map = map_single(hwdev, buffer, size, dir);
-+      if (!map) {
-+              swiotlb_full(hwdev, size, dir, 1);
-+              map = io_tlb_overflow_buffer;
-+      }
-+
-+      dev_addr = virt_to_bus(map);
-+      return dev_addr;
-+}
-+
-+/*
-+ * Unmap a single streaming mode DMA translation.  The dma_addr and size must
-+ * match what was provided for in a previous swiotlb_map_single call.  All
-+ * other usages are undefined.
-+ *
-+ * After this call, reads by the cpu to the buffer are guaranteed to see
-+ * whatever the device wrote there.
-+ */
-+void
-+swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size,
-+                   int dir)
-+{
-+      BUG_ON(dir == DMA_NONE);
-+      if (in_swiotlb_aperture(dev_addr))
-+              unmap_single(hwdev, bus_to_virt(dev_addr), size, dir);
-+}
-+
-+/*
-+ * Make physical memory consistent for a single streaming mode DMA translation
-+ * after a transfer.
-+ *
-+ * If you perform a swiotlb_map_single() but wish to interrogate the buffer
-+ * using the cpu, yet do not wish to teardown the PCI dma mapping, you must
-+ * call this function before doing so.  At the next point you give the PCI dma
-+ * address back to the card, you must first perform a
-+ * swiotlb_dma_sync_for_device, and then the device again owns the buffer
-+ */
-+void
-+swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
-+                          size_t size, int dir)
-+{
-+      BUG_ON(dir == DMA_NONE);
-+      if (in_swiotlb_aperture(dev_addr))
-+              sync_single(hwdev, bus_to_virt(dev_addr), size, dir);
-+}
-+
-+void
-+swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
-+                             size_t size, int dir)
-+{
-+      BUG_ON(dir == DMA_NONE);
-+      if (in_swiotlb_aperture(dev_addr))
-+              sync_single(hwdev, bus_to_virt(dev_addr), size, dir);
-+}
-+
-+/*
-+ * Map a set of buffers described by scatterlist in streaming mode for DMA.
-+ * This is the scatter-gather version of the above swiotlb_map_single
-+ * interface.  Here the scatter gather list elements are each tagged with the
-+ * appropriate dma address and length.  They are obtained via
-+ * sg_dma_{address,length}(SG).
-+ *
-+ * NOTE: An implementation may be able to use a smaller number of
-+ *       DMA address/length pairs than there are SG table elements.
-+ *       (for example via virtual mapping capabilities)
-+ *       The routine returns the number of addr/length pairs actually
-+ *       used, at most nents.
-+ *
-+ * Device ownership issues as mentioned above for swiotlb_map_single are the
-+ * same here.
-+ */
-+int
-+swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
-+             int dir)
-+{
-+      struct phys_addr buffer;
-+      dma_addr_t dev_addr;
-+      char *map;
-+      int i;
-+
-+      BUG_ON(dir == DMA_NONE);
-+
-+      for (i = 0; i < nelems; i++, sg++) {
-+              dev_addr = SG_ENT_PHYS_ADDRESS(sg);
-+              if (address_needs_mapping(hwdev, dev_addr)) {
-+                      buffer.page   = sg->page;
-+                      buffer.offset = sg->offset;
-+                      map = map_single(hwdev, buffer, sg->length, dir);
-+                      if (!map) {
-+                              /* Don't panic here, we expect map_sg users
-+                                 to do proper error handling. */
-+                              swiotlb_full(hwdev, sg->length, dir, 0);
-+                              swiotlb_unmap_sg(hwdev, sg - i, i, dir);
-+                              sg[0].dma_length = 0;
-+                              return 0;
-+                      }
-+                      sg->dma_address = (dma_addr_t)virt_to_bus(map);
-+              } else
-+                      sg->dma_address = dev_addr;
-+              sg->dma_length = sg->length;
-+      }
-+      return nelems;
-+}
-+
-+/*
-+ * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
-+ * concerning calls here are the same as for swiotlb_unmap_single() above.
-+ */
-+void
-+swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
-+               int dir)
-+{
-+      int i;
-+
-+      BUG_ON(dir == DMA_NONE);
-+
-+      for (i = 0; i < nelems; i++, sg++)
-+              if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-+                      unmap_single(hwdev, 
-+                                   (void *)bus_to_virt(sg->dma_address),
-+                                   sg->dma_length, dir);
-+}
-+
-+/*
-+ * Make physical memory consistent for a set of streaming mode DMA translations
-+ * after a transfer.
-+ *
-+ * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
-+ * and usage.
-+ */
-+void
-+swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
-+                      int nelems, int dir)
-+{
-+      int i;
-+
-+      BUG_ON(dir == DMA_NONE);
-+
-+      for (i = 0; i < nelems; i++, sg++)
-+              if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-+                      sync_single(hwdev,
-+                                  (void *)bus_to_virt(sg->dma_address),
-+                                  sg->dma_length, dir);
-+}
-+
-+void
-+swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
-+                         int nelems, int dir)
-+{
-+      int i;
-+
-+      BUG_ON(dir == DMA_NONE);
-+
-+      for (i = 0; i < nelems; i++, sg++)
-+              if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-+                      sync_single(hwdev,
-+                                  (void *)bus_to_virt(sg->dma_address),
-+                                  sg->dma_length, dir);
-+}
-+
-+dma_addr_t
-+swiotlb_map_page(struct device *hwdev, struct page *page,
-+               unsigned long offset, size_t size,
-+               enum dma_data_direction direction)
-+{
-+      struct phys_addr buffer;
-+      dma_addr_t dev_addr;
-+      char *map;
-+
-+      dev_addr = page_to_bus(page) + offset;
-+      if (address_needs_mapping(hwdev, dev_addr)) {
-+              buffer.page   = page;
-+              buffer.offset = offset;
-+              map = map_single(hwdev, buffer, size, direction);
-+              if (!map) {
-+                      swiotlb_full(hwdev, size, direction, 1);
-+                      map = io_tlb_overflow_buffer;
-+              }
-+              dev_addr = (dma_addr_t)virt_to_bus(map);
-+      }
-+
-+      return dev_addr;
-+}
-+
-+void
-+swiotlb_unmap_page(struct device *hwdev, dma_addr_t dma_address,
-+                 size_t size, enum dma_data_direction direction)
-+{
-+      BUG_ON(direction == DMA_NONE);
-+      if (in_swiotlb_aperture(dma_address))
-+              unmap_single(hwdev, bus_to_virt(dma_address), size, direction);
-+}
-+
-+int
-+swiotlb_dma_mapping_error(dma_addr_t dma_addr)
-+{
-+      return (dma_addr == virt_to_bus(io_tlb_overflow_buffer));
-+}
-+
-+/*
-+ * Return whether the given PCI device DMA address mask can be supported
-+ * properly.  For example, if your device can only drive the low 24-bits
-+ * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
-+ * this function.
-+ */
-+int
-+swiotlb_dma_supported (struct device *hwdev, u64 mask)
-+{
-+      return (mask >= ((1UL << dma_bits) - 1));
-+}
-+
-+EXPORT_SYMBOL(swiotlb_init);
-+EXPORT_SYMBOL(swiotlb_map_single);
-+EXPORT_SYMBOL(swiotlb_unmap_single);
-+EXPORT_SYMBOL(swiotlb_map_sg);
-+EXPORT_SYMBOL(swiotlb_unmap_sg);
-+EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
-+EXPORT_SYMBOL(swiotlb_sync_single_for_device);
-+EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
-+EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
-+EXPORT_SYMBOL(swiotlb_map_page);
-+EXPORT_SYMBOL(swiotlb_unmap_page);
-+EXPORT_SYMBOL(swiotlb_dma_mapping_error);
-+EXPORT_SYMBOL(swiotlb_dma_supported);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/sysenter.c linux-2.6.16.33/arch/i386/kernel/sysenter.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/sysenter.c  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/sysenter.c        2007-01-08 15:00:45.000000000 +0000
-@@ -13,16 +13,22 @@
- #include <linux/gfp.h>
- #include <linux/string.h>
- #include <linux/elf.h>
-+#include <linux/mm.h>
- #include <asm/cpufeature.h>
- #include <asm/msr.h>
- #include <asm/pgtable.h>
- #include <asm/unistd.h>
-+#ifdef CONFIG_XEN
-+#include <xen/interface/callback.h>
-+#endif
-+
- extern asmlinkage void sysenter_entry(void);
- void enable_sep_cpu(void)
- {
-+#ifndef CONFIG_X86_NO_TSS
-       int cpu = get_cpu();
-       struct tss_struct *tss = &per_cpu(init_tss, cpu);
-@@ -37,6 +43,7 @@
-       wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
-       wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
-       put_cpu();      
-+#endif
- }
- /*
-@@ -45,23 +52,100 @@
-  */
- extern const char vsyscall_int80_start, vsyscall_int80_end;
- extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
-+static void *syscall_page;
- int __init sysenter_setup(void)
- {
--      void *page = (void *)get_zeroed_page(GFP_ATOMIC);
-+      syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
--      __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC);
-+#ifdef CONFIG_XEN
-+      if (boot_cpu_has(X86_FEATURE_SEP)) {
-+              static struct callback_register __initdata sysenter = {
-+                      .type = CALLBACKTYPE_sysenter,
-+                      .address = { __KERNEL_CS, (unsigned long)sysenter_entry },
-+              };
--      if (!boot_cpu_has(X86_FEATURE_SEP)) {
--              memcpy(page,
--                     &vsyscall_int80_start,
--                     &vsyscall_int80_end - &vsyscall_int80_start);
-+              if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0)
-+                      clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability);
-+      }
-+#endif
-+
-+      if (boot_cpu_has(X86_FEATURE_SEP)) {
-+              memcpy(syscall_page,
-+                     &vsyscall_sysenter_start,
-+                     &vsyscall_sysenter_end - &vsyscall_sysenter_start);
-               return 0;
-       }
--      memcpy(page,
--             &vsyscall_sysenter_start,
--             &vsyscall_sysenter_end - &vsyscall_sysenter_start);
-+      memcpy(syscall_page,
-+             &vsyscall_int80_start,
-+             &vsyscall_int80_end - &vsyscall_int80_start);
-+
-+      return 0;
-+}
-+
-+static struct page*
-+syscall_nopage(struct vm_area_struct *vma, unsigned long adr, int *type)
-+{
-+      struct page *p = virt_to_page(adr - vma->vm_start + syscall_page);
-+      get_page(p);
-+      return p;
-+}
-+
-+/* Prevent VMA merging */
-+static void syscall_vma_close(struct vm_area_struct *vma)
-+{
-+}
-+
-+static struct vm_operations_struct syscall_vm_ops = {
-+      .close = syscall_vma_close,
-+      .nopage = syscall_nopage,
-+};
-+/* Setup a VMA at program startup for the vsyscall page */
-+int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
-+{
-+      struct vm_area_struct *vma;
-+      struct mm_struct *mm = current->mm;
-+      int ret;
-+
-+      vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-+      if (!vma)
-+              return -ENOMEM;
-+
-+      memset(vma, 0, sizeof(struct vm_area_struct));
-+      /* Could randomize here */
-+      vma->vm_start = VSYSCALL_BASE;
-+      vma->vm_end = VSYSCALL_BASE + PAGE_SIZE;
-+      /* MAYWRITE to allow gdb to COW and set breakpoints */
-+      vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
-+      vma->vm_flags |= mm->def_flags;
-+      vma->vm_page_prot = protection_map[vma->vm_flags & 7];
-+      vma->vm_ops = &syscall_vm_ops;
-+      vma->vm_mm = mm;
-+
-+      down_write(&mm->mmap_sem);
-+      if ((ret = insert_vm_struct(mm, vma))) {
-+              up_write(&mm->mmap_sem);
-+              kmem_cache_free(vm_area_cachep, vma);
-+              return ret;
-+      }
-+      mm->total_vm++;
-+      up_write(&mm->mmap_sem);
-+      return 0;
-+}
-+
-+struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
-+{
-+      return NULL;
-+}
-+
-+int in_gate_area(struct task_struct *task, unsigned long addr)
-+{
-+      return 0;
-+}
-+
-+int in_gate_area_no_task(unsigned long addr)
-+{
-       return 0;
- }
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/time-xen.c linux-2.6.16.33/arch/i386/kernel/time-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/time-xen.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/time-xen.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1121 @@
-+/*
-+ *  linux/arch/i386/kernel/time.c
-+ *
-+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
-+ *
-+ * This file contains the PC-specific time handling details:
-+ * reading the RTC at bootup, etc..
-+ * 1994-07-02    Alan Modra
-+ *    fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
-+ * 1995-03-26    Markus Kuhn
-+ *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
-+ *      precision CMOS clock update
-+ * 1996-05-03    Ingo Molnar
-+ *      fixed time warps in do_[slow|fast]_gettimeoffset()
-+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
-+ *            "A Kernel Model for Precision Timekeeping" by Dave Mills
-+ * 1998-09-05    (Various)
-+ *    More robust do_fast_gettimeoffset() algorithm implemented
-+ *    (works with APM, Cyrix 6x86MX and Centaur C6),
-+ *    monotonic gettimeofday() with fast_get_timeoffset(),
-+ *    drift-proof precision TSC calibration on boot
-+ *    (C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
-+ *    Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
-+ *    ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
-+ * 1998-12-16    Andrea Arcangeli
-+ *    Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
-+ *    because was not accounting lost_ticks.
-+ * 1998-12-24 Copyright (C) 1998  Andrea Arcangeli
-+ *    Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
-+ *    serialize accesses to xtime/lost_ticks).
-+ */
-+
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/param.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/interrupt.h>
-+#include <linux/time.h>
-+#include <linux/delay.h>
-+#include <linux/init.h>
-+#include <linux/smp.h>
-+#include <linux/module.h>
-+#include <linux/sysdev.h>
-+#include <linux/bcd.h>
-+#include <linux/efi.h>
-+#include <linux/mca.h>
-+#include <linux/sysctl.h>
-+#include <linux/percpu.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/posix-timers.h>
-+
-+#include <asm/io.h>
-+#include <asm/smp.h>
-+#include <asm/irq.h>
-+#include <asm/msr.h>
-+#include <asm/delay.h>
-+#include <asm/mpspec.h>
-+#include <asm/uaccess.h>
-+#include <asm/processor.h>
-+#include <asm/timer.h>
-+#include <asm/sections.h>
-+
-+#include "mach_time.h"
-+
-+#include <linux/timex.h>
-+#include <linux/config.h>
-+
-+#include <asm/hpet.h>
-+
-+#include <asm/arch_hooks.h>
-+
-+#include <xen/evtchn.h>
-+#include <xen/interface/vcpu.h>
-+
-+#if defined (__i386__)
-+#include <asm/i8259.h>
-+#endif
-+
-+int pit_latch_buggy;              /* extern */
-+
-+#if defined(__x86_64__)
-+unsigned long vxtime_hz = PIT_TICK_RATE;
-+struct vxtime_data __vxtime __section_vxtime;   /* for vsyscalls */
-+volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
-+unsigned long __wall_jiffies __section_wall_jiffies = INITIAL_JIFFIES;
-+struct timespec __xtime __section_xtime;
-+struct timezone __sys_tz __section_sys_tz;
-+#endif
-+
-+unsigned int cpu_khz; /* Detected as we calibrate the TSC */
-+EXPORT_SYMBOL(cpu_khz);
-+
-+extern unsigned long wall_jiffies;
-+
-+DEFINE_SPINLOCK(rtc_lock);
-+EXPORT_SYMBOL(rtc_lock);
-+
-+#if defined (__i386__)
-+#include <asm/i8253.h>
-+#endif
-+
-+DEFINE_SPINLOCK(i8253_lock);
-+EXPORT_SYMBOL(i8253_lock);
-+
-+extern struct init_timer_opts timer_tsc_init;
-+extern struct timer_opts timer_tsc;
-+#define timer_none timer_tsc
-+struct timer_opts *cur_timer __read_mostly = &timer_tsc;
-+
-+/* These are peridically updated in shared_info, and then copied here. */
-+struct shadow_time_info {
-+      u64 tsc_timestamp;     /* TSC at last update of time vals.  */
-+      u64 system_timestamp;  /* Time, in nanosecs, since boot.    */
-+      u32 tsc_to_nsec_mul;
-+      u32 tsc_to_usec_mul;
-+      int tsc_shift;
-+      u32 version;
-+};
-+static DEFINE_PER_CPU(struct shadow_time_info, shadow_time);
-+static struct timespec shadow_tv;
-+static u32 shadow_tv_version;
-+
-+/* Keep track of last time we did processing/updating of jiffies and xtime. */
-+static u64 processed_system_time;   /* System time (ns) at last processing. */
-+static DEFINE_PER_CPU(u64, processed_system_time);
-+
-+/* How much CPU time was spent blocked and how much was 'stolen'? */
-+static DEFINE_PER_CPU(u64, processed_stolen_time);
-+static DEFINE_PER_CPU(u64, processed_blocked_time);
-+
-+/* Current runstate of each CPU (updated automatically by the hypervisor). */
-+static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate);
-+
-+/* Must be signed, as it's compared with s64 quantities which can be -ve. */
-+#define NS_PER_TICK (1000000000LL/HZ)
-+
-+static inline void __normalize_time(time_t *sec, s64 *nsec)
-+{
-+      while (*nsec >= NSEC_PER_SEC) {
-+              (*nsec) -= NSEC_PER_SEC;
-+              (*sec)++;
-+      }
-+      while (*nsec < 0) {
-+              (*nsec) += NSEC_PER_SEC;
-+              (*sec)--;
-+      }
-+}
-+
-+/* Does this guest OS track Xen time, or set its wall clock independently? */
-+static int independent_wallclock = 0;
-+static int __init __independent_wallclock(char *str)
-+{
-+      independent_wallclock = 1;
-+      return 1;
-+}
-+__setup("independent_wallclock", __independent_wallclock);
-+
-+/* Permitted clock jitter, in nsecs, beyond which a warning will be printed. */
-+static unsigned long permitted_clock_jitter = 10000000UL; /* 10ms */
-+static int __init __permitted_clock_jitter(char *str)
-+{
-+      permitted_clock_jitter = simple_strtoul(str, NULL, 0);
-+      return 1;
-+}
-+__setup("permitted_clock_jitter=", __permitted_clock_jitter);
-+
-+int tsc_disable __devinitdata = 0;
-+
-+static void delay_tsc(unsigned long loops)
-+{
-+      unsigned long bclock, now;
-+
-+      rdtscl(bclock);
-+      do {
-+              rep_nop();
-+              rdtscl(now);
-+      } while ((now - bclock) < loops);
-+}
-+
-+struct timer_opts timer_tsc = {
-+      .name = "tsc",
-+      .delay = delay_tsc,
-+};
-+
-+/*
-+ * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
-+ * yielding a 64-bit result.
-+ */
-+static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
-+{
-+      u64 product;
-+#ifdef __i386__
-+      u32 tmp1, tmp2;
-+#endif
-+
-+      if (shift < 0)
-+              delta >>= -shift;
-+      else
-+              delta <<= shift;
-+
-+#ifdef __i386__
-+      __asm__ (
-+              "mul  %5       ; "
-+              "mov  %4,%%eax ; "
-+              "mov  %%edx,%4 ; "
-+              "mul  %5       ; "
-+              "xor  %5,%5    ; "
-+              "add  %4,%%eax ; "
-+              "adc  %5,%%edx ; "
-+              : "=A" (product), "=r" (tmp1), "=r" (tmp2)
-+              : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
-+#else
-+      __asm__ (
-+              "mul %%rdx ; shrd $32,%%rdx,%%rax"
-+              : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
-+#endif
-+
-+      return product;
-+}
-+
-+#if defined (__i386__)
-+int read_current_timer(unsigned long *timer_val)
-+{
-+      rdtscl(*timer_val);
-+      return 0;
-+}
-+#endif
-+
-+void init_cpu_khz(void)
-+{
-+      u64 __cpu_khz = 1000000ULL << 32;
-+      struct vcpu_time_info *info;
-+      info = &HYPERVISOR_shared_info->vcpu_info[0].time;
-+      do_div(__cpu_khz, info->tsc_to_system_mul);
-+      if (info->tsc_shift < 0)
-+              cpu_khz = __cpu_khz << -info->tsc_shift;
-+      else
-+              cpu_khz = __cpu_khz >> info->tsc_shift;
-+}
-+
-+static u64 get_nsec_offset(struct shadow_time_info *shadow)
-+{
-+      u64 now, delta;
-+      rdtscll(now);
-+      delta = now - shadow->tsc_timestamp;
-+      return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
-+}
-+
-+static unsigned long get_usec_offset(struct shadow_time_info *shadow)
-+{
-+      u64 now, delta;
-+      rdtscll(now);
-+      delta = now - shadow->tsc_timestamp;
-+      return scale_delta(delta, shadow->tsc_to_usec_mul, shadow->tsc_shift);
-+}
-+
-+static void __update_wallclock(time_t sec, long nsec)
-+{
-+      long wtm_nsec, xtime_nsec;
-+      time_t wtm_sec, xtime_sec;
-+      u64 tmp, wc_nsec;
-+
-+      /* Adjust wall-clock time base based on wall_jiffies ticks. */
-+      wc_nsec = processed_system_time;
-+      wc_nsec += sec * (u64)NSEC_PER_SEC;
-+      wc_nsec += nsec;
-+      wc_nsec -= (jiffies - wall_jiffies) * (u64)NS_PER_TICK;
-+
-+      /* Split wallclock base into seconds and nanoseconds. */
-+      tmp = wc_nsec;
-+      xtime_nsec = do_div(tmp, 1000000000);
-+      xtime_sec  = (time_t)tmp;
-+
-+      wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - xtime_sec);
-+      wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - xtime_nsec);
-+
-+      set_normalized_timespec(&xtime, xtime_sec, xtime_nsec);
-+      set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-+
-+      ntp_clear();
-+}
-+
-+static void update_wallclock(void)
-+{
-+      shared_info_t *s = HYPERVISOR_shared_info;
-+
-+      do {
-+              shadow_tv_version = s->wc_version;
-+              rmb();
-+              shadow_tv.tv_sec  = s->wc_sec;
-+              shadow_tv.tv_nsec = s->wc_nsec;
-+              rmb();
-+      } while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
-+
-+      if (!independent_wallclock)
-+              __update_wallclock(shadow_tv.tv_sec, shadow_tv.tv_nsec);
-+}
-+
-+/*
-+ * Reads a consistent set of time-base values from Xen, into a shadow data
-+ * area.
-+ */
-+static void get_time_values_from_xen(void)
-+{
-+      shared_info_t           *s = HYPERVISOR_shared_info;
-+      struct vcpu_time_info   *src;
-+      struct shadow_time_info *dst;
-+
-+      src = &s->vcpu_info[smp_processor_id()].time;
-+      dst = &per_cpu(shadow_time, smp_processor_id());
-+
-+      do {
-+              dst->version = src->version;
-+              rmb();
-+              dst->tsc_timestamp     = src->tsc_timestamp;
-+              dst->system_timestamp  = src->system_time;
-+              dst->tsc_to_nsec_mul   = src->tsc_to_system_mul;
-+              dst->tsc_shift         = src->tsc_shift;
-+              rmb();
-+      } while ((src->version & 1) | (dst->version ^ src->version));
-+
-+      dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000;
-+}
-+
-+static inline int time_values_up_to_date(int cpu)
-+{
-+      struct vcpu_time_info   *src;
-+      struct shadow_time_info *dst;
-+
-+      src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
-+      dst = &per_cpu(shadow_time, cpu);
-+
-+      rmb();
-+      return (dst->version == src->version);
-+}
-+
-+/*
-+ * This is a special lock that is owned by the CPU and holds the index
-+ * register we are working with.  It is required for NMI access to the
-+ * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
-+ */
-+volatile unsigned long cmos_lock = 0;
-+EXPORT_SYMBOL(cmos_lock);
-+
-+/* Routines for accessing the CMOS RAM/RTC. */
-+unsigned char rtc_cmos_read(unsigned char addr)
-+{
-+      unsigned char val;
-+      lock_cmos_prefix(addr);
-+      outb_p(addr, RTC_PORT(0));
-+      val = inb_p(RTC_PORT(1));
-+      lock_cmos_suffix(addr);
-+      return val;
-+}
-+EXPORT_SYMBOL(rtc_cmos_read);
-+
-+void rtc_cmos_write(unsigned char val, unsigned char addr)
-+{
-+      lock_cmos_prefix(addr);
-+      outb_p(addr, RTC_PORT(0));
-+      outb_p(val, RTC_PORT(1));
-+      lock_cmos_suffix(addr);
-+}
-+EXPORT_SYMBOL(rtc_cmos_write);
-+
-+/*
-+ * This version of gettimeofday has microsecond resolution
-+ * and better than microsecond precision on fast x86 machines with TSC.
-+ */
-+void do_gettimeofday(struct timeval *tv)
-+{
-+      unsigned long seq;
-+      unsigned long usec, sec;
-+      unsigned long max_ntp_tick;
-+      s64 nsec;
-+      unsigned int cpu;
-+      struct shadow_time_info *shadow;
-+      u32 local_time_version;
-+
-+      cpu = get_cpu();
-+      shadow = &per_cpu(shadow_time, cpu);
-+
-+      do {
-+              unsigned long lost;
-+
-+              local_time_version = shadow->version;
-+              seq = read_seqbegin(&xtime_lock);
-+
-+              usec = get_usec_offset(shadow);
-+              lost = jiffies - wall_jiffies;
-+
-+              /*
-+               * If time_adjust is negative then NTP is slowing the clock
-+               * so make sure not to go into next possible interval.
-+               * Better to lose some accuracy than have time go backwards..
-+               */
-+              if (unlikely(time_adjust < 0)) {
-+                      max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
-+                      usec = min(usec, max_ntp_tick);
-+
-+                      if (lost)
-+                              usec += lost * max_ntp_tick;
-+              }
-+              else if (unlikely(lost))
-+                      usec += lost * (USEC_PER_SEC / HZ);
-+
-+              sec = xtime.tv_sec;
-+              usec += (xtime.tv_nsec / NSEC_PER_USEC);
-+
-+              nsec = shadow->system_timestamp - processed_system_time;
-+              __normalize_time(&sec, &nsec);
-+              usec += (long)nsec / NSEC_PER_USEC;
-+
-+              if (unlikely(!time_values_up_to_date(cpu))) {
-+                      /*
-+                       * We may have blocked for a long time,
-+                       * rendering our calculations invalid
-+                       * (e.g. the time delta may have
-+                       * overflowed). Detect that and recalculate
-+                       * with fresh values.
-+                       */
-+                      get_time_values_from_xen();
-+                      continue;
-+              }
-+      } while (read_seqretry(&xtime_lock, seq) ||
-+               (local_time_version != shadow->version));
-+
-+      put_cpu();
-+
-+      while (usec >= USEC_PER_SEC) {
-+              usec -= USEC_PER_SEC;
-+              sec++;
-+      }
-+
-+      tv->tv_sec = sec;
-+      tv->tv_usec = usec;
-+}
-+
-+EXPORT_SYMBOL(do_gettimeofday);
-+
-+int do_settimeofday(struct timespec *tv)
-+{
-+      time_t sec;
-+      s64 nsec;
-+      unsigned int cpu;
-+      struct shadow_time_info *shadow;
-+      dom0_op_t op;
-+
-+      if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-+              return -EINVAL;
-+
-+      cpu = get_cpu();
-+      shadow = &per_cpu(shadow_time, cpu);
-+
-+      write_seqlock_irq(&xtime_lock);
-+
-+      /*
-+       * Ensure we don't get blocked for a long time so that our time delta
-+       * overflows. If that were to happen then our shadow time values would
-+       * be stale, so we can retry with fresh ones.
-+       */
-+      for (;;) {
-+              nsec = tv->tv_nsec - get_nsec_offset(shadow);
-+              if (time_values_up_to_date(cpu))
-+                      break;
-+              get_time_values_from_xen();
-+      }
-+      sec = tv->tv_sec;
-+      __normalize_time(&sec, &nsec);
-+
-+      if (is_initial_xendomain() && !independent_wallclock) {
-+              op.cmd = DOM0_SETTIME;
-+              op.u.settime.secs        = sec;
-+              op.u.settime.nsecs       = nsec;
-+              op.u.settime.system_time = shadow->system_timestamp;
-+              HYPERVISOR_dom0_op(&op);
-+              update_wallclock();
-+      } else if (independent_wallclock) {
-+              nsec -= shadow->system_timestamp;
-+              __normalize_time(&sec, &nsec);
-+              __update_wallclock(sec, nsec);
-+      }
-+
-+      write_sequnlock_irq(&xtime_lock);
-+
-+      put_cpu();
-+
-+      clock_was_set();
-+      return 0;
-+}
-+
-+EXPORT_SYMBOL(do_settimeofday);
-+
-+static void sync_xen_wallclock(unsigned long dummy);
-+static DEFINE_TIMER(sync_xen_wallclock_timer, sync_xen_wallclock, 0, 0);
-+static void sync_xen_wallclock(unsigned long dummy)
-+{
-+      time_t sec;
-+      s64 nsec;
-+      dom0_op_t op;
-+
-+      if (!ntp_synced() || independent_wallclock || !is_initial_xendomain())
-+              return;
-+
-+      write_seqlock_irq(&xtime_lock);
-+
-+      sec  = xtime.tv_sec;
-+      nsec = xtime.tv_nsec + ((jiffies - wall_jiffies) * (u64)NS_PER_TICK);
-+      __normalize_time(&sec, &nsec);
-+
-+      op.cmd = DOM0_SETTIME;
-+      op.u.settime.secs        = sec;
-+      op.u.settime.nsecs       = nsec;
-+      op.u.settime.system_time = processed_system_time;
-+      HYPERVISOR_dom0_op(&op);
-+
-+      update_wallclock();
-+
-+      write_sequnlock_irq(&xtime_lock);
-+
-+      /* Once per minute. */
-+      mod_timer(&sync_xen_wallclock_timer, jiffies + 60*HZ);
-+}
-+
-+static int set_rtc_mmss(unsigned long nowtime)
-+{
-+      int retval;
-+
-+      WARN_ON(irqs_disabled());
-+
-+      if (independent_wallclock || !is_initial_xendomain())
-+              return 0;
-+
-+      /* gets recalled with irq locally disabled */
-+      spin_lock_irq(&rtc_lock);
-+      if (efi_enabled)
-+              retval = efi_set_rtc_mmss(nowtime);
-+      else
-+              retval = mach_set_rtc_mmss(nowtime);
-+      spin_unlock_irq(&rtc_lock);
-+
-+      return retval;
-+}
-+
-+/* monotonic_clock(): returns # of nanoseconds passed since time_init()
-+ *            Note: This function is required to return accurate
-+ *            time even in the absence of multiple timer ticks.
-+ */
-+unsigned long long monotonic_clock(void)
-+{
-+      int cpu = get_cpu();
-+      struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
-+      u64 time;
-+      u32 local_time_version;
-+
-+      do {
-+              local_time_version = shadow->version;
-+              barrier();
-+              time = shadow->system_timestamp + get_nsec_offset(shadow);
-+              if (!time_values_up_to_date(cpu))
-+                      get_time_values_from_xen();
-+              barrier();
-+      } while (local_time_version != shadow->version);
-+
-+      put_cpu();
-+
-+      return time;
-+}
-+EXPORT_SYMBOL(monotonic_clock);
-+
-+unsigned long long sched_clock(void)
-+{
-+      return monotonic_clock();
-+}
-+
-+#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
-+unsigned long profile_pc(struct pt_regs *regs)
-+{
-+      unsigned long pc = instruction_pointer(regs);
-+
-+#ifdef __x86_64__
-+      /* Assume the lock function has either no stack frame or only a single word.
-+         This checks if the address on the stack looks like a kernel text address.
-+         There is a small window for false hits, but in that case the tick
-+         is just accounted to the spinlock function.
-+         Better would be to write these functions in assembler again
-+         and check exactly. */
-+      if (in_lock_functions(pc)) {
-+              char *v = *(char **)regs->rsp;
-+              if ((v >= _stext && v <= _etext) ||
-+                      (v >= _sinittext && v <= _einittext) ||
-+                      (v >= (char *)MODULES_VADDR  && v <= (char *)MODULES_END))
-+                      return (unsigned long)v;
-+              return ((unsigned long *)regs->rsp)[1];
-+      }
-+#else
-+      if (in_lock_functions(pc))
-+              return *(unsigned long *)(regs->ebp + 4);
-+#endif
-+
-+      return pc;
-+}
-+EXPORT_SYMBOL(profile_pc);
-+#endif
-+
-+irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      s64 delta, delta_cpu, stolen, blocked;
-+      u64 sched_time;
-+      int i, cpu = smp_processor_id();
-+      struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
-+      struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
-+
-+      write_seqlock(&xtime_lock);
-+
-+      do {
-+              get_time_values_from_xen();
-+
-+              /* Obtain a consistent snapshot of elapsed wallclock cycles. */
-+              delta = delta_cpu =
-+                      shadow->system_timestamp + get_nsec_offset(shadow);
-+              delta     -= processed_system_time;
-+              delta_cpu -= per_cpu(processed_system_time, cpu);
-+
-+              /*
-+               * Obtain a consistent snapshot of stolen/blocked cycles. We
-+               * can use state_entry_time to detect if we get preempted here.
-+               */
-+              do {
-+                      sched_time = runstate->state_entry_time;
-+                      barrier();
-+                      stolen = runstate->time[RUNSTATE_runnable] +
-+                              runstate->time[RUNSTATE_offline] -
-+                              per_cpu(processed_stolen_time, cpu);
-+                      blocked = runstate->time[RUNSTATE_blocked] -
-+                              per_cpu(processed_blocked_time, cpu);
-+                      barrier();
-+              } while (sched_time != runstate->state_entry_time);
-+      } while (!time_values_up_to_date(cpu));
-+
-+      if ((unlikely(delta < -(s64)permitted_clock_jitter) ||
-+           unlikely(delta_cpu < -(s64)permitted_clock_jitter))
-+          && printk_ratelimit()) {
-+              printk("Timer ISR/%d: Time went backwards: "
-+                     "delta=%lld delta_cpu=%lld shadow=%lld "
-+                     "off=%lld processed=%lld cpu_processed=%lld\n",
-+                     cpu, delta, delta_cpu, shadow->system_timestamp,
-+                     (s64)get_nsec_offset(shadow),
-+                     processed_system_time,
-+                     per_cpu(processed_system_time, cpu));
-+              for (i = 0; i < num_online_cpus(); i++)
-+                      printk(" %d: %lld\n", i,
-+                             per_cpu(processed_system_time, i));
-+      }
-+
-+      /* System-wide jiffy work. */
-+      while (delta >= NS_PER_TICK) {
-+              delta -= NS_PER_TICK;
-+              processed_system_time += NS_PER_TICK;
-+              do_timer(regs);
-+      }
-+
-+      if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
-+              update_wallclock();
-+              clock_was_set();
-+      }
-+
-+      write_sequnlock(&xtime_lock);
-+
-+      /*
-+       * Account stolen ticks.
-+       * HACK: Passing NULL to account_steal_time()
-+       * ensures that the ticks are accounted as stolen.
-+       */
-+      if ((stolen > 0) && (delta_cpu > 0)) {
-+              delta_cpu -= stolen;
-+              if (unlikely(delta_cpu < 0))
-+                      stolen += delta_cpu; /* clamp local-time progress */
-+              do_div(stolen, NS_PER_TICK);
-+              per_cpu(processed_stolen_time, cpu) += stolen * NS_PER_TICK;
-+              per_cpu(processed_system_time, cpu) += stolen * NS_PER_TICK;
-+              account_steal_time(NULL, (cputime_t)stolen);
-+      }
-+
-+      /*
-+       * Account blocked ticks.
-+       * HACK: Passing idle_task to account_steal_time()
-+       * ensures that the ticks are accounted as idle/wait.
-+       */
-+      if ((blocked > 0) && (delta_cpu > 0)) {
-+              delta_cpu -= blocked;
-+              if (unlikely(delta_cpu < 0))
-+                      blocked += delta_cpu; /* clamp local-time progress */
-+              do_div(blocked, NS_PER_TICK);
-+              per_cpu(processed_blocked_time, cpu) += blocked * NS_PER_TICK;
-+              per_cpu(processed_system_time, cpu)  += blocked * NS_PER_TICK;
-+              account_steal_time(idle_task(cpu), (cputime_t)blocked);
-+      }
-+
-+      /* Account user/system ticks. */
-+      if (delta_cpu > 0) {
-+              do_div(delta_cpu, NS_PER_TICK);
-+              per_cpu(processed_system_time, cpu) += delta_cpu * NS_PER_TICK;
-+              if (user_mode(regs))
-+                      account_user_time(current, (cputime_t)delta_cpu);
-+              else
-+                      account_system_time(current, HARDIRQ_OFFSET,
-+                                          (cputime_t)delta_cpu);
-+      }
-+
-+      /* Offlined for more than a few seconds? Avoid lockup warnings. */
-+      if (stolen > 5*HZ)
-+              touch_softlockup_watchdog();
-+
-+      /* Local timer processing (see update_process_times()). */
-+      run_local_timers();
-+      if (rcu_pending(cpu))
-+              rcu_check_callbacks(cpu, user_mode(regs));
-+      scheduler_tick();
-+      run_posix_cpu_timers(current);
-+      profile_tick(CPU_PROFILING, regs);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static void init_missing_ticks_accounting(int cpu)
-+{
-+      struct vcpu_register_runstate_memory_area area;
-+      struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu);
-+
-+      memset(runstate, 0, sizeof(*runstate));
-+
-+      area.addr.v = runstate;
-+      HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, cpu, &area);
-+
-+      per_cpu(processed_blocked_time, cpu) =
-+              runstate->time[RUNSTATE_blocked];
-+      per_cpu(processed_stolen_time, cpu) =
-+              runstate->time[RUNSTATE_runnable] +
-+              runstate->time[RUNSTATE_offline];
-+}
-+
-+/* not static: needed by APM */
-+unsigned long get_cmos_time(void)
-+{
-+      unsigned long retval;
-+
-+      spin_lock(&rtc_lock);
-+
-+      if (efi_enabled)
-+              retval = efi_get_time();
-+      else
-+              retval = mach_get_cmos_time();
-+
-+      spin_unlock(&rtc_lock);
-+
-+      return retval;
-+}
-+EXPORT_SYMBOL(get_cmos_time);
-+
-+static void sync_cmos_clock(unsigned long dummy);
-+
-+static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
-+
-+static void sync_cmos_clock(unsigned long dummy)
-+{
-+      struct timeval now, next;
-+      int fail = 1;
-+
-+      /*
-+       * If we have an externally synchronized Linux clock, then update
-+       * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-+       * called as close as possible to 500 ms before the new second starts.
-+       * This code is run on a timer.  If the clock is set, that timer
-+       * may not expire at the correct time.  Thus, we adjust...
-+       */
-+      if (!ntp_synced())
-+              /*
-+               * Not synced, exit, do not restart a timer (if one is
-+               * running, let it run out).
-+               */
-+              return;
-+
-+      do_gettimeofday(&now);
-+      if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
-+          now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2)
-+              fail = set_rtc_mmss(now.tv_sec);
-+
-+      next.tv_usec = USEC_AFTER - now.tv_usec;
-+      if (next.tv_usec <= 0)
-+              next.tv_usec += USEC_PER_SEC;
-+
-+      if (!fail)
-+              next.tv_sec = 659;
-+      else
-+              next.tv_sec = 0;
-+
-+      if (next.tv_usec >= USEC_PER_SEC) {
-+              next.tv_sec++;
-+              next.tv_usec -= USEC_PER_SEC;
-+      }
-+      mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next));
-+}
-+
-+void notify_arch_cmos_timer(void)
-+{
-+      mod_timer(&sync_cmos_timer, jiffies + 1);
-+      mod_timer(&sync_xen_wallclock_timer, jiffies + 1);
-+}
-+
-+static long clock_cmos_diff, sleep_start;
-+
-+static struct timer_opts *last_timer;
-+static int timer_suspend(struct sys_device *dev, pm_message_t state)
-+{
-+      /*
-+       * Estimate time zone so that set_time can update the clock
-+       */
-+      clock_cmos_diff = -get_cmos_time();
-+      clock_cmos_diff += get_seconds();
-+      sleep_start = get_cmos_time();
-+      last_timer = cur_timer;
-+      cur_timer = &timer_none;
-+      if (last_timer->suspend)
-+              last_timer->suspend(state);
-+      return 0;
-+}
-+
-+static int timer_resume(struct sys_device *dev)
-+{
-+      unsigned long flags;
-+      unsigned long sec;
-+      unsigned long sleep_length;
-+
-+#ifdef CONFIG_HPET_TIMER
-+      if (is_hpet_enabled())
-+              hpet_reenable();
-+#endif
-+      sec = get_cmos_time() + clock_cmos_diff;
-+      sleep_length = (get_cmos_time() - sleep_start) * HZ;
-+      write_seqlock_irqsave(&xtime_lock, flags);
-+      xtime.tv_sec = sec;
-+      xtime.tv_nsec = 0;
-+      jiffies_64 += sleep_length;
-+      wall_jiffies += sleep_length;
-+      write_sequnlock_irqrestore(&xtime_lock, flags);
-+      if (last_timer->resume)
-+              last_timer->resume();
-+      cur_timer = last_timer;
-+      last_timer = NULL;
-+      touch_softlockup_watchdog();
-+      return 0;
-+}
-+
-+static struct sysdev_class timer_sysclass = {
-+      .resume = timer_resume,
-+      .suspend = timer_suspend,
-+      set_kset_name("timer"),
-+};
-+
-+
-+/* XXX this driverfs stuff should probably go elsewhere later -john */
-+static struct sys_device device_timer = {
-+      .id     = 0,
-+      .cls    = &timer_sysclass,
-+};
-+
-+static int time_init_device(void)
-+{
-+      int error = sysdev_class_register(&timer_sysclass);
-+      if (!error)
-+              error = sysdev_register(&device_timer);
-+      return error;
-+}
-+
-+device_initcall(time_init_device);
-+
-+#ifdef CONFIG_HPET_TIMER
-+extern void (*late_time_init)(void);
-+/* Duplicate of time_init() below, with hpet_enable part added */
-+static void __init hpet_time_init(void)
-+{
-+      xtime.tv_sec = get_cmos_time();
-+      xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-+      set_normalized_timespec(&wall_to_monotonic,
-+              -xtime.tv_sec, -xtime.tv_nsec);
-+
-+      if ((hpet_enable() >= 0) && hpet_use_timer) {
-+              printk("Using HPET for base-timer\n");
-+      }
-+
-+      cur_timer = select_timer();
-+      printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
-+
-+      time_init_hook();
-+}
-+#endif
-+
-+/* Dynamically-mapped IRQ. */
-+DEFINE_PER_CPU(int, timer_irq);
-+
-+extern void (*late_time_init)(void);
-+static void setup_cpu0_timer_irq(void)
-+{
-+      per_cpu(timer_irq, 0) =
-+              bind_virq_to_irqhandler(
-+                      VIRQ_TIMER,
-+                      0,
-+                      timer_interrupt,
-+                      SA_INTERRUPT,
-+                      "timer0",
-+                      NULL);
-+      BUG_ON(per_cpu(timer_irq, 0) < 0);
-+}
-+
-+void __init time_init(void)
-+{
-+#ifdef CONFIG_HPET_TIMER
-+      if (is_hpet_capable()) {
-+              /*
-+               * HPET initialization needs to do memory-mapped io. So, let
-+               * us do a late initialization after mem_init().
-+               */
-+              late_time_init = hpet_time_init;
-+              return;
-+      }
-+#endif
-+      get_time_values_from_xen();
-+
-+      processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
-+      per_cpu(processed_system_time, 0) = processed_system_time;
-+      init_missing_ticks_accounting(0);
-+
-+      update_wallclock();
-+
-+      init_cpu_khz();
-+      printk(KERN_INFO "Xen reported: %u.%03u MHz processor.\n",
-+             cpu_khz / 1000, cpu_khz % 1000);
-+
-+#if defined(__x86_64__)
-+      vxtime.mode = VXTIME_TSC;
-+      vxtime.quot = (1000000L << 32) / vxtime_hz;
-+      vxtime.tsc_quot = (1000L << 32) / cpu_khz;
-+      sync_core();
-+      rdtscll(vxtime.last_tsc);
-+#endif
-+
-+      /* Cannot request_irq() until kmem is initialised. */
-+      late_time_init = setup_cpu0_timer_irq;
-+}
-+
-+/* Convert jiffies to system time. */
-+u64 jiffies_to_st(unsigned long j)
-+{
-+      unsigned long seq;
-+      long delta;
-+      u64 st;
-+
-+      do {
-+              seq = read_seqbegin(&xtime_lock);
-+              delta = j - jiffies;
-+              if (delta < 1) {
-+                      /* Triggers in some wrap-around cases, but that's okay:
-+                       * we just end up with a shorter timeout. */
-+                      st = processed_system_time + NS_PER_TICK;
-+              } else if (((unsigned long)delta >> (BITS_PER_LONG-3)) != 0) {
-+                      /* Very long timeout means there is no pending timer.
-+                       * We indicate this to Xen by passing zero timeout. */
-+                      st = 0;
-+              } else {
-+                      st = processed_system_time + delta * (u64)NS_PER_TICK;
-+              }
-+      } while (read_seqretry(&xtime_lock, seq));
-+
-+      return st;
-+}
-+EXPORT_SYMBOL(jiffies_to_st);
-+
-+/*
-+ * stop_hz_timer / start_hz_timer - enter/exit 'tickless mode' on an idle cpu
-+ * These functions are based on implementations from arch/s390/kernel/time.c
-+ */
-+static void stop_hz_timer(void)
-+{
-+      unsigned int cpu = smp_processor_id();
-+      unsigned long j;
-+
-+      cpu_set(cpu, nohz_cpu_mask);
-+
-+      /* See matching smp_mb in rcu_start_batch in rcupdate.c.  These mbs  */
-+      /* ensure that if __rcu_pending (nested in rcu_needs_cpu) fetches a  */
-+      /* value of rcp->cur that matches rdp->quiescbatch and allows us to  */
-+      /* stop the hz timer then the cpumasks created for subsequent values */
-+      /* of cur in rcu_start_batch are guaranteed to pick up the updated   */
-+      /* nohz_cpu_mask and so will not depend on this cpu.                 */
-+
-+      smp_mb();
-+
-+      /* Leave ourselves in tick mode if rcu or softirq or timer pending. */
-+      if (rcu_needs_cpu(cpu) || local_softirq_pending() ||
-+          (j = next_timer_interrupt(), time_before_eq(j, jiffies))) {
-+              cpu_clear(cpu, nohz_cpu_mask);
-+              j = jiffies + 1;
-+      }
-+
-+      if (HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0)
-+              BUG();
-+}
-+
-+static void start_hz_timer(void)
-+{
-+      cpu_clear(smp_processor_id(), nohz_cpu_mask);
-+}
-+
-+void safe_halt(void)
-+{
-+      stop_hz_timer();
-+      /* Blocking includes an implicit local_irq_enable(). */
-+      HYPERVISOR_block();
-+      start_hz_timer();
-+}
-+EXPORT_SYMBOL(safe_halt);
-+
-+void halt(void)
-+{
-+      if (irqs_disabled())
-+              HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
-+}
-+EXPORT_SYMBOL(halt);
-+
-+/* No locking required. We are only CPU running, and interrupts are off. */
-+void time_resume(void)
-+{
-+      init_cpu_khz();
-+
-+      get_time_values_from_xen();
-+
-+      processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
-+      per_cpu(processed_system_time, 0) = processed_system_time;
-+      init_missing_ticks_accounting(0);
-+
-+      update_wallclock();
-+}
-+
-+#ifdef CONFIG_SMP
-+static char timer_name[NR_CPUS][15];
-+
-+int local_setup_timer(unsigned int cpu)
-+{
-+      int seq, irq;
-+
-+      BUG_ON(cpu == 0);
-+
-+      do {
-+              seq = read_seqbegin(&xtime_lock);
-+              /* Use cpu0 timestamp: cpu's shadow is not initialised yet. */
-+              per_cpu(processed_system_time, cpu) =
-+                      per_cpu(shadow_time, 0).system_timestamp;
-+              init_missing_ticks_accounting(cpu);
-+      } while (read_seqretry(&xtime_lock, seq));
-+
-+      sprintf(timer_name[cpu], "timer%d", cpu);
-+      irq = bind_virq_to_irqhandler(VIRQ_TIMER,
-+                                    cpu,
-+                                    timer_interrupt,
-+                                    SA_INTERRUPT,
-+                                    timer_name[cpu],
-+                                    NULL);
-+      if (irq < 0)
-+              return irq;
-+      per_cpu(timer_irq, cpu) = irq;
-+
-+      return 0;
-+}
-+
-+void local_teardown_timer(unsigned int cpu)
-+{
-+      BUG_ON(cpu == 0);
-+      unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
-+}
-+#endif
-+
-+/*
-+ * /proc/sys/xen: This really belongs in another file. It can stay here for
-+ * now however.
-+ */
-+static ctl_table xen_subtable[] = {
-+      {
-+              .ctl_name       = 1,
-+              .procname       = "independent_wallclock",
-+              .data           = &independent_wallclock,
-+              .maxlen         = sizeof(independent_wallclock),
-+              .mode           = 0644,
-+              .proc_handler   = proc_dointvec
-+      },
-+      {
-+              .ctl_name       = 2,
-+              .procname       = "permitted_clock_jitter",
-+              .data           = &permitted_clock_jitter,
-+              .maxlen         = sizeof(permitted_clock_jitter),
-+              .mode           = 0644,
-+              .proc_handler   = proc_doulongvec_minmax
-+      },
-+      { 0 }
-+};
-+static ctl_table xen_table[] = {
-+      {
-+              .ctl_name       = 123,
-+              .procname       = "xen",
-+              .mode           = 0555,
-+              .child          = xen_subtable},
-+      { 0 }
-+};
-+static int __init xen_sysctl_init(void)
-+{
-+      (void)register_sysctl_table(xen_table, 0);
-+      return 0;
-+}
-+__initcall(xen_sysctl_init);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/traps-xen.c linux-2.6.16.33/arch/i386/kernel/traps-xen.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/traps-xen.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/traps-xen.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1094 @@
-+/*
-+ *  linux/arch/i386/traps.c
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ *
-+ *  Pentium III FXSR, SSE support
-+ *    Gareth Hughes <gareth@valinux.com>, May 2000
-+ */
-+
-+/*
-+ * 'Traps.c' handles hardware traps and faults after we have saved some
-+ * state in 'asm.s'.
-+ */
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/timer.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/spinlock.h>
-+#include <linux/interrupt.h>
-+#include <linux/highmem.h>
-+#include <linux/kallsyms.h>
-+#include <linux/ptrace.h>
-+#include <linux/utsname.h>
-+#include <linux/kprobes.h>
-+#include <linux/kexec.h>
-+
-+#ifdef CONFIG_EISA
-+#include <linux/ioport.h>
-+#include <linux/eisa.h>
-+#endif
-+
-+#ifdef CONFIG_MCA
-+#include <linux/mca.h>
-+#endif
-+
-+#include <asm/processor.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <asm/atomic.h>
-+#include <asm/debugreg.h>
-+#include <asm/desc.h>
-+#include <asm/i387.h>
-+#include <asm/nmi.h>
-+
-+#include <asm/smp.h>
-+#include <asm/arch_hooks.h>
-+#include <asm/kdebug.h>
-+
-+#include <linux/module.h>
-+
-+#include "mach_traps.h"
-+
-+asmlinkage int system_call(void);
-+
-+struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
-+              { 0, 0 }, { 0, 0 } };
-+
-+/* Do we ignore FPU interrupts ? */
-+char ignore_fpu_irq = 0;
-+
-+#ifndef CONFIG_X86_NO_IDT
-+/*
-+ * The IDT has to be page-aligned to simplify the Pentium
-+ * F0 0F bug workaround.. We have a special link segment
-+ * for this.
-+ */
-+struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
-+#endif
-+
-+asmlinkage void divide_error(void);
-+asmlinkage void debug(void);
-+asmlinkage void nmi(void);
-+asmlinkage void int3(void);
-+asmlinkage void overflow(void);
-+asmlinkage void bounds(void);
-+asmlinkage void invalid_op(void);
-+asmlinkage void device_not_available(void);
-+asmlinkage void coprocessor_segment_overrun(void);
-+asmlinkage void invalid_TSS(void);
-+asmlinkage void segment_not_present(void);
-+asmlinkage void stack_segment(void);
-+asmlinkage void general_protection(void);
-+asmlinkage void page_fault(void);
-+asmlinkage void coprocessor_error(void);
-+asmlinkage void simd_coprocessor_error(void);
-+asmlinkage void alignment_check(void);
-+#ifndef CONFIG_XEN
-+asmlinkage void spurious_interrupt_bug(void);
-+#else
-+asmlinkage void fixup_4gb_segment(void);
-+#endif
-+asmlinkage void machine_check(void);
-+
-+static int kstack_depth_to_print = 24;
-+struct notifier_block *i386die_chain;
-+static DEFINE_SPINLOCK(die_notifier_lock);
-+
-+int register_die_notifier(struct notifier_block *nb)
-+{
-+      int err = 0;
-+      unsigned long flags;
-+      spin_lock_irqsave(&die_notifier_lock, flags);
-+      err = notifier_chain_register(&i386die_chain, nb);
-+      spin_unlock_irqrestore(&die_notifier_lock, flags);
-+      return err;
-+}
-+EXPORT_SYMBOL(register_die_notifier);
-+
-+static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
-+{
-+      return  p > (void *)tinfo &&
-+              p < (void *)tinfo + THREAD_SIZE - 3;
-+}
-+
-+static void print_addr_and_symbol(unsigned long addr, char *log_lvl)
-+{
-+      printk(log_lvl);
-+      printk(" [<%08lx>] ", addr);
-+      print_symbol("%s", addr);
-+      printk("\n");
-+}
-+
-+static inline unsigned long print_context_stack(struct thread_info *tinfo,
-+                              unsigned long *stack, unsigned long ebp,
-+                              char *log_lvl)
-+{
-+      unsigned long addr;
-+
-+#ifdef        CONFIG_FRAME_POINTER
-+      while (valid_stack_ptr(tinfo, (void *)ebp)) {
-+              addr = *(unsigned long *)(ebp + 4);
-+              print_addr_and_symbol(addr, log_lvl);
-+              ebp = *(unsigned long *)ebp;
-+      }
-+#else
-+      while (valid_stack_ptr(tinfo, stack)) {
-+              addr = *stack++;
-+              if (__kernel_text_address(addr))
-+                      print_addr_and_symbol(addr, log_lvl);
-+      }
-+#endif
-+      return ebp;
-+}
-+
-+static void show_trace_log_lvl(struct task_struct *task,
-+                             unsigned long *stack, char *log_lvl)
-+{
-+      unsigned long ebp;
-+
-+      if (!task)
-+              task = current;
-+
-+      if (task == current) {
-+              /* Grab ebp right from our regs */
-+              asm ("movl %%ebp, %0" : "=r" (ebp) : );
-+      } else {
-+              /* ebp is the last reg pushed by switch_to */
-+              ebp = *(unsigned long *) task->thread.esp;
-+      }
-+
-+      while (1) {
-+              struct thread_info *context;
-+              context = (struct thread_info *)
-+                      ((unsigned long)stack & (~(THREAD_SIZE - 1)));
-+              ebp = print_context_stack(context, stack, ebp, log_lvl);
-+              stack = (unsigned long*)context->previous_esp;
-+              if (!stack)
-+                      break;
-+              printk(log_lvl);
-+              printk(" =======================\n");
-+      }
-+}
-+
-+void show_trace(struct task_struct *task, unsigned long * stack)
-+{
-+      show_trace_log_lvl(task, stack, "");
-+}
-+
-+static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp,
-+                             char *log_lvl)
-+{
-+      unsigned long *stack;
-+      int i;
-+
-+      if (esp == NULL) {
-+              if (task)
-+                      esp = (unsigned long*)task->thread.esp;
-+              else
-+                      esp = (unsigned long *)&esp;
-+      }
-+
-+      stack = esp;
-+      printk(log_lvl);
-+      for(i = 0; i < kstack_depth_to_print; i++) {
-+              if (kstack_end(stack))
-+                      break;
-+              if (i && ((i % 8) == 0)) {
-+                      printk("\n");
-+                      printk(log_lvl);
-+                      printk("       ");
-+              }
-+              printk("%08lx ", *stack++);
-+      }
-+      printk("\n");
-+      printk(log_lvl);
-+      printk("Call Trace:\n");
-+      show_trace_log_lvl(task, esp, log_lvl);
-+}
-+
-+void show_stack(struct task_struct *task, unsigned long *esp)
-+{
-+      show_stack_log_lvl(task, esp, "");
-+}
-+
-+/*
-+ * The architecture-independent dump_stack generator
-+ */
-+void dump_stack(void)
-+{
-+      unsigned long stack;
-+
-+      show_trace(current, &stack);
-+}
-+
-+EXPORT_SYMBOL(dump_stack);
-+
-+void show_registers(struct pt_regs *regs)
-+{
-+      int i;
-+      int in_kernel = 1;
-+      unsigned long esp;
-+      unsigned short ss;
-+
-+      esp = (unsigned long) (&regs->esp);
-+      savesegment(ss, ss);
-+      if (user_mode(regs)) {
-+              in_kernel = 0;
-+              esp = regs->esp;
-+              ss = regs->xss & 0xffff;
-+      }
-+      print_modules();
-+      printk(KERN_EMERG "CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\n"
-+                      "EFLAGS: %08lx   (%s %.*s) \n",
-+              smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-+              print_tainted(), regs->eflags, system_utsname.release,
-+              (int)strcspn(system_utsname.version, " "),
-+              system_utsname.version);
-+      print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
-+      printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
-+              regs->eax, regs->ebx, regs->ecx, regs->edx);
-+      printk(KERN_EMERG "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
-+              regs->esi, regs->edi, regs->ebp, esp);
-+      printk(KERN_EMERG "ds: %04x   es: %04x   ss: %04x\n",
-+              regs->xds & 0xffff, regs->xes & 0xffff, ss);
-+      printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)",
-+              current->comm, current->pid, current_thread_info(), current);
-+      /*
-+       * When in-kernel, we also print out the stack and code at the
-+       * time of the fault..
-+       */
-+      if (in_kernel) {
-+              u8 __user *eip;
-+
-+              printk("\n" KERN_EMERG "Stack: ");
-+              show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG);
-+
-+              printk(KERN_EMERG "Code: ");
-+
-+              eip = (u8 __user *)regs->eip - 43;
-+              for (i = 0; i < 64; i++, eip++) {
-+                      unsigned char c;
-+
-+                      if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
-+                              printk(" Bad EIP value.");
-+                              break;
-+                      }
-+                      if (eip == (u8 __user *)regs->eip)
-+                              printk("<%02x> ", c);
-+                      else
-+                              printk("%02x ", c);
-+              }
-+      }
-+      printk("\n");
-+}     
-+
-+static void handle_BUG(struct pt_regs *regs)
-+{
-+      unsigned short ud2;
-+      unsigned short line;
-+      char *file;
-+      char c;
-+      unsigned long eip;
-+
-+      eip = regs->eip;
-+
-+      if (eip < PAGE_OFFSET)
-+              goto no_bug;
-+      if (__get_user(ud2, (unsigned short __user *)eip))
-+              goto no_bug;
-+      if (ud2 != 0x0b0f)
-+              goto no_bug;
-+      if (__get_user(line, (unsigned short __user *)(eip + 2)))
-+              goto bug;
-+      if (__get_user(file, (char * __user *)(eip + 4)) ||
-+              (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
-+              file = "<bad filename>";
-+
-+      printk(KERN_EMERG "------------[ cut here ]------------\n");
-+      printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
-+
-+no_bug:
-+      return;
-+
-+      /* Here we know it was a BUG but file-n-line is unavailable */
-+bug:
-+      printk(KERN_EMERG "Kernel BUG\n");
-+}
-+
-+/* This is gone through when something in the kernel
-+ * has done something bad and is about to be terminated.
-+*/
-+void die(const char * str, struct pt_regs * regs, long err)
-+{
-+      static struct {
-+              spinlock_t lock;
-+              u32 lock_owner;
-+              int lock_owner_depth;
-+      } die = {
-+              .lock =                 SPIN_LOCK_UNLOCKED,
-+              .lock_owner =           -1,
-+              .lock_owner_depth =     0
-+      };
-+      static int die_counter;
-+      unsigned long flags;
-+
-+      if (die.lock_owner != raw_smp_processor_id()) {
-+              console_verbose();
-+              spin_lock_irqsave(&die.lock, flags);
-+              die.lock_owner = smp_processor_id();
-+              die.lock_owner_depth = 0;
-+              bust_spinlocks(1);
-+      }
-+      else
-+              local_save_flags(flags);
-+
-+      if (++die.lock_owner_depth < 3) {
-+              int nl = 0;
-+              handle_BUG(regs);
-+              printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
-+#ifdef CONFIG_PREEMPT
-+              printk(KERN_EMERG "PREEMPT ");
-+              nl = 1;
-+#endif
-+#ifdef CONFIG_SMP
-+              if (!nl)
-+                      printk(KERN_EMERG);
-+              printk("SMP ");
-+              nl = 1;
-+#endif
-+#ifdef CONFIG_DEBUG_PAGEALLOC
-+              if (!nl)
-+                      printk(KERN_EMERG);
-+              printk("DEBUG_PAGEALLOC");
-+              nl = 1;
-+#endif
-+              if (nl)
-+                      printk("\n");
-+      notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
-+              show_registers(regs);
-+      } else
-+              printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
-+
-+      bust_spinlocks(0);
-+      die.lock_owner = -1;
-+      spin_unlock_irqrestore(&die.lock, flags);
-+
-+      if (kexec_should_crash(current))
-+              crash_kexec(regs);
-+
-+      if (in_interrupt())
-+              panic("Fatal exception in interrupt");
-+
-+      if (panic_on_oops) {
-+              printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
-+              ssleep(5);
-+              panic("Fatal exception");
-+      }
-+      do_exit(SIGSEGV);
-+}
-+
-+static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
-+{
-+      if (!user_mode_vm(regs))
-+              die(str, regs, err);
-+}
-+
-+static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86,
-+                            struct pt_regs * regs, long error_code,
-+                            siginfo_t *info)
-+{
-+      struct task_struct *tsk = current;
-+      tsk->thread.error_code = error_code;
-+      tsk->thread.trap_no = trapnr;
-+
-+      if (regs->eflags & VM_MASK) {
-+              if (vm86)
-+                      goto vm86_trap;
-+              goto trap_signal;
-+      }
-+
-+      if (!user_mode(regs))
-+              goto kernel_trap;
-+
-+      trap_signal: {
-+              if (info)
-+                      force_sig_info(signr, info, tsk);
-+              else
-+                      force_sig(signr, tsk);
-+              return;
-+      }
-+
-+      kernel_trap: {
-+              if (!fixup_exception(regs))
-+                      die(str, regs, error_code);
-+              return;
-+      }
-+
-+      vm86_trap: {
-+              int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr);
-+              if (ret) goto trap_signal;
-+              return;
-+      }
-+}
-+
-+#define DO_ERROR(trapnr, signr, str, name) \
-+fastcall void do_##name(struct pt_regs * regs, long error_code) \
-+{ \
-+      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-+                                              == NOTIFY_STOP) \
-+              return; \
-+      do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
-+}
-+
-+#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
-+fastcall void do_##name(struct pt_regs * regs, long error_code) \
-+{ \
-+      siginfo_t info; \
-+      info.si_signo = signr; \
-+      info.si_errno = 0; \
-+      info.si_code = sicode; \
-+      info.si_addr = (void __user *)siaddr; \
-+      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-+                                              == NOTIFY_STOP) \
-+              return; \
-+      do_trap(trapnr, signr, str, 0, regs, error_code, &info); \
-+}
-+
-+#define DO_VM86_ERROR(trapnr, signr, str, name) \
-+fastcall void do_##name(struct pt_regs * regs, long error_code) \
-+{ \
-+      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-+                                              == NOTIFY_STOP) \
-+              return; \
-+      do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
-+}
-+
-+#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
-+fastcall void do_##name(struct pt_regs * regs, long error_code) \
-+{ \
-+      siginfo_t info; \
-+      info.si_signo = signr; \
-+      info.si_errno = 0; \
-+      info.si_code = sicode; \
-+      info.si_addr = (void __user *)siaddr; \
-+      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-+                                              == NOTIFY_STOP) \
-+              return; \
-+      do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
-+}
-+
-+DO_VM86_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->eip)
-+#ifndef CONFIG_KPROBES
-+DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
-+#endif
-+DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
-+DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
-+DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip)
-+DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
-+DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
-+DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
-+DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
-+DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
-+DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
-+
-+fastcall void __kprobes do_general_protection(struct pt_regs * regs,
-+                                            long error_code)
-+{
-+      current->thread.error_code = error_code;
-+      current->thread.trap_no = 13;
-+
-+      if (regs->eflags & VM_MASK)
-+              goto gp_in_vm86;
-+
-+      if (!user_mode(regs))
-+              goto gp_in_kernel;
-+
-+      current->thread.error_code = error_code;
-+      current->thread.trap_no = 13;
-+      force_sig(SIGSEGV, current);
-+      return;
-+
-+gp_in_vm86:
-+      local_irq_enable();
-+      handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
-+      return;
-+
-+gp_in_kernel:
-+      if (!fixup_exception(regs)) {
-+              if (notify_die(DIE_GPF, "general protection fault", regs,
-+                              error_code, 13, SIGSEGV) == NOTIFY_STOP)
-+                      return;
-+              die("general protection fault", regs, error_code);
-+      }
-+}
-+
-+static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
-+{
-+      printk(KERN_EMERG "Uhhuh. NMI received. Dazed and confused, but trying "
-+                      "to continue\n");
-+      printk(KERN_EMERG "You probably have a hardware problem with your RAM "
-+                      "chips\n");
-+
-+      /* Clear and disable the memory parity error line. */
-+      clear_mem_error(reason);
-+}
-+
-+static void io_check_error(unsigned char reason, struct pt_regs * regs)
-+{
-+      printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
-+      show_registers(regs);
-+
-+      /* Re-enable the IOCK line, wait for a few seconds */
-+      clear_io_check_error(reason);
-+}
-+
-+static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
-+{
-+#ifdef CONFIG_MCA
-+      /* Might actually be able to figure out what the guilty party
-+      * is. */
-+      if( MCA_bus ) {
-+              mca_handle_nmi();
-+              return;
-+      }
-+#endif
-+      printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
-+              reason, smp_processor_id());
-+      printk("Dazed and confused, but trying to continue\n");
-+      printk("Do you have a strange power saving mode enabled?\n");
-+}
-+
-+static DEFINE_SPINLOCK(nmi_print_lock);
-+
-+void die_nmi (struct pt_regs *regs, const char *msg)
-+{
-+      if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) ==
-+          NOTIFY_STOP)
-+              return;
-+
-+      spin_lock(&nmi_print_lock);
-+      /*
-+      * We are in trouble anyway, lets at least try
-+      * to get a message out.
-+      */
-+      bust_spinlocks(1);
-+      printk(KERN_EMERG "%s", msg);
-+      printk(" on CPU%d, eip %08lx, registers:\n",
-+              smp_processor_id(), regs->eip);
-+      show_registers(regs);
-+      printk(KERN_EMERG "console shuts up ...\n");
-+      console_silent();
-+      spin_unlock(&nmi_print_lock);
-+      bust_spinlocks(0);
-+
-+      /* If we are in kernel we are probably nested up pretty bad
-+       * and might aswell get out now while we still can.
-+      */
-+      if (!user_mode(regs)) {
-+              current->thread.trap_no = 2;
-+              crash_kexec(regs);
-+      }
-+
-+      do_exit(SIGSEGV);
-+}
-+
-+static void default_do_nmi(struct pt_regs * regs)
-+{
-+      unsigned char reason = 0;
-+
-+      /* Only the BSP gets external NMIs from the system.  */
-+      if (!smp_processor_id())
-+              reason = get_nmi_reason();
-+ 
-+      if (!(reason & 0xc0)) {
-+              if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
-+                                                      == NOTIFY_STOP)
-+                      return;
-+#ifdef CONFIG_X86_LOCAL_APIC
-+              /*
-+               * Ok, so this is none of the documented NMI sources,
-+               * so it must be the NMI watchdog.
-+               */
-+              if (nmi_watchdog) {
-+                      nmi_watchdog_tick(regs);
-+                      return;
-+              }
-+#endif
-+              unknown_nmi_error(reason, regs);
-+              return;
-+      }
-+      if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP)
-+              return;
-+      if (reason & 0x80)
-+              mem_parity_error(reason, regs);
-+      if (reason & 0x40)
-+              io_check_error(reason, regs);
-+      /*
-+       * Reassert NMI in case it became active meanwhile
-+       * as it's edge-triggered.
-+       */
-+      reassert_nmi();
-+}
-+
-+static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
-+{
-+      return 0;
-+}
-+ 
-+static nmi_callback_t nmi_callback = dummy_nmi_callback;
-+ 
-+fastcall void do_nmi(struct pt_regs * regs, long error_code)
-+{
-+      int cpu;
-+
-+      nmi_enter();
-+
-+      cpu = smp_processor_id();
-+
-+      ++nmi_count(cpu);
-+
-+      if (!rcu_dereference(nmi_callback)(regs, cpu))
-+              default_do_nmi(regs);
-+
-+      nmi_exit();
-+}
-+
-+void set_nmi_callback(nmi_callback_t callback)
-+{
-+      rcu_assign_pointer(nmi_callback, callback);
-+}
-+EXPORT_SYMBOL_GPL(set_nmi_callback);
-+
-+void unset_nmi_callback(void)
-+{
-+      nmi_callback = dummy_nmi_callback;
-+}
-+EXPORT_SYMBOL_GPL(unset_nmi_callback);
-+
-+#ifdef CONFIG_KPROBES
-+fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
-+{
-+      if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
-+                      == NOTIFY_STOP)
-+              return;
-+      /* This is an interrupt gate, because kprobes wants interrupts
-+      disabled.  Normal trap handlers don't. */
-+      restore_interrupts(regs);
-+      do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
-+}
-+#endif
-+
-+/*
-+ * Our handling of the processor debug registers is non-trivial.
-+ * We do not clear them on entry and exit from the kernel. Therefore
-+ * it is possible to get a watchpoint trap here from inside the kernel.
-+ * However, the code in ./ptrace.c has ensured that the user can
-+ * only set watchpoints on userspace addresses. Therefore the in-kernel
-+ * watchpoint trap can only occur in code which is reading/writing
-+ * from user space. Such code must not hold kernel locks (since it
-+ * can equally take a page fault), therefore it is safe to call
-+ * force_sig_info even though that claims and releases locks.
-+ * 
-+ * Code in ./signal.c ensures that the debug control register
-+ * is restored before we deliver any signal, and therefore that
-+ * user code runs with the correct debug control register even though
-+ * we clear it here.
-+ *
-+ * Being careful here means that we don't have to be as careful in a
-+ * lot of more complicated places (task switching can be a bit lazy
-+ * about restoring all the debug state, and ptrace doesn't have to
-+ * find every occurrence of the TF bit that could be saved away even
-+ * by user code)
-+ */
-+fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
-+{
-+      unsigned int condition;
-+      struct task_struct *tsk = current;
-+
-+      get_debugreg(condition, 6);
-+
-+      if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
-+                                      SIGTRAP) == NOTIFY_STOP)
-+              return;
-+      /* It's safe to allow irq's after DR6 has been saved */
-+      if (regs->eflags & X86_EFLAGS_IF)
-+              local_irq_enable();
-+
-+      /* Mask out spurious debug traps due to lazy DR7 setting */
-+      if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
-+              if (!tsk->thread.debugreg[7])
-+                      goto clear_dr7;
-+      }
-+
-+      if (regs->eflags & VM_MASK)
-+              goto debug_vm86;
-+
-+      /* Save debug status register where ptrace can see it */
-+      tsk->thread.debugreg[6] = condition;
-+
-+      /*
-+       * Single-stepping through TF: make sure we ignore any events in
-+       * kernel space (but re-enable TF when returning to user mode).
-+       */
-+      if (condition & DR_STEP) {
-+              /*
-+               * We already checked v86 mode above, so we can
-+               * check for kernel mode by just checking the CPL
-+               * of CS.
-+               */
-+              if (!user_mode(regs))
-+                      goto clear_TF_reenable;
-+      }
-+
-+      /* Ok, finally something we can handle */
-+      send_sigtrap(tsk, regs, error_code);
-+
-+      /* Disable additional traps. They'll be re-enabled when
-+       * the signal is delivered.
-+       */
-+clear_dr7:
-+      set_debugreg(0, 7);
-+      return;
-+
-+debug_vm86:
-+      handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
-+      return;
-+
-+clear_TF_reenable:
-+      set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
-+      regs->eflags &= ~TF_MASK;
-+      return;
-+}
-+
-+/*
-+ * Note that we play around with the 'TS' bit in an attempt to get
-+ * the correct behaviour even in the presence of the asynchronous
-+ * IRQ13 behaviour
-+ */
-+void math_error(void __user *eip)
-+{
-+      struct task_struct * task;
-+      siginfo_t info;
-+      unsigned short cwd, swd;
-+
-+      /*
-+       * Save the info for the exception handler and clear the error.
-+       */
-+      task = current;
-+      save_init_fpu(task);
-+      task->thread.trap_no = 16;
-+      task->thread.error_code = 0;
-+      info.si_signo = SIGFPE;
-+      info.si_errno = 0;
-+      info.si_code = __SI_FAULT;
-+      info.si_addr = eip;
-+      /*
-+       * (~cwd & swd) will mask out exceptions that are not set to unmasked
-+       * status.  0x3f is the exception bits in these regs, 0x200 is the
-+       * C1 reg you need in case of a stack fault, 0x040 is the stack
-+       * fault bit.  We should only be taking one exception at a time,
-+       * so if this combination doesn't produce any single exception,
-+       * then we have a bad program that isn't syncronizing its FPU usage
-+       * and it will suffer the consequences since we won't be able to
-+       * fully reproduce the context of the exception
-+       */
-+      cwd = get_fpu_cwd(task);
-+      swd = get_fpu_swd(task);
-+      switch (swd & ~cwd & 0x3f) {
-+              case 0x000: /* No unmasked exception */
-+                      return;
-+              default:    /* Multiple exceptions */
-+                      break;
-+              case 0x001: /* Invalid Op */
-+                      /*
-+                       * swd & 0x240 == 0x040: Stack Underflow
-+                       * swd & 0x240 == 0x240: Stack Overflow
-+                       * User must clear the SF bit (0x40) if set
-+                       */
-+                      info.si_code = FPE_FLTINV;
-+                      break;
-+              case 0x002: /* Denormalize */
-+              case 0x010: /* Underflow */
-+                      info.si_code = FPE_FLTUND;
-+                      break;
-+              case 0x004: /* Zero Divide */
-+                      info.si_code = FPE_FLTDIV;
-+                      break;
-+              case 0x008: /* Overflow */
-+                      info.si_code = FPE_FLTOVF;
-+                      break;
-+              case 0x020: /* Precision */
-+                      info.si_code = FPE_FLTRES;
-+                      break;
-+      }
-+      force_sig_info(SIGFPE, &info, task);
-+}
-+
-+fastcall void do_coprocessor_error(struct pt_regs * regs, long error_code)
-+{
-+      ignore_fpu_irq = 1;
-+      math_error((void __user *)regs->eip);
-+}
-+
-+static void simd_math_error(void __user *eip)
-+{
-+      struct task_struct * task;
-+      siginfo_t info;
-+      unsigned short mxcsr;
-+
-+      /*
-+       * Save the info for the exception handler and clear the error.
-+       */
-+      task = current;
-+      save_init_fpu(task);
-+      task->thread.trap_no = 19;
-+      task->thread.error_code = 0;
-+      info.si_signo = SIGFPE;
-+      info.si_errno = 0;
-+      info.si_code = __SI_FAULT;
-+      info.si_addr = eip;
-+      /*
-+       * The SIMD FPU exceptions are handled a little differently, as there
-+       * is only a single status/control register.  Thus, to determine which
-+       * unmasked exception was caught we must mask the exception mask bits
-+       * at 0x1f80, and then use these to mask the exception bits at 0x3f.
-+       */
-+      mxcsr = get_fpu_mxcsr(task);
-+      switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
-+              case 0x000:
-+              default:
-+                      break;
-+              case 0x001: /* Invalid Op */
-+                      info.si_code = FPE_FLTINV;
-+                      break;
-+              case 0x002: /* Denormalize */
-+              case 0x010: /* Underflow */
-+                      info.si_code = FPE_FLTUND;
-+                      break;
-+              case 0x004: /* Zero Divide */
-+                      info.si_code = FPE_FLTDIV;
-+                      break;
-+              case 0x008: /* Overflow */
-+                      info.si_code = FPE_FLTOVF;
-+                      break;
-+              case 0x020: /* Precision */
-+                      info.si_code = FPE_FLTRES;
-+                      break;
-+      }
-+      force_sig_info(SIGFPE, &info, task);
-+}
-+
-+fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
-+                                        long error_code)
-+{
-+      if (cpu_has_xmm) {
-+              /* Handle SIMD FPU exceptions on PIII+ processors. */
-+              ignore_fpu_irq = 1;
-+              simd_math_error((void __user *)regs->eip);
-+      } else {
-+              /*
-+               * Handle strange cache flush from user space exception
-+               * in all other cases.  This is undocumented behaviour.
-+               */
-+              if (regs->eflags & VM_MASK) {
-+                      handle_vm86_fault((struct kernel_vm86_regs *)regs,
-+                                        error_code);
-+                      return;
-+              }
-+              current->thread.trap_no = 19;
-+              current->thread.error_code = error_code;
-+              die_if_kernel("cache flush denied", regs, error_code);
-+              force_sig(SIGSEGV, current);
-+      }
-+}
-+
-+#ifndef CONFIG_XEN
-+fastcall void do_spurious_interrupt_bug(struct pt_regs * regs,
-+                                        long error_code)
-+{
-+#if 0
-+      /* No need to warn about this any longer. */
-+      printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
-+#endif
-+}
-+
-+fastcall void setup_x86_bogus_stack(unsigned char * stk)
-+{
-+      unsigned long *switch16_ptr, *switch32_ptr;
-+      struct pt_regs *regs;
-+      unsigned long stack_top, stack_bot;
-+      unsigned short iret_frame16_off;
-+      int cpu = smp_processor_id();
-+      /* reserve the space on 32bit stack for the magic switch16 pointer */
-+      memmove(stk, stk + 8, sizeof(struct pt_regs));
-+      switch16_ptr = (unsigned long *)(stk + sizeof(struct pt_regs));
-+      regs = (struct pt_regs *)stk;
-+      /* now the switch32 on 16bit stack */
-+      stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu);
-+      stack_top = stack_bot + CPU_16BIT_STACK_SIZE;
-+      switch32_ptr = (unsigned long *)(stack_top - 8);
-+      iret_frame16_off = CPU_16BIT_STACK_SIZE - 8 - 20;
-+      /* copy iret frame on 16bit stack */
-+      memcpy((void *)(stack_bot + iret_frame16_off), &regs->eip, 20);
-+      /* fill in the switch pointers */
-+      switch16_ptr[0] = (regs->esp & 0xffff0000) | iret_frame16_off;
-+      switch16_ptr[1] = __ESPFIX_SS;
-+      switch32_ptr[0] = (unsigned long)stk + sizeof(struct pt_regs) +
-+              8 - CPU_16BIT_STACK_SIZE;
-+      switch32_ptr[1] = __KERNEL_DS;
-+}
-+
-+fastcall unsigned char * fixup_x86_bogus_stack(unsigned short sp)
-+{
-+      unsigned long *switch32_ptr;
-+      unsigned char *stack16, *stack32;
-+      unsigned long stack_top, stack_bot;
-+      int len;
-+      int cpu = smp_processor_id();
-+      stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu);
-+      stack_top = stack_bot + CPU_16BIT_STACK_SIZE;
-+      switch32_ptr = (unsigned long *)(stack_top - 8);
-+      /* copy the data from 16bit stack to 32bit stack */
-+      len = CPU_16BIT_STACK_SIZE - 8 - sp;
-+      stack16 = (unsigned char *)(stack_bot + sp);
-+      stack32 = (unsigned char *)
-+              (switch32_ptr[0] + CPU_16BIT_STACK_SIZE - 8 - len);
-+      memcpy(stack32, stack16, len);
-+      return stack32;
-+}
-+#endif
-+
-+/*
-+ *  'math_state_restore()' saves the current math information in the
-+ * old math state array, and gets the new ones from the current task
-+ *
-+ * Careful.. There are problems with IBM-designed IRQ13 behaviour.
-+ * Don't touch unless you *really* know how it works.
-+ *
-+ * Must be called with kernel preemption disabled (in this case,
-+ * local interrupts are disabled at the call-site in entry.S).
-+ */
-+asmlinkage void math_state_restore(struct pt_regs regs)
-+{
-+      struct thread_info *thread = current_thread_info();
-+      struct task_struct *tsk = thread->task;
-+
-+      /* NB. 'clts' is done for us by Xen during virtual trap. */
-+      if (!tsk_used_math(tsk))
-+              init_fpu(tsk);
-+      restore_fpu(tsk);
-+      thread->status |= TS_USEDFPU;   /* So we fnsave on switch_to() */
-+}
-+
-+#ifndef CONFIG_MATH_EMULATION
-+
-+asmlinkage void math_emulate(long arg)
-+{
-+      printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n");
-+      printk(KERN_EMERG "killing %s.\n",current->comm);
-+      force_sig(SIGFPE,current);
-+      schedule();
-+}
-+
-+#endif /* CONFIG_MATH_EMULATION */
-+
-+#ifdef CONFIG_X86_F00F_BUG
-+void __init trap_init_f00f_bug(void)
-+{
-+      __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
-+
-+      /*
-+       * Update the IDT descriptor and reload the IDT so that
-+       * it uses the read-only mapped virtual address.
-+       */
-+      idt_descr.address = fix_to_virt(FIX_F00F_IDT);
-+      load_idt(&idt_descr);
-+}
-+#endif
-+
-+
-+/*
-+ * NB. All these are "trap gates" (i.e. events_mask isn't set) except
-+ * for those that specify <dpl>|4 in the second field.
-+ */
-+static trap_info_t trap_table[] = {
-+      {  0, 0, __KERNEL_CS, (unsigned long)divide_error               },
-+      {  1, 0|4, __KERNEL_CS, (unsigned long)debug                    },
-+      {  3, 3|4, __KERNEL_CS, (unsigned long)int3                     },
-+      {  4, 3, __KERNEL_CS, (unsigned long)overflow                   },
-+      {  5, 0, __KERNEL_CS, (unsigned long)bounds                     },
-+      {  6, 0, __KERNEL_CS, (unsigned long)invalid_op                 },
-+      {  7, 0|4, __KERNEL_CS, (unsigned long)device_not_available     },
-+      {  9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
-+      { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS                },
-+      { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present        },
-+      { 12, 0, __KERNEL_CS, (unsigned long)stack_segment              },
-+      { 13, 0, __KERNEL_CS, (unsigned long)general_protection         },
-+      { 14, 0|4, __KERNEL_CS, (unsigned long)page_fault               },
-+      { 15, 0, __KERNEL_CS, (unsigned long)fixup_4gb_segment          },
-+      { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error          },
-+      { 17, 0, __KERNEL_CS, (unsigned long)alignment_check            },
-+#ifdef CONFIG_X86_MCE
-+      { 18, 0, __KERNEL_CS, (unsigned long)machine_check              },
-+#endif
-+      { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error     },
-+      { SYSCALL_VECTOR,  3, __KERNEL_CS, (unsigned long)system_call   },
-+      {  0, 0,           0, 0                                         }
-+};
-+
-+void __init trap_init(void)
-+{
-+      HYPERVISOR_set_trap_table(trap_table);
-+
-+      if (cpu_has_fxsr) {
-+              /*
-+               * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
-+               * Generates a compile-time "error: zero width for bit-field" if
-+               * the alignment is wrong.
-+               */
-+              struct fxsrAlignAssert {
-+                      int _:!(offsetof(struct task_struct,
-+                                      thread.i387.fxsave) & 15);
-+              };
-+
-+              printk(KERN_INFO "Enabling fast FPU save and restore... ");
-+              set_in_cr4(X86_CR4_OSFXSR);
-+              printk("done.\n");
-+      }
-+      if (cpu_has_xmm) {
-+              printk(KERN_INFO "Enabling unmasked SIMD FPU exception "
-+                              "support... ");
-+              set_in_cr4(X86_CR4_OSXMMEXCPT);
-+              printk("done.\n");
-+      }
-+
-+      /*
-+       * Should be a barrier for any external CPU state.
-+       */
-+      cpu_init();
-+}
-+
-+void smp_trap_init(trap_info_t *trap_ctxt)
-+{
-+      trap_info_t *t = trap_table;
-+
-+      for (t = trap_table; t->address; t++) {
-+              trap_ctxt[t->vector].flags = t->flags;
-+              trap_ctxt[t->vector].cs = t->cs;
-+              trap_ctxt[t->vector].address = t->address;
-+      }
-+}
-+
-+static int __init kstack_setup(char *s)
-+{
-+      kstack_depth_to_print = simple_strtoul(s, NULL, 0);
-+      return 0;
-+}
-+__setup("kstack=", kstack_setup);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/traps.c linux-2.6.16.33/arch/i386/kernel/traps.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/traps.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/traps.c   2007-01-08 15:00:45.000000000 +0000
-@@ -567,18 +567,11 @@
- static void io_check_error(unsigned char reason, struct pt_regs * regs)
- {
--      unsigned long i;
--
-       printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
-       show_registers(regs);
-       /* Re-enable the IOCK line, wait for a few seconds */
--      reason = (reason & 0xf) | 8;
--      outb(reason, 0x61);
--      i = 2000;
--      while (--i) udelay(1000);
--      reason &= ~8;
--      outb(reason, 0x61);
-+      clear_io_check_error(reason);
- }
- static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/vm86.c linux-2.6.16.33/arch/i386/kernel/vm86.c
---- linux-2.6.16.33-noxen/arch/i386/kernel/vm86.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/vm86.c    2007-01-08 15:00:45.000000000 +0000
-@@ -98,7 +98,9 @@
- struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs));
- struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
- {
-+#ifndef CONFIG_X86_NO_TSS
-       struct tss_struct *tss;
-+#endif
-       struct pt_regs *ret;
-       unsigned long tmp;
-@@ -123,12 +125,16 @@
-               do_exit(SIGSEGV);
-       }
-+#ifndef CONFIG_X86_NO_TSS
-       tss = &per_cpu(init_tss, get_cpu());
-+#endif
-       current->thread.esp0 = current->thread.saved_esp0;
-       current->thread.sysenter_cs = __KERNEL_CS;
-       load_esp0(tss, &current->thread);
-       current->thread.saved_esp0 = 0;
-+#ifndef CONFIG_X86_NO_TSS
-       put_cpu();
-+#endif
-       loadsegment(fs, current->thread.saved_fs);
-       loadsegment(gs, current->thread.saved_gs);
-@@ -252,7 +258,9 @@
- static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk)
- {
-+#ifndef CONFIG_X86_NO_TSS
-       struct tss_struct *tss;
-+#endif
-       long eax;
- /*
-  * make sure the vm86() system call doesn't try to do anything silly
-@@ -297,12 +305,16 @@
-       savesegment(fs, tsk->thread.saved_fs);
-       savesegment(gs, tsk->thread.saved_gs);
-+#ifndef CONFIG_X86_NO_TSS
-       tss = &per_cpu(init_tss, get_cpu());
-+#endif
-       tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
-       if (cpu_has_sep)
-               tsk->thread.sysenter_cs = 0;
-       load_esp0(tss, &tsk->thread);
-+#ifndef CONFIG_X86_NO_TSS
-       put_cpu();
-+#endif
-       tsk->thread.screen_bitmap = info->screen_bitmap;
-       if (info->flags & VM86_SCREEN_BITMAP)
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/vmlinux.lds.S linux-2.6.16.33/arch/i386/kernel/vmlinux.lds.S
---- linux-2.6.16.33-noxen/arch/i386/kernel/vmlinux.lds.S       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/vmlinux.lds.S     2007-01-08 15:00:45.000000000 +0000
-@@ -12,6 +12,12 @@
- OUTPUT_ARCH(i386)
- ENTRY(phys_startup_32)
- jiffies = jiffies_64;
-+
-+PHDRS {
-+      text PT_LOAD FLAGS(5);  /* R_E */
-+      data PT_LOAD FLAGS(7);  /* RWE */
-+      note PT_NOTE FLAGS(4);  /* R__ */
-+}
- SECTIONS
- {
-   . = __KERNEL_START;
-@@ -25,7 +31,7 @@
-       KPROBES_TEXT
-       *(.fixup)
-       *(.gnu.warning)
--      } = 0x9090
-+      } :text = 0x9090
-   _etext = .;                 /* End of text section */
-@@ -34,13 +40,20 @@
-   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
-   __stop___ex_table = .;
-+  . = ALIGN(16);
-+  __start_smp_alternatives_table = .;
-+  __smp_alternatives : AT(ADDR(__smp_alternatives) - LOAD_OFFSET) { *(__smp_alternatives) }
-+  __stop_smp_alternatives_table = .;
-+
-+  __smp_replacements : AT(ADDR(__smp_replacements) - LOAD_OFFSET) { *(__smp_replacements) }
-+
-   RODATA
-   /* writeable */
-   .data : AT(ADDR(.data) - LOAD_OFFSET) {     /* Data */
-       *(.data)
-       CONSTRUCTORS
--      }
-+      } :data
-   . = ALIGN(4096);
-   __nosave_begin = .;
-@@ -147,4 +160,6 @@
-   STABS_DEBUG
-   DWARF_DEBUG
-+
-+  NOTES
- }
-diff -Nur linux-2.6.16.33-noxen/arch/i386/kernel/vsyscall-note-xen.S linux-2.6.16.33/arch/i386/kernel/vsyscall-note-xen.S
---- linux-2.6.16.33-noxen/arch/i386/kernel/vsyscall-note-xen.S 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/kernel/vsyscall-note-xen.S       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,32 @@
-+/*
-+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
-+ * Here we can supply some information useful to userland.
-+ * First we get the vanilla i386 note that supplies the kernel version info.
-+ */
-+
-+#include "vsyscall-note.S"
-+
-+/*
-+ * Now we add a special note telling glibc's dynamic linker a fake hardware
-+ * flavor that it will use to choose the search path for libraries in the
-+ * same way it uses real hardware capabilities like "mmx".
-+ * We supply "nosegneg" as the fake capability, to indicate that we
-+ * do not like negative offsets in instructions using segment overrides,
-+ * since we implement those inefficiently.  This makes it possible to
-+ * install libraries optimized to avoid those access patterns in someplace
-+ * like /lib/i686/tls/nosegneg.  Note that an /etc/ld.so.conf.d/file
-+ * corresponding to the bits here is needed to make ldconfig work right.
-+ * It should contain:
-+ *    hwcap 0 nosegneg
-+ * to match the mapping of bit to name that we give here.
-+ */
-+#define NOTE_KERNELCAP_BEGIN(ncaps, mask) \
-+      ASM_ELF_NOTE_BEGIN(".note.kernelcap", "a", "GNU", 2) \
-+      .long ncaps, mask
-+#define NOTE_KERNELCAP(bit, name) \
-+      .byte bit; .asciz name
-+#define NOTE_KERNELCAP_END ASM_ELF_NOTE_END
-+
-+NOTE_KERNELCAP_BEGIN(1, 1)
-+NOTE_KERNELCAP(1, "nosegneg")  /* Change 1 back to 0 when glibc is fixed! */
-+NOTE_KERNELCAP_END
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mach-xen/Makefile linux-2.6.16.33/arch/i386/mach-xen/Makefile
---- linux-2.6.16.33-noxen/arch/i386/mach-xen/Makefile  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mach-xen/Makefile        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,5 @@
-+#
-+# Makefile for the linux kernel.
-+#
-+
-+obj-y                         := setup.o
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mach-xen/setup.c linux-2.6.16.33/arch/i386/mach-xen/setup.c
---- linux-2.6.16.33-noxen/arch/i386/mach-xen/setup.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mach-xen/setup.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,37 @@
-+/*
-+ *    Machine specific setup for generic
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/smp.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <asm/acpi.h>
-+#include <asm/arch_hooks.h>
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+#define DEFAULT_SEND_IPI      (1)
-+#else
-+#define DEFAULT_SEND_IPI      (0)
-+#endif
-+
-+int no_broadcast=DEFAULT_SEND_IPI;
-+
-+static __init int no_ipi_broadcast(char *str)
-+{
-+      get_option(&str, &no_broadcast);
-+      printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" :
-+                                                                                      "IPI Broadcast");
-+      return 1;
-+}
-+
-+__setup("no_ipi_broadcast", no_ipi_broadcast);
-+
-+static int __init print_ipi_mode(void)
-+{
-+      printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" :
-+                                                                                      "Shortcut");
-+      return 0;
-+}
-+
-+late_initcall(print_ipi_mode);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/Makefile linux-2.6.16.33/arch/i386/mm/Makefile
---- linux-2.6.16.33-noxen/arch/i386/mm/Makefile        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/Makefile      2007-01-08 15:00:45.000000000 +0000
-@@ -8,3 +8,11 @@
- obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
- obj-$(CONFIG_HIGHMEM) += highmem.o
- obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
-+
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y         += hypervisor.o
-+
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/fault-xen.c linux-2.6.16.33/arch/i386/mm/fault-xen.c
---- linux-2.6.16.33-noxen/arch/i386/mm/fault-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/fault-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,662 @@
-+/*
-+ *  linux/arch/i386/mm/fault.c
-+ *
-+ *  Copyright (C) 1995  Linus Torvalds
-+ */
-+
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/ptrace.h>
-+#include <linux/mman.h>
-+#include <linux/mm.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/tty.h>
-+#include <linux/vt_kern.h>            /* For unblank_screen() */
-+#include <linux/highmem.h>
-+#include <linux/module.h>
-+#include <linux/kprobes.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/desc.h>
-+#include <asm/kdebug.h>
-+
-+extern void die(const char *,struct pt_regs *,long);
-+
-+/*
-+ * Unlock any spinlocks which will prevent us from getting the
-+ * message out 
-+ */
-+void bust_spinlocks(int yes)
-+{
-+      int loglevel_save = console_loglevel;
-+
-+      if (yes) {
-+              oops_in_progress = 1;
-+              return;
-+      }
-+#ifdef CONFIG_VT
-+      unblank_screen();
-+#endif
-+      oops_in_progress = 0;
-+      /*
-+       * OK, the message is on the console.  Now we call printk()
-+       * without oops_in_progress set so that printk will give klogd
-+       * a poke.  Hold onto your hats...
-+       */
-+      console_loglevel = 15;          /* NMI oopser may have shut the console up */
-+      printk(" ");
-+      console_loglevel = loglevel_save;
-+}
-+
-+/*
-+ * Return EIP plus the CS segment base.  The segment limit is also
-+ * adjusted, clamped to the kernel/user address space (whichever is
-+ * appropriate), and returned in *eip_limit.
-+ *
-+ * The segment is checked, because it might have been changed by another
-+ * task between the original faulting instruction and here.
-+ *
-+ * If CS is no longer a valid code segment, or if EIP is beyond the
-+ * limit, or if it is a kernel address when CS is not a kernel segment,
-+ * then the returned value will be greater than *eip_limit.
-+ * 
-+ * This is slow, but is very rarely executed.
-+ */
-+static inline unsigned long get_segment_eip(struct pt_regs *regs,
-+                                          unsigned long *eip_limit)
-+{
-+      unsigned long eip = regs->eip;
-+      unsigned seg = regs->xcs & 0xffff;
-+      u32 seg_ar, seg_limit, base, *desc;
-+
-+      /* The standard kernel/user address space limit. */
-+      *eip_limit = (seg & 2) ? USER_DS.seg : KERNEL_DS.seg;
-+
-+      /* Unlikely, but must come before segment checks. */
-+      if (unlikely((regs->eflags & VM_MASK) != 0))
-+              return eip + (seg << 4);
-+      
-+      /* By far the most common cases. */
-+      if (likely(seg == __USER_CS || seg == GET_KERNEL_CS()))
-+              return eip;
-+
-+      /* Check the segment exists, is within the current LDT/GDT size,
-+         that kernel/user (ring 0..3) has the appropriate privilege,
-+         that it's a code segment, and get the limit. */
-+      __asm__ ("larl %3,%0; lsll %3,%1"
-+               : "=&r" (seg_ar), "=r" (seg_limit) : "0" (0), "rm" (seg));
-+      if ((~seg_ar & 0x9800) || eip > seg_limit) {
-+              *eip_limit = 0;
-+              return 1;        /* So that returned eip > *eip_limit. */
-+      }
-+
-+      /* Get the GDT/LDT descriptor base. 
-+         When you look for races in this code remember that
-+         LDT and other horrors are only used in user space. */
-+      if (seg & (1<<2)) {
-+              /* Must lock the LDT while reading it. */
-+              down(&current->mm->context.sem);
-+              desc = current->mm->context.ldt;
-+              desc = (void *)desc + (seg & ~7);
-+      } else {
-+              /* Must disable preemption while reading the GDT. */
-+              desc = (u32 *)get_cpu_gdt_table(get_cpu());
-+              desc = (void *)desc + (seg & ~7);
-+      }
-+
-+      /* Decode the code segment base from the descriptor */
-+      base = get_desc_base((unsigned long *)desc);
-+
-+      if (seg & (1<<2)) { 
-+              up(&current->mm->context.sem);
-+      } else
-+              put_cpu();
-+
-+      /* Adjust EIP and segment limit, and clamp at the kernel limit.
-+         It's legitimate for segments to wrap at 0xffffffff. */
-+      seg_limit += base;
-+      if (seg_limit < *eip_limit && seg_limit >= base)
-+              *eip_limit = seg_limit;
-+      return eip + base;
-+}
-+
-+/* 
-+ * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
-+ * Check that here and ignore it.
-+ */
-+static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
-+{ 
-+      unsigned long limit;
-+      unsigned long instr = get_segment_eip (regs, &limit);
-+      int scan_more = 1;
-+      int prefetch = 0; 
-+      int i;
-+
-+      for (i = 0; scan_more && i < 15; i++) { 
-+              unsigned char opcode;
-+              unsigned char instr_hi;
-+              unsigned char instr_lo;
-+
-+              if (instr > limit)
-+                      break;
-+              if (__get_user(opcode, (unsigned char __user *) instr))
-+                      break; 
-+
-+              instr_hi = opcode & 0xf0; 
-+              instr_lo = opcode & 0x0f; 
-+              instr++;
-+
-+              switch (instr_hi) { 
-+              case 0x20:
-+              case 0x30:
-+                      /* Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes. */
-+                      scan_more = ((instr_lo & 7) == 0x6);
-+                      break;
-+                      
-+              case 0x60:
-+                      /* 0x64 thru 0x67 are valid prefixes in all modes. */
-+                      scan_more = (instr_lo & 0xC) == 0x4;
-+                      break;          
-+              case 0xF0:
-+                      /* 0xF0, 0xF2, and 0xF3 are valid prefixes */
-+                      scan_more = !instr_lo || (instr_lo>>1) == 1;
-+                      break;                  
-+              case 0x00:
-+                      /* Prefetch instruction is 0x0F0D or 0x0F18 */
-+                      scan_more = 0;
-+                      if (instr > limit)
-+                              break;
-+                      if (__get_user(opcode, (unsigned char __user *) instr))
-+                              break;
-+                      prefetch = (instr_lo == 0xF) &&
-+                              (opcode == 0x0D || opcode == 0x18);
-+                      break;                  
-+              default:
-+                      scan_more = 0;
-+                      break;
-+              } 
-+      }
-+      return prefetch;
-+}
-+
-+static inline int is_prefetch(struct pt_regs *regs, unsigned long addr,
-+                            unsigned long error_code)
-+{
-+      if (unlikely(boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-+                   boot_cpu_data.x86 >= 6)) {
-+              /* Catch an obscure case of prefetch inside an NX page. */
-+              if (nx_enabled && (error_code & 16))
-+                      return 0;
-+              return __is_prefetch(regs, addr);
-+      }
-+      return 0;
-+} 
-+
-+static noinline void force_sig_info_fault(int si_signo, int si_code,
-+      unsigned long address, struct task_struct *tsk)
-+{
-+      siginfo_t info;
-+
-+      info.si_signo = si_signo;
-+      info.si_errno = 0;
-+      info.si_code = si_code;
-+      info.si_addr = (void __user *)address;
-+      force_sig_info(si_signo, &info, tsk);
-+}
-+
-+fastcall void do_invalid_op(struct pt_regs *, unsigned long);
-+
-+#ifdef CONFIG_X86_PAE
-+static void dump_fault_path(unsigned long address)
-+{
-+      unsigned long *p, page;
-+      unsigned long mfn; 
-+
-+      page = read_cr3();
-+      p  = (unsigned long *)__va(page);
-+      p += (address >> 30) * 2;
-+      printk(KERN_ALERT "%08lx -> *pde = %08lx:%08lx\n", page, p[1], p[0]);
-+      if (p[0] & 1) {
-+              mfn  = (p[0] >> PAGE_SHIFT) | ((p[1] & 0x7) << 20); 
-+              page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
-+              p  = (unsigned long *)__va(page);
-+              address &= 0x3fffffff;
-+              p += (address >> 21) * 2;
-+              printk(KERN_ALERT "%08lx -> *pme = %08lx:%08lx\n", 
-+                     page, p[1], p[0]);
-+#ifndef CONFIG_HIGHPTE
-+              if (p[0] & 1) {
-+                      mfn  = (p[0] >> PAGE_SHIFT) | ((p[1] & 0x7) << 20); 
-+                      page = mfn_to_pfn(mfn) << PAGE_SHIFT; 
-+                      p  = (unsigned long *) __va(page);
-+                      address &= 0x001fffff;
-+                      p += (address >> 12) * 2;
-+                      printk(KERN_ALERT "%08lx -> *pte = %08lx:%08lx\n",
-+                             page, p[1], p[0]);
-+              }
-+#endif
-+      }
-+}
-+#else
-+static void dump_fault_path(unsigned long address)
-+{
-+      unsigned long page;
-+
-+      page = read_cr3();
-+      page = ((unsigned long *) __va(page))[address >> 22];
-+      printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page,
-+             machine_to_phys(page));
-+      /*
-+       * We must not directly access the pte in the highpte
-+       * case, the page table might be allocated in highmem.
-+       * And lets rather not kmap-atomic the pte, just in case
-+       * it's allocated already.
-+       */
-+#ifndef CONFIG_HIGHPTE
-+      if (page & 1) {
-+              page &= PAGE_MASK;
-+              address &= 0x003ff000;
-+              page = machine_to_phys(page);
-+              page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
-+              printk(KERN_ALERT "*pte = ma %08lx pa %08lx\n", page,
-+                     machine_to_phys(page));
-+      }
-+#endif
-+}
-+#endif
-+
-+static int spurious_fault(struct pt_regs *regs,
-+                        unsigned long address,
-+                        unsigned long error_code)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+
-+      /* Reserved-bit violation or user access to kernel space? */
-+      if (error_code & 0x0c)
-+              return 0;
-+
-+      pgd = init_mm.pgd + pgd_index(address);
-+      if (!pgd_present(*pgd))
-+              return 0;
-+
-+      pud = pud_offset(pgd, address);
-+      if (!pud_present(*pud))
-+              return 0;
-+
-+      pmd = pmd_offset(pud, address);
-+      if (!pmd_present(*pmd))
-+              return 0;
-+
-+      pte = pte_offset_kernel(pmd, address);
-+      if (!pte_present(*pte))
-+              return 0;
-+      if ((error_code & 0x02) && !pte_write(*pte))
-+              return 0;
-+#ifdef CONFIG_X86_PAE
-+      if ((error_code & 0x10) && (pte_val(*pte) & _PAGE_NX))
-+              return 0;
-+#endif
-+
-+      return 1;
-+}
-+
-+/*
-+ * This routine handles page faults.  It determines the address,
-+ * and the problem, and then passes it off to one of the appropriate
-+ * routines.
-+ *
-+ * error_code:
-+ *    bit 0 == 0 means no page found, 1 means protection fault
-+ *    bit 1 == 0 means read, 1 means write
-+ *    bit 2 == 0 means kernel, 1 means user-mode
-+ */
-+fastcall void __kprobes do_page_fault(struct pt_regs *regs,
-+                                    unsigned long error_code)
-+{
-+      struct task_struct *tsk;
-+      struct mm_struct *mm;
-+      struct vm_area_struct * vma;
-+      unsigned long address;
-+      int write, si_code;
-+
-+      /* get the address */
-+        address = read_cr2();
-+
-+      /* Set the "privileged fault" bit to something sane. */
-+      error_code &= ~4;
-+      error_code |= (regs->xcs & 2) << 1;
-+      if (regs->eflags & X86_EFLAGS_VM)
-+              error_code |= 4;
-+
-+      if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
-+                                      SIGSEGV) == NOTIFY_STOP)
-+              return;
-+      /* It's safe to allow irq's after cr2 has been saved */
-+      if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
-+              local_irq_enable();
-+
-+      tsk = current;
-+
-+      si_code = SEGV_MAPERR;
-+
-+      /*
-+       * We fault-in kernel-space virtual memory on-demand. The
-+       * 'reference' page table is init_mm.pgd.
-+       *
-+       * NOTE! We MUST NOT take any locks for this case. We may
-+       * be in an interrupt or a critical region, and should
-+       * only copy the information from the master page table,
-+       * nothing more.
-+       *
-+       * This verifies that the fault happens in kernel space
-+       * (error_code & 4) == 0, and that the fault was not a
-+       * protection error (error_code & 1) == 0.
-+       */
-+      if (unlikely(address >= TASK_SIZE)) { 
-+#ifdef CONFIG_XEN
-+              /* Faults in hypervisor area can never be patched up. */
-+              if (address >= hypervisor_virt_start)
-+                      goto bad_area_nosemaphore;
-+#endif
-+              if (!(error_code & 5))
-+                      goto vmalloc_fault;
-+              /* Can take a spurious fault if mapping changes R/O -> R/W. */
-+              if (spurious_fault(regs, address, error_code))
-+                      return;
-+              /* 
-+               * Don't take the mm semaphore here. If we fixup a prefetch
-+               * fault we could otherwise deadlock.
-+               */
-+              goto bad_area_nosemaphore;
-+      } 
-+
-+      mm = tsk->mm;
-+
-+      /*
-+       * If we're in an interrupt, have no user context or are running in an
-+       * atomic region then we must not take the fault..
-+       */
-+      if (in_atomic() || !mm)
-+              goto bad_area_nosemaphore;
-+
-+      /* When running in the kernel we expect faults to occur only to
-+       * addresses in user space.  All other faults represent errors in the
-+       * kernel and should generate an OOPS.  Unfortunatly, in the case of an
-+       * erroneous fault occuring in a code path which already holds mmap_sem
-+       * we will deadlock attempting to validate the fault against the
-+       * address space.  Luckily the kernel only validly references user
-+       * space from well defined areas of code, which are listed in the
-+       * exceptions table.
-+       *
-+       * As the vast majority of faults will be valid we will only perform
-+       * the source reference check when there is a possibilty of a deadlock.
-+       * Attempt to lock the address space, if we cannot we then validate the
-+       * source.  If this is invalid we can skip the address space check,
-+       * thus avoiding the deadlock.
-+       */
-+      if (!down_read_trylock(&mm->mmap_sem)) {
-+              if ((error_code & 4) == 0 &&
-+                  !search_exception_tables(regs->eip))
-+                      goto bad_area_nosemaphore;
-+              down_read(&mm->mmap_sem);
-+      }
-+
-+      vma = find_vma(mm, address);
-+      if (!vma)
-+              goto bad_area;
-+      if (vma->vm_start <= address)
-+              goto good_area;
-+      if (!(vma->vm_flags & VM_GROWSDOWN))
-+              goto bad_area;
-+      if (error_code & 4) {
-+              /*
-+               * accessing the stack below %esp is always a bug.
-+               * The "+ 32" is there due to some instructions (like
-+               * pusha) doing post-decrement on the stack and that
-+               * doesn't show up until later..
-+               */
-+              if (address + 32 < regs->esp)
-+                      goto bad_area;
-+      }
-+      if (expand_stack(vma, address))
-+              goto bad_area;
-+/*
-+ * Ok, we have a good vm_area for this memory access, so
-+ * we can handle it..
-+ */
-+good_area:
-+      si_code = SEGV_ACCERR;
-+      write = 0;
-+      switch (error_code & 3) {
-+              default:        /* 3: write, present */
-+#ifdef TEST_VERIFY_AREA
-+                      if (regs->cs == GET_KERNEL_CS())
-+                              printk("WP fault at %08lx\n", regs->eip);
-+#endif
-+                      /* fall through */
-+              case 2:         /* write, not present */
-+                      if (!(vma->vm_flags & VM_WRITE))
-+                              goto bad_area;
-+                      write++;
-+                      break;
-+              case 1:         /* read, present */
-+                      goto bad_area;
-+              case 0:         /* read, not present */
-+                      if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
-+                              goto bad_area;
-+      }
-+
-+ survive:
-+      /*
-+       * If for any reason at all we couldn't handle the fault,
-+       * make sure we exit gracefully rather than endlessly redo
-+       * the fault.
-+       */
-+      switch (handle_mm_fault(mm, vma, address, write)) {
-+              case VM_FAULT_MINOR:
-+                      tsk->min_flt++;
-+                      break;
-+              case VM_FAULT_MAJOR:
-+                      tsk->maj_flt++;
-+                      break;
-+              case VM_FAULT_SIGBUS:
-+                      goto do_sigbus;
-+              case VM_FAULT_OOM:
-+                      goto out_of_memory;
-+              default:
-+                      BUG();
-+      }
-+
-+      /*
-+       * Did it hit the DOS screen memory VA from vm86 mode?
-+       */
-+      if (regs->eflags & VM_MASK) {
-+              unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
-+              if (bit < 32)
-+                      tsk->thread.screen_bitmap |= 1 << bit;
-+      }
-+      up_read(&mm->mmap_sem);
-+      return;
-+
-+/*
-+ * Something tried to access memory that isn't in our memory map..
-+ * Fix it, but check if it's kernel or user first..
-+ */
-+bad_area:
-+      up_read(&mm->mmap_sem);
-+
-+bad_area_nosemaphore:
-+      /* User mode accesses just cause a SIGSEGV */
-+      if (error_code & 4) {
-+              /* 
-+               * Valid to do another page fault here because this one came 
-+               * from user space.
-+               */
-+              if (is_prefetch(regs, address, error_code))
-+                      return;
-+
-+              tsk->thread.cr2 = address;
-+              /* Kernel addresses are always protection faults */
-+              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
-+              tsk->thread.trap_no = 14;
-+              force_sig_info_fault(SIGSEGV, si_code, address, tsk);
-+              return;
-+      }
-+
-+#ifdef CONFIG_X86_F00F_BUG
-+      /*
-+       * Pentium F0 0F C7 C8 bug workaround.
-+       */
-+      if (boot_cpu_data.f00f_bug) {
-+              unsigned long nr;
-+              
-+              nr = (address - idt_descr.address) >> 3;
-+
-+              if (nr == 6) {
-+                      do_invalid_op(regs, 0);
-+                      return;
-+              }
-+      }
-+#endif
-+
-+no_context:
-+      /* Are we prepared to handle this kernel fault?  */
-+      if (fixup_exception(regs))
-+              return;
-+
-+      /* 
-+       * Valid to do another page fault here, because if this fault
-+       * had been triggered by is_prefetch fixup_exception would have 
-+       * handled it.
-+       */
-+      if (is_prefetch(regs, address, error_code))
-+              return;
-+
-+/*
-+ * Oops. The kernel tried to access some bad page. We'll have to
-+ * terminate things with extreme prejudice.
-+ */
-+
-+      bust_spinlocks(1);
-+
-+#ifdef CONFIG_X86_PAE
-+      if (error_code & 16) {
-+              pte_t *pte = lookup_address(address);
-+
-+              if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
-+                      printk(KERN_CRIT "kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n", current->uid);
-+      }
-+#endif
-+      if (address < PAGE_SIZE)
-+              printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-+      else
-+              printk(KERN_ALERT "Unable to handle kernel paging request");
-+      printk(" at virtual address %08lx\n",address);
-+      printk(KERN_ALERT " printing eip:\n");
-+      printk("%08lx\n", regs->eip);
-+      dump_fault_path(address);
-+      tsk->thread.cr2 = address;
-+      tsk->thread.trap_no = 14;
-+      tsk->thread.error_code = error_code;
-+      die("Oops", regs, error_code);
-+      bust_spinlocks(0);
-+      do_exit(SIGKILL);
-+
-+/*
-+ * We ran out of memory, or some other thing happened to us that made
-+ * us unable to handle the page fault gracefully.
-+ */
-+out_of_memory:
-+      up_read(&mm->mmap_sem);
-+      if (tsk->pid == 1) {
-+              yield();
-+              down_read(&mm->mmap_sem);
-+              goto survive;
-+      }
-+      printk("VM: killing process %s\n", tsk->comm);
-+      if (error_code & 4)
-+              do_exit(SIGKILL);
-+      goto no_context;
-+
-+do_sigbus:
-+      up_read(&mm->mmap_sem);
-+
-+      /* Kernel mode? Handle exceptions or die */
-+      if (!(error_code & 4))
-+              goto no_context;
-+
-+      /* User space => ok to do another page fault */
-+      if (is_prefetch(regs, address, error_code))
-+              return;
-+
-+      tsk->thread.cr2 = address;
-+      tsk->thread.error_code = error_code;
-+      tsk->thread.trap_no = 14;
-+      force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
-+      return;
-+
-+vmalloc_fault:
-+      {
-+              /*
-+               * Synchronize this task's top level page-table
-+               * with the 'reference' page table.
-+               *
-+               * Do _not_ use "tsk" here. We might be inside
-+               * an interrupt in the middle of a task switch..
-+               */
-+              int index = pgd_index(address);
-+              unsigned long pgd_paddr;
-+              pgd_t *pgd, *pgd_k;
-+              pud_t *pud, *pud_k;
-+              pmd_t *pmd, *pmd_k;
-+              pte_t *pte_k;
-+
-+              pgd_paddr = read_cr3();
-+              pgd = index + (pgd_t *)__va(pgd_paddr);
-+              pgd_k = init_mm.pgd + index;
-+
-+              if (!pgd_present(*pgd_k))
-+                      goto no_context;
-+
-+              /*
-+               * set_pgd(pgd, *pgd_k); here would be useless on PAE
-+               * and redundant with the set_pmd() on non-PAE. As would
-+               * set_pud.
-+               */
-+
-+              pud = pud_offset(pgd, address);
-+              pud_k = pud_offset(pgd_k, address);
-+              if (!pud_present(*pud_k))
-+                      goto no_context;
-+              
-+              pmd = pmd_offset(pud, address);
-+              pmd_k = pmd_offset(pud_k, address);
-+              if (!pmd_present(*pmd_k))
-+                      goto no_context;
-+#ifndef CONFIG_XEN
-+              set_pmd(pmd, *pmd_k);
-+#else
-+              /*
-+               * When running on Xen we must launder *pmd_k through
-+               * pmd_val() to ensure that _PAGE_PRESENT is correctly set.
-+               */
-+              set_pmd(pmd, __pmd(pmd_val(*pmd_k)));
-+#endif
-+
-+              pte_k = pte_offset_kernel(pmd_k, address);
-+              if (!pte_present(*pte_k))
-+                      goto no_context;
-+              return;
-+      }
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/highmem-xen.c linux-2.6.16.33/arch/i386/mm/highmem-xen.c
---- linux-2.6.16.33-noxen/arch/i386/mm/highmem-xen.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/highmem-xen.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,133 @@
-+#include <linux/highmem.h>
-+#include <linux/module.h>
-+
-+void *kmap(struct page *page)
-+{
-+      might_sleep();
-+      if (!PageHighMem(page))
-+              return page_address(page);
-+      return kmap_high(page);
-+}
-+
-+void kunmap(struct page *page)
-+{
-+      if (in_interrupt())
-+              BUG();
-+      if (!PageHighMem(page))
-+              return;
-+      kunmap_high(page);
-+}
-+
-+/*
-+ * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
-+ * no global lock is needed and because the kmap code must perform a global TLB
-+ * invalidation when the kmap pool wraps.
-+ *
-+ * However when holding an atomic kmap is is not legal to sleep, so atomic
-+ * kmaps are appropriate for short, tight code paths only.
-+ */
-+static void *__kmap_atomic(struct page *page, enum km_type type, pgprot_t prot)
-+{
-+      enum fixed_addresses idx;
-+      unsigned long vaddr;
-+
-+      /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
-+      inc_preempt_count();
-+      if (!PageHighMem(page))
-+              return page_address(page);
-+
-+      idx = type + KM_TYPE_NR*smp_processor_id();
-+      vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-+#ifdef CONFIG_DEBUG_HIGHMEM
-+      if (!pte_none(*(kmap_pte-idx)))
-+              BUG();
-+#endif
-+      set_pte_at_sync(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
-+
-+      return (void*) vaddr;
-+}
-+
-+void *kmap_atomic(struct page *page, enum km_type type)
-+{
-+      return __kmap_atomic(page, type, kmap_prot);
-+}
-+
-+/* Same as kmap_atomic but with PAGE_KERNEL_RO page protection. */
-+void *kmap_atomic_pte(struct page *page, enum km_type type)
-+{
-+      return __kmap_atomic(page, type, PAGE_KERNEL_RO);
-+}
-+
-+void kunmap_atomic(void *kvaddr, enum km_type type)
-+{
-+#if defined(CONFIG_DEBUG_HIGHMEM) || defined(CONFIG_XEN)
-+      unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
-+      enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
-+
-+      if (vaddr < FIXADDR_START) { // FIXME
-+              dec_preempt_count();
-+              preempt_check_resched();
-+              return;
-+      }
-+#endif
-+
-+#if defined(CONFIG_DEBUG_HIGHMEM)
-+      if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
-+              BUG();
-+
-+      /*
-+       * force other mappings to Oops if they'll try to access
-+       * this pte without first remap it
-+       */
-+      pte_clear(&init_mm, vaddr, kmap_pte-idx);
-+      __flush_tlb_one(vaddr);
-+#elif defined(CONFIG_XEN)
-+      /*
-+       * We must ensure there are no dangling pagetable references when
-+       * returning memory to Xen (decrease_reservation).
-+       * XXX TODO: We could make this faster by only zapping when
-+       * kmap_flush_unused is called but that is trickier and more invasive.
-+       */
-+      pte_clear(&init_mm, vaddr, kmap_pte-idx);
-+#endif
-+
-+      dec_preempt_count();
-+      preempt_check_resched();
-+}
-+
-+/* This is the same as kmap_atomic() but can map memory that doesn't
-+ * have a struct page associated with it.
-+ */
-+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
-+{
-+      enum fixed_addresses idx;
-+      unsigned long vaddr;
-+
-+      inc_preempt_count();
-+
-+      idx = type + KM_TYPE_NR*smp_processor_id();
-+      vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-+      set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
-+      __flush_tlb_one(vaddr);
-+
-+      return (void*) vaddr;
-+}
-+
-+struct page *kmap_atomic_to_page(void *ptr)
-+{
-+      unsigned long idx, vaddr = (unsigned long)ptr;
-+      pte_t *pte;
-+
-+      if (vaddr < FIXADDR_START)
-+              return virt_to_page(ptr);
-+
-+      idx = virt_to_fix(vaddr);
-+      pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
-+      return pte_page(*pte);
-+}
-+
-+EXPORT_SYMBOL(kmap);
-+EXPORT_SYMBOL(kunmap);
-+EXPORT_SYMBOL(kmap_atomic);
-+EXPORT_SYMBOL(kunmap_atomic);
-+EXPORT_SYMBOL(kmap_atomic_to_page);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/hypervisor.c linux-2.6.16.33/arch/i386/mm/hypervisor.c
---- linux-2.6.16.33-noxen/arch/i386/mm/hypervisor.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/hypervisor.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,450 @@
-+/******************************************************************************
-+ * mm/hypervisor.c
-+ * 
-+ * Update page tables via the hypervisor.
-+ * 
-+ * Copyright (c) 2002-2004, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/vmalloc.h>
-+#include <asm/page.h>
-+#include <asm/pgtable.h>
-+#include <asm/hypervisor.h>
-+#include <xen/balloon.h>
-+#include <xen/features.h>
-+#include <xen/interface/memory.h>
-+#include <linux/module.h>
-+#include <linux/percpu.h>
-+#include <asm/tlbflush.h>
-+
-+#ifdef CONFIG_X86_64
-+#define pmd_val_ma(v) (v).pmd
-+#else
-+#ifdef CONFIG_X86_PAE
-+# define pmd_val_ma(v) ((v).pmd)
-+# define pud_val_ma(v) ((v).pgd.pgd)
-+#else
-+# define pmd_val_ma(v) ((v).pud.pgd.pgd)
-+#endif
-+#endif
-+
-+void xen_l1_entry_update(pte_t *ptr, pte_t val)
-+{
-+      mmu_update_t u;
-+      u.ptr = virt_to_machine(ptr);
-+      u.val = pte_val_ma(val);
-+      BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_l2_entry_update(pmd_t *ptr, pmd_t val)
-+{
-+      mmu_update_t u;
-+      u.ptr = virt_to_machine(ptr);
-+      u.val = pmd_val_ma(val);
-+      BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+#ifdef CONFIG_X86_PAE
-+void xen_l3_entry_update(pud_t *ptr, pud_t val)
-+{
-+      mmu_update_t u;
-+      u.ptr = virt_to_machine(ptr);
-+      u.val = pud_val_ma(val);
-+      BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
-+}
-+#endif
-+
-+#ifdef CONFIG_X86_64
-+void xen_l3_entry_update(pud_t *ptr, pud_t val)
-+{
-+      mmu_update_t u;
-+      u.ptr = virt_to_machine(ptr);
-+      u.val = val.pud;
-+      BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_l4_entry_update(pgd_t *ptr, pgd_t val)
-+{
-+      mmu_update_t u;
-+      u.ptr = virt_to_machine(ptr);
-+      u.val = val.pgd;
-+      BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
-+}
-+#endif /* CONFIG_X86_64 */
-+
-+void xen_pt_switch(unsigned long ptr)
-+{
-+      struct mmuext_op op;
-+      op.cmd = MMUEXT_NEW_BASEPTR;
-+      op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_new_user_pt(unsigned long ptr)
-+{
-+      struct mmuext_op op;
-+      op.cmd = MMUEXT_NEW_USER_BASEPTR;
-+      op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_tlb_flush(void)
-+{
-+      struct mmuext_op op;
-+      op.cmd = MMUEXT_TLB_FLUSH_LOCAL;
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+EXPORT_SYMBOL(xen_tlb_flush);
-+
-+void xen_invlpg(unsigned long ptr)
-+{
-+      struct mmuext_op op;
-+      op.cmd = MMUEXT_INVLPG_LOCAL;
-+      op.arg1.linear_addr = ptr & PAGE_MASK;
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+EXPORT_SYMBOL(xen_invlpg);
-+
-+#ifdef CONFIG_SMP
-+
-+void xen_tlb_flush_all(void)
-+{
-+      struct mmuext_op op;
-+      op.cmd = MMUEXT_TLB_FLUSH_ALL;
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_tlb_flush_mask(cpumask_t *mask)
-+{
-+      struct mmuext_op op;
-+      if ( cpus_empty(*mask) )
-+              return;
-+      op.cmd = MMUEXT_TLB_FLUSH_MULTI;
-+      op.arg2.vcpumask = mask->bits;
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_invlpg_all(unsigned long ptr)
-+{
-+      struct mmuext_op op;
-+      op.cmd = MMUEXT_INVLPG_ALL;
-+      op.arg1.linear_addr = ptr & PAGE_MASK;
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_invlpg_mask(cpumask_t *mask, unsigned long ptr)
-+{
-+      struct mmuext_op op;
-+      if ( cpus_empty(*mask) )
-+              return;
-+      op.cmd = MMUEXT_INVLPG_MULTI;
-+      op.arg1.linear_addr = ptr & PAGE_MASK;
-+      op.arg2.vcpumask    = mask->bits;
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+#endif /* CONFIG_SMP */
-+
-+void xen_pgd_pin(unsigned long ptr)
-+{
-+      struct mmuext_op op;
-+#ifdef CONFIG_X86_64
-+      op.cmd = MMUEXT_PIN_L4_TABLE;
-+#elif defined(CONFIG_X86_PAE)
-+      op.cmd = MMUEXT_PIN_L3_TABLE;
-+#else
-+      op.cmd = MMUEXT_PIN_L2_TABLE;
-+#endif
-+      op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_pgd_unpin(unsigned long ptr)
-+{
-+      struct mmuext_op op;
-+      op.cmd = MMUEXT_UNPIN_TABLE;
-+      op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+void xen_set_ldt(unsigned long ptr, unsigned long len)
-+{
-+      struct mmuext_op op;
-+      op.cmd = MMUEXT_SET_LDT;
-+      op.arg1.linear_addr = ptr;
-+      op.arg2.nr_ents     = len;
-+      BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-+}
-+
-+/*
-+ * Bitmap is indexed by page number. If bit is set, the page is part of a
-+ * xen_create_contiguous_region() area of memory.
-+ */
-+unsigned long *contiguous_bitmap;
-+
-+static void contiguous_bitmap_set(
-+      unsigned long first_page, unsigned long nr_pages)
-+{
-+      unsigned long start_off, end_off, curr_idx, end_idx;
-+
-+      curr_idx  = first_page / BITS_PER_LONG;
-+      start_off = first_page & (BITS_PER_LONG-1);
-+      end_idx   = (first_page + nr_pages) / BITS_PER_LONG;
-+      end_off   = (first_page + nr_pages) & (BITS_PER_LONG-1);
-+
-+      if (curr_idx == end_idx) {
-+              contiguous_bitmap[curr_idx] |=
-+                      ((1UL<<end_off)-1) & -(1UL<<start_off);
-+      } else {
-+              contiguous_bitmap[curr_idx] |= -(1UL<<start_off);
-+              while ( ++curr_idx < end_idx )
-+                      contiguous_bitmap[curr_idx] = ~0UL;
-+              contiguous_bitmap[curr_idx] |= (1UL<<end_off)-1;
-+      }
-+}
-+
-+static void contiguous_bitmap_clear(
-+      unsigned long first_page, unsigned long nr_pages)
-+{
-+      unsigned long start_off, end_off, curr_idx, end_idx;
-+
-+      curr_idx  = first_page / BITS_PER_LONG;
-+      start_off = first_page & (BITS_PER_LONG-1);
-+      end_idx   = (first_page + nr_pages) / BITS_PER_LONG;
-+      end_off   = (first_page + nr_pages) & (BITS_PER_LONG-1);
-+
-+      if (curr_idx == end_idx) {
-+              contiguous_bitmap[curr_idx] &=
-+                      -(1UL<<end_off) | ((1UL<<start_off)-1);
-+      } else {
-+              contiguous_bitmap[curr_idx] &= (1UL<<start_off)-1;
-+              while ( ++curr_idx != end_idx )
-+                      contiguous_bitmap[curr_idx] = 0;
-+              contiguous_bitmap[curr_idx] &= -(1UL<<end_off);
-+      }
-+}
-+
-+/* Protected by balloon_lock. */
-+#define MAX_CONTIG_ORDER 9 /* 2MB */
-+static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
-+static multicall_entry_t cr_mcl[1<<MAX_CONTIG_ORDER];
-+
-+/* Ensure multi-page extents are contiguous in machine memory. */
-+int xen_create_contiguous_region(
-+      unsigned long vstart, unsigned int order, unsigned int address_bits)
-+{
-+      unsigned long *in_frames = discontig_frames, out_frame;
-+      unsigned long  frame, i, flags;
-+      long           rc;
-+      int            success;
-+      struct xen_memory_exchange exchange = {
-+              .in = {
-+                      .nr_extents   = 1UL << order,
-+                      .extent_order = 0,
-+                      .domid        = DOMID_SELF
-+              },
-+              .out = {
-+                      .nr_extents   = 1,
-+                      .extent_order = order,
-+                      .address_bits = address_bits,
-+                      .domid        = DOMID_SELF
-+              }
-+      };
-+
-+      /*
-+       * Currently an auto-translated guest will not perform I/O, nor will
-+       * it require PAE page directories below 4GB. Therefore any calls to
-+       * this function are redundant and can be ignored.
-+       */
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return 0;
-+
-+      if (unlikely(order > MAX_CONTIG_ORDER))
-+              return -ENOMEM;
-+
-+      set_xen_guest_handle(exchange.in.extent_start, in_frames);
-+      set_xen_guest_handle(exchange.out.extent_start, &out_frame);
-+
-+      scrub_pages(vstart, 1 << order);
-+
-+      balloon_lock(flags);
-+
-+      /* 1. Zap current PTEs, remembering MFNs. */
-+      for (i = 0; i < (1UL<<order); i++) {
-+              in_frames[i] = pfn_to_mfn((__pa(vstart) >> PAGE_SHIFT) + i);
-+              MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
-+                                      __pte_ma(0), 0);
-+              set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
-+                      INVALID_P2M_ENTRY);
-+      }
-+      if (HYPERVISOR_multicall(cr_mcl, i))
-+              BUG();
-+
-+      /* 2. Get a new contiguous memory extent. */
-+      out_frame = __pa(vstart) >> PAGE_SHIFT;
-+      rc = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
-+      success = (exchange.nr_exchanged == (1UL << order));
-+      BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
-+      BUG_ON(success && (rc != 0));
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (unlikely(rc == -ENOSYS)) {
-+              /* Compatibility when XENMEM_exchange is unsupported. */
-+              if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-+                                       &exchange.in) != (1UL << order))
-+                      BUG();
-+              success = (HYPERVISOR_memory_op(XENMEM_populate_physmap,
-+                                              &exchange.out) == 1);
-+              if (!success) {
-+                      /* Couldn't get special memory: fall back to normal. */
-+                      for (i = 0; i < (1UL<<order); i++)
-+                              in_frames[i] = (__pa(vstart)>>PAGE_SHIFT) + i;
-+                      if (HYPERVISOR_memory_op(XENMEM_populate_physmap,
-+                                               &exchange.in) != (1UL<<order))
-+                              BUG();
-+              }
-+      }
-+#endif
-+
-+      /* 3. Map the new extent in place of old pages. */
-+      for (i = 0; i < (1UL<<order); i++) {
-+              frame = success ? (out_frame + i) : in_frames[i];
-+              MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
-+                                      pfn_pte_ma(frame, PAGE_KERNEL), 0);
-+              set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, frame);
-+      }
-+
-+      cr_mcl[i - 1].args[MULTI_UVMFLAGS_INDEX] = order
-+                                                 ? UVMF_TLB_FLUSH|UVMF_ALL
-+                                                 : UVMF_INVLPG|UVMF_ALL;
-+      if (HYPERVISOR_multicall(cr_mcl, i))
-+              BUG();
-+
-+      if (success)
-+              contiguous_bitmap_set(__pa(vstart) >> PAGE_SHIFT,
-+                                    1UL << order);
-+
-+      balloon_unlock(flags);
-+
-+      return success ? 0 : -ENOMEM;
-+}
-+
-+void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
-+{
-+      unsigned long *out_frames = discontig_frames, in_frame;
-+      unsigned long  frame, i, flags;
-+      long           rc;
-+      int            success;
-+      struct xen_memory_exchange exchange = {
-+              .in = {
-+                      .nr_extents   = 1,
-+                      .extent_order = order,
-+                      .domid        = DOMID_SELF
-+              },
-+              .out = {
-+                      .nr_extents   = 1UL << order,
-+                      .extent_order = 0,
-+                      .domid        = DOMID_SELF
-+              }
-+      };
-+
-+      if (xen_feature(XENFEAT_auto_translated_physmap) ||
-+          !test_bit(__pa(vstart) >> PAGE_SHIFT, contiguous_bitmap))
-+              return;
-+
-+      if (unlikely(order > MAX_CONTIG_ORDER))
-+              return;
-+
-+      set_xen_guest_handle(exchange.in.extent_start, &in_frame);
-+      set_xen_guest_handle(exchange.out.extent_start, out_frames);
-+
-+      scrub_pages(vstart, 1 << order);
-+
-+      balloon_lock(flags);
-+
-+      contiguous_bitmap_clear(__pa(vstart) >> PAGE_SHIFT, 1UL << order);
-+
-+      /* 1. Find start MFN of contiguous extent. */
-+      in_frame = pfn_to_mfn(__pa(vstart) >> PAGE_SHIFT);
-+
-+      /* 2. Zap current PTEs. */
-+      for (i = 0; i < (1UL<<order); i++) {
-+              MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
-+                                      __pte_ma(0), 0);
-+              set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
-+                      INVALID_P2M_ENTRY);
-+              out_frames[i] = (__pa(vstart) >> PAGE_SHIFT) + i;
-+      }
-+      if (HYPERVISOR_multicall(cr_mcl, i))
-+              BUG();
-+
-+      /* 3. Do the exchange for non-contiguous MFNs. */
-+      rc = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
-+      success = (exchange.nr_exchanged == 1);
-+      BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
-+      BUG_ON(success && (rc != 0));
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (unlikely(rc == -ENOSYS)) {
-+              /* Compatibility when XENMEM_exchange is unsupported. */
-+              if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-+                                       &exchange.in) != 1)
-+                      BUG();
-+              if (HYPERVISOR_memory_op(XENMEM_populate_physmap,
-+                                       &exchange.out) != (1UL << order))
-+                      BUG();
-+              success = 1;
-+      }
-+#endif
-+
-+      /* 4. Map new pages in place of old pages. */
-+      for (i = 0; i < (1UL<<order); i++) {
-+              frame = success ? out_frames[i] : (in_frame + i);
-+              MULTI_update_va_mapping(cr_mcl + i, vstart + (i*PAGE_SIZE),
-+                                      pfn_pte_ma(frame, PAGE_KERNEL), 0);
-+              set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i, frame);
-+      }
-+
-+      cr_mcl[i - 1].args[MULTI_UVMFLAGS_INDEX] = order
-+                                                 ? UVMF_TLB_FLUSH|UVMF_ALL
-+                                                 : UVMF_INVLPG|UVMF_ALL;
-+      if (HYPERVISOR_multicall(cr_mcl, i))
-+              BUG();
-+
-+      balloon_unlock(flags);
-+}
-+
-+#ifdef __i386__
-+int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b)
-+{
-+      __u32 *lp = (__u32 *)((char *)ldt + entry * 8);
-+      maddr_t mach_lp = arbitrary_virt_to_machine(lp);
-+      return HYPERVISOR_update_descriptor(
-+              mach_lp, (u64)entry_a | ((u64)entry_b<<32));
-+}
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/init-xen.c linux-2.6.16.33/arch/i386/mm/init-xen.c
---- linux-2.6.16.33-noxen/arch/i386/mm/init-xen.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/init-xen.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,849 @@
-+/*
-+ *  linux/arch/i386/mm/init.c
-+ *
-+ *  Copyright (C) 1995  Linus Torvalds
-+ *
-+ *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/ptrace.h>
-+#include <linux/mman.h>
-+#include <linux/mm.h>
-+#include <linux/hugetlb.h>
-+#include <linux/swap.h>
-+#include <linux/smp.h>
-+#include <linux/init.h>
-+#include <linux/highmem.h>
-+#include <linux/pagemap.h>
-+#include <linux/bootmem.h>
-+#include <linux/slab.h>
-+#include <linux/proc_fs.h>
-+#include <linux/efi.h>
-+#include <linux/memory_hotplug.h>
-+#include <linux/initrd.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/scatterlist.h>
-+
-+#include <asm/processor.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/pgtable.h>
-+#include <asm/dma.h>
-+#include <asm/fixmap.h>
-+#include <asm/e820.h>
-+#include <asm/apic.h>
-+#include <asm/tlb.h>
-+#include <asm/tlbflush.h>
-+#include <asm/sections.h>
-+#include <asm/hypervisor.h>
-+#include <asm/swiotlb.h>
-+
-+extern unsigned long *contiguous_bitmap;
-+
-+unsigned int __VMALLOC_RESERVE = 128 << 20;
-+
-+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-+unsigned long highstart_pfn, highend_pfn;
-+
-+static int noinline do_test_wp_bit(void);
-+
-+/*
-+ * Creates a middle page table and puts a pointer to it in the
-+ * given global directory entry. This only returns the gd entry
-+ * in non-PAE compilation mode, since the middle layer is folded.
-+ */
-+static pmd_t * __init one_md_table_init(pgd_t *pgd)
-+{
-+      pud_t *pud;
-+      pmd_t *pmd_table;
-+              
-+#ifdef CONFIG_X86_PAE
-+      pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-+      make_lowmem_page_readonly(pmd_table, XENFEAT_writable_page_tables);
-+      set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
-+      pud = pud_offset(pgd, 0);
-+      if (pmd_table != pmd_offset(pud, 0)) 
-+              BUG();
-+#else
-+      pud = pud_offset(pgd, 0);
-+      pmd_table = pmd_offset(pud, 0);
-+#endif
-+
-+      return pmd_table;
-+}
-+
-+/*
-+ * Create a page table and place a pointer to it in a middle page
-+ * directory entry.
-+ */
-+static pte_t * __init one_page_table_init(pmd_t *pmd)
-+{
-+      if (pmd_none(*pmd)) {
-+              pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-+              make_lowmem_page_readonly(page_table,
-+                                        XENFEAT_writable_page_tables);
-+              set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
-+              if (page_table != pte_offset_kernel(pmd, 0))
-+                      BUG();  
-+
-+              return page_table;
-+      }
-+      
-+      return pte_offset_kernel(pmd, 0);
-+}
-+
-+/*
-+ * This function initializes a certain range of kernel virtual memory 
-+ * with new bootmem page tables, everywhere page tables are missing in
-+ * the given range.
-+ */
-+
-+/*
-+ * NOTE: The pagetables are allocated contiguous on the physical space 
-+ * so we can cache the place of the first one and move around without 
-+ * checking the pgd every time.
-+ */
-+static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      int pgd_idx, pmd_idx;
-+      unsigned long vaddr;
-+
-+      vaddr = start;
-+      pgd_idx = pgd_index(vaddr);
-+      pmd_idx = pmd_index(vaddr);
-+      pgd = pgd_base + pgd_idx;
-+
-+      for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
-+              if (pgd_none(*pgd)) 
-+                      one_md_table_init(pgd);
-+              pud = pud_offset(pgd, vaddr);
-+              pmd = pmd_offset(pud, vaddr);
-+              for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
-+                      if (vaddr < hypervisor_virt_start && pmd_none(*pmd))
-+                              one_page_table_init(pmd);
-+
-+                      vaddr += PMD_SIZE;
-+              }
-+              pmd_idx = 0;
-+      }
-+}
-+
-+static inline int is_kernel_text(unsigned long addr)
-+{
-+      if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * This maps the physical memory to kernel virtual address space, a total 
-+ * of max_low_pfn pages, by creating page tables starting from address 
-+ * PAGE_OFFSET.
-+ */
-+static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
-+{
-+      unsigned long pfn;
-+      pgd_t *pgd;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+      int pgd_idx, pmd_idx, pte_ofs;
-+
-+      unsigned long max_ram_pfn = xen_start_info->nr_pages;
-+      if (max_ram_pfn > max_low_pfn)
-+              max_ram_pfn = max_low_pfn;
-+
-+      pgd_idx = pgd_index(PAGE_OFFSET);
-+      pgd = pgd_base + pgd_idx;
-+      pfn = 0;
-+      pmd_idx = pmd_index(PAGE_OFFSET);
-+      pte_ofs = pte_index(PAGE_OFFSET);
-+
-+      for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
-+#ifdef CONFIG_XEN
-+              /*
-+               * Native linux hasn't PAE-paging enabled yet at this
-+               * point.  When running as xen domain we are in PAE
-+               * mode already, thus we can't simply hook a empty
-+               * pmd.  That would kill the mappings we are currently
-+               * using ...
-+               */
-+              pmd = pmd_offset(pud_offset(pgd, PAGE_OFFSET), PAGE_OFFSET);
-+#else
-+              pmd = one_md_table_init(pgd);
-+#endif
-+              if (pfn >= max_low_pfn)
-+                      continue;
-+              pmd += pmd_idx;
-+              for (; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
-+                      unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
-+                      if (address >= hypervisor_virt_start)
-+                              continue;
-+
-+                      /* Map with big pages if possible, otherwise create normal page tables. */
-+                      if (cpu_has_pse) {
-+                              unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
-+
-+                              if (is_kernel_text(address) || is_kernel_text(address2))
-+                                      set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
-+                              else
-+                                      set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
-+                              pfn += PTRS_PER_PTE;
-+                      } else {
-+                              pte = one_page_table_init(pmd);
-+
-+                              pte += pte_ofs;
-+                              for (; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
-+                                              /* XEN: Only map initial RAM allocation. */
-+                                              if ((pfn >= max_ram_pfn) || pte_present(*pte))
-+                                                      continue;
-+                                              if (is_kernel_text(address))
-+                                                      set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
-+                                              else
-+                                                      set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
-+                              }
-+                              pte_ofs = 0;
-+                      }
-+              }
-+              pmd_idx = 0;
-+      }
-+}
-+
-+#ifndef CONFIG_XEN
-+
-+static inline int page_kills_ppro(unsigned long pagenr)
-+{
-+      if (pagenr >= 0x70000 && pagenr <= 0x7003F)
-+              return 1;
-+      return 0;
-+}
-+
-+#else
-+
-+#define page_kills_ppro(p)    0
-+
-+#endif
-+
-+extern int is_available_memory(efi_memory_desc_t *);
-+
-+int page_is_ram(unsigned long pagenr)
-+{
-+      int i;
-+      unsigned long addr, end;
-+
-+      if (efi_enabled) {
-+              efi_memory_desc_t *md;
-+              void *p;
-+
-+              for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
-+                      md = p;
-+                      if (!is_available_memory(md))
-+                              continue;
-+                      addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT;
-+                      end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT;
-+
-+                      if ((pagenr >= addr) && (pagenr < end))
-+                              return 1;
-+              }
-+              return 0;
-+      }
-+
-+      for (i = 0; i < e820.nr_map; i++) {
-+
-+              if (e820.map[i].type != E820_RAM)       /* not usable memory */
-+                      continue;
-+              /*
-+               *      !!!FIXME!!! Some BIOSen report areas as RAM that
-+               *      are not. Notably the 640->1Mb area. We need a sanity
-+               *      check here.
-+               */
-+              addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
-+              end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
-+              if  ((pagenr >= addr) && (pagenr < end))
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+#ifdef CONFIG_HIGHMEM
-+pte_t *kmap_pte;
-+pgprot_t kmap_prot;
-+
-+#define kmap_get_fixmap_pte(vaddr)                                    \
-+      pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr))
-+
-+static void __init kmap_init(void)
-+{
-+      unsigned long kmap_vstart;
-+
-+      /* cache the first kmap pte */
-+      kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
-+      kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
-+
-+      kmap_prot = PAGE_KERNEL;
-+}
-+
-+static void __init permanent_kmaps_init(pgd_t *pgd_base)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+      unsigned long vaddr;
-+
-+      vaddr = PKMAP_BASE;
-+      page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
-+
-+      pgd = swapper_pg_dir + pgd_index(vaddr);
-+      pud = pud_offset(pgd, vaddr);
-+      pmd = pmd_offset(pud, vaddr);
-+      pte = pte_offset_kernel(pmd, vaddr);
-+      pkmap_page_table = pte; 
-+}
-+
-+static void __meminit free_new_highpage(struct page *page, int pfn)
-+{
-+      set_page_count(page, 1);
-+      if (pfn < xen_start_info->nr_pages)
-+              __free_page(page);
-+      totalhigh_pages++;
-+}
-+
-+void __init add_one_highpage_init(struct page *page, int pfn, int bad_ppro)
-+{
-+      if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) {
-+              ClearPageReserved(page);
-+              free_new_highpage(page, pfn);
-+      } else
-+              SetPageReserved(page);
-+}
-+
-+static int add_one_highpage_hotplug(struct page *page, unsigned long pfn)
-+{
-+      free_new_highpage(page, pfn);
-+      totalram_pages++;
-+#ifdef CONFIG_FLATMEM
-+      max_mapnr = max(pfn, max_mapnr);
-+#endif
-+      num_physpages++;
-+      return 0;
-+}
-+
-+/*
-+ * Not currently handling the NUMA case.
-+ * Assuming single node and all memory that
-+ * has been added dynamically that would be
-+ * onlined here is in HIGHMEM
-+ */
-+void online_page(struct page *page)
-+{
-+      ClearPageReserved(page);
-+      add_one_highpage_hotplug(page, page_to_pfn(page));
-+}
-+
-+
-+#ifdef CONFIG_NUMA
-+extern void set_highmem_pages_init(int);
-+#else
-+static void __init set_highmem_pages_init(int bad_ppro)
-+{
-+      int pfn;
-+      for (pfn = highstart_pfn; pfn < highend_pfn; pfn++)
-+              add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
-+      totalram_pages += totalhigh_pages;
-+}
-+#endif /* CONFIG_FLATMEM */
-+
-+#else
-+#define kmap_init() do { } while (0)
-+#define permanent_kmaps_init(pgd_base) do { } while (0)
-+#define set_highmem_pages_init(bad_ppro) do { } while (0)
-+#endif /* CONFIG_HIGHMEM */
-+
-+unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
-+EXPORT_SYMBOL(__PAGE_KERNEL);
-+unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
-+
-+#ifdef CONFIG_NUMA
-+extern void __init remap_numa_kva(void);
-+#else
-+#define remap_numa_kva() do {} while (0)
-+#endif
-+
-+pgd_t *swapper_pg_dir;
-+
-+static void __init pagetable_init (void)
-+{
-+      unsigned long vaddr;
-+      pgd_t *pgd_base = (pgd_t *)xen_start_info->pt_base;
-+
-+      swapper_pg_dir = pgd_base;
-+      init_mm.pgd    = pgd_base;
-+
-+      /* Enable PSE if available */
-+      if (cpu_has_pse) {
-+              set_in_cr4(X86_CR4_PSE);
-+      }
-+
-+      /* Enable PGE if available */
-+      if (cpu_has_pge) {
-+              set_in_cr4(X86_CR4_PGE);
-+              __PAGE_KERNEL |= _PAGE_GLOBAL;
-+              __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
-+      }
-+
-+      kernel_physical_mapping_init(pgd_base);
-+      remap_numa_kva();
-+
-+      /*
-+       * Fixed mappings, only the page table structure has to be
-+       * created - mappings will be set by set_fixmap():
-+       */
-+      vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-+      page_table_range_init(vaddr, hypervisor_virt_start, pgd_base);
-+
-+      permanent_kmaps_init(pgd_base);
-+}
-+
-+#ifdef CONFIG_SOFTWARE_SUSPEND
-+/*
-+ * Swap suspend & friends need this for resume because things like the intel-agp
-+ * driver might have split up a kernel 4MB mapping.
-+ */
-+char __nosavedata swsusp_pg_dir[PAGE_SIZE]
-+      __attribute__ ((aligned (PAGE_SIZE)));
-+
-+static inline void save_pg_dir(void)
-+{
-+      memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
-+}
-+#else
-+static inline void save_pg_dir(void)
-+{
-+}
-+#endif
-+
-+void zap_low_mappings (void)
-+{
-+      int i;
-+
-+      save_pg_dir();
-+
-+      /*
-+       * Zap initial low-memory mappings.
-+       *
-+       * Note that "pgd_clear()" doesn't do it for
-+       * us, because pgd_clear() is a no-op on i386.
-+       */
-+      for (i = 0; i < USER_PTRS_PER_PGD; i++)
-+#if defined(CONFIG_X86_PAE) && !defined(CONFIG_XEN)
-+              set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
-+#else
-+              set_pgd(swapper_pg_dir+i, __pgd(0));
-+#endif
-+      flush_tlb_all();
-+}
-+
-+static int disable_nx __initdata = 0;
-+u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
-+EXPORT_SYMBOL(__supported_pte_mask);
-+
-+/*
-+ * noexec = on|off
-+ *
-+ * Control non executable mappings.
-+ *
-+ * on      Enable
-+ * off     Disable
-+ */
-+void __init noexec_setup(const char *str)
-+{
-+      if (!strncmp(str, "on",2) && cpu_has_nx) {
-+              __supported_pte_mask |= _PAGE_NX;
-+              disable_nx = 0;
-+      } else if (!strncmp(str,"off",3)) {
-+              disable_nx = 1;
-+              __supported_pte_mask &= ~_PAGE_NX;
-+      }
-+}
-+
-+int nx_enabled = 0;
-+#ifdef CONFIG_X86_PAE
-+
-+static void __init set_nx(void)
-+{
-+      unsigned int v[4], l, h;
-+
-+      if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
-+              cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
-+              if ((v[3] & (1 << 20)) && !disable_nx) {
-+                      rdmsr(MSR_EFER, l, h);
-+                      l |= EFER_NX;
-+                      wrmsr(MSR_EFER, l, h);
-+                      nx_enabled = 1;
-+                      __supported_pte_mask |= _PAGE_NX;
-+              }
-+      }
-+}
-+
-+/*
-+ * Enables/disables executability of a given kernel page and
-+ * returns the previous setting.
-+ */
-+int __init set_kernel_exec(unsigned long vaddr, int enable)
-+{
-+      pte_t *pte;
-+      int ret = 1;
-+
-+      if (!nx_enabled)
-+              goto out;
-+
-+      pte = lookup_address(vaddr);
-+      BUG_ON(!pte);
-+
-+      if (!pte_exec_kernel(*pte))
-+              ret = 0;
-+
-+      if (enable)
-+              pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
-+      else
-+              pte->pte_high |= 1 << (_PAGE_BIT_NX - 32);
-+      __flush_tlb_all();
-+out:
-+      return ret;
-+}
-+
-+#endif
-+
-+/*
-+ * paging_init() sets up the page tables - note that the first 8MB are
-+ * already mapped by head.S.
-+ *
-+ * This routines also unmaps the page at virtual kernel address 0, so
-+ * that we can trap those pesky NULL-reference errors in the kernel.
-+ */
-+void __init paging_init(void)
-+{
-+      int i;
-+
-+#ifdef CONFIG_X86_PAE
-+      set_nx();
-+      if (nx_enabled)
-+              printk("NX (Execute Disable) protection: active\n");
-+#endif
-+
-+      pagetable_init();
-+
-+#if defined(CONFIG_X86_PAE) && !defined(CONFIG_XEN)
-+      /*
-+       * We will bail out later - printk doesn't work right now so
-+       * the user would just see a hanging kernel.
-+       * when running as xen domain we are already in PAE mode at
-+       * this point.
-+       */
-+      if (cpu_has_pae)
-+              set_in_cr4(X86_CR4_PAE);
-+#endif
-+      __flush_tlb_all();
-+
-+      kmap_init();
-+
-+      /* Switch to the real shared_info page, and clear the
-+       * dummy page. */
-+      set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-+      HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-+      memset(empty_zero_page, 0, sizeof(empty_zero_page));
-+
-+      /* Setup mapping of lower 1st MB */
-+      for (i = 0; i < NR_FIX_ISAMAPS; i++)
-+              if (is_initial_xendomain())
-+                      set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
-+              else
-+                      __set_fixmap(FIX_ISAMAP_BEGIN - i,
-+                                   virt_to_machine(empty_zero_page),
-+                                   PAGE_KERNEL_RO);
-+}
-+
-+/*
-+ * Test if the WP bit works in supervisor mode. It isn't supported on 386's
-+ * and also on some strange 486's (NexGen etc.). All 586+'s are OK. This
-+ * used to involve black magic jumps to work around some nasty CPU bugs,
-+ * but fortunately the switch to using exceptions got rid of all that.
-+ */
-+
-+static void __init test_wp_bit(void)
-+{
-+      printk("Checking if this processor honours the WP bit even in supervisor mode... ");
-+
-+      /* Any page-aligned address will do, the test is non-destructive */
-+      __set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_READONLY);
-+      boot_cpu_data.wp_works_ok = do_test_wp_bit();
-+      clear_fixmap(FIX_WP_TEST);
-+
-+      if (!boot_cpu_data.wp_works_ok) {
-+              printk("No.\n");
-+#ifdef CONFIG_X86_WP_WORKS_OK
-+              panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
-+#endif
-+      } else {
-+              printk("Ok.\n");
-+      }
-+}
-+
-+static void __init set_max_mapnr_init(void)
-+{
-+#ifdef CONFIG_HIGHMEM
-+      num_physpages = highend_pfn;
-+#else
-+      num_physpages = max_low_pfn;
-+#endif
-+#ifdef CONFIG_FLATMEM
-+      max_mapnr = num_physpages;
-+#endif
-+}
-+
-+static struct kcore_list kcore_mem, kcore_vmalloc; 
-+
-+void __init mem_init(void)
-+{
-+      extern int ppro_with_ram_bug(void);
-+      int codesize, reservedpages, datasize, initsize;
-+      int tmp;
-+      int bad_ppro;
-+      unsigned long pfn;
-+
-+      contiguous_bitmap = alloc_bootmem_low_pages(
-+              (max_low_pfn + 2*BITS_PER_LONG) >> 3);
-+      BUG_ON(!contiguous_bitmap);
-+      memset(contiguous_bitmap, 0, (max_low_pfn + 2*BITS_PER_LONG) >> 3);
-+
-+#if defined(CONFIG_SWIOTLB)
-+      swiotlb_init(); 
-+#endif
-+
-+#ifdef CONFIG_FLATMEM
-+      if (!mem_map)
-+              BUG();
-+#endif
-+      
-+      bad_ppro = ppro_with_ram_bug();
-+
-+#ifdef CONFIG_HIGHMEM
-+      /* check that fixmap and pkmap do not overlap */
-+      if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
-+              printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n");
-+              printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",
-+                              PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START);
-+              BUG();
-+      }
-+#endif
-+ 
-+      set_max_mapnr_init();
-+
-+#ifdef CONFIG_HIGHMEM
-+      high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
-+#else
-+      high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
-+#endif
-+      printk("vmalloc area: %lx-%lx, maxmem %lx\n",
-+             VMALLOC_START,VMALLOC_END,MAXMEM);
-+      BUG_ON(VMALLOC_START > VMALLOC_END);
-+      
-+      /* this will put all low memory onto the freelists */
-+      totalram_pages += free_all_bootmem();
-+      /* XEN: init and count low-mem pages outside initial allocation. */
-+      for (pfn = xen_start_info->nr_pages; pfn < max_low_pfn; pfn++) {
-+              ClearPageReserved(pfn_to_page(pfn));
-+              set_page_count(pfn_to_page(pfn), 1);
-+              totalram_pages++;
-+      }
-+
-+      reservedpages = 0;
-+      for (tmp = 0; tmp < max_low_pfn; tmp++)
-+              /*
-+               * Only count reserved RAM pages
-+               */
-+              if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
-+                      reservedpages++;
-+
-+      set_highmem_pages_init(bad_ppro);
-+
-+      codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-+      datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-+      initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-+
-+      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
-+      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 
-+                 VMALLOC_END-VMALLOC_START);
-+
-+      printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
-+              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-+              num_physpages << (PAGE_SHIFT-10),
-+              codesize >> 10,
-+              reservedpages << (PAGE_SHIFT-10),
-+              datasize >> 10,
-+              initsize >> 10,
-+              (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
-+             );
-+
-+#ifdef CONFIG_X86_PAE
-+      if (!cpu_has_pae)
-+              panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
-+#endif
-+      if (boot_cpu_data.wp_works_ok < 0)
-+              test_wp_bit();
-+
-+      /*
-+       * Subtle. SMP is doing it's boot stuff late (because it has to
-+       * fork idle threads) - but it also needs low mappings for the
-+       * protected-mode entry to work. We zap these entries only after
-+       * the WP-bit has been tested.
-+       */
-+#ifndef CONFIG_SMP
-+      zap_low_mappings();
-+#endif
-+
-+      set_bit(PG_pinned, &virt_to_page(init_mm.pgd)->flags);
-+}
-+
-+/*
-+ * this is for the non-NUMA, single node SMP system case.
-+ * Specifically, in the case of x86, we will always add
-+ * memory to the highmem for now.
-+ */
-+#ifndef CONFIG_NEED_MULTIPLE_NODES
-+int add_memory(u64 start, u64 size)
-+{
-+      struct pglist_data *pgdata = &contig_page_data;
-+      struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
-+      unsigned long start_pfn = start >> PAGE_SHIFT;
-+      unsigned long nr_pages = size >> PAGE_SHIFT;
-+
-+      return __add_pages(zone, start_pfn, nr_pages);
-+}
-+
-+int remove_memory(u64 start, u64 size)
-+{
-+      return -EINVAL;
-+}
-+#endif
-+
-+kmem_cache_t *pgd_cache;
-+kmem_cache_t *pmd_cache;
-+
-+void __init pgtable_cache_init(void)
-+{
-+      if (PTRS_PER_PMD > 1) {
-+              pmd_cache = kmem_cache_create("pmd",
-+                                      PTRS_PER_PMD*sizeof(pmd_t),
-+                                      PTRS_PER_PMD*sizeof(pmd_t),
-+                                      0,
-+                                      pmd_ctor,
-+                                      NULL);
-+              if (!pmd_cache)
-+                      panic("pgtable_cache_init(): cannot create pmd cache");
-+      }
-+      pgd_cache = kmem_cache_create("pgd",
-+#ifndef CONFIG_XEN
-+                              PTRS_PER_PGD*sizeof(pgd_t),
-+                              PTRS_PER_PGD*sizeof(pgd_t),
-+#else
-+                              PAGE_SIZE,
-+                              PAGE_SIZE,
-+#endif
-+                              0,
-+                              pgd_ctor,
-+                              PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
-+      if (!pgd_cache)
-+              panic("pgtable_cache_init(): Cannot create pgd cache");
-+}
-+
-+/*
-+ * This function cannot be __init, since exceptions don't work in that
-+ * section.  Put this after the callers, so that it cannot be inlined.
-+ */
-+static int noinline do_test_wp_bit(void)
-+{
-+      char tmp_reg;
-+      int flag;
-+
-+      __asm__ __volatile__(
-+              "       movb %0,%1      \n"
-+              "1:     movb %1,%0      \n"
-+              "       xorl %2,%2      \n"
-+              "2:                     \n"
-+              ".section __ex_table,\"a\"\n"
-+              "       .align 4        \n"
-+              "       .long 1b,2b     \n"
-+              ".previous              \n"
-+              :"=m" (*(char *)fix_to_virt(FIX_WP_TEST)),
-+               "=q" (tmp_reg),
-+               "=r" (flag)
-+              :"2" (1)
-+              :"memory");
-+      
-+      return flag;
-+}
-+
-+void free_initmem(void)
-+{
-+      unsigned long addr;
-+
-+      addr = (unsigned long)(&__init_begin);
-+      for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
-+              ClearPageReserved(virt_to_page(addr));
-+              set_page_count(virt_to_page(addr), 1);
-+              memset((void *)addr, 0xcc, PAGE_SIZE);
-+              free_page(addr);
-+              totalram_pages++;
-+      }
-+      printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
-+}
-+
-+#ifdef CONFIG_DEBUG_RODATA
-+
-+extern char __start_rodata, __end_rodata;
-+void mark_rodata_ro(void)
-+{
-+      unsigned long addr = (unsigned long)&__start_rodata;
-+
-+      for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
-+              change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO);
-+
-+      printk ("Write protecting the kernel read-only data: %luk\n",
-+                      (unsigned long)(&__end_rodata - &__start_rodata) >> 10);
-+
-+      /*
-+       * change_page_attr() requires a global_flush_tlb() call after it.
-+       * We do this after the printk so that if something went wrong in the
-+       * change, the printk gets out at least to give a better debug hint
-+       * of who is the culprit.
-+       */
-+      global_flush_tlb();
-+}
-+#endif
-+
-+
-+#ifdef CONFIG_BLK_DEV_INITRD
-+void free_initrd_mem(unsigned long start, unsigned long end)
-+{
-+      if (start < end)
-+              printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
-+      for (; start < end; start += PAGE_SIZE) {
-+              ClearPageReserved(virt_to_page(start));
-+              set_page_count(virt_to_page(start), 1);
-+              free_page(start);
-+              totalram_pages++;
-+      }
-+}
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/ioremap-xen.c linux-2.6.16.33/arch/i386/mm/ioremap-xen.c
---- linux-2.6.16.33-noxen/arch/i386/mm/ioremap-xen.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/ioremap-xen.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,447 @@
-+/*
-+ * arch/i386/mm/ioremap.c
-+ *
-+ * Re-map IO memory to kernel address space so that we can access it.
-+ * This is needed for high PCI addresses that aren't mapped in the
-+ * 640k-1MB IO memory area on PC's
-+ *
-+ * (C) Copyright 1995 1996 Linus Torvalds
-+ */
-+
-+#include <linux/vmalloc.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <asm/io.h>
-+#include <asm/fixmap.h>
-+#include <asm/cacheflush.h>
-+#include <asm/tlbflush.h>
-+#include <asm/pgtable.h>
-+#include <asm/pgalloc.h>
-+
-+#define ISA_START_ADDRESS     0x0
-+#define ISA_END_ADDRESS               0x100000
-+
-+static int direct_remap_area_pte_fn(pte_t *pte, 
-+                                  struct page *pmd_page,
-+                                  unsigned long address, 
-+                                  void *data)
-+{
-+      mmu_update_t **v = (mmu_update_t **)data;
-+
-+      BUG_ON(!pte_none(*pte));
-+
-+      (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
-+                   PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
-+      (*v)++;
-+
-+      return 0;
-+}
-+
-+static int __direct_remap_pfn_range(struct mm_struct *mm,
-+                                  unsigned long address, 
-+                                  unsigned long mfn,
-+                                  unsigned long size, 
-+                                  pgprot_t prot,
-+                                  domid_t  domid)
-+{
-+      int rc;
-+      unsigned long i, start_address;
-+      mmu_update_t *u, *v, *w;
-+
-+      u = v = w = (mmu_update_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-+      if (u == NULL)
-+              return -ENOMEM;
-+
-+      start_address = address;
-+
-+      flush_cache_all();
-+
-+      for (i = 0; i < size; i += PAGE_SIZE) {
-+              if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
-+                      /* Flush a full batch after filling in the PTE ptrs. */
-+                      rc = apply_to_page_range(mm, start_address, 
-+                                               address - start_address,
-+                                               direct_remap_area_pte_fn, &w);
-+                      if (rc)
-+                              goto out;
-+                      rc = -EFAULT;
-+                      if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
-+                              goto out;
-+                      v = w = u;
-+                      start_address = address;
-+              }
-+
-+              /*
-+               * Fill in the machine address: PTE ptr is done later by
-+               * __direct_remap_area_pages(). 
-+               */
-+              v->val = pte_val_ma(pfn_pte_ma(mfn, prot));
-+
-+              mfn++;
-+              address += PAGE_SIZE; 
-+              v++;
-+      }
-+
-+      if (v != u) {
-+              /* Final batch. */
-+              rc = apply_to_page_range(mm, start_address,
-+                                       address - start_address,
-+                                       direct_remap_area_pte_fn, &w);
-+              if (rc)
-+                      goto out;
-+              rc = -EFAULT;
-+              if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
-+                      goto out;
-+      }
-+
-+      rc = 0;
-+
-+ out:
-+      flush_tlb_all();
-+
-+      free_page((unsigned long)u);
-+
-+      return rc;
-+}
-+
-+int direct_remap_pfn_range(struct vm_area_struct *vma,
-+                         unsigned long address, 
-+                         unsigned long mfn,
-+                         unsigned long size, 
-+                         pgprot_t prot,
-+                         domid_t  domid)
-+{
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return remap_pfn_range(vma, address, mfn, size, prot);
-+
-+      if (domid == DOMID_SELF)
-+              return -EINVAL;
-+
-+      vma->vm_flags |= VM_IO | VM_RESERVED;
-+
-+      vma->vm_mm->context.has_foreign_mappings = 1;
-+
-+      return __direct_remap_pfn_range(
-+              vma->vm_mm, address, mfn, size, prot, domid);
-+}
-+EXPORT_SYMBOL(direct_remap_pfn_range);
-+
-+int direct_kernel_remap_pfn_range(unsigned long address, 
-+                                unsigned long mfn,
-+                                unsigned long size, 
-+                                pgprot_t prot,
-+                                domid_t  domid)
-+{
-+      return __direct_remap_pfn_range(
-+              &init_mm, address, mfn, size, prot, domid);
-+}
-+EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
-+
-+static int lookup_pte_fn(
-+      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
-+{
-+      uint64_t *ptep = (uint64_t *)data;
-+      if (ptep)
-+              *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
-+                       PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
-+      return 0;
-+}
-+
-+int create_lookup_pte_addr(struct mm_struct *mm, 
-+                         unsigned long address,
-+                         uint64_t *ptep)
-+{
-+      return apply_to_page_range(mm, address, PAGE_SIZE,
-+                                 lookup_pte_fn, ptep);
-+}
-+
-+EXPORT_SYMBOL(create_lookup_pte_addr);
-+
-+static int noop_fn(
-+      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
-+{
-+      return 0;
-+}
-+
-+int touch_pte_range(struct mm_struct *mm,
-+                  unsigned long address,
-+                  unsigned long size)
-+{
-+      return apply_to_page_range(mm, address, size, noop_fn, NULL);
-+} 
-+
-+EXPORT_SYMBOL(touch_pte_range);
-+
-+/*
-+ * Does @address reside within a non-highmem page that is local to this virtual
-+ * machine (i.e., not an I/O page, nor a memory page belonging to another VM).
-+ * See the comment that accompanies mfn_to_local_pfn() in page.h to understand
-+ * why this works.
-+ */
-+static inline int is_local_lowmem(unsigned long address)
-+{
-+      extern unsigned long max_low_pfn;
-+      return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
-+}
-+
-+/*
-+ * Generic mapping function (not visible outside):
-+ */
-+
-+/*
-+ * Remap an arbitrary physical address space into the kernel virtual
-+ * address space. Needed when the kernel wants to access high addresses
-+ * directly.
-+ *
-+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
-+ * have to convert them into an offset in a page-aligned mapping, but the
-+ * caller shouldn't need to know that small detail.
-+ */
-+void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
-+{
-+      void __iomem * addr;
-+      struct vm_struct * area;
-+      unsigned long offset, last_addr;
-+      domid_t domid = DOMID_IO;
-+
-+      /* Don't allow wraparound or zero size */
-+      last_addr = phys_addr + size - 1;
-+      if (!size || last_addr < phys_addr)
-+              return NULL;
-+
-+      /*
-+       * Don't remap the low PCI/ISA area, it's always mapped..
-+       */
-+      if (is_initial_xendomain() &&
-+          phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
-+              return (void __iomem *) isa_bus_to_virt(phys_addr);
-+
-+      /*
-+       * Don't allow anybody to remap normal RAM that we're using..
-+       */
-+      if (is_local_lowmem(phys_addr)) {
-+              char *t_addr, *t_end;
-+              struct page *page;
-+
-+              t_addr = bus_to_virt(phys_addr);
-+              t_end = t_addr + (size - 1);
-+         
-+              for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
-+                      if(!PageReserved(page))
-+                              return NULL;
-+
-+              domid = DOMID_SELF;
-+      }
-+
-+      /*
-+       * Mappings have to be page-aligned
-+       */
-+      offset = phys_addr & ~PAGE_MASK;
-+      phys_addr &= PAGE_MASK;
-+      size = PAGE_ALIGN(last_addr+1) - phys_addr;
-+
-+      /*
-+       * Ok, go for it..
-+       */
-+      area = get_vm_area(size, VM_IOREMAP | (flags << 20));
-+      if (!area)
-+              return NULL;
-+      area->phys_addr = phys_addr;
-+      addr = (void __iomem *) area->addr;
-+      flags |= _KERNPG_TABLE;
-+      if (__direct_remap_pfn_range(&init_mm, (unsigned long)addr,
-+                                   phys_addr>>PAGE_SHIFT,
-+                                   size, __pgprot(flags), domid)) {
-+              vunmap((void __force *) addr);
-+              return NULL;
-+      }
-+      return (void __iomem *) (offset + (char __iomem *)addr);
-+}
-+EXPORT_SYMBOL(__ioremap);
-+
-+/**
-+ * ioremap_nocache     -   map bus memory into CPU space
-+ * @offset:    bus address of the memory
-+ * @size:      size of the resource to map
-+ *
-+ * ioremap_nocache performs a platform specific sequence of operations to
-+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
-+ * writew/writel functions and the other mmio helpers. The returned
-+ * address is not guaranteed to be usable directly as a virtual
-+ * address. 
-+ *
-+ * This version of ioremap ensures that the memory is marked uncachable
-+ * on the CPU as well as honouring existing caching rules from things like
-+ * the PCI bus. Note that there are other caches and buffers on many 
-+ * busses. In particular driver authors should read up on PCI writes
-+ *
-+ * It's useful if some control registers are in such an area and
-+ * write combining or read caching is not desirable:
-+ * 
-+ * Must be freed with iounmap.
-+ */
-+
-+void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
-+{
-+      unsigned long last_addr;
-+      void __iomem *p = __ioremap(phys_addr, size, _PAGE_PCD);
-+      if (!p) 
-+              return p; 
-+
-+      /* Guaranteed to be > phys_addr, as per __ioremap() */
-+      last_addr = phys_addr + size - 1;
-+
-+      if (is_local_lowmem(last_addr)) { 
-+              struct page *ppage = virt_to_page(bus_to_virt(phys_addr));
-+              unsigned long npages;
-+
-+              phys_addr &= PAGE_MASK;
-+
-+              /* This might overflow and become zero.. */
-+              last_addr = PAGE_ALIGN(last_addr);
-+
-+              /* .. but that's ok, because modulo-2**n arithmetic will make
-+              * the page-aligned "last - first" come out right.
-+              */
-+              npages = (last_addr - phys_addr) >> PAGE_SHIFT;
-+
-+              if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) { 
-+                      iounmap(p); 
-+                      p = NULL;
-+              }
-+              global_flush_tlb();
-+      }
-+
-+      return p;                                       
-+}
-+EXPORT_SYMBOL(ioremap_nocache);
-+
-+/**
-+ * iounmap - Free a IO remapping
-+ * @addr: virtual address from ioremap_*
-+ *
-+ * Caller must ensure there is only one unmapping for the same pointer.
-+ */
-+void iounmap(volatile void __iomem *addr)
-+{
-+      struct vm_struct *p, *o;
-+
-+      if ((void __force *)addr <= high_memory)
-+              return;
-+
-+      /*
-+       * __ioremap special-cases the PCI/ISA range by not instantiating a
-+       * vm_area and by simply returning an address into the kernel mapping
-+       * of ISA space.   So handle that here.
-+       */
-+      if ((unsigned long) addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
-+              return;
-+
-+      addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr);
-+
-+      /* Use the vm area unlocked, assuming the caller
-+         ensures there isn't another iounmap for the same address
-+         in parallel. Reuse of the virtual address is prevented by
-+         leaving it in the global lists until we're done with it.
-+         cpa takes care of the direct mappings. */
-+      read_lock(&vmlist_lock);
-+      for (p = vmlist; p; p = p->next) {
-+              if (p->addr == addr)
-+                      break;
-+      }
-+      read_unlock(&vmlist_lock);
-+
-+      if (!p) {
-+              printk("iounmap: bad address %p\n", addr);
-+              dump_stack();
-+              return;
-+      }
-+
-+      /* Reset the direct mapping. Can block */
-+      if ((p->flags >> 20) && is_local_lowmem(p->phys_addr)) {
-+              /* p->size includes the guard page, but cpa doesn't like that */
-+              change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)),
-+                               (p->size - PAGE_SIZE) >> PAGE_SHIFT,
-+                               PAGE_KERNEL);
-+              global_flush_tlb();
-+      } 
-+
-+      /* Finally remove it */
-+      o = remove_vm_area((void *)addr);
-+      BUG_ON(p != o || o == NULL);
-+      kfree(p); 
-+}
-+EXPORT_SYMBOL(iounmap);
-+
-+#ifdef __i386__
-+
-+void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
-+{
-+      unsigned long offset, last_addr;
-+      unsigned int nrpages;
-+      enum fixed_addresses idx;
-+
-+      /* Don't allow wraparound or zero size */
-+      last_addr = phys_addr + size - 1;
-+      if (!size || last_addr < phys_addr)
-+              return NULL;
-+
-+      /*
-+       * Don't remap the low PCI/ISA area, it's always mapped..
-+       */
-+      if (is_initial_xendomain() &&
-+          phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
-+              return isa_bus_to_virt(phys_addr);
-+
-+      /*
-+       * Mappings have to be page-aligned
-+       */
-+      offset = phys_addr & ~PAGE_MASK;
-+      phys_addr &= PAGE_MASK;
-+      size = PAGE_ALIGN(last_addr) - phys_addr;
-+
-+      /*
-+       * Mappings have to fit in the FIX_BTMAP area.
-+       */
-+      nrpages = size >> PAGE_SHIFT;
-+      if (nrpages > NR_FIX_BTMAPS)
-+              return NULL;
-+
-+      /*
-+       * Ok, go for it..
-+       */
-+      idx = FIX_BTMAP_BEGIN;
-+      while (nrpages > 0) {
-+              set_fixmap(idx, phys_addr);
-+              phys_addr += PAGE_SIZE;
-+              --idx;
-+              --nrpages;
-+      }
-+      return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
-+}
-+
-+void __init bt_iounmap(void *addr, unsigned long size)
-+{
-+      unsigned long virt_addr;
-+      unsigned long offset;
-+      unsigned int nrpages;
-+      enum fixed_addresses idx;
-+
-+      virt_addr = (unsigned long)addr;
-+      if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))
-+              return;
-+      if (virt_addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
-+              return;
-+      offset = virt_addr & ~PAGE_MASK;
-+      nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
-+
-+      idx = FIX_BTMAP_BEGIN;
-+      while (nrpages > 0) {
-+              clear_fixmap(idx);
-+              --idx;
-+              --nrpages;
-+      }
-+}
-+
-+#endif /* __i386__ */
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/pageattr.c linux-2.6.16.33/arch/i386/mm/pageattr.c
---- linux-2.6.16.33-noxen/arch/i386/mm/pageattr.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/pageattr.c    2007-05-23 21:00:01.000000000 +0000
-@@ -78,7 +78,7 @@
-       unsigned long flags;
-       set_pte_atomic(kpte, pte);      /* change init_mm */
--      if (PTRS_PER_PMD > 1)
-+      if (HAVE_SHARED_KERNEL_PMD)
-               return;
-       spin_lock_irqsave(&pgd_lock, flags);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/pgtable-xen.c linux-2.6.16.33/arch/i386/mm/pgtable-xen.c
---- linux-2.6.16.33-noxen/arch/i386/mm/pgtable-xen.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/pgtable-xen.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,707 @@
-+/*
-+ *  linux/arch/i386/mm/pgtable.c
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/mm.h>
-+#include <linux/swap.h>
-+#include <linux/smp.h>
-+#include <linux/highmem.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
-+#include <linux/spinlock.h>
-+#include <linux/module.h>
-+
-+#include <asm/system.h>
-+#include <asm/pgtable.h>
-+#include <asm/pgalloc.h>
-+#include <asm/fixmap.h>
-+#include <asm/e820.h>
-+#include <asm/tlb.h>
-+#include <asm/tlbflush.h>
-+#include <asm/io.h>
-+#include <asm/mmu_context.h>
-+
-+#include <xen/features.h>
-+#include <xen/foreign_page.h>
-+#include <asm/hypervisor.h>
-+
-+static void pgd_test_and_unpin(pgd_t *pgd);
-+
-+void show_mem(void)
-+{
-+      int total = 0, reserved = 0;
-+      int shared = 0, cached = 0;
-+      int highmem = 0;
-+      struct page *page;
-+      pg_data_t *pgdat;
-+      unsigned long i;
-+      struct page_state ps;
-+      unsigned long flags;
-+
-+      printk(KERN_INFO "Mem-info:\n");
-+      show_free_areas();
-+      printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-+      for_each_pgdat(pgdat) {
-+              pgdat_resize_lock(pgdat, &flags);
-+              for (i = 0; i < pgdat->node_spanned_pages; ++i) {
-+                      page = pgdat_page_nr(pgdat, i);
-+                      total++;
-+                      if (PageHighMem(page))
-+                              highmem++;
-+                      if (PageReserved(page))
-+                              reserved++;
-+                      else if (PageSwapCache(page))
-+                              cached++;
-+                      else if (page_count(page))
-+                              shared += page_count(page) - 1;
-+              }
-+              pgdat_resize_unlock(pgdat, &flags);
-+      }
-+      printk(KERN_INFO "%d pages of RAM\n", total);
-+      printk(KERN_INFO "%d pages of HIGHMEM\n", highmem);
-+      printk(KERN_INFO "%d reserved pages\n", reserved);
-+      printk(KERN_INFO "%d pages shared\n", shared);
-+      printk(KERN_INFO "%d pages swap cached\n", cached);
-+
-+      get_page_state(&ps);
-+      printk(KERN_INFO "%lu pages dirty\n", ps.nr_dirty);
-+      printk(KERN_INFO "%lu pages writeback\n", ps.nr_writeback);
-+      printk(KERN_INFO "%lu pages mapped\n", ps.nr_mapped);
-+      printk(KERN_INFO "%lu pages slab\n", ps.nr_slab);
-+      printk(KERN_INFO "%lu pages pagetables\n", ps.nr_page_table_pages);
-+}
-+
-+/*
-+ * Associate a virtual page frame with a given physical page frame 
-+ * and protection flags for that frame.
-+ */ 
-+static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+
-+      pgd = swapper_pg_dir + pgd_index(vaddr);
-+      if (pgd_none(*pgd)) {
-+              BUG();
-+              return;
-+      }
-+      pud = pud_offset(pgd, vaddr);
-+      if (pud_none(*pud)) {
-+              BUG();
-+              return;
-+      }
-+      pmd = pmd_offset(pud, vaddr);
-+      if (pmd_none(*pmd)) {
-+              BUG();
-+              return;
-+      }
-+      pte = pte_offset_kernel(pmd, vaddr);
-+      if (pgprot_val(flags))
-+              /* <pfn,flags> stored as-is, to permit clearing entries */
-+              set_pte(pte, pfn_pte(pfn, flags));
-+      else
-+              pte_clear(&init_mm, vaddr, pte);
-+
-+      /*
-+       * It's enough to flush this one mapping.
-+       * (PGE mappings get flushed as well)
-+       */
-+      __flush_tlb_one(vaddr);
-+}
-+
-+/*
-+ * Associate a virtual page frame with a given physical page frame 
-+ * and protection flags for that frame.
-+ */ 
-+static void set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn,
-+                         pgprot_t flags)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+
-+      pgd = swapper_pg_dir + pgd_index(vaddr);
-+      if (pgd_none(*pgd)) {
-+              BUG();
-+              return;
-+      }
-+      pud = pud_offset(pgd, vaddr);
-+      if (pud_none(*pud)) {
-+              BUG();
-+              return;
-+      }
-+      pmd = pmd_offset(pud, vaddr);
-+      if (pmd_none(*pmd)) {
-+              BUG();
-+              return;
-+      }
-+      pte = pte_offset_kernel(pmd, vaddr);
-+      if (pgprot_val(flags))
-+              /* <pfn,flags> stored as-is, to permit clearing entries */
-+              set_pte(pte, pfn_pte_ma(pfn, flags));
-+      else
-+              pte_clear(&init_mm, vaddr, pte);
-+
-+      /*
-+       * It's enough to flush this one mapping.
-+       * (PGE mappings get flushed as well)
-+       */
-+      __flush_tlb_one(vaddr);
-+}
-+
-+/*
-+ * Associate a large virtual page frame with a given physical page frame 
-+ * and protection flags for that frame. pfn is for the base of the page,
-+ * vaddr is what the page gets mapped to - both must be properly aligned. 
-+ * The pmd must already be instantiated. Assumes PAE mode.
-+ */ 
-+void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+
-+      if (vaddr & (PMD_SIZE-1)) {             /* vaddr is misaligned */
-+              printk(KERN_WARNING "set_pmd_pfn: vaddr misaligned\n");
-+              return; /* BUG(); */
-+      }
-+      if (pfn & (PTRS_PER_PTE-1)) {           /* pfn is misaligned */
-+              printk(KERN_WARNING "set_pmd_pfn: pfn misaligned\n");
-+              return; /* BUG(); */
-+      }
-+      pgd = swapper_pg_dir + pgd_index(vaddr);
-+      if (pgd_none(*pgd)) {
-+              printk(KERN_WARNING "set_pmd_pfn: pgd_none\n");
-+              return; /* BUG(); */
-+      }
-+      pud = pud_offset(pgd, vaddr);
-+      pmd = pmd_offset(pud, vaddr);
-+      set_pmd(pmd, pfn_pmd(pfn, flags));
-+      /*
-+       * It's enough to flush this one mapping.
-+       * (PGE mappings get flushed as well)
-+       */
-+      __flush_tlb_one(vaddr);
-+}
-+
-+static int nr_fixmaps = 0;
-+unsigned long hypervisor_virt_start = HYPERVISOR_VIRT_START;
-+unsigned long __FIXADDR_TOP = (HYPERVISOR_VIRT_START - 2 * PAGE_SIZE);
-+EXPORT_SYMBOL(__FIXADDR_TOP);
-+
-+void __init set_fixaddr_top()
-+{
-+      BUG_ON(nr_fixmaps > 0);
-+      __FIXADDR_TOP = hypervisor_virt_start - 2 * PAGE_SIZE;
-+}
-+
-+void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
-+{
-+      unsigned long address = __fix_to_virt(idx);
-+
-+      if (idx >= __end_of_fixed_addresses) {
-+              BUG();
-+              return;
-+      }
-+      switch (idx) {
-+      case FIX_WP_TEST:
-+#ifdef CONFIG_X86_F00F_BUG
-+      case FIX_F00F_IDT:
-+#endif
-+              set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
-+              break;
-+      default:
-+              set_pte_pfn_ma(address, phys >> PAGE_SHIFT, flags);
-+              break;
-+      }
-+      nr_fixmaps++;
-+}
-+
-+pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
-+{
-+      pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
-+      if (pte)
-+              make_lowmem_page_readonly(pte, XENFEAT_writable_page_tables);
-+      return pte;
-+}
-+
-+struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
-+{
-+      struct page *pte;
-+
-+#ifdef CONFIG_HIGHPTE
-+      pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
-+#else
-+      pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
-+      if (pte) {
-+              SetPageForeign(pte, pte_free);
-+              set_page_count(pte, 1);
-+      }
-+#endif
-+      return pte;
-+}
-+
-+void pte_free(struct page *pte)
-+{
-+      unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
-+
-+      if (!pte_write(*virt_to_ptep(va)))
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                      va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
-+
-+      ClearPageForeign(pte);
-+      set_page_count(pte, 1);
-+
-+      __free_page(pte);
-+}
-+
-+void pmd_ctor(void *pmd, kmem_cache_t *cache, unsigned long flags)
-+{
-+      memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
-+}
-+
-+/*
-+ * List of all pgd's needed for non-PAE so it can invalidate entries
-+ * in both cached and uncached pgd's; not needed for PAE since the
-+ * kernel pmd is shared. If PAE were not to share the pmd a similar
-+ * tactic would be needed. This is essentially codepath-based locking
-+ * against pageattr.c; it is the unique case in which a valid change
-+ * of kernel pagetables can't be lazily synchronized by vmalloc faults.
-+ * vmalloc faults work because attached pagetables are never freed.
-+ * The locking scheme was chosen on the basis of manfred's
-+ * recommendations and having no core impact whatsoever.
-+ * -- wli
-+ */
-+DEFINE_SPINLOCK(pgd_lock);
-+struct page *pgd_list;
-+
-+static inline void pgd_list_add(pgd_t *pgd)
-+{
-+      struct page *page = virt_to_page(pgd);
-+      page->index = (unsigned long)pgd_list;
-+      if (pgd_list)
-+              set_page_private(pgd_list, (unsigned long)&page->index);
-+      pgd_list = page;
-+      set_page_private(page, (unsigned long)&pgd_list);
-+}
-+
-+static inline void pgd_list_del(pgd_t *pgd)
-+{
-+      struct page *next, **pprev, *page = virt_to_page(pgd);
-+      next = (struct page *)page->index;
-+      pprev = (struct page **)page_private(page);
-+      *pprev = next;
-+      if (next)
-+              set_page_private(next, (unsigned long)pprev);
-+}
-+
-+void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
-+{
-+      unsigned long flags;
-+
-+      if (PTRS_PER_PMD > 1) {
-+              if (HAVE_SHARED_KERNEL_PMD)
-+                      clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
-+                                      swapper_pg_dir + USER_PTRS_PER_PGD,
-+                                      KERNEL_PGD_PTRS);
-+      } else {
-+              spin_lock_irqsave(&pgd_lock, flags);
-+              clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
-+                              swapper_pg_dir + USER_PTRS_PER_PGD,
-+                              KERNEL_PGD_PTRS);
-+              memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
-+              pgd_list_add(pgd);
-+              spin_unlock_irqrestore(&pgd_lock, flags);
-+      }
-+}
-+
-+/* never called when PTRS_PER_PMD > 1 */
-+void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
-+{
-+      unsigned long flags; /* can be called from interrupt context */
-+
-+      spin_lock_irqsave(&pgd_lock, flags);
-+      pgd_list_del(pgd);
-+      spin_unlock_irqrestore(&pgd_lock, flags);
-+
-+      pgd_test_and_unpin(pgd);
-+}
-+
-+pgd_t *pgd_alloc(struct mm_struct *mm)
-+{
-+      int i;
-+      pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
-+      pmd_t **pmd;
-+      unsigned long flags;
-+
-+      pgd_test_and_unpin(pgd);
-+
-+      if (PTRS_PER_PMD == 1 || !pgd)
-+              return pgd;
-+
-+      if (HAVE_SHARED_KERNEL_PMD) {
-+              for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
-+                      pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
-+                      if (!pmd)
-+                              goto out_oom;
-+                      set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
-+              }
-+              return pgd;
-+      }
-+
-+      /*
-+       * We can race save/restore (if we sleep during a GFP_KERNEL memory
-+       * allocation). We therefore store virtual addresses of pmds as they
-+       * do not change across save/restore, and poke the machine addresses
-+       * into the pgdir under the pgd_lock.
-+       */
-+      pmd = kmalloc(PTRS_PER_PGD * sizeof(pmd_t *), GFP_KERNEL);
-+      if (!pmd) {
-+              kmem_cache_free(pgd_cache, pgd);
-+              return NULL;
-+      }
-+
-+      /* Allocate pmds, remember virtual addresses. */
-+      for (i = 0; i < PTRS_PER_PGD; ++i) {
-+              pmd[i] = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
-+              if (!pmd[i])
-+                      goto out_oom;
-+      }
-+
-+      spin_lock_irqsave(&pgd_lock, flags);
-+
-+      /* Protect against save/restore: move below 4GB under pgd_lock. */
-+      if (!xen_feature(XENFEAT_pae_pgdir_above_4gb)) {
-+              int rc = xen_create_contiguous_region(
-+                      (unsigned long)pgd, 0, 32);
-+              if (rc) {
-+                      spin_unlock_irqrestore(&pgd_lock, flags);
-+                      goto out_oom;
-+              }
-+      }
-+
-+      /* Copy kernel pmd contents and write-protect the new pmds. */
-+      for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
-+              unsigned long v = (unsigned long)i << PGDIR_SHIFT;
-+              pgd_t *kpgd = pgd_offset_k(v);
-+              pud_t *kpud = pud_offset(kpgd, v);
-+              pmd_t *kpmd = pmd_offset(kpud, v);
-+              memcpy(pmd[i], kpmd, PAGE_SIZE);
-+              make_lowmem_page_readonly(
-+                      pmd[i], XENFEAT_writable_page_tables);
-+      }
-+
-+      /* It is safe to poke machine addresses of pmds under the pmd_lock. */
-+      for (i = 0; i < PTRS_PER_PGD; i++)
-+              set_pgd(&pgd[i], __pgd(1 + __pa(pmd[i])));
-+
-+      /* Ensure this pgd gets picked up and pinned on save/restore. */
-+      pgd_list_add(pgd);
-+
-+      spin_unlock_irqrestore(&pgd_lock, flags);
-+
-+      kfree(pmd);
-+
-+      return pgd;
-+
-+out_oom:
-+      if (HAVE_SHARED_KERNEL_PMD) {
-+              for (i--; i >= 0; i--)
-+                      kmem_cache_free(pmd_cache,
-+                                      (void *)__va(pgd_val(pgd[i])-1));
-+      } else {
-+              for (i--; i >= 0; i--)
-+                      kmem_cache_free(pmd_cache, pmd[i]);
-+              kfree(pmd);
-+      }
-+      kmem_cache_free(pgd_cache, pgd);
-+      return NULL;
-+}
-+
-+void pgd_free(pgd_t *pgd)
-+{
-+      int i;
-+
-+      /*
-+       * After this the pgd should not be pinned for the duration of this
-+       * function's execution. We should never sleep and thus never race:
-+       *  1. User pmds will not become write-protected under our feet due
-+       *     to a concurrent mm_pin_all().
-+       *  2. The machine addresses in PGD entries will not become invalid
-+       *     due to a concurrent save/restore.
-+       */
-+      pgd_test_and_unpin(pgd);
-+
-+      /* in the PAE case user pgd entries are overwritten before usage */
-+      if (PTRS_PER_PMD > 1) {
-+              for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
-+                      pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-+                      kmem_cache_free(pmd_cache, pmd);
-+              }
-+
-+              if (!HAVE_SHARED_KERNEL_PMD) {
-+                      unsigned long flags;
-+                      spin_lock_irqsave(&pgd_lock, flags);
-+                      pgd_list_del(pgd);
-+                      spin_unlock_irqrestore(&pgd_lock, flags);
-+
-+                      for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
-+                              pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
-+                              make_lowmem_page_writable(
-+                                      pmd, XENFEAT_writable_page_tables);
-+                              memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
-+                              kmem_cache_free(pmd_cache, pmd);
-+                      }
-+
-+                      if (!xen_feature(XENFEAT_pae_pgdir_above_4gb))
-+                              xen_destroy_contiguous_region(
-+                                      (unsigned long)pgd, 0);
-+              }
-+      }
-+
-+      /* in the non-PAE case, free_pgtables() clears user pgd entries */
-+      kmem_cache_free(pgd_cache, pgd);
-+}
-+
-+void make_lowmem_page_readonly(void *va, unsigned int feature)
-+{
-+      pte_t *pte;
-+      int rc;
-+
-+      if (xen_feature(feature))
-+              return;
-+
-+      pte = virt_to_ptep(va);
-+      rc = HYPERVISOR_update_va_mapping(
-+              (unsigned long)va, pte_wrprotect(*pte), 0);
-+      BUG_ON(rc);
-+}
-+
-+void make_lowmem_page_writable(void *va, unsigned int feature)
-+{
-+      pte_t *pte;
-+      int rc;
-+
-+      if (xen_feature(feature))
-+              return;
-+
-+      pte = virt_to_ptep(va);
-+      rc = HYPERVISOR_update_va_mapping(
-+              (unsigned long)va, pte_mkwrite(*pte), 0);
-+      BUG_ON(rc);
-+}
-+
-+void make_page_readonly(void *va, unsigned int feature)
-+{
-+      pte_t *pte;
-+      int rc;
-+
-+      if (xen_feature(feature))
-+              return;
-+
-+      pte = virt_to_ptep(va);
-+      rc = HYPERVISOR_update_va_mapping(
-+              (unsigned long)va, pte_wrprotect(*pte), 0);
-+      if (rc) /* fallback? */
-+              xen_l1_entry_update(pte, pte_wrprotect(*pte));
-+      if ((unsigned long)va >= (unsigned long)high_memory) {
-+              unsigned long pfn = pte_pfn(*pte);
-+#ifdef CONFIG_HIGHMEM
-+              if (pfn >= highstart_pfn)
-+                      kmap_flush_unused(); /* flush stale writable kmaps */
-+              else
-+#endif
-+                      make_lowmem_page_readonly(
-+                              phys_to_virt(pfn << PAGE_SHIFT), feature); 
-+      }
-+}
-+
-+void make_page_writable(void *va, unsigned int feature)
-+{
-+      pte_t *pte;
-+      int rc;
-+
-+      if (xen_feature(feature))
-+              return;
-+
-+      pte = virt_to_ptep(va);
-+      rc = HYPERVISOR_update_va_mapping(
-+              (unsigned long)va, pte_mkwrite(*pte), 0);
-+      if (rc) /* fallback? */
-+              xen_l1_entry_update(pte, pte_mkwrite(*pte));
-+      if ((unsigned long)va >= (unsigned long)high_memory) {
-+              unsigned long pfn = pte_pfn(*pte); 
-+#ifdef CONFIG_HIGHMEM
-+              if (pfn < highstart_pfn)
-+#endif
-+                      make_lowmem_page_writable(
-+                              phys_to_virt(pfn << PAGE_SHIFT), feature);
-+      }
-+}
-+
-+void make_pages_readonly(void *va, unsigned int nr, unsigned int feature)
-+{
-+      if (xen_feature(feature))
-+              return;
-+
-+      while (nr-- != 0) {
-+              make_page_readonly(va, feature);
-+              va = (void *)((unsigned long)va + PAGE_SIZE);
-+      }
-+}
-+
-+void make_pages_writable(void *va, unsigned int nr, unsigned int feature)
-+{
-+      if (xen_feature(feature))
-+              return;
-+
-+      while (nr-- != 0) {
-+              make_page_writable(va, feature);
-+              va = (void *)((unsigned long)va + PAGE_SIZE);
-+      }
-+}
-+
-+static inline void pgd_walk_set_prot(void *pt, pgprot_t flags)
-+{
-+      struct page *page = virt_to_page(pt);
-+      unsigned long pfn = page_to_pfn(page);
-+
-+      if (PageHighMem(page))
-+              return;
-+      BUG_ON(HYPERVISOR_update_va_mapping(
-+              (unsigned long)__va(pfn << PAGE_SHIFT),
-+              pfn_pte(pfn, flags), 0));
-+}
-+
-+static void pgd_walk(pgd_t *pgd_base, pgprot_t flags)
-+{
-+      pgd_t *pgd = pgd_base;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+      int    g, u, m;
-+
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return;
-+
-+      for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
-+              if (pgd_none(*pgd))
-+                      continue;
-+              pud = pud_offset(pgd, 0);
-+              if (PTRS_PER_PUD > 1) /* not folded */
-+                      pgd_walk_set_prot(pud,flags);
-+              for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
-+                      if (pud_none(*pud))
-+                              continue;
-+                      pmd = pmd_offset(pud, 0);
-+                      if (PTRS_PER_PMD > 1) /* not folded */
-+                              pgd_walk_set_prot(pmd,flags);
-+                      for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
-+                              if (pmd_none(*pmd))
-+                                      continue;
-+                              pte = pte_offset_kernel(pmd,0);
-+                              pgd_walk_set_prot(pte,flags);
-+                      }
-+              }
-+      }
-+
-+      BUG_ON(HYPERVISOR_update_va_mapping(
-+              (unsigned long)pgd_base,
-+              pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags),
-+              UVMF_TLB_FLUSH));
-+}
-+
-+static void __pgd_pin(pgd_t *pgd)
-+{
-+      pgd_walk(pgd, PAGE_KERNEL_RO);
-+      xen_pgd_pin(__pa(pgd));
-+      set_bit(PG_pinned, &virt_to_page(pgd)->flags);
-+}
-+
-+static void __pgd_unpin(pgd_t *pgd)
-+{
-+      xen_pgd_unpin(__pa(pgd));
-+      pgd_walk(pgd, PAGE_KERNEL);
-+      clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
-+}
-+
-+static void pgd_test_and_unpin(pgd_t *pgd)
-+{
-+      if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
-+              __pgd_unpin(pgd);
-+}
-+
-+void mm_pin(struct mm_struct *mm)
-+{
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
-+      spin_lock(&mm->page_table_lock);
-+      __pgd_pin(mm->pgd);
-+      spin_unlock(&mm->page_table_lock);
-+}
-+
-+void mm_unpin(struct mm_struct *mm)
-+{
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
-+      spin_lock(&mm->page_table_lock);
-+      __pgd_unpin(mm->pgd);
-+      spin_unlock(&mm->page_table_lock);
-+}
-+
-+void mm_pin_all(void)
-+{
-+      struct page *page;
-+
-+      /* Only pgds on the pgd_list please: none hidden in the slab cache. */
-+      kmem_cache_shrink(pgd_cache);
-+
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
-+
-+      for (page = pgd_list; page; page = (struct page *)page->index) {
-+              if (!test_bit(PG_pinned, &page->flags))
-+                      __pgd_pin((pgd_t *)page_address(page));
-+      }
-+}
-+
-+void _arch_dup_mmap(struct mm_struct *mm)
-+{
-+      if (!test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags))
-+              mm_pin(mm);
-+}
-+
-+void _arch_exit_mmap(struct mm_struct *mm)
-+{
-+      struct task_struct *tsk = current;
-+
-+      task_lock(tsk);
-+
-+      /*
-+       * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
-+       * *much* faster this way, as no tlb flushes means bigger wrpt batches.
-+       */
-+      if (tsk->active_mm == mm) {
-+              tsk->active_mm = &init_mm;
-+              atomic_inc(&init_mm.mm_count);
-+
-+              switch_mm(mm, &init_mm, tsk);
-+
-+              atomic_dec(&mm->mm_count);
-+              BUG_ON(atomic_read(&mm->mm_count) == 0);
-+      }
-+
-+      task_unlock(tsk);
-+
-+      if (test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags) &&
-+          (atomic_read(&mm->mm_count) == 1) &&
-+          !mm->context.has_foreign_mappings)
-+              mm_unpin(mm);
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/mm/pgtable.c linux-2.6.16.33/arch/i386/mm/pgtable.c
---- linux-2.6.16.33-noxen/arch/i386/mm/pgtable.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/mm/pgtable.c     2007-01-08 15:00:45.000000000 +0000
-@@ -13,6 +13,7 @@
- #include <linux/slab.h>
- #include <linux/pagemap.h>
- #include <linux/spinlock.h>
-+#include <linux/module.h>
- #include <asm/system.h>
- #include <asm/pgtable.h>
-@@ -138,6 +139,10 @@
-       __flush_tlb_one(vaddr);
- }
-+static int nr_fixmaps = 0;
-+unsigned long __FIXADDR_TOP = 0xfffff000;
-+EXPORT_SYMBOL(__FIXADDR_TOP);
-+
- void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
- {
-       unsigned long address = __fix_to_virt(idx);
-@@ -147,6 +152,13 @@
-               return;
-       }
-       set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
-+      nr_fixmaps++;
-+}
-+
-+void set_fixaddr_top(unsigned long top)
-+{
-+      BUG_ON(nr_fixmaps > 0);
-+      __FIXADDR_TOP = top - PAGE_SIZE;
- }
- pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
-diff -Nur linux-2.6.16.33-noxen/arch/i386/oprofile/Makefile linux-2.6.16.33/arch/i386/oprofile/Makefile
---- linux-2.6.16.33-noxen/arch/i386/oprofile/Makefile  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/oprofile/Makefile        2007-01-08 15:00:45.000000000 +0000
-@@ -6,7 +6,14 @@
-               oprofilefs.o oprofile_stats.o  \
-               timer_int.o )
-+ifdef CONFIG_XEN
-+XENOPROF_COMMON_OBJS = $(addprefix ../../../drivers/xen/xenoprof/, \
-+                       xenoprofile.o)
-+oprofile-y                            := $(DRIVER_OBJS) \
-+                                         $(XENOPROF_COMMON_OBJS) xenoprof.o
-+else 
- oprofile-y                            := $(DRIVER_OBJS) init.o backtrace.o
- oprofile-$(CONFIG_X86_LOCAL_APIC)     += nmi_int.o op_model_athlon.o \
-                                          op_model_ppro.o op_model_p4.o
- oprofile-$(CONFIG_X86_IO_APIC)                += nmi_timer_int.o
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/oprofile/xenoprof.c linux-2.6.16.33/arch/i386/oprofile/xenoprof.c
---- linux-2.6.16.33-noxen/arch/i386/oprofile/xenoprof.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/oprofile/xenoprof.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,179 @@
-+/**
-+ * @file xenoprof.c
-+ *
-+ * @remark Copyright 2002 OProfile authors
-+ * @remark Read the file COPYING
-+ *
-+ * @author John Levon <levon@movementarian.org>
-+ *
-+ * Modified by Aravind Menon and Jose Renato Santos for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ *
-+ * x86-specific part
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/oprofile.h>
-+#include <linux/sched.h>
-+#include <asm/pgtable.h>
-+
-+#include <xen/driver_util.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/xenoprof.h>
-+#include <xen/xenoprof.h>
-+#include "op_counter.h"
-+
-+static unsigned int num_events = 0;
-+
-+void __init xenoprof_arch_init_counter(struct xenoprof_init *init)
-+{
-+      num_events = init->num_events;
-+      /* just in case - make sure we do not overflow event list 
-+         (i.e. counter_config list) */
-+      if (num_events > OP_MAX_COUNTER) {
-+              num_events = OP_MAX_COUNTER;
-+              init->num_events = num_events;
-+      }
-+}
-+
-+void xenoprof_arch_counter(void)
-+{
-+      int i;
-+      struct xenoprof_counter counter;
-+
-+      for (i=0; i<num_events; i++) {
-+              counter.ind       = i;
-+              counter.count     = (uint64_t)counter_config[i].count;
-+              counter.enabled   = (uint32_t)counter_config[i].enabled;
-+              counter.event     = (uint32_t)counter_config[i].event;
-+              counter.kernel    = (uint32_t)counter_config[i].kernel;
-+              counter.user      = (uint32_t)counter_config[i].user;
-+              counter.unit_mask = (uint64_t)counter_config[i].unit_mask;
-+              HYPERVISOR_xenoprof_op(XENOPROF_counter, 
-+                                     &counter);
-+      }
-+}
-+
-+void xenoprof_arch_start(void) 
-+{
-+      /* nothing */
-+}
-+
-+void xenoprof_arch_stop(void)
-+{
-+      /* nothing */
-+}
-+
-+void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer * sbuf)
-+{
-+      if (sbuf->buffer) {
-+              vunmap(sbuf->buffer);
-+              sbuf->buffer = NULL;
-+      }
-+}
-+
-+int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer * get_buffer,
-+                                  struct xenoprof_shared_buffer * sbuf)
-+{
-+      int npages, ret;
-+      struct vm_struct *area;
-+
-+      sbuf->buffer = NULL;
-+      if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, get_buffer)) )
-+              return ret;
-+
-+      npages = (get_buffer->bufsize * get_buffer->nbuf - 1) / PAGE_SIZE + 1;
-+
-+      area = alloc_vm_area(npages * PAGE_SIZE);
-+      if (area == NULL)
-+              return -ENOMEM;
-+
-+      if ( (ret = direct_kernel_remap_pfn_range(
-+                    (unsigned long)area->addr,
-+                    get_buffer->buf_gmaddr >> PAGE_SHIFT,
-+                    npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE),
-+                    DOMID_SELF)) ) {
-+              vunmap(area->addr);
-+              return ret;
-+      }
-+
-+      sbuf->buffer = area->addr;
-+      return ret;
-+}
-+
-+int xenoprof_arch_set_passive(struct xenoprof_passive * pdomain,
-+                            struct xenoprof_shared_buffer * sbuf)
-+{
-+      int ret;
-+      int npages;
-+      struct vm_struct *area;
-+      pgprot_t prot = __pgprot(_KERNPG_TABLE);
-+
-+      sbuf->buffer = NULL;
-+      ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, pdomain);
-+      if (ret)
-+              goto out;
-+
-+      npages = (pdomain->bufsize * pdomain->nbuf - 1) / PAGE_SIZE + 1;
-+
-+      area = alloc_vm_area(npages * PAGE_SIZE);
-+      if (area == NULL) {
-+              ret = -ENOMEM;
-+              goto out;
-+      }
-+
-+      ret = direct_kernel_remap_pfn_range(
-+              (unsigned long)area->addr,
-+              pdomain->buf_gmaddr >> PAGE_SHIFT,
-+              npages * PAGE_SIZE, prot, DOMID_SELF);
-+      if (ret) {
-+              vunmap(area->addr);
-+              goto out;
-+      }
-+      sbuf->buffer = area->addr;
-+
-+out:
-+      return ret;
-+}
-+
-+struct op_counter_config counter_config[OP_MAX_COUNTER];
-+
-+int xenoprof_create_files(struct super_block * sb, struct dentry * root)
-+{
-+      unsigned int i;
-+
-+      for (i = 0; i < num_events; ++i) {
-+              struct dentry * dir;
-+              char buf[2];
-+ 
-+              snprintf(buf, 2, "%d", i);
-+              dir = oprofilefs_mkdir(sb, root, buf);
-+              oprofilefs_create_ulong(sb, dir, "enabled",
-+                                      &counter_config[i].enabled);
-+              oprofilefs_create_ulong(sb, dir, "event",
-+                                      &counter_config[i].event);
-+              oprofilefs_create_ulong(sb, dir, "count",
-+                                      &counter_config[i].count);
-+              oprofilefs_create_ulong(sb, dir, "unit_mask",
-+                                      &counter_config[i].unit_mask);
-+              oprofilefs_create_ulong(sb, dir, "kernel",
-+                                      &counter_config[i].kernel);
-+              oprofilefs_create_ulong(sb, dir, "user",
-+                                      &counter_config[i].user);
-+      }
-+
-+      return 0;
-+}
-+
-+int __init oprofile_arch_init(struct oprofile_operations * ops)
-+{
-+      return xenoprofile_init(ops);
-+}
-+
-+void oprofile_arch_exit(void)
-+{
-+      xenoprofile_exit();
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/pci/Makefile linux-2.6.16.33/arch/i386/pci/Makefile
---- linux-2.6.16.33-noxen/arch/i386/pci/Makefile       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/pci/Makefile     2007-01-08 15:00:45.000000000 +0000
-@@ -4,6 +4,10 @@
- obj-$(CONFIG_PCI_MMCONFIG)    += mmconfig.o direct.o
- obj-$(CONFIG_PCI_DIRECT)      += direct.o
-+# pcifront should be after pcbios.o, mmconfig.o, and direct.o as it should only
-+# take over if direct access to the PCI bus is unavailable
-+obj-$(CONFIG_XEN_PCIDEV_FRONTEND)     += pcifront.o
-+
- pci-y                         := fixup.o
- pci-$(CONFIG_ACPI)            += acpi.o
- pci-y                         += legacy.o irq.o
-@@ -12,3 +16,8 @@
- pci-$(CONFIG_X86_NUMAQ)               := numa.o irq.o
- obj-y                         += $(pci-y) common.o
-+
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/i386/pci/irq-xen.c linux-2.6.16.33/arch/i386/pci/irq-xen.c
---- linux-2.6.16.33-noxen/arch/i386/pci/irq-xen.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/pci/irq-xen.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1204 @@
-+/*
-+ *    Low-Level PCI Support for PC -- Routing of Interrupts
-+ *
-+ *    (c) 1999--2000 Martin Mares <mj@ucw.cz>
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/dmi.h>
-+#include <asm/io.h>
-+#include <asm/smp.h>
-+#include <asm/io_apic.h>
-+#include <linux/irq.h>
-+#include <linux/acpi.h>
-+
-+#include "pci.h"
-+
-+#define PIRQ_SIGNATURE        (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
-+#define PIRQ_VERSION 0x0100
-+
-+static int broken_hp_bios_irq9;
-+static int acer_tm360_irqrouting;
-+
-+static struct irq_routing_table *pirq_table;
-+
-+static int pirq_enable_irq(struct pci_dev *dev);
-+
-+/*
-+ * Never use: 0, 1, 2 (timer, keyboard, and cascade)
-+ * Avoid using: 13, 14 and 15 (FP error and IDE).
-+ * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse)
-+ */
-+unsigned int pcibios_irq_mask = 0xfff8;
-+
-+static int pirq_penalty[16] = {
-+      1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000,
-+      0, 0, 0, 0, 1000, 100000, 100000, 100000
-+};
-+
-+struct irq_router {
-+      char *name;
-+      u16 vendor, device;
-+      int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
-+      int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
-+};
-+
-+struct irq_router_handler {
-+      u16 vendor;
-+      int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
-+};
-+
-+int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
-+void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
-+
-+/*
-+ *  Check passed address for the PCI IRQ Routing Table signature
-+ *  and perform checksum verification.
-+ */
-+
-+static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
-+{
-+      struct irq_routing_table *rt;
-+      int i;
-+      u8 sum;
-+
-+      rt = (struct irq_routing_table *) addr;
-+      if (rt->signature != PIRQ_SIGNATURE ||
-+          rt->version != PIRQ_VERSION ||
-+          rt->size % 16 ||
-+          rt->size < sizeof(struct irq_routing_table))
-+              return NULL;
-+      sum = 0;
-+      for (i=0; i < rt->size; i++)
-+              sum += addr[i];
-+      if (!sum) {
-+              DBG(KERN_DEBUG "PCI: Interrupt Routing Table found at 0x%p\n", rt);
-+              return rt;
-+      }
-+      return NULL;
-+}
-+
-+
-+
-+/*
-+ *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
-+ */
-+
-+static struct irq_routing_table * __init pirq_find_routing_table(void)
-+{
-+      u8 *addr;
-+      struct irq_routing_table *rt;
-+
-+#ifdef CONFIG_XEN
-+      if (!is_initial_xendomain())
-+              return NULL;
-+#endif
-+      if (pirq_table_addr) {
-+              rt = pirq_check_routing_table((u8 *) isa_bus_to_virt(pirq_table_addr));
-+              if (rt)
-+                      return rt;
-+              printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
-+      }
-+      for(addr = (u8 *) isa_bus_to_virt(0xf0000); addr < (u8 *) isa_bus_to_virt(0x100000); addr += 16) {
-+              rt = pirq_check_routing_table(addr);
-+              if (rt)
-+                      return rt;
-+      }
-+      
-+      return NULL;
-+}
-+
-+/*
-+ *  If we have a IRQ routing table, use it to search for peer host
-+ *  bridges.  It's a gross hack, but since there are no other known
-+ *  ways how to get a list of buses, we have to go this way.
-+ */
-+
-+static void __init pirq_peer_trick(void)
-+{
-+      struct irq_routing_table *rt = pirq_table;
-+      u8 busmap[256];
-+      int i;
-+      struct irq_info *e;
-+
-+      memset(busmap, 0, sizeof(busmap));
-+      for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
-+              e = &rt->slots[i];
-+#ifdef DEBUG
-+              {
-+                      int j;
-+                      DBG(KERN_DEBUG "%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot);
-+                      for(j=0; j<4; j++)
-+                              DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap);
-+                      DBG("\n");
-+              }
-+#endif
-+              busmap[e->bus] = 1;
-+      }
-+      for(i = 1; i < 256; i++) {
-+              if (!busmap[i] || pci_find_bus(0, i))
-+                      continue;
-+              if (pci_scan_bus(i, &pci_root_ops, NULL))
-+                      printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
-+      }
-+      pcibios_last_bus = -1;
-+}
-+
-+/*
-+ *  Code for querying and setting of IRQ routes on various interrupt routers.
-+ */
-+
-+void eisa_set_level_irq(unsigned int irq)
-+{
-+      unsigned char mask = 1 << (irq & 7);
-+      unsigned int port = 0x4d0 + (irq >> 3);
-+      unsigned char val;
-+      static u16 eisa_irq_mask;
-+
-+      if (irq >= 16 || (1 << irq) & eisa_irq_mask)
-+              return;
-+
-+      eisa_irq_mask |= (1 << irq);
-+      printk(KERN_DEBUG "PCI: setting IRQ %u as level-triggered\n", irq);
-+      val = inb(port);
-+      if (!(val & mask)) {
-+              DBG(KERN_DEBUG " -> edge");
-+              outb(val | mask, port);
-+      }
-+}
-+
-+/*
-+ * Common IRQ routing practice: nybbles in config space,
-+ * offset by some magic constant.
-+ */
-+static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr)
-+{
-+      u8 x;
-+      unsigned reg = offset + (nr >> 1);
-+
-+      pci_read_config_byte(router, reg, &x);
-+      return (nr & 1) ? (x >> 4) : (x & 0xf);
-+}
-+
-+static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val)
-+{
-+      u8 x;
-+      unsigned reg = offset + (nr >> 1);
-+
-+      pci_read_config_byte(router, reg, &x);
-+      x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val);
-+      pci_write_config_byte(router, reg, x);
-+}
-+
-+/*
-+ * ALI pirq entries are damn ugly, and completely undocumented.
-+ * This has been figured out from pirq tables, and it's not a pretty
-+ * picture.
-+ */
-+static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
-+
-+      return irqmap[read_config_nybble(router, 0x48, pirq-1)];
-+}
-+
-+static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
-+      unsigned int val = irqmap[irq];
-+              
-+      if (val) {
-+              write_config_nybble(router, 0x48, pirq-1, val);
-+              return 1;
-+      }
-+      return 0;
-+}
-+
-+/*
-+ * The Intel PIIX4 pirq rules are fairly simple: "pirq" is
-+ * just a pointer to the config space.
-+ */
-+static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      u8 x;
-+
-+      pci_read_config_byte(router, pirq, &x);
-+      return (x < 16) ? x : 0;
-+}
-+
-+static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      pci_write_config_byte(router, pirq, irq);
-+      return 1;
-+}
-+
-+/*
-+ * The VIA pirq rules are nibble-based, like ALI,
-+ * but without the ugly irq number munging.
-+ * However, PIRQD is in the upper instead of lower 4 bits.
-+ */
-+static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq);
-+}
-+
-+static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq);
-+      return 1;
-+}
-+
-+/*
-+ * The VIA pirq rules are nibble-based, like ALI,
-+ * but without the ugly irq number munging.
-+ * However, for 82C586, nibble map is different .
-+ */
-+static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
-+      return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
-+}
-+
-+static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
-+      write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
-+      return 1;
-+}
-+
-+/*
-+ * ITE 8330G pirq rules are nibble-based
-+ * FIXME: pirqmap may be { 1, 0, 3, 2 },
-+ *      2+3 are both mapped to irq 9 on my system
-+ */
-+static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      static unsigned char pirqmap[4] = { 1, 0, 2, 3 };
-+      return read_config_nybble(router,0x43, pirqmap[pirq-1]);
-+}
-+
-+static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      static unsigned char pirqmap[4] = { 1, 0, 2, 3 };
-+      write_config_nybble(router, 0x43, pirqmap[pirq-1], irq);
-+      return 1;
-+}
-+
-+/*
-+ * OPTI: high four bits are nibble pointer..
-+ * I wonder what the low bits do?
-+ */
-+static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      return read_config_nybble(router, 0xb8, pirq >> 4);
-+}
-+
-+static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      write_config_nybble(router, 0xb8, pirq >> 4, irq);
-+      return 1;
-+}
-+
-+/*
-+ * Cyrix: nibble offset 0x5C
-+ * 0x5C bits 7:4 is INTB bits 3:0 is INTA 
-+ * 0x5D bits 7:4 is INTD bits 3:0 is INTC
-+ */
-+static int pirq_cyrix_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      return read_config_nybble(router, 0x5C, (pirq-1)^1);
-+}
-+
-+static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      write_config_nybble(router, 0x5C, (pirq-1)^1, irq);
-+      return 1;
-+}
-+
-+/*
-+ *    PIRQ routing for SiS 85C503 router used in several SiS chipsets.
-+ *    We have to deal with the following issues here:
-+ *    - vendors have different ideas about the meaning of link values
-+ *    - some onboard devices (integrated in the chipset) have special
-+ *      links and are thus routed differently (i.e. not via PCI INTA-INTD)
-+ *    - different revision of the router have a different layout for
-+ *      the routing registers, particularly for the onchip devices
-+ *
-+ *    For all routing registers the common thing is we have one byte
-+ *    per routeable link which is defined as:
-+ *             bit 7      IRQ mapping enabled (0) or disabled (1)
-+ *             bits [6:4] reserved (sometimes used for onchip devices)
-+ *             bits [3:0] IRQ to map to
-+ *                 allowed: 3-7, 9-12, 14-15
-+ *                 reserved: 0, 1, 2, 8, 13
-+ *
-+ *    The config-space registers located at 0x41/0x42/0x43/0x44 are
-+ *    always used to route the normal PCI INT A/B/C/D respectively.
-+ *    Apparently there are systems implementing PCI routing table using
-+ *    link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D.
-+ *    We try our best to handle both link mappings.
-+ *    
-+ *    Currently (2003-05-21) it appears most SiS chipsets follow the
-+ *    definition of routing registers from the SiS-5595 southbridge.
-+ *    According to the SiS 5595 datasheets the revision id's of the
-+ *    router (ISA-bridge) should be 0x01 or 0xb0.
-+ *
-+ *    Furthermore we've also seen lspci dumps with revision 0x00 and 0xb1.
-+ *    Looks like these are used in a number of SiS 5xx/6xx/7xx chipsets.
-+ *    They seem to work with the current routing code. However there is
-+ *    some concern because of the two USB-OHCI HCs (original SiS 5595
-+ *    had only one). YMMV.
-+ *
-+ *    Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1:
-+ *
-+ *    0x61:   IDEIRQ:
-+ *            bits [6:5] must be written 01
-+ *            bit 4 channel-select primary (0), secondary (1)
-+ *
-+ *    0x62:   USBIRQ:
-+ *            bit 6 OHCI function disabled (0), enabled (1)
-+ *    
-+ *    0x6a:   ACPI/SCI IRQ: bits 4-6 reserved
-+ *
-+ *    0x7e:   Data Acq. Module IRQ - bits 4-6 reserved
-+ *
-+ *    We support USBIRQ (in addition to INTA-INTD) and keep the
-+ *    IDE, ACPI and DAQ routing untouched as set by the BIOS.
-+ *
-+ *    Currently the only reported exception is the new SiS 65x chipset
-+ *    which includes the SiS 69x southbridge. Here we have the 85C503
-+ *    router revision 0x04 and there are changes in the register layout
-+ *    mostly related to the different USB HCs with USB 2.0 support.
-+ *
-+ *    Onchip routing for router rev-id 0x04 (try-and-error observation)
-+ *
-+ *    0x60/0x61/0x62/0x63:    1xEHCI and 3xOHCI (companion) USB-HCs
-+ *                            bit 6-4 are probably unused, not like 5595
-+ */
-+
-+#define PIRQ_SIS_IRQ_MASK     0x0f
-+#define PIRQ_SIS_IRQ_DISABLE  0x80
-+#define PIRQ_SIS_USB_ENABLE   0x40
-+
-+static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      u8 x;
-+      int reg;
-+
-+      reg = pirq;
-+      if (reg >= 0x01 && reg <= 0x04)
-+              reg += 0x40;
-+      pci_read_config_byte(router, reg, &x);
-+      return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK);
-+}
-+
-+static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      u8 x;
-+      int reg;
-+
-+      reg = pirq;
-+      if (reg >= 0x01 && reg <= 0x04)
-+              reg += 0x40;
-+      pci_read_config_byte(router, reg, &x);
-+      x &= ~(PIRQ_SIS_IRQ_MASK | PIRQ_SIS_IRQ_DISABLE);
-+      x |= irq ? irq: PIRQ_SIS_IRQ_DISABLE;
-+      pci_write_config_byte(router, reg, x);
-+      return 1;
-+}
-+
-+
-+/*
-+ * VLSI: nibble offset 0x74 - educated guess due to routing table and
-+ *       config space of VLSI 82C534 PCI-bridge/router (1004:0102)
-+ *       Tested on HP OmniBook 800 covering PIRQ 1, 2, 4, 8 for onboard
-+ *       devices, PIRQ 3 for non-pci(!) soundchip and (untested) PIRQ 6
-+ *       for the busbridge to the docking station.
-+ */
-+
-+static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      if (pirq > 8) {
-+              printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
-+              return 0;
-+      }
-+      return read_config_nybble(router, 0x74, pirq-1);
-+}
-+
-+static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      if (pirq > 8) {
-+              printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
-+              return 0;
-+      }
-+      write_config_nybble(router, 0x74, pirq-1, irq);
-+      return 1;
-+}
-+
-+/*
-+ * ServerWorks: PCI interrupts mapped to system IRQ lines through Index
-+ * and Redirect I/O registers (0x0c00 and 0x0c01).  The Index register
-+ * format is (PCIIRQ## | 0x10), e.g.: PCIIRQ10=0x1a.  The Redirect
-+ * register is a straight binary coding of desired PIC IRQ (low nibble).
-+ *
-+ * The 'link' value in the PIRQ table is already in the correct format
-+ * for the Index register.  There are some special index values:
-+ * 0x00 for ACPI (SCI), 0x01 for USB, 0x02 for IDE0, 0x04 for IDE1,
-+ * and 0x03 for SMBus.
-+ */
-+static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      outb_p(pirq, 0xc00);
-+      return inb(0xc01) & 0xf;
-+}
-+
-+static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      outb_p(pirq, 0xc00);
-+      outb_p(irq, 0xc01);
-+      return 1;
-+}
-+
-+/* Support for AMD756 PCI IRQ Routing
-+ * Jhon H. Caicedo <jhcaiced@osso.org.co>
-+ * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced)
-+ * Jun/19/2001 Alpha Release 0.1.0 (jhcaiced)
-+ * The AMD756 pirq rules are nibble-based
-+ * offset 0x56 0-3 PIRQA  4-7  PIRQB
-+ * offset 0x57 0-3 PIRQC  4-7  PIRQD
-+ */
-+static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-+{
-+      u8 irq;
-+      irq = 0;
-+      if (pirq <= 4)
-+      {
-+              irq = read_config_nybble(router, 0x56, pirq - 1);
-+      }
-+      printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n",
-+              dev->vendor, dev->device, pirq, irq);
-+      return irq;
-+}
-+
-+static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", 
-+              dev->vendor, dev->device, pirq, irq);
-+      if (pirq <= 4)
-+      {
-+              write_config_nybble(router, 0x56, pirq - 1, irq);
-+      }
-+      return 1;
-+}
-+
-+#ifdef CONFIG_PCI_BIOS
-+
-+static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-+{
-+      struct pci_dev *bridge;
-+      int pin = pci_get_interrupt_pin(dev, &bridge);
-+      return pcibios_set_irq_routing(bridge, pin, irq);
-+}
-+
-+#endif
-+
-+static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      static struct pci_device_id pirq_440gx[] = {
-+              { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
-+              { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
-+              { },
-+      };
-+
-+      /* 440GX has a proprietary PIRQ router -- don't use it */
-+      if (pci_dev_present(pirq_440gx))
-+              return 0;
-+
-+      switch(device)
-+      {
-+              case PCI_DEVICE_ID_INTEL_82371FB_0:
-+              case PCI_DEVICE_ID_INTEL_82371SB_0:
-+              case PCI_DEVICE_ID_INTEL_82371AB_0:
-+              case PCI_DEVICE_ID_INTEL_82371MX:
-+              case PCI_DEVICE_ID_INTEL_82443MX_0:
-+              case PCI_DEVICE_ID_INTEL_82801AA_0:
-+              case PCI_DEVICE_ID_INTEL_82801AB_0:
-+              case PCI_DEVICE_ID_INTEL_82801BA_0:
-+              case PCI_DEVICE_ID_INTEL_82801BA_10:
-+              case PCI_DEVICE_ID_INTEL_82801CA_0:
-+              case PCI_DEVICE_ID_INTEL_82801CA_12:
-+              case PCI_DEVICE_ID_INTEL_82801DB_0:
-+              case PCI_DEVICE_ID_INTEL_82801E_0:
-+              case PCI_DEVICE_ID_INTEL_82801EB_0:
-+              case PCI_DEVICE_ID_INTEL_ESB_1:
-+              case PCI_DEVICE_ID_INTEL_ICH6_0:
-+              case PCI_DEVICE_ID_INTEL_ICH6_1:
-+              case PCI_DEVICE_ID_INTEL_ICH7_0:
-+              case PCI_DEVICE_ID_INTEL_ICH7_1:
-+              case PCI_DEVICE_ID_INTEL_ICH7_30:
-+              case PCI_DEVICE_ID_INTEL_ICH7_31:
-+              case PCI_DEVICE_ID_INTEL_ESB2_0:
-+              case PCI_DEVICE_ID_INTEL_ICH8_0:
-+              case PCI_DEVICE_ID_INTEL_ICH8_1:
-+              case PCI_DEVICE_ID_INTEL_ICH8_2:
-+              case PCI_DEVICE_ID_INTEL_ICH8_3:
-+              case PCI_DEVICE_ID_INTEL_ICH8_4:
-+                      r->name = "PIIX/ICH";
-+                      r->get = pirq_piix_get;
-+                      r->set = pirq_piix_set;
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+static __init int via_router_probe(struct irq_router *r,
-+                              struct pci_dev *router, u16 device)
-+{
-+      /* FIXME: We should move some of the quirk fixup stuff here */
-+
-+      /*
-+       * work arounds for some buggy BIOSes
-+       */
-+      if (device == PCI_DEVICE_ID_VIA_82C586_0) {
-+              switch(router->device) {
-+              case PCI_DEVICE_ID_VIA_82C686:
-+                      /*
-+                       * Asus k7m bios wrongly reports 82C686A
-+                       * as 586-compatible
-+                       */
-+                      device = PCI_DEVICE_ID_VIA_82C686;
-+                      break;
-+              case PCI_DEVICE_ID_VIA_8235:
-+                      /**
-+                       * Asus a7v-x bios wrongly reports 8235
-+                       * as 586-compatible
-+                       */
-+                      device = PCI_DEVICE_ID_VIA_8235;
-+                      break;
-+              }
-+      }
-+
-+      switch(device) {
-+      case PCI_DEVICE_ID_VIA_82C586_0:
-+              r->name = "VIA";
-+              r->get = pirq_via586_get;
-+              r->set = pirq_via586_set;
-+              return 1;
-+      case PCI_DEVICE_ID_VIA_82C596:
-+      case PCI_DEVICE_ID_VIA_82C686:
-+      case PCI_DEVICE_ID_VIA_8231:
-+      case PCI_DEVICE_ID_VIA_8235:
-+              /* FIXME: add new ones for 8233/5 */
-+              r->name = "VIA";
-+              r->get = pirq_via_get;
-+              r->set = pirq_via_set;
-+              return 1;
-+      }
-+      return 0;
-+}
-+
-+static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      switch(device)
-+      {
-+              case PCI_DEVICE_ID_VLSI_82C534:
-+                      r->name = "VLSI 82C534";
-+                      r->get = pirq_vlsi_get;
-+                      r->set = pirq_vlsi_set;
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+
-+static __init int serverworks_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      switch(device)
-+      {
-+              case PCI_DEVICE_ID_SERVERWORKS_OSB4:
-+              case PCI_DEVICE_ID_SERVERWORKS_CSB5:
-+                      r->name = "ServerWorks";
-+                      r->get = pirq_serverworks_get;
-+                      r->set = pirq_serverworks_set;
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      if (device != PCI_DEVICE_ID_SI_503)
-+              return 0;
-+              
-+      r->name = "SIS";
-+      r->get = pirq_sis_get;
-+      r->set = pirq_sis_set;
-+      return 1;
-+}
-+
-+static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      switch(device)
-+      {
-+              case PCI_DEVICE_ID_CYRIX_5520:
-+                      r->name = "NatSemi";
-+                      r->get = pirq_cyrix_get;
-+                      r->set = pirq_cyrix_set;
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+static __init int opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      switch(device)
-+      {
-+              case PCI_DEVICE_ID_OPTI_82C700:
-+                      r->name = "OPTI";
-+                      r->get = pirq_opti_get;
-+                      r->set = pirq_opti_set;
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      switch(device)
-+      {
-+              case PCI_DEVICE_ID_ITE_IT8330G_0:
-+                      r->name = "ITE";
-+                      r->get = pirq_ite_get;
-+                      r->set = pirq_ite_set;
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      switch(device)
-+      {
-+      case PCI_DEVICE_ID_AL_M1533:
-+      case PCI_DEVICE_ID_AL_M1563:
-+              printk(KERN_DEBUG "PCI: Using ALI IRQ Router\n");
-+              r->name = "ALI";
-+              r->get = pirq_ali_get;
-+              r->set = pirq_ali_set;
-+              return 1;
-+      }
-+      return 0;
-+}
-+
-+static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
-+{
-+      switch(device)
-+      {
-+              case PCI_DEVICE_ID_AMD_VIPER_740B:
-+                      r->name = "AMD756";
-+                      break;
-+              case PCI_DEVICE_ID_AMD_VIPER_7413:
-+                      r->name = "AMD766";
-+                      break;
-+              case PCI_DEVICE_ID_AMD_VIPER_7443:
-+                      r->name = "AMD768";
-+                      break;
-+              default:
-+                      return 0;
-+      }
-+      r->get = pirq_amd756_get;
-+      r->set = pirq_amd756_set;
-+      return 1;
-+}
-+              
-+static __initdata struct irq_router_handler pirq_routers[] = {
-+      { PCI_VENDOR_ID_INTEL, intel_router_probe },
-+      { PCI_VENDOR_ID_AL, ali_router_probe },
-+      { PCI_VENDOR_ID_ITE, ite_router_probe },
-+      { PCI_VENDOR_ID_VIA, via_router_probe },
-+      { PCI_VENDOR_ID_OPTI, opti_router_probe },
-+      { PCI_VENDOR_ID_SI, sis_router_probe },
-+      { PCI_VENDOR_ID_CYRIX, cyrix_router_probe },
-+      { PCI_VENDOR_ID_VLSI, vlsi_router_probe },
-+      { PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe },
-+      { PCI_VENDOR_ID_AMD, amd_router_probe },
-+      /* Someone with docs needs to add the ATI Radeon IGP */
-+      { 0, NULL }
-+};
-+static struct irq_router pirq_router;
-+static struct pci_dev *pirq_router_dev;
-+
-+
-+/*
-+ *    FIXME: should we have an option to say "generic for
-+ *    chipset" ?
-+ */
-+ 
-+static void __init pirq_find_router(struct irq_router *r)
-+{
-+      struct irq_routing_table *rt = pirq_table;
-+      struct irq_router_handler *h;
-+
-+#ifdef CONFIG_PCI_BIOS
-+      if (!rt->signature) {
-+              printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n");
-+              r->set = pirq_bios_set;
-+              r->name = "BIOS";
-+              return;
-+      }
-+#endif
-+
-+      /* Default unless a driver reloads it */
-+      r->name = "default";
-+      r->get = NULL;
-+      r->set = NULL;
-+      
-+      DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n",
-+          rt->rtr_vendor, rt->rtr_device);
-+
-+      pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
-+      if (!pirq_router_dev) {
-+              DBG(KERN_DEBUG "PCI: Interrupt router not found at "
-+                      "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
-+              return;
-+      }
-+
-+      for( h = pirq_routers; h->vendor; h++) {
-+              /* First look for a router match */
-+              if (rt->rtr_vendor == h->vendor && h->probe(r, pirq_router_dev, rt->rtr_device))
-+                      break;
-+              /* Fall back to a device match */
-+              if (pirq_router_dev->vendor == h->vendor && h->probe(r, pirq_router_dev, pirq_router_dev->device))
-+                      break;
-+      }
-+      printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
-+              pirq_router.name,
-+              pirq_router_dev->vendor,
-+              pirq_router_dev->device,
-+              pci_name(pirq_router_dev));
-+}
-+
-+static struct irq_info *pirq_get_info(struct pci_dev *dev)
-+{
-+      struct irq_routing_table *rt = pirq_table;
-+      int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
-+      struct irq_info *info;
-+
-+      for (info = rt->slots; entries--; info++)
-+              if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn))
-+                      return info;
-+      return NULL;
-+}
-+
-+static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
-+{
-+      u8 pin;
-+      struct irq_info *info;
-+      int i, pirq, newirq;
-+      int irq = 0;
-+      u32 mask;
-+      struct irq_router *r = &pirq_router;
-+      struct pci_dev *dev2 = NULL;
-+      char *msg = NULL;
-+
-+      /* Find IRQ pin */
-+      pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-+      if (!pin) {
-+              DBG(KERN_DEBUG " -> no interrupt pin\n");
-+              return 0;
-+      }
-+      pin = pin - 1;
-+
-+      /* Find IRQ routing entry */
-+
-+      if (!pirq_table)
-+              return 0;
-+      
-+      DBG(KERN_DEBUG "IRQ for %s[%c]", pci_name(dev), 'A' + pin);
-+      info = pirq_get_info(dev);
-+      if (!info) {
-+              DBG(" -> not found in routing table\n" KERN_DEBUG);
-+              return 0;
-+      }
-+      pirq = info->irq[pin].link;
-+      mask = info->irq[pin].bitmap;
-+      if (!pirq) {
-+              DBG(" -> not routed\n" KERN_DEBUG);
-+              return 0;
-+      }
-+      DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
-+      mask &= pcibios_irq_mask;
-+
-+      /* Work around broken HP Pavilion Notebooks which assign USB to
-+         IRQ 9 even though it is actually wired to IRQ 11 */
-+
-+      if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) {
-+              dev->irq = 11;
-+              pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
-+              r->set(pirq_router_dev, dev, pirq, 11);
-+      }
-+
-+      /* same for Acer Travelmate 360, but with CB and irq 11 -> 10 */
-+      if (acer_tm360_irqrouting && dev->irq == 11 && dev->vendor == PCI_VENDOR_ID_O2) {
-+              pirq = 0x68;
-+              mask = 0x400;
-+              dev->irq = r->get(pirq_router_dev, dev, pirq);
-+              pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-+      }
-+
-+      /*
-+       * Find the best IRQ to assign: use the one
-+       * reported by the device if possible.
-+       */
-+      newirq = dev->irq;
-+      if (newirq && !((1 << newirq) & mask)) {
-+              if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
-+              else printk("\n" KERN_WARNING
-+                      "PCI: IRQ %i for device %s doesn't match PIRQ mask "
-+                      "- try pci=usepirqmask\n" KERN_DEBUG, newirq,
-+                      pci_name(dev));
-+      }
-+      if (!newirq && assign) {
-+              for (i = 0; i < 16; i++) {
-+                      if (!(mask & (1 << i)))
-+                              continue;
-+                      if (pirq_penalty[i] < pirq_penalty[newirq] && can_request_irq(i, SA_SHIRQ))
-+                              newirq = i;
-+              }
-+      }
-+      DBG(" -> newirq=%d", newirq);
-+
-+      /* Check if it is hardcoded */
-+      if ((pirq & 0xf0) == 0xf0) {
-+              irq = pirq & 0xf;
-+              DBG(" -> hardcoded IRQ %d\n", irq);
-+              msg = "Hardcoded";
-+      } else if ( r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \
-+      ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) {
-+              DBG(" -> got IRQ %d\n", irq);
-+              msg = "Found";
-+      } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
-+              DBG(" -> assigning IRQ %d", newirq);
-+              if (r->set(pirq_router_dev, dev, pirq, newirq)) {
-+                      eisa_set_level_irq(newirq);
-+                      DBG(" ... OK\n");
-+                      msg = "Assigned";
-+                      irq = newirq;
-+              }
-+      }
-+
-+      if (!irq) {
-+              DBG(" ... failed\n");
-+              if (newirq && mask == (1 << newirq)) {
-+                      msg = "Guessed";
-+                      irq = newirq;
-+              } else
-+                      return 0;
-+      }
-+      printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, pci_name(dev));
-+
-+      /* Update IRQ for all devices with the same pirq value */
-+      while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
-+              pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
-+              if (!pin)
-+                      continue;
-+              pin--;
-+              info = pirq_get_info(dev2);
-+              if (!info)
-+                      continue;
-+              if (info->irq[pin].link == pirq) {
-+                      /* We refuse to override the dev->irq information. Give a warning! */
-+                      if ( dev2->irq && dev2->irq != irq && \
-+                      (!(pci_probe & PCI_USE_PIRQ_MASK) || \
-+                      ((1 << dev2->irq) & mask)) ) {
-+#ifndef CONFIG_PCI_MSI
-+                              printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
-+                                     pci_name(dev2), dev2->irq, irq);
-+#endif
-+                              continue;
-+                      }
-+                      dev2->irq = irq;
-+                      pirq_penalty[irq]++;
-+                      if (dev != dev2)
-+                              printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, pci_name(dev2));
-+              }
-+      }
-+      return 1;
-+}
-+
-+static void __init pcibios_fixup_irqs(void)
-+{
-+      struct pci_dev *dev = NULL;
-+      u8 pin;
-+
-+      DBG(KERN_DEBUG "PCI: IRQ fixup\n");
-+      while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-+              /*
-+               * If the BIOS has set an out of range IRQ number, just ignore it.
-+               * Also keep track of which IRQ's are already in use.
-+               */
-+              if (dev->irq >= 16) {
-+                      DBG(KERN_DEBUG "%s: ignoring bogus IRQ %d\n", pci_name(dev), dev->irq);
-+                      dev->irq = 0;
-+              }
-+              /* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */
-+              if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000)
-+                      pirq_penalty[dev->irq] = 0;
-+              pirq_penalty[dev->irq]++;
-+      }
-+
-+      dev = NULL;
-+      while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-+              pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-+#ifdef CONFIG_X86_IO_APIC
-+              /*
-+               * Recalculate IRQ numbers if we use the I/O APIC.
-+               */
-+              if (io_apic_assign_pci_irqs)
-+              {
-+                      int irq;
-+
-+                      if (pin) {
-+                              pin--;          /* interrupt pins are numbered starting from 1 */
-+                              irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
-+      /*
-+       * Busses behind bridges are typically not listed in the MP-table.
-+       * In this case we have to look up the IRQ based on the parent bus,
-+       * parent slot, and pin number. The SMP code detects such bridged
-+       * busses itself so we should get into this branch reliably.
-+       */
-+                              if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
-+                                      struct pci_dev * bridge = dev->bus->self;
-+
-+                                      pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-+                                      irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
-+                                                      PCI_SLOT(bridge->devfn), pin);
-+                                      if (irq >= 0)
-+                                              printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n",
-+                                                      pci_name(bridge), 'A' + pin, irq);
-+                              }
-+                              if (irq >= 0) {
-+                                      if (use_pci_vector() &&
-+                                              !platform_legacy_irq(irq))
-+                                              irq = IO_APIC_VECTOR(irq);
-+
-+                                      printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
-+                                              pci_name(dev), 'A' + pin, irq);
-+                                      dev->irq = irq;
-+                              }
-+                      }
-+              }
-+#endif
-+              /*
-+               * Still no IRQ? Try to lookup one...
-+               */
-+              if (pin && !dev->irq)
-+                      pcibios_lookup_irq(dev, 0);
-+      }
-+}
-+
-+/*
-+ * Work around broken HP Pavilion Notebooks which assign USB to
-+ * IRQ 9 even though it is actually wired to IRQ 11
-+ */
-+static int __init fix_broken_hp_bios_irq9(struct dmi_system_id *d)
-+{
-+      if (!broken_hp_bios_irq9) {
-+              broken_hp_bios_irq9 = 1;
-+              printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
-+      }
-+      return 0;
-+}
-+
-+/*
-+ * Work around broken Acer TravelMate 360 Notebooks which assign
-+ * Cardbus to IRQ 11 even though it is actually wired to IRQ 10
-+ */
-+static int __init fix_acer_tm360_irqrouting(struct dmi_system_id *d)
-+{
-+      if (!acer_tm360_irqrouting) {
-+              acer_tm360_irqrouting = 1;
-+              printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
-+      }
-+      return 0;
-+}
-+
-+static struct dmi_system_id __initdata pciirq_dmi_table[] = {
-+      {
-+              .callback = fix_broken_hp_bios_irq9,
-+              .ident = "HP Pavilion N5400 Series Laptop",
-+              .matches = {
-+                      DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-+                      DMI_MATCH(DMI_BIOS_VERSION, "GE.M1.03"),
-+                      DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
-+                      DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"),
-+              },
-+      },
-+      {
-+              .callback = fix_acer_tm360_irqrouting,
-+              .ident = "Acer TravelMate 36x Laptop",
-+              .matches = {
-+                      DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-+                      DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
-+              },
-+      },
-+      { }
-+};
-+
-+static int __init pcibios_irq_init(void)
-+{
-+      DBG(KERN_DEBUG "PCI: IRQ init\n");
-+
-+      if (pcibios_enable_irq || raw_pci_ops == NULL)
-+              return 0;
-+
-+      dmi_check_system(pciirq_dmi_table);
-+
-+      pirq_table = pirq_find_routing_table();
-+
-+#ifdef CONFIG_PCI_BIOS
-+      if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
-+              pirq_table = pcibios_get_irq_routing_table();
-+#endif
-+      if (pirq_table) {
-+              pirq_peer_trick();
-+              pirq_find_router(&pirq_router);
-+              if (pirq_table->exclusive_irqs) {
-+                      int i;
-+                      for (i=0; i<16; i++)
-+                              if (!(pirq_table->exclusive_irqs & (1 << i)))
-+                                      pirq_penalty[i] += 100;
-+              }
-+              /* If we're using the I/O APIC, avoid using the PCI IRQ routing table */
-+              if (io_apic_assign_pci_irqs)
-+                      pirq_table = NULL;
-+      }
-+
-+      pcibios_enable_irq = pirq_enable_irq;
-+
-+      pcibios_fixup_irqs();
-+      return 0;
-+}
-+
-+subsys_initcall(pcibios_irq_init);
-+
-+
-+static void pirq_penalize_isa_irq(int irq, int active)
-+{
-+      /*
-+       *  If any ISAPnP device reports an IRQ in its list of possible
-+       *  IRQ's, we try to avoid assigning it to PCI devices.
-+       */
-+      if (irq < 16) {
-+              if (active)
-+                      pirq_penalty[irq] += 1000;
-+              else
-+                      pirq_penalty[irq] += 100;
-+      }
-+}
-+
-+void pcibios_penalize_isa_irq(int irq, int active)
-+{
-+#ifdef CONFIG_ACPI
-+      if (!acpi_noirq)
-+              acpi_penalize_isa_irq(irq, active);
-+      else
-+#endif
-+              pirq_penalize_isa_irq(irq, active);
-+}
-+
-+static int pirq_enable_irq(struct pci_dev *dev)
-+{
-+      u8 pin;
-+      struct pci_dev *temp_dev;
-+
-+      pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-+      if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
-+              char *msg = "";
-+
-+              pin--;          /* interrupt pins are numbered starting from 1 */
-+
-+              if (io_apic_assign_pci_irqs) {
-+                      int irq;
-+
-+                      irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
-+                      /*
-+                       * Busses behind bridges are typically not listed in the MP-table.
-+                       * In this case we have to look up the IRQ based on the parent bus,
-+                       * parent slot, and pin number. The SMP code detects such bridged
-+                       * busses itself so we should get into this branch reliably.
-+                       */
-+                      temp_dev = dev;
-+                      while (irq < 0 && dev->bus->parent) { /* go back to the bridge */
-+                              struct pci_dev * bridge = dev->bus->self;
-+
-+                              pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-+                              irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
-+                                              PCI_SLOT(bridge->devfn), pin);
-+                              if (irq >= 0)
-+                                      printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n",
-+                                              pci_name(bridge), 'A' + pin, irq);
-+                              dev = bridge;
-+                      }
-+                      dev = temp_dev;
-+                      if (irq >= 0) {
-+#ifdef CONFIG_PCI_MSI
-+                              if (!platform_legacy_irq(irq))
-+                                      irq = IO_APIC_VECTOR(irq);
-+#endif
-+                              printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
-+                                      pci_name(dev), 'A' + pin, irq);
-+                              dev->irq = irq;
-+                              return 0;
-+                      } else
-+                              msg = " Probably buggy MP table.";
-+              } else if (pci_probe & PCI_BIOS_IRQ_SCAN)
-+                      msg = "";
-+              else
-+                      msg = " Please try using pci=biosirq.";
-+
-+              /* With IDE legacy devices the IRQ lookup failure is not a problem.. */
-+              if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && !(dev->class & 0x5))
-+                      return 0;
-+
-+              printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
-+                     'A' + pin, pci_name(dev), msg);
-+      }
-+      return 0;
-+}
-+
-+int pci_vector_resources(int last, int nr_released)
-+{
-+      int count = nr_released;
-+
-+      int next = last;
-+      int offset = (last % 8);
-+
-+      while (next < FIRST_SYSTEM_VECTOR) {
-+              next += 8;
-+#ifdef CONFIG_X86_64
-+              if (next == IA32_SYSCALL_VECTOR)
-+                      continue;
-+#else
-+              if (next == SYSCALL_VECTOR)
-+                      continue;
-+#endif
-+              count++;
-+              if (next >= FIRST_SYSTEM_VECTOR) {
-+                      if (offset%8) {
-+                              next = FIRST_DEVICE_VECTOR + offset;
-+                              offset++;
-+                              continue;
-+                      }
-+                      count--;
-+              }
-+      }
-+
-+      return count;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/i386/pci/mmconfig.c linux-2.6.16.33/arch/i386/pci/mmconfig.c
---- linux-2.6.16.33-noxen/arch/i386/pci/mmconfig.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/pci/mmconfig.c   2007-05-23 21:00:01.000000000 +0000
-@@ -12,14 +12,22 @@
- #include <linux/pci.h>
- #include <linux/init.h>
- #include <linux/acpi.h>
-+#include <asm/e820.h>
- #include "pci.h"
-+/* aperture is up to 256MB but BIOS may reserve less */
-+#define MMCONFIG_APER_MIN     (2 * 1024*1024)
-+#define MMCONFIG_APER_MAX     (256 * 1024*1024)
-+
-+/* Assume systems with more busses have correct MCFG */
-+#define MAX_CHECK_BUS 16
-+
- #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
- /* The base address of the last MMCONFIG device accessed */
- static u32 mmcfg_last_accessed_device;
--static DECLARE_BITMAP(fallback_slots, 32);
-+static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32);
- /*
-  * Functions for accessing PCI configuration space with MMCONFIG accesses
-@@ -29,8 +37,8 @@
-       int cfg_num = -1;
-       struct acpi_table_mcfg_config *cfg;
--      if (seg == 0 && bus == 0 &&
--          test_bit(PCI_SLOT(devfn), fallback_slots))
-+      if (seg == 0 && bus < MAX_CHECK_BUS &&
-+          test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots))
-               return 0;
-       while (1) {
-@@ -74,8 +82,10 @@
-       unsigned long flags;
-       u32 base;
--      if (!value || (bus > 255) || (devfn > 255) || (reg > 4095))
-+      if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
-+              *value = -1;
-               return -EINVAL;
-+      }
-       base = get_base_addr(seg, bus, devfn);
-       if (!base)
-@@ -146,30 +156,66 @@
-    Normally this can be expressed in the MCFG by not listing them
-    and assigning suitable _SEGs, but this isn't implemented in some BIOS.
-    Instead try to discover all devices on bus 0 that are unreachable using MM
--   and fallback for them.
--   We only do this for bus 0/seg 0 */
-+   and fallback for them. */
- static __init void unreachable_devices(void)
- {
--      int i;
-+      int i, k;
-       unsigned long flags;
--      for (i = 0; i < 32; i++) {
--              u32 val1;
--              u32 addr;
-+      for (k = 0; k < MAX_CHECK_BUS; k++) {
-+              for (i = 0; i < 32; i++) {
-+                      u32 val1;
-+                      u32 addr;
-+
-+                      pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1);
-+                      if (val1 == 0xffffffff)
-+                              continue;
-+
-+                      /* Locking probably not needed, but safer */
-+                      spin_lock_irqsave(&pci_config_lock, flags);
-+                      addr = get_base_addr(0, k, PCI_DEVFN(i, 0));
-+                      if (addr != 0)
-+                              pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0));
-+                      if (addr == 0 ||
-+                          readl((u32 __iomem *)mmcfg_virt_addr) != val1) {
-+                              set_bit(i, fallback_slots);
-+                              printk(KERN_NOTICE
-+                      "PCI: No mmconfig possible on %x:%x\n", k, i);
-+                      }
-+                      spin_unlock_irqrestore(&pci_config_lock, flags);
-+              }
-+      }
-+}
--              pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1);
--              if (val1 == 0xffffffff)
-+/* NB. Ripped from arch/i386/kernel/setup.c for this Xen bugfix patch. */
-+#ifdef CONFIG_XEN
-+extern struct e820map machine_e820;
-+#define e820 machine_e820
-+#endif
-+static int __init
-+e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
-+{
-+      u64 start = s;
-+      u64 end = e;
-+      int i;
-+      for (i = 0; i < e820.nr_map; i++) {
-+              struct e820entry *ei = &e820.map[i];
-+              if (type && ei->type != type)
-                       continue;
--
--              /* Locking probably not needed, but safer */
--              spin_lock_irqsave(&pci_config_lock, flags);
--              addr = get_base_addr(0, 0, PCI_DEVFN(i, 0));
--              if (addr != 0)
--                      pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0));
--              if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1)
--                      set_bit(i, fallback_slots);
--              spin_unlock_irqrestore(&pci_config_lock, flags);
-+              /* is the region (part) in overlap with the current region ?*/
-+              if (ei->addr >= end || ei->addr + ei->size <= start)
-+                      continue;
-+              /* if the region is at the beginning of <start,end> we move
-+               * start to the end of the region since it's ok until there
-+               */
-+              if (ei->addr <= start)
-+                      start = ei->addr + ei->size;
-+              /* if start is now at or beyond end, we're done, full
-+               * coverage */
-+              if (start >= end)
-+                      return 1; /* we're done */
-       }
-+      return 0;
- }
- static int __init pci_mmcfg_init(void)
-@@ -183,6 +229,15 @@
-           (pci_mmcfg_config[0].base_address == 0))
-               goto out;
-+      if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
-+                      pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
-+                      E820_RESERVED)) {
-+              printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
-+                              pci_mmcfg_config[0].base_address);
-+              printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
-+              goto out;
-+      }
-+
-       printk(KERN_INFO "PCI: Using MMCONFIG\n");
-       raw_pci_ops = &pci_mmcfg;
-       pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
-diff -Nur linux-2.6.16.33-noxen/arch/i386/pci/pcifront.c linux-2.6.16.33/arch/i386/pci/pcifront.c
---- linux-2.6.16.33-noxen/arch/i386/pci/pcifront.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/pci/pcifront.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,55 @@
-+/*
-+ * PCI Frontend Stub - puts some "dummy" functions in to the Linux x86 PCI core
-+ *                     to support the Xen PCI Frontend's operation
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <asm/acpi.h>
-+#include "pci.h"
-+
-+static int pcifront_enable_irq(struct pci_dev *dev)
-+{
-+      u8 irq;
-+      pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
-+      dev->irq = irq;
-+
-+      return 0;
-+}
-+
-+extern u8 pci_cache_line_size;
-+
-+static int __init pcifront_x86_stub_init(void)
-+{
-+      struct cpuinfo_x86 *c = &boot_cpu_data;
-+
-+      /* Only install our method if we haven't found real hardware already */
-+      if (raw_pci_ops)
-+              return 0;
-+
-+      printk(KERN_INFO "PCI: setting up Xen PCI frontend stub\n");
-+
-+      /* Copied from arch/i386/pci/common.c */
-+      pci_cache_line_size = 32 >> 2;
-+      if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
-+              pci_cache_line_size = 64 >> 2;  /* K7 & K8 */
-+      else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
-+              pci_cache_line_size = 128 >> 2; /* P4 */
-+
-+      /* On x86, we need to disable the normal IRQ routing table and
-+       * just ask the backend
-+       */
-+      pcibios_enable_irq = pcifront_enable_irq;
-+      pcibios_disable_irq = NULL;
-+
-+#ifdef CONFIG_ACPI
-+      /* Keep ACPI out of the picture */
-+      acpi_noirq = 1;
-+#endif
-+
-+      return 0;
-+}
-+
-+arch_initcall(pcifront_x86_stub_init);
-diff -Nur linux-2.6.16.33-noxen/arch/i386/power/Makefile linux-2.6.16.33/arch/i386/power/Makefile
---- linux-2.6.16.33-noxen/arch/i386/power/Makefile     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/i386/power/Makefile   2007-01-08 15:00:45.000000000 +0000
-@@ -1,2 +1,4 @@
--obj-$(CONFIG_PM)              += cpu.o
-+obj-$(CONFIG_PM_LEGACY)               += cpu.o
-+obj-$(CONFIG_SOFTWARE_SUSPEND)        += cpu.o
-+obj-$(CONFIG_ACPI_SLEEP)      += cpu.o
- obj-$(CONFIG_SOFTWARE_SUSPEND)        += swsusp.o
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/Kconfig linux-2.6.16.33/arch/ia64/Kconfig
---- linux-2.6.16.33-noxen/arch/ia64/Kconfig    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/Kconfig  2007-01-08 15:00:45.000000000 +0000
-@@ -50,6 +50,34 @@
-       bool
-       default y
-+config XEN
-+      bool "Xen hypervisor support"
-+      default y
-+      help
-+        Enable Xen hypervisor support.  Resulting kernel runs
-+        both as a guest OS on Xen and natively on hardware.
-+
-+config XEN_IA64_VDSO_PARAVIRT
-+      bool
-+      depends on XEN && !ITANIUM
-+      default y
-+      help
-+        vDSO paravirtualization
-+
-+config XEN_IA64_EXPOSE_P2M
-+      bool "Xen/IA64 exposure p2m table"
-+      depends on XEN
-+      default y
-+      help
-+        expose p2m from xen
-+
-+config XEN_IA64_EXPOSE_P2M_USE_DTR
-+      bool "Xen/IA64 map p2m table with dtr"
-+      depends on XEN_IA64_EXPOSE_P2M
-+      default y
-+      help
-+        use dtr to map the exposed p2m table
-+
- config SCHED_NO_NO_OMIT_FRAME_POINTER
-       bool
-       default y
-@@ -413,6 +441,21 @@
-       bool
-       default PCI
-+config XEN_PCIDEV_FRONTEND
-+      bool "Xen PCI Frontend"
-+      depends on PCI && XEN
-+      default y
-+      help
-+        The PCI device frontend driver allows the kernel to import arbitrary
-+        PCI devices from a PCI backend to support PCI driver domains.
-+
-+config XEN_PCIDEV_FE_DEBUG
-+      bool "Xen PCI Frontend Debugging"
-+      depends on XEN_PCIDEV_FRONTEND
-+      default n
-+      help
-+        Enables some debug statements within the PCI Frontend.
-+
- source "drivers/pci/Kconfig"
- source "drivers/pci/hotplug/Kconfig"
-@@ -470,3 +513,32 @@
- source "security/Kconfig"
- source "crypto/Kconfig"
-+
-+#
-+# override default values of drivers/xen/Kconfig
-+#
-+if XEN
-+config XEN_UTIL
-+      default n
-+
-+config HAVE_ARCH_ALLOC_SKB
-+      default y
-+
-+config HAVE_ARCH_DEV_ALLOC_SKB
-+      default y
-+
-+config XEN_BALLOON
-+      default y
-+
-+config XEN_SKBUFF
-+      default y
-+      depends on NET
-+
-+config XEN_REBOOT
-+      default y
-+
-+config XEN_SMPBOOT
-+      default n
-+endif
-+
-+source "drivers/xen/Kconfig"
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/Makefile linux-2.6.16.33/arch/ia64/Makefile
---- linux-2.6.16.33-noxen/arch/ia64/Makefile   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/Makefile 2007-01-08 15:00:45.000000000 +0000
-@@ -42,6 +42,12 @@
- endif
- CFLAGS += $(cflags-y)
-+
-+cppflags-$(CONFIG_XEN) += \
-+      -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION)
-+
-+CPPFLAGS += $(cppflags-y)
-+
- head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
- libs-y                                += arch/ia64/lib/
-@@ -52,9 +58,15 @@
- core-$(CONFIG_IA64_HP_ZX1)    += arch/ia64/dig/
- core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
- core-$(CONFIG_IA64_SGI_SN2)   += arch/ia64/sn/
-+core-$(CONFIG_XEN)            += arch/ia64/xen/
- drivers-$(CONFIG_PCI)         += arch/ia64/pci/
-+ifneq ($(CONFIG_XEN),y)
- drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
-+endif
-+ifneq ($(CONFIG_IA64_GENERIC),y)
-+drivers-$(CONFIG_XEN)         += arch/ia64/hp/sim/
-+endif
- drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
- drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
- drivers-$(CONFIG_IA64_GENERIC)        += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/
-@@ -68,6 +80,8 @@
- compressed: vmlinux.gz
-+vmlinuz: vmlinux.gz
-+
- vmlinux.gz: vmlinux
-       $(Q)$(MAKE) $(build)=$(boot) $@
-@@ -82,8 +96,8 @@
- boot: lib/lib.a vmlinux
-       $(Q)$(MAKE) $(build)=$(boot) $@
--install: vmlinux.gz
--      sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
-+install:
-+      -yes | sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
- define archhelp
-   echo '* compressed  - Build compressed kernel image'
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/dig/setup.c linux-2.6.16.33/arch/ia64/dig/setup.c
---- linux-2.6.16.33-noxen/arch/ia64/dig/setup.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/dig/setup.c      2007-01-08 15:00:45.000000000 +0000
-@@ -25,6 +25,8 @@
- #include <asm/machvec.h>
- #include <asm/system.h>
-+#include <xen/xencons.h>
-+
- void __init
- dig_setup (char **cmdline_p)
- {
-@@ -68,6 +70,21 @@
-       screen_info.orig_video_mode = 3;        /* XXX fake */
-       screen_info.orig_video_isVGA = 1;       /* XXX fake */
-       screen_info.orig_video_ega_bx = 3;      /* XXX fake */
-+#ifdef CONFIG_XEN
-+      if (!is_running_on_xen() || !is_initial_xendomain())
-+              return;
-+
-+      if (xen_start_info->console.dom0.info_size >=
-+          sizeof(struct dom0_vga_console_info)) {
-+              const struct dom0_vga_console_info *info =
-+                      (struct dom0_vga_console_info *)(
-+                              (char *)xen_start_info +
-+                              xen_start_info->console.dom0.info_off);
-+              dom0_init_screen_info(info);
-+      }
-+      xen_start_info->console.domU.mfn = 0;
-+      xen_start_info->console.domU.evtchn = 0;
-+#endif
- }
- void __init
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/hp/sim/Makefile linux-2.6.16.33/arch/ia64/hp/sim/Makefile
---- linux-2.6.16.33-noxen/arch/ia64/hp/sim/Makefile    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/hp/sim/Makefile  2007-01-08 15:00:45.000000000 +0000
-@@ -14,3 +14,5 @@
- obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
- obj-$(CONFIG_HP_SIMSERIAL_CONSOLE) += hpsim_console.o
- obj-$(CONFIG_HP_SIMSCSI) += simscsi.o
-+obj-$(CONFIG_XEN) += simserial.o
-+obj-$(CONFIG_XEN) += hpsim_console.o
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/Makefile linux-2.6.16.33/arch/ia64/kernel/Makefile
---- linux-2.6.16.33-noxen/arch/ia64/kernel/Makefile    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/Makefile  2007-01-08 15:00:45.000000000 +0000
-@@ -44,7 +44,8 @@
- quiet_cmd_gate = GATE $@
-       cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
--GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1
-+GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
-+                   $(call ld-option, -Wl$(comma)--hash-style=sysv)
- $(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
-       $(call if_changed,gate)
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/asm-offsets.c linux-2.6.16.33/arch/ia64/kernel/asm-offsets.c
---- linux-2.6.16.33-noxen/arch/ia64/kernel/asm-offsets.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/asm-offsets.c     2007-01-08 15:00:45.000000000 +0000
-@@ -261,4 +261,28 @@
-       DEFINE(IA64_TIME_SOURCE_MMIO64, TIME_SOURCE_MMIO64);
-       DEFINE(IA64_TIME_SOURCE_MMIO32, TIME_SOURCE_MMIO32);
-       DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec));
-+
-+#ifdef CONFIG_XEN
-+      BLANK();
-+
-+#define DEFINE_MAPPED_REG_OFS(sym, field) \
-+      DEFINE(sym, (XMAPPEDREGS_OFS + offsetof(mapped_regs_t, field)))
-+
-+      DEFINE_MAPPED_REG_OFS(XSI_PSR_I_ADDR_OFS, interrupt_mask_addr);
-+      DEFINE_MAPPED_REG_OFS(XSI_IPSR_OFS, ipsr);
-+      DEFINE_MAPPED_REG_OFS(XSI_IIP_OFS, iip);
-+      DEFINE_MAPPED_REG_OFS(XSI_IFS_OFS, ifs);
-+      DEFINE_MAPPED_REG_OFS(XSI_PRECOVER_IFS_OFS, precover_ifs);
-+      DEFINE_MAPPED_REG_OFS(XSI_ISR_OFS, isr);
-+      DEFINE_MAPPED_REG_OFS(XSI_IFA_OFS, ifa);
-+      DEFINE_MAPPED_REG_OFS(XSI_IIPA_OFS, iipa);
-+      DEFINE_MAPPED_REG_OFS(XSI_IIM_OFS, iim);
-+      DEFINE_MAPPED_REG_OFS(XSI_IHA_OFS, iha);
-+      DEFINE_MAPPED_REG_OFS(XSI_ITIR_OFS, itir);
-+      DEFINE_MAPPED_REG_OFS(XSI_PSR_IC_OFS, interrupt_collection_enabled);
-+      DEFINE_MAPPED_REG_OFS(XSI_INCOMPL_REGFR_OFS, incomplete_regframe);
-+      DEFINE_MAPPED_REG_OFS(XSI_BANKNUM_OFS, banknum);
-+      DEFINE_MAPPED_REG_OFS(XSI_BANK0_R16_OFS, bank0_regs[0]);
-+      DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]);
-+#endif /* CONFIG_XEN */
- }
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/entry.S linux-2.6.16.33/arch/ia64/kernel/entry.S
---- linux-2.6.16.33-noxen/arch/ia64/kernel/entry.S     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/entry.S   2007-01-08 15:00:45.000000000 +0000
-@@ -181,7 +181,7 @@
-  *    called.  The code starting at .map relies on this.  The rest of the code
-  *    doesn't care about the interrupt masking status.
-  */
--GLOBAL_ENTRY(ia64_switch_to)
-+GLOBAL_ENTRY(__ia64_switch_to)
-       .prologue
-       alloc r16=ar.pfs,1,0,0,0
-       DO_SAVE_SWITCH_STACK
-@@ -235,7 +235,7 @@
-       ;;
-       srlz.d
-       br.cond.sptk .done
--END(ia64_switch_to)
-+END(__ia64_switch_to)
- /*
-  * Note that interrupts are enabled during save_switch_stack and load_switch_stack.  This
-@@ -376,7 +376,7 @@
-  *    - b7 holds address to return to
-  *    - must not touch r8-r11
-  */
--ENTRY(load_switch_stack)
-+GLOBAL_ENTRY(load_switch_stack)
-       .prologue
-       .altrp b7
-@@ -511,7 +511,7 @@
-        * because some system calls (such as ia64_execve) directly
-        * manipulate ar.pfs.
-        */
--GLOBAL_ENTRY(ia64_trace_syscall)
-+GLOBAL_ENTRY(__ia64_trace_syscall)
-       PT_REGS_UNWIND_INFO(0)
-       /*
-        * We need to preserve the scratch registers f6-f11 in case the system
-@@ -583,7 +583,7 @@
- (p6)  mov r10=-1
- (p6)  mov r8=r9
-       br.cond.sptk .strace_save_retval
--END(ia64_trace_syscall)
-+END(__ia64_trace_syscall)
-       /*
-        * When traced and returning from sigreturn, we invoke syscall_trace but then
-@@ -602,7 +602,7 @@
- .ret4:        br.cond.sptk ia64_leave_kernel
- END(ia64_strace_leave_kernel)
--GLOBAL_ENTRY(ia64_ret_from_clone)
-+GLOBAL_ENTRY(__ia64_ret_from_clone)
-       PT_REGS_UNWIND_INFO(0)
- {     /*
-        * Some versions of gas generate bad unwind info if the first instruction of a
-@@ -628,7 +628,7 @@
-       cmp.ne p6,p0=r2,r0
- (p6)  br.cond.spnt .strace_check_retval
-       ;;                                      // added stop bits to prevent r8 dependency
--END(ia64_ret_from_clone)
-+END(__ia64_ret_from_clone)
-       // fall through
- GLOBAL_ENTRY(ia64_ret_from_syscall)
-       PT_REGS_UNWIND_INFO(0)
-@@ -636,8 +636,11 @@
-       adds r2=PT(R8)+16,sp                    // r2 = &pt_regs.r8
-       mov r10=r0                              // clear error indication in r10
- (p7)  br.cond.spnt handle_syscall_error       // handle potential syscall failure
-+      ;;
-+      // don't fall through, ia64_leave_syscall may be #define'd
-+      br.cond.sptk.few ia64_leave_syscall
-+      ;;
- END(ia64_ret_from_syscall)
--      // fall through
- /*
-  * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
-  *    need to switch to bank 0 and doesn't restore the scratch registers.
-@@ -682,7 +685,7 @@
-  *          ar.csd: cleared
-  *          ar.ssd: cleared
-  */
--ENTRY(ia64_leave_syscall)
-+GLOBAL_ENTRY(__ia64_leave_syscall)
-       PT_REGS_UNWIND_INFO(0)
-       /*
-        * work.need_resched etc. mustn't get changed by this CPU before it returns to
-@@ -790,7 +793,7 @@
-       mov.m ar.ssd=r0                 // M2   clear ar.ssd
-       mov f11=f0                      // F    clear f11
-       br.cond.sptk.many rbs_switch    // B
--END(ia64_leave_syscall)
-+END(__ia64_leave_syscall)
- #ifdef CONFIG_IA32_SUPPORT
- GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
-@@ -802,10 +805,13 @@
-       st8.spill [r2]=r8       // store return value in slot for r8 and set unat bit
-       .mem.offset 8,0
-       st8.spill [r3]=r0       // clear error indication in slot for r10 and set unat bit
-+      ;;
-+      // don't fall through, ia64_leave_kernel may be #define'd
-+      br.cond.sptk.few ia64_leave_kernel
-+      ;;
- END(ia64_ret_from_ia32_execve)
--      // fall through
- #endif /* CONFIG_IA32_SUPPORT */
--GLOBAL_ENTRY(ia64_leave_kernel)
-+GLOBAL_ENTRY(__ia64_leave_kernel)
-       PT_REGS_UNWIND_INFO(0)
-       /*
-        * work.need_resched etc. mustn't get changed by this CPU before it returns to
-@@ -1150,7 +1156,7 @@
-       ld8 r10=[r3]
-       br.cond.sptk.many .work_processed_syscall       // re-check
--END(ia64_leave_kernel)
-+END(__ia64_leave_kernel)
- ENTRY(handle_syscall_error)
-       /*
-@@ -1190,7 +1196,7 @@
-        * be set up by the caller.  We declare 8 input registers so the system call
-        * args get preserved, in case we need to restart a system call.
-        */
--ENTRY(notify_resume_user)
-+GLOBAL_ENTRY(notify_resume_user)
-       .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
-       alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
-       mov r9=ar.unat
-@@ -1278,7 +1284,7 @@
-       adds sp=16,sp
-       ;;
-       ld8 r9=[sp]                             // load new ar.unat
--      mov.sptk b7=r8,ia64_leave_kernel
-+      mov.sptk b7=r8,__ia64_leave_kernel
-       ;;
-       mov ar.unat=r9
-       br.many b7
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/gate.S linux-2.6.16.33/arch/ia64/kernel/gate.S
---- linux-2.6.16.33-noxen/arch/ia64/kernel/gate.S      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/gate.S    2007-01-08 15:00:45.000000000 +0000
-@@ -14,6 +14,9 @@
- #include <asm/sigcontext.h>
- #include <asm/system.h>
- #include <asm/unistd.h>
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+# include <asm/privop.h>
-+#endif
- /*
-  * We can't easily refer to symbols inside the kernel.  To avoid full runtime relocation,
-@@ -33,6 +36,52 @@
- [1:](pr)brl.cond.sptk 0;                              \
-       .xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+      // The page in which hyperprivop lives must be pinned by ITR.
-+      // However vDSO area isn't pinned. So issuing hyperprivop
-+      // from vDSO page causes trouble that Kevin pointed out.
-+      // After clearing vpsr.ic, the vcpu is pre-empted and the itlb
-+      // is flushed. Then vcpu get cpu again, tlb miss fault occures.
-+      // However it results in nested dtlb fault because vpsr.ic is off.
-+      // To avoid such a situation, we jump into the kernel text area
-+      // which is pinned, and then issue hyperprivop and return back
-+      // to vDSO page.
-+      // This is Dan Magenheimer's idea.
-+
-+      // Currently is_running_on_xen() is defined as running_on_xen.
-+      // If is_running_on_xen() is a real function, we must update
-+      // according to it.
-+      .section ".data.patch.running_on_xen", "a"
-+      .previous
-+#define LOAD_RUNNING_ON_XEN(reg)                      \
-+[1:]  movl reg=0;                                     \
-+      .xdata4 ".data.patch.running_on_xen", 1b-.
-+
-+      .section ".data.patch.brl_xen_rsm_be_i", "a"
-+      .previous
-+#define BRL_COND_XEN_RSM_BE_I(pr)                     \
-+[1:](pr)brl.cond.sptk 0;                              \
-+      .xdata4 ".data.patch.brl_xen_rsm_be_i", 1b-.
-+
-+      .section ".data.patch.brl_xen_get_psr", "a"
-+      .previous
-+#define BRL_COND_XEN_GET_PSR(pr)                      \
-+[1:](pr)brl.cond.sptk 0;                              \
-+      .xdata4 ".data.patch.brl_xen_get_psr", 1b-.
-+
-+      .section ".data.patch.brl_xen_ssm_i_0", "a"
-+      .previous
-+#define BRL_COND_XEN_SSM_I_0(pr)                      \
-+[1:](pr)brl.cond.sptk 0;                              \
-+      .xdata4 ".data.patch.brl_xen_ssm_i_0", 1b-.
-+
-+      .section ".data.patch.brl_xen_ssm_i_1", "a"
-+      .previous
-+#define BRL_COND_XEN_SSM_I_1(pr)                      \
-+[1:](pr)brl.cond.sptk 0;                              \
-+      .xdata4 ".data.patch.brl_xen_ssm_i_1", 1b-.
-+#endif
-+
- GLOBAL_ENTRY(__kernel_syscall_via_break)
-       .prologue
-       .altrp b6
-@@ -77,7 +126,42 @@
-       epc                                     // B    causes split-issue
- }
-       ;;
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+      // r20 = 1
-+      // r22 = &vcpu->vcpu_info->evtchn_upcall_mask
-+      // r23 = &vpsr.ic
-+      // r24 = &vcpu->vcpu_info->evtchn_upcall_pending
-+      // r25 = tmp
-+      // r28 = &running_on_xen
-+      // r30 = running_on_xen
-+      // r31 = tmp
-+      // p11 = tmp
-+      // p12 = running_on_xen
-+      // p13 = !running_on_xen
-+      // p14 = tmp
-+      // p15 = tmp
-+#define isXen p12
-+#define isRaw p13
-+      LOAD_RUNNING_ON_XEN(r28)
-+      movl r22=XSI_PSR_I_ADDR
-+      ;;
-+      ld8 r22=[r22]
-+      ;;
-+      movl r23=XSI_PSR_IC
-+      adds r24=-1,r22
-+      mov r20=1
-+      ;;
-+      ld4 r30=[r28]
-+      ;;
-+      cmp.ne isXen,isRaw=r0,r30
-+      ;;
-+(isRaw)       rsm psr.be | psr.i
-+      BRL_COND_XEN_RSM_BE_I(isXen)
-+      .global .vdso_rsm_be_i_ret
-+.vdso_rsm_be_i_ret:
-+#else
-       rsm psr.be | psr.i                      // M2 (5 cyc to srlz.d)
-+#endif
-       LOAD_FSYSCALL_TABLE(r14)                // X
-       ;;
-       mov r16=IA64_KR(CURRENT)                // M2 (12 cyc)
-@@ -85,7 +169,14 @@
-       mov r19=NR_syscalls-1                   // A
-       ;;
-       lfetch [r18]                            // M0|1
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+(isRaw)       mov r29=psr
-+      BRL_COND_XEN_GET_PSR(isXen)
-+      .global .vdso_get_psr_ret
-+.vdso_get_psr_ret:
-+#else
-       mov r29=psr                             // M2 (12 cyc)
-+#endif
-       // If r17 is a NaT, p6 will be zero
-       cmp.geu p6,p7=r19,r17                   // A    (sysnr > 0 && sysnr < 1024+NR_syscalls)?
-       ;;
-@@ -99,9 +190,21 @@
-       ;;
-       nop.m 0
- (p6)  tbit.z.unc p8,p0=r18,0                  // I0 (dual-issues with "mov b7=r18"!)
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+      ;;
-+      // p14 = running_on_xen && p8
-+      // p15 = !running_on_xen && p8
-+(p8)  cmp.ne.unc p14,p15=r0,r30
-+      ;;
-+(p15) ssm psr.i
-+      BRL_COND_XEN_SSM_I_0(p14)
-+      .global .vdso_ssm_i_0_ret
-+.vdso_ssm_i_0_ret:
-+#else
-       nop.i 0
-       ;;
- (p8)  ssm psr.i
-+#endif
- (p6)  mov b7=r18                              // I0
- (p8)  br.dptk.many b7                         // B
-@@ -122,9 +225,21 @@
- #else
-       BRL_COND_FSYS_BUBBLE_DOWN(p6)
- #endif
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+(isRaw)       ssm psr.i
-+      BRL_COND_XEN_SSM_I_1(isXen)
-+      .global .vdso_ssm_i_1_ret
-+.vdso_ssm_i_1_ret:
-+#else
-       ssm psr.i
-+#endif
-       mov r10=-1
- (p10) mov r8=EINVAL
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+      dv_serialize_data // shut up gas warning.
-+                        // we know xen_hyper_ssm_i_0 or xen_hyper_ssm_i_1
-+                        // doesn't change p9 and p10
-+#endif
- (p9)  mov r8=ENOSYS
-       FSYS_RETURN
- END(__kernel_syscall_via_epc)
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/gate.lds.S linux-2.6.16.33/arch/ia64/kernel/gate.lds.S
---- linux-2.6.16.33-noxen/arch/ia64/kernel/gate.lds.S  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/gate.lds.S        2007-01-08 15:00:45.000000000 +0000
-@@ -13,6 +13,7 @@
-   . = GATE_ADDR + SIZEOF_HEADERS;
-   .hash                               : { *(.hash) }                          :readable
-+  .gnu.hash                   : { *(.gnu.hash) }
-   .dynsym                     : { *(.dynsym) }
-   .dynstr                     : { *(.dynstr) }
-   .gnu.version                        : { *(.gnu.version) }
-@@ -43,6 +44,28 @@
-                                   __start_gate_brl_fsys_bubble_down_patchlist = .;
-                                   *(.data.patch.brl_fsys_bubble_down)
-                                   __end_gate_brl_fsys_bubble_down_patchlist = .;
-+
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+                                  __start_gate_running_on_xen_patchlist = .;
-+                                  *(.data.patch.running_on_xen)
-+                                  __end_gate_running_on_xen_patchlist = .;
-+
-+                                  __start_gate_brl_xen_rsm_be_i_patchlist = .;
-+                                  *(.data.patch.brl_xen_rsm_be_i)
-+                                  __end_gate_brl_xen_rsm_be_i_patchlist = .;
-+
-+                                  __start_gate_brl_xen_get_psr_patchlist = .;
-+                                  *(.data.patch.brl_xen_get_psr)
-+                                  __end_gate_brl_xen_get_psr_patchlist = .;
-+
-+                                  __start_gate_brl_xen_ssm_i_0_patchlist = .;
-+                                  *(.data.patch.brl_xen_ssm_i_0)
-+                                  __end_gate_brl_xen_ssm_i_0_patchlist = .;
-+
-+                                  __start_gate_brl_xen_ssm_i_1_patchlist = .;
-+                                  *(.data.patch.brl_xen_ssm_i_1)
-+                                  __end_gate_brl_xen_ssm_i_1_patchlist = .;
-+#endif
-   }                                                                   :readable
-   .IA_64.unwind_info          : { *(.IA_64.unwind_info*) }
-   .IA_64.unwind                       : { *(.IA_64.unwind*) }                 :readable :unwind
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/head.S linux-2.6.16.33/arch/ia64/kernel/head.S
---- linux-2.6.16.33-noxen/arch/ia64/kernel/head.S      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/head.S    2007-01-08 15:00:45.000000000 +0000
-@@ -363,6 +363,12 @@
-       ;;
- (isBP)        st8 [r2]=r28            // save the address of the boot param area passed by the bootloader
-+#ifdef CONFIG_XEN
-+      //  Note: isBP is used by the subprogram.
-+      br.call.sptk.many rp=early_xen_setup
-+      ;;
-+#endif
-+
- #ifdef CONFIG_SMP
- (isAP)        br.call.sptk.many rp=start_secondary
- .ret0:
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/iosapic.c linux-2.6.16.33/arch/ia64/kernel/iosapic.c
---- linux-2.6.16.33-noxen/arch/ia64/kernel/iosapic.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/iosapic.c 2007-01-08 15:00:45.000000000 +0000
-@@ -140,6 +140,75 @@
- static int iosapic_kmalloc_ok;
- static LIST_HEAD(free_rte_list);
-+#ifdef CONFIG_XEN
-+#include <xen/interface/xen.h>
-+#include <xen/interface/physdev.h>
-+#include <asm/hypervisor.h>
-+static inline unsigned int xen_iosapic_read(char __iomem *iosapic, unsigned int reg)
-+{
-+      struct physdev_apic apic_op;
-+      int ret;
-+
-+      apic_op.apic_physbase = (unsigned long)iosapic -
-+                                      __IA64_UNCACHED_OFFSET;
-+      apic_op.reg = reg;
-+      ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
-+      if (ret)
-+              return ret;
-+      return apic_op.value;
-+}
-+
-+static inline void xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
-+{
-+      struct physdev_apic apic_op;
-+
-+      apic_op.apic_physbase = (unsigned long)iosapic - 
-+                                      __IA64_UNCACHED_OFFSET;
-+      apic_op.reg = reg;
-+      apic_op.value = val;
-+      HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
-+}
-+
-+static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int reg)
-+{
-+      if (!is_running_on_xen()) {
-+              writel(reg, iosapic + IOSAPIC_REG_SELECT);
-+              return readl(iosapic + IOSAPIC_WINDOW);
-+      } else
-+              return xen_iosapic_read(iosapic, reg);
-+}
-+
-+static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
-+{
-+      if (!is_running_on_xen()) {
-+              writel(reg, iosapic + IOSAPIC_REG_SELECT);
-+              writel(val, iosapic + IOSAPIC_WINDOW);
-+      } else
-+              xen_iosapic_write(iosapic, reg, val);
-+}
-+
-+int xen_assign_irq_vector(int irq)
-+{
-+      struct physdev_irq irq_op;
-+
-+      irq_op.irq = irq;
-+      if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
-+              return -ENOSPC;
-+
-+      return irq_op.vector;
-+}
-+
-+void xen_free_irq_vector(int vector)
-+{
-+      struct physdev_irq irq_op;
-+
-+      irq_op.vector = vector;
-+      if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op))
-+              printk(KERN_WARNING "%s: xen_free_irq_vecotr fail vector=%d\n",
-+                     __FUNCTION__, vector);
-+}
-+#endif /* XEN */
-+
- /*
-  * Find an IOSAPIC associated with a GSI
-  */
-@@ -611,6 +680,9 @@
-       iosapic_intr_info[vector].dmode    = delivery;
-       iosapic_intr_info[vector].trigger  = trigger;
-+      if (is_running_on_xen())
-+              return 0;
-+
-       if (trigger == IOSAPIC_EDGE)
-               irq_type = &irq_type_iosapic_edge;
-       else
-@@ -953,6 +1025,9 @@
-       }
-       pcat_compat = system_pcat_compat;
-+      if (is_running_on_xen())
-+              return;
-+
-       if (pcat_compat) {
-               /*
-                * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/irq_ia64.c linux-2.6.16.33/arch/ia64/kernel/irq_ia64.c
---- linux-2.6.16.33-noxen/arch/ia64/kernel/irq_ia64.c  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/irq_ia64.c        2007-01-08 15:00:45.000000000 +0000
-@@ -31,6 +31,9 @@
- #include <linux/smp_lock.h>
- #include <linux/threads.h>
- #include <linux/bitops.h>
-+#ifdef CONFIG_XEN
-+#include <linux/cpu.h>
-+#endif
- #include <asm/delay.h>
- #include <asm/intrinsics.h>
-@@ -66,6 +69,13 @@
- assign_irq_vector (int irq)
- {
-       int pos, vector;
-+
-+#ifdef CONFIG_XEN
-+      if (is_running_on_xen()) {
-+              extern int xen_assign_irq_vector(int);
-+              return xen_assign_irq_vector(irq);
-+      }
-+#endif
-  again:
-       pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
-       vector = IA64_FIRST_DEVICE_VECTOR + pos;
-@@ -84,6 +94,13 @@
-       if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR)
-               return;
-+#ifdef CONFIG_XEN
-+      if (is_running_on_xen()) {
-+              extern void xen_free_irq_vector(int);
-+              xen_free_irq_vector(vector);
-+              return;
-+      }
-+#endif
-       pos = vector - IA64_FIRST_DEVICE_VECTOR;
-       if (!test_and_clear_bit(pos, ia64_vector_mask))
-               printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
-@@ -224,12 +241,264 @@
- };
- #endif
-+#ifdef CONFIG_XEN
-+#include <xen/evtchn.h>
-+#include <xen/interface/callback.h>
-+
-+static DEFINE_PER_CPU(int, timer_irq) = -1;
-+static DEFINE_PER_CPU(int, ipi_irq) = -1;
-+static DEFINE_PER_CPU(int, resched_irq) = -1;
-+static DEFINE_PER_CPU(int, cmc_irq) = -1;
-+static DEFINE_PER_CPU(int, cmcp_irq) = -1;
-+static DEFINE_PER_CPU(int, cpep_irq) = -1;
-+static char timer_name[NR_CPUS][15];
-+static char ipi_name[NR_CPUS][15];
-+static char resched_name[NR_CPUS][15];
-+static char cmc_name[NR_CPUS][15];
-+static char cmcp_name[NR_CPUS][15];
-+static char cpep_name[NR_CPUS][15];
-+
-+struct saved_irq {
-+      unsigned int irq;
-+      struct irqaction *action;
-+};
-+/* 16 should be far optimistic value, since only several percpu irqs
-+ * are registered early.
-+ */
-+#define MAX_LATE_IRQ  16
-+static struct saved_irq saved_percpu_irqs[MAX_LATE_IRQ];
-+static unsigned short late_irq_cnt = 0;
-+static unsigned short saved_irq_cnt = 0;
-+static int xen_slab_ready = 0;
-+
-+#ifdef CONFIG_SMP
-+/* Dummy stub. Though we may check RESCHEDULE_VECTOR before __do_IRQ,
-+ * it ends up to issue several memory accesses upon percpu data and
-+ * thus adds unnecessary traffic to other paths.
-+ */
-+static irqreturn_t
-+handle_reschedule(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static struct irqaction resched_irqaction = {
-+      .handler =      handle_reschedule,
-+      .flags =        SA_INTERRUPT,
-+      .name =         "RESCHED"
-+};
-+#endif
-+
-+/*
-+ * This is xen version percpu irq registration, which needs bind
-+ * to xen specific evtchn sub-system. One trick here is that xen
-+ * evtchn binding interface depends on kmalloc because related
-+ * port needs to be freed at device/cpu down. So we cache the
-+ * registration on BSP before slab is ready and then deal them
-+ * at later point. For rest instances happening after slab ready,
-+ * we hook them to xen evtchn immediately.
-+ *
-+ * FIXME: MCA is not supported by far, and thus "nomca" boot param is
-+ * required.
-+ */
-+static void
-+xen_register_percpu_irq (unsigned int irq, struct irqaction *action, int save)
-+{
-+      unsigned int cpu = smp_processor_id();
-+      int ret = 0;
-+
-+      if (xen_slab_ready) {
-+              switch (irq) {
-+              case IA64_TIMER_VECTOR:
-+                      sprintf(timer_name[cpu], "%s%d", action->name, cpu);
-+                      ret = bind_virq_to_irqhandler(VIRQ_ITC, cpu,
-+                              action->handler, action->flags,
-+                              timer_name[cpu], action->dev_id);
-+                      per_cpu(timer_irq,cpu) = ret;
-+                      printk(KERN_INFO "register VIRQ_ITC (%s) to xen irq (%d)\n", timer_name[cpu], ret);
-+                      break;
-+              case IA64_IPI_RESCHEDULE:
-+                      sprintf(resched_name[cpu], "%s%d", action->name, cpu);
-+                      ret = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR, cpu,
-+                              action->handler, action->flags,
-+                              resched_name[cpu], action->dev_id);
-+                      per_cpu(resched_irq,cpu) = ret;
-+                      printk(KERN_INFO "register RESCHEDULE_VECTOR (%s) to xen irq (%d)\n", resched_name[cpu], ret);
-+                      break;
-+              case IA64_IPI_VECTOR:
-+                      sprintf(ipi_name[cpu], "%s%d", action->name, cpu);
-+                      ret = bind_ipi_to_irqhandler(IPI_VECTOR, cpu,
-+                              action->handler, action->flags,
-+                              ipi_name[cpu], action->dev_id);
-+                      per_cpu(ipi_irq,cpu) = ret;
-+                      printk(KERN_INFO "register IPI_VECTOR (%s) to xen irq (%d)\n", ipi_name[cpu], ret);
-+                      break;
-+              case IA64_SPURIOUS_INT_VECTOR:
-+                      break;
-+              case IA64_CMC_VECTOR:
-+                      sprintf(cmc_name[cpu], "%s%d", action->name, cpu);
-+                      ret = bind_virq_to_irqhandler(VIRQ_MCA_CMC, cpu,
-+                                                    action->handler,
-+                                                    action->flags,
-+                                                    cmc_name[cpu],
-+                                                    action->dev_id);
-+                      per_cpu(cmc_irq,cpu) = ret;
-+                      printk(KERN_INFO "register VIRQ_MCA_CMC (%s) to xen "
-+                             "irq (%d)\n", cmc_name[cpu], ret);
-+                      break;
-+              case IA64_CMCP_VECTOR:
-+                      sprintf(cmcp_name[cpu], "%s%d", action->name, cpu);
-+                      ret = bind_ipi_to_irqhandler(CMCP_VECTOR, cpu,
-+                                                   action->handler,
-+                                                   action->flags,
-+                                                   cmcp_name[cpu],
-+                                                   action->dev_id);
-+                      per_cpu(cmcp_irq,cpu) = ret;
-+                      printk(KERN_INFO "register CMCP_VECTOR (%s) to xen "
-+                             "irq (%d)\n", cmcp_name[cpu], ret);
-+                      break;
-+              case IA64_CPEP_VECTOR:
-+                      sprintf(cpep_name[cpu], "%s%d", action->name, cpu);
-+                      ret = bind_ipi_to_irqhandler(CPEP_VECTOR, cpu,
-+                                                   action->handler,
-+                                                   action->flags,
-+                                                   cpep_name[cpu],
-+                                                   action->dev_id);
-+                      per_cpu(cpep_irq,cpu) = ret;
-+                      printk(KERN_INFO "register CPEP_VECTOR (%s) to xen "
-+                             "irq (%d)\n", cpep_name[cpu], ret);
-+                      break;
-+              case IA64_CPE_VECTOR:
-+                      printk(KERN_WARNING "register IA64_CPE_VECTOR "
-+                             "IGNORED\n");
-+                      break;
-+              default:
-+                      printk(KERN_WARNING "Percpu irq %d is unsupported by xen!\n", irq);
-+                      break;
-+              }
-+              BUG_ON(ret < 0);
-+      } 
-+
-+      /* For BSP, we cache registered percpu irqs, and then re-walk
-+       * them when initializing APs
-+       */
-+      if (!cpu && save) {
-+              BUG_ON(saved_irq_cnt == MAX_LATE_IRQ);
-+              saved_percpu_irqs[saved_irq_cnt].irq = irq;
-+              saved_percpu_irqs[saved_irq_cnt].action = action;
-+              saved_irq_cnt++;
-+              if (!xen_slab_ready)
-+                      late_irq_cnt++;
-+      }
-+}
-+
-+static void
-+xen_bind_early_percpu_irq (void)
-+{
-+      int i;
-+
-+      xen_slab_ready = 1;
-+      /* There's no race when accessing this cached array, since only
-+       * BSP will face with such step shortly
-+       */
-+      for (i = 0; i < late_irq_cnt; i++)
-+              xen_register_percpu_irq(saved_percpu_irqs[i].irq,
-+                                      saved_percpu_irqs[i].action, 0);
-+}
-+
-+/* FIXME: There's no obvious point to check whether slab is ready. So
-+ * a hack is used here by utilizing a late time hook.
-+ */
-+extern void (*late_time_init)(void);
-+extern char xen_event_callback;
-+extern void xen_init_IRQ(void);
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+static int __devinit
-+unbind_evtchn_callback(struct notifier_block *nfb,
-+                       unsigned long action, void *hcpu)
-+{
-+      unsigned int cpu = (unsigned long)hcpu;
-+
-+      if (action == CPU_DEAD) {
-+              /* Unregister evtchn.  */
-+              if (per_cpu(cpep_irq,cpu) >= 0) {
-+                      unbind_from_irqhandler(per_cpu(cpep_irq, cpu), NULL);
-+                      per_cpu(cpep_irq, cpu) = -1;
-+              }
-+              if (per_cpu(cmcp_irq,cpu) >= 0) {
-+                      unbind_from_irqhandler(per_cpu(cmcp_irq, cpu), NULL);
-+                      per_cpu(cmcp_irq, cpu) = -1;
-+              }
-+              if (per_cpu(cmc_irq,cpu) >= 0) {
-+                      unbind_from_irqhandler(per_cpu(cmc_irq, cpu), NULL);
-+                      per_cpu(cmc_irq, cpu) = -1;
-+              }
-+              if (per_cpu(ipi_irq,cpu) >= 0) {
-+                      unbind_from_irqhandler (per_cpu(ipi_irq, cpu), NULL);
-+                      per_cpu(ipi_irq, cpu) = -1;
-+              }
-+              if (per_cpu(resched_irq,cpu) >= 0) {
-+                      unbind_from_irqhandler (per_cpu(resched_irq, cpu),
-+                                              NULL);
-+                      per_cpu(resched_irq, cpu) = -1;
-+              }
-+              if (per_cpu(timer_irq,cpu) >= 0) {
-+                      unbind_from_irqhandler (per_cpu(timer_irq, cpu), NULL);
-+                      per_cpu(timer_irq, cpu) = -1;
-+              }
-+      }
-+      return NOTIFY_OK;
-+}
-+
-+static struct notifier_block unbind_evtchn_notifier = {
-+      .notifier_call = unbind_evtchn_callback,
-+      .priority = 0
-+};
-+#endif
-+
-+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
-+void xen_smp_intr_init(void)
-+{
-+#ifdef CONFIG_SMP
-+      unsigned int cpu = smp_processor_id();
-+      unsigned int i = 0;
-+      struct callback_register event = {
-+              .type = CALLBACKTYPE_event,
-+              .address = (unsigned long)&xen_event_callback,
-+      };
-+
-+      if (cpu == 0) {
-+              /* Initialization was already done for boot cpu.  */
-+#ifdef CONFIG_HOTPLUG_CPU
-+              /* Register the notifier only once.  */
-+              register_cpu_notifier(&unbind_evtchn_notifier);
-+#endif
-+              return;
-+      }
-+
-+      /* This should be piggyback when setup vcpu guest context */
-+      BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
-+
-+      for (i = 0; i < saved_irq_cnt; i++)
-+              xen_register_percpu_irq(saved_percpu_irqs[i].irq,
-+                                      saved_percpu_irqs[i].action, 0);
-+#endif /* CONFIG_SMP */
-+}
-+#endif /* CONFIG_XEN */
-+
- void
- register_percpu_irq (ia64_vector vec, struct irqaction *action)
- {
-       irq_desc_t *desc;
-       unsigned int irq;
-+#ifdef CONFIG_XEN
-+      if (is_running_on_xen())
-+              return xen_register_percpu_irq(vec, action, 1);
-+#endif
-+
-       for (irq = 0; irq < NR_IRQS; ++irq)
-               if (irq_to_vector(irq) == vec) {
-                       desc = irq_descp(irq);
-@@ -243,6 +512,21 @@
- void __init
- init_IRQ (void)
- {
-+#ifdef CONFIG_XEN
-+      /* Maybe put into platform_irq_init later */
-+      if (is_running_on_xen()) {
-+              struct callback_register event = {
-+                      .type = CALLBACKTYPE_event,
-+                      .address = (unsigned long)&xen_event_callback,
-+              };
-+              xen_init_IRQ();
-+              BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
-+              late_time_init = xen_bind_early_percpu_irq;
-+#ifdef CONFIG_SMP
-+              register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
-+#endif /* CONFIG_SMP */
-+      }
-+#endif /* CONFIG_XEN */
-       register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
- #ifdef CONFIG_SMP
-       register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
-@@ -260,6 +544,45 @@
-       unsigned long ipi_data;
-       unsigned long phys_cpu_id;
-+#ifdef CONFIG_XEN
-+        if (is_running_on_xen()) {
-+              int irq = -1;
-+
-+#ifdef CONFIG_SMP
-+              /* TODO: we need to call vcpu_up here */
-+              if (unlikely(vector == ap_wakeup_vector)) {
-+                      extern void xen_send_ipi (int cpu, int vec);
-+                      xen_send_ipi (cpu, vector);
-+                      //vcpu_prepare_and_up(cpu);
-+                      return;
-+              }
-+#endif
-+
-+              switch(vector) {
-+              case IA64_IPI_VECTOR:
-+                      irq = per_cpu(ipi_to_irq, cpu)[IPI_VECTOR];
-+                      break;
-+              case IA64_IPI_RESCHEDULE:
-+                      irq = per_cpu(ipi_to_irq, cpu)[RESCHEDULE_VECTOR];
-+                      break;
-+              case IA64_CMCP_VECTOR:
-+                      irq = per_cpu(ipi_to_irq, cpu)[CMCP_VECTOR];
-+                      break;
-+              case IA64_CPEP_VECTOR:
-+                      irq = per_cpu(ipi_to_irq, cpu)[CPEP_VECTOR];
-+                      break;
-+              default:
-+                      printk(KERN_WARNING"Unsupported IPI type 0x%x\n", vector);
-+                      irq = 0;
-+                      break;
-+              }               
-+      
-+              BUG_ON(irq < 0);
-+              notify_remote_via_irq(irq);
-+              return;
-+        }
-+#endif /* CONFIG_XEN */
-+
- #ifdef CONFIG_SMP
-       phys_cpu_id = cpu_physical_id(cpu);
- #else
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/pal.S linux-2.6.16.33/arch/ia64/kernel/pal.S
---- linux-2.6.16.33-noxen/arch/ia64/kernel/pal.S       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/pal.S     2007-01-08 15:00:45.000000000 +0000
-@@ -16,6 +16,7 @@
- #include <asm/processor.h>
-       .data
-+      .globl pal_entry_point
- pal_entry_point:
-       data8 ia64_pal_default_handler
-       .text
-@@ -53,7 +54,7 @@
-  * in4               1 ==> clear psr.ic,  0 ==> don't clear psr.ic
-  *
-  */
--GLOBAL_ENTRY(ia64_pal_call_static)
-+GLOBAL_ENTRY(__ia64_pal_call_static)
-       .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
-       alloc loc1 = ar.pfs,5,5,0,0
-       movl loc2 = pal_entry_point
-@@ -90,7 +91,7 @@
-       ;;
-       srlz.d                          // seralize restoration of psr.l
-       br.ret.sptk.many b0
--END(ia64_pal_call_static)
-+END(__ia64_pal_call_static)
- /*
-  * Make a PAL call using the stacked registers calling convention.
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/patch.c linux-2.6.16.33/arch/ia64/kernel/patch.c
---- linux-2.6.16.33-noxen/arch/ia64/kernel/patch.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/patch.c   2007-01-08 15:00:45.000000000 +0000
-@@ -184,6 +184,73 @@
-       ia64_srlz_i();
- }
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+extern char __start_gate_running_on_xen_patchlist[];
-+extern char __end_gate_running_on_xen_patchlist[];
-+
-+void
-+patch_running_on_xen(unsigned long start, unsigned long end)
-+{
-+      extern int running_on_xen;
-+      s32 *offp = (s32 *)start;
-+      u64 ip;
-+
-+      while (offp < (s32 *)end) {
-+              ip = (u64)ia64_imva((char *)offp + *offp);
-+              ia64_patch_imm64(ip, (u64)&running_on_xen);
-+              ia64_fc((void *)ip);
-+              ++offp;
-+      }
-+      ia64_sync_i();
-+      ia64_srlz_i();
-+}
-+
-+static void
-+patch_brl_symaddr(unsigned long start, unsigned long end,
-+                  unsigned long symaddr)
-+{
-+      s32 *offp = (s32 *)start;
-+      u64 ip;
-+
-+      while (offp < (s32 *)end) {
-+              ip = (u64)offp + *offp;
-+              ia64_patch_imm60((u64)ia64_imva((void *)ip),
-+                               (u64)(symaddr - (ip & -16)) / 16);
-+              ia64_fc((void *)ip);
-+              ++offp;
-+      }
-+      ia64_sync_i();
-+      ia64_srlz_i();
-+}
-+
-+#define EXTERN_PATCHLIST(name)                                        \
-+      extern char __start_gate_brl_##name##_patchlist[];      \
-+      extern char __end_gate_brl_##name##_patchlist[];        \
-+      extern char name[]
-+
-+#define PATCH_BRL_SYMADDR(name)                                               \
-+      patch_brl_symaddr((unsigned long)__start_gate_brl_##name##_patchlist, \
-+                        (unsigned long)__end_gate_brl_##name##_patchlist,   \
-+                        (unsigned long)name)
-+
-+static void
-+patch_brl_in_vdso(void)
-+{
-+      EXTERN_PATCHLIST(xen_rsm_be_i);
-+      EXTERN_PATCHLIST(xen_get_psr);
-+      EXTERN_PATCHLIST(xen_ssm_i_0);
-+      EXTERN_PATCHLIST(xen_ssm_i_1);
-+
-+      PATCH_BRL_SYMADDR(xen_rsm_be_i);
-+      PATCH_BRL_SYMADDR(xen_get_psr);
-+      PATCH_BRL_SYMADDR(xen_ssm_i_0);
-+      PATCH_BRL_SYMADDR(xen_ssm_i_1);
-+}
-+#else
-+#define patch_running_on_xen(start, end)      do { } while (0)
-+#define patch_brl_in_vdso()                   do { } while (0)
-+#endif
-+
- void
- ia64_patch_gate (void)
- {
-@@ -192,6 +259,10 @@
-       patch_fsyscall_table(START(fsyscall), END(fsyscall));
-       patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
-+#ifdef CONFIG_XEN
-+      patch_running_on_xen(START(running_on_xen), END(running_on_xen));
-+      patch_brl_in_vdso();
-+#endif
-       ia64_patch_vtop(START(vtop), END(vtop));
-       ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
- }
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/perfmon.c linux-2.6.16.33/arch/ia64/kernel/perfmon.c
---- linux-2.6.16.33-noxen/arch/ia64/kernel/perfmon.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/perfmon.c 2007-01-08 15:00:45.000000000 +0000
-@@ -53,6 +53,28 @@
- #include <asm/delay.h>
- #ifdef CONFIG_PERFMON
-+#ifdef CONFIG_XEN
-+//#include <xen/xenoprof.h>
-+#include <xen/interface/xenoprof.h>
-+
-+static int xenoprof_is_primary = 0;
-+#define init_xenoprof_primary(is_primary)  (xenoprof_is_primary = (is_primary))
-+#define is_xenoprof_primary() (xenoprof_is_primary)
-+#define XEN_NOT_SUPPORTED_YET                                         \
-+      do {                                                            \
-+              if (is_running_on_xen()) {                              \
-+                      printk("%s is not supported yet under xen.\n",  \
-+                             __func__);                               \
-+                      return -ENOSYS;                                 \
-+              }                                                       \
-+      } while (0)
-+#else
-+#define init_xenoprof_primary(is_primary)     do { } while (0)
-+#define is_xenoprof_primary()                 (0)
-+#define XEN_NOT_SUPPORTED_YET                 do { } while (0)
-+#define HYPERVISOR_perfmon_op(cmd, arg, count)        do { } while (0)
-+#endif
-+
- /*
-  * perfmon context state
-  */
-@@ -1515,6 +1537,7 @@
-       ssize_t ret;
-       unsigned long flags;
-       DECLARE_WAITQUEUE(wait, current);
-+      XEN_NOT_SUPPORTED_YET;
-       if (PFM_IS_FILE(filp) == 0) {
-               printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
-               return -EINVAL;
-@@ -2113,6 +2136,15 @@
-        */
-       if (free_possible) pfm_context_free(ctx);
-+      if (is_running_on_xen()) {
-+              if (is_xenoprof_primary()) {
-+                      int ret = HYPERVISOR_perfmon_op(PFM_DESTROY_CONTEXT,
-+                                                      NULL, 0);
-+                      if (ret)
-+                              printk("%s:%d PFM_DESTROY_CONTEXT hypercall "
-+                                     "failed\n", __func__, __LINE__);
-+              }
-+      }
-       return 0;
- }
-@@ -2736,6 +2768,23 @@
-        */
-       pfm_reset_pmu_state(ctx);
-+      if (is_running_on_xen()) {
-+              /*
-+               * kludge to get xenoprof.is_primary.
-+               * XENOPROF_init/ia64 is nop. so it is safe to call it here.
-+               */
-+              struct xenoprof_init init;
-+              ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init);
-+              if (ret)
-+                      goto buffer_error;
-+              init_xenoprof_primary(init.is_primary);
-+
-+              if (is_xenoprof_primary()) {
-+                      ret = HYPERVISOR_perfmon_op(PFM_CREATE_CONTEXT, arg, 0);
-+                      if (ret)
-+                              goto buffer_error;
-+              }
-+      }
-       return 0;
- buffer_error:
-@@ -2872,6 +2921,12 @@
-       pfm_reg_check_t wr_func;
- #define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
-+      if (is_running_on_xen()) {
-+              if (is_xenoprof_primary())
-+                      return HYPERVISOR_perfmon_op(PFM_WRITE_PMCS,
-+                                                   arg, count);
-+              return 0;
-+      }
-       state     = ctx->ctx_state;
-       is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
-       is_system = ctx->ctx_fl_system;
-@@ -3112,6 +3167,12 @@
-       int ret = -EINVAL;
-       pfm_reg_check_t wr_func;
-+      if (is_running_on_xen()) {
-+              if (is_xenoprof_primary())
-+                      return HYPERVISOR_perfmon_op(PFM_WRITE_PMDS,
-+                                                   arg, count);
-+              return 0;
-+      }
-       state     = ctx->ctx_state;
-       is_loaded = state == PFM_CTX_LOADED ? 1 : 0;
-@@ -3309,6 +3370,7 @@
-       int is_loaded, is_system, is_counting, expert_mode;
-       int ret = -EINVAL;
-       pfm_reg_check_t rd_func;
-+      XEN_NOT_SUPPORTED_YET;
-       /*
-        * access is possible when loaded only for
-@@ -3560,6 +3622,7 @@
-       pfm_ovfl_ctrl_t rst_ctrl;
-       int state, is_system;
-       int ret = 0;
-+      XEN_NOT_SUPPORTED_YET;
-       state     = ctx->ctx_state;
-       fmt       = ctx->ctx_buf_fmt;
-@@ -3709,6 +3772,7 @@
- pfm_debug(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
- {
-       unsigned int m = *(unsigned int *)arg;
-+      XEN_NOT_SUPPORTED_YET;
-       pfm_sysctl.debug = m == 0 ? 0 : 1;
-@@ -3979,6 +4043,8 @@
- {
-       pfarg_features_t *req = (pfarg_features_t *)arg;
-+      if (is_running_on_xen())
-+              return HYPERVISOR_perfmon_op(PFM_GET_FEATURES, &arg, 0);
-       req->ft_version = PFM_VERSION;
-       return 0;
- }
-@@ -3990,6 +4056,12 @@
-       struct task_struct *task = PFM_CTX_TASK(ctx);
-       int state, is_system;
-+      if (is_running_on_xen()) {
-+              if (is_xenoprof_primary())
-+                      return HYPERVISOR_perfmon_op(PFM_STOP, NULL, 0);
-+              return 0;
-+      }
-+
-       state     = ctx->ctx_state;
-       is_system = ctx->ctx_fl_system;
-@@ -4078,6 +4150,11 @@
-       struct pt_regs *tregs;
-       int state, is_system;
-+      if (is_running_on_xen()) {
-+              if (is_xenoprof_primary())
-+                      return HYPERVISOR_perfmon_op(PFM_START, NULL, 0);
-+              return 0;
-+      }
-       state     = ctx->ctx_state;
-       is_system = ctx->ctx_fl_system;
-@@ -4160,6 +4237,7 @@
-       unsigned int cnum;
-       int i;
-       int ret = -EINVAL;
-+      XEN_NOT_SUPPORTED_YET;
-       for (i = 0; i < count; i++, req++) {
-@@ -4218,6 +4296,11 @@
-       int ret = 0;
-       int state, is_system, set_dbregs = 0;
-+      if (is_running_on_xen()) {
-+              if (is_xenoprof_primary())
-+                      return HYPERVISOR_perfmon_op(PFM_LOAD_CONTEXT, arg, 0);
-+              return 0;
-+      }
-       state     = ctx->ctx_state;
-       is_system = ctx->ctx_fl_system;
-       /*
-@@ -4466,6 +4549,12 @@
-       int prev_state, is_system;
-       int ret;
-+      if (is_running_on_xen()) {
-+              if (is_xenoprof_primary())
-+                      return HYPERVISOR_perfmon_op(PFM_UNLOAD_CONTEXT,
-+                                                   NULL, 0);
-+              return 0;
-+      }
-       DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
-       prev_state = ctx->ctx_state;
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/kernel/setup.c linux-2.6.16.33/arch/ia64/kernel/setup.c
---- linux-2.6.16.33-noxen/arch/ia64/kernel/setup.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/kernel/setup.c   2007-01-08 15:00:45.000000000 +0000
-@@ -61,6 +61,11 @@
- #include <asm/system.h>
- #include <asm/unistd.h>
- #include <asm/system.h>
-+#ifdef CONFIG_XEN
-+#include <asm/hypervisor.h>
-+#include <asm/xen/xencomm.h>
-+#endif
-+#include <linux/dma-mapping.h>
- #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
- # error "struct cpuinfo_ia64 too big!"
-@@ -71,6 +76,20 @@
- EXPORT_SYMBOL(__per_cpu_offset);
- #endif
-+#ifdef CONFIG_XEN
-+static int
-+xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
-+{
-+      HYPERVISOR_shutdown(SHUTDOWN_crash);
-+      /* we're never actually going to get here... */
-+      return NOTIFY_DONE;
-+}
-+
-+static struct notifier_block xen_panic_block = {
-+      xen_panic_event, NULL, 0 /* try to go last */
-+};
-+#endif
-+
- extern void ia64_setup_printk_clock(void);
- DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
-@@ -243,6 +262,14 @@
-       rsvd_region[n].end   = (unsigned long) ia64_imva(_end);
-       n++;
-+#ifdef CONFIG_XEN
-+      if (is_running_on_xen()) {
-+              rsvd_region[n].start = (unsigned long)__va((HYPERVISOR_shared_info->arch.start_info_pfn << PAGE_SHIFT));
-+              rsvd_region[n].end   = rsvd_region[n].start + PAGE_SIZE;
-+              n++;
-+      }
-+#endif
-+
- #ifdef CONFIG_BLK_DEV_INITRD
-       if (ia64_boot_param->initrd_start) {
-               rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
-@@ -260,6 +287,7 @@
-       n++;
-       num_rsvd_regions = n;
-+      BUG_ON(IA64_MAX_RSVD_REGIONS + 1 < n);
-       sort_regions(rsvd_region, num_rsvd_regions);
- }
-@@ -333,6 +361,16 @@
- {
-       int earlycons = 0;
-+#ifdef CONFIG_XEN
-+#ifndef CONFIG_IA64_HP_SIM
-+      if (is_running_on_xen()) {
-+              extern struct console hpsim_cons;
-+              hpsim_cons.flags |= CON_BOOT;
-+              register_console(&hpsim_cons);
-+              earlycons++;
-+      }
-+#endif
-+#endif
- #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
-       {
-               extern int sn_serial_console_early_setup(void);
-@@ -394,6 +432,17 @@
- {
-       unw_init();
-+#ifdef CONFIG_XEN
-+      if (is_running_on_xen()) {
-+              /* Must be done before any hypercall.  */
-+              xencomm_init();
-+
-+              setup_xen_features();
-+              /* Register a call for panic conditions. */
-+              notifier_chain_register(&panic_notifier_list, &xen_panic_block);
-+      }
-+#endif
-+
-       ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
-       *cmdline_p = __va(ia64_boot_param->command_line);
-@@ -490,7 +539,26 @@
-                       conswitchp = &vga_con;
- # endif
-       }
-+#ifdef CONFIG_XEN
-+      if (is_running_on_xen()) {
-+              shared_info_t *s = HYPERVISOR_shared_info;
-+
-+              xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT);
-+
-+              printk("Running on Xen! start_info_pfn=0x%lx nr_pages=%ld "
-+                     "flags=0x%x\n", s->arch.start_info_pfn,
-+                     xen_start_info->nr_pages, xen_start_info->flags);
-+
-+              if (!is_initial_xendomain()) {
-+#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE)
-+                      conswitchp = NULL;
-+#endif
-+              }
-+      }
-+      xencons_early_setup();
- #endif
-+#endif
-+
-       /* enable IA-64 Machine Check Abort Handling unless disabled */
-       if (!strstr(saved_command_line, "nomca"))
-@@ -498,6 +566,9 @@
-       platform_setup(cmdline_p);
-       paging_init();
-+#ifdef CONFIG_XEN
-+      contiguous_bitmap_init(max_pfn);
-+#endif
- }
- /*
-@@ -882,6 +953,15 @@
-       /* size of physical stacked register partition plus 8 bytes: */
-       __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
-       platform_cpu_init();
-+
-+#ifdef CONFIG_XEN
-+      /* Need to be moved into platform_cpu_init later */
-+      if (is_running_on_xen()) {
-+              extern void xen_smp_intr_init(void);
-+              xen_smp_intr_init();
-+      }
-+#endif
-+
-       pm_idle = default_idle;
- }
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/oprofile/Makefile linux-2.6.16.33/arch/ia64/oprofile/Makefile
---- linux-2.6.16.33-noxen/arch/ia64/oprofile/Makefile  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/oprofile/Makefile        2007-01-08 15:00:45.000000000 +0000
-@@ -8,3 +8,7 @@
- oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
- oprofile-$(CONFIG_PERFMON) += perfmon.o
-+ifeq ($(CONFIG_XEN), y)
-+oprofile-$(CONFIG_PERFMON) += xenoprof.o \
-+      ../../../drivers/xen/xenoprof/xenoprofile.o
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/oprofile/init.c linux-2.6.16.33/arch/ia64/oprofile/init.c
---- linux-2.6.16.33-noxen/arch/ia64/oprofile/init.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/oprofile/init.c  2007-01-08 15:00:45.000000000 +0000
-@@ -11,6 +11,7 @@
- #include <linux/oprofile.h>
- #include <linux/init.h>
- #include <linux/errno.h>
-+#include "oprofile_perfmon.h"
-  
- extern int perfmon_init(struct oprofile_operations * ops);
- extern void perfmon_exit(void);
-@@ -20,6 +21,13 @@
- {
-       int ret = -ENODEV;
-+      if (is_running_on_xen()) {
-+              ret = xen_perfmon_init();
-+              if (ret)
-+                      return ret;
-+              return xenoprofile_init(ops);
-+      }
-+
- #ifdef CONFIG_PERFMON
-       /* perfmon_init() can fail, but we have no way to report it */
-       ret = perfmon_init(ops);
-@@ -32,6 +40,12 @@
- void oprofile_arch_exit(void)
- {
-+      if (is_running_on_xen()) {
-+              xenoprofile_exit();
-+              xen_perfmon_exit();
-+              return;
-+      }
-+
- #ifdef CONFIG_PERFMON
-       perfmon_exit();
- #endif
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/oprofile/oprofile_perfmon.h linux-2.6.16.33/arch/ia64/oprofile/oprofile_perfmon.h
---- linux-2.6.16.33-noxen/arch/ia64/oprofile/oprofile_perfmon.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/oprofile/oprofile_perfmon.h      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,30 @@
-+#ifndef OPROFILE_PERFMON_H
-+#define OPROFILE_PERFMON_H
-+
-+#include <linux/config.h>
-+
-+#ifdef CONFIG_PERFMON
-+int __perfmon_init(void);
-+void __perfmon_exit(void);
-+int perfmon_start(void);
-+void perfmon_stop(void);
-+#else
-+#define __perfmon_init()      (-ENOSYS)
-+#define __perfmon_exit()      do {} while (0)
-+#endif /* CONFIG_PERFMON */
-+
-+#ifdef CONFIG_XEN
-+#define STATIC_IF_NO_XEN      /* nothing */
-+#define xen_perfmon_init()    __perfmon_init()
-+#define xen_perfmon_exit()    __perfmon_exit()
-+extern int xenoprofile_init(struct oprofile_operations * ops);
-+extern void xenoprofile_exit(void);
-+#else
-+#define STATIC_IF_NO_XEN      static
-+#define xen_perfmon_init()    (-ENOSYS)
-+#define xen_perfmon_exit()    do {} while (0)
-+#define xenoprofile_init()    (-ENOSYS)
-+#define xenoprofile_exit()    do {} while (0)
-+#endif /* CONFIG_XEN */
-+
-+#endif /* OPROFILE_PERFMON_H */
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/oprofile/perfmon.c linux-2.6.16.33/arch/ia64/oprofile/perfmon.c
---- linux-2.6.16.33-noxen/arch/ia64/oprofile/perfmon.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/oprofile/perfmon.c       2007-01-08 15:00:45.000000000 +0000
-@@ -14,6 +14,7 @@
- #include <asm/perfmon.h>
- #include <asm/ptrace.h>
- #include <asm/errno.h>
-+#include "oprofile_perfmon.h"
- static int allow_ints;
-@@ -34,14 +35,16 @@
- }
--static int perfmon_start(void)
-+STATIC_IF_NO_XEN
-+int perfmon_start(void)
- {
-       allow_ints = 1;
-       return 0;
- }
--static void perfmon_stop(void)
-+STATIC_IF_NO_XEN
-+void perfmon_stop(void)
- {
-       allow_ints = 0;
- }
-@@ -76,16 +79,35 @@
- static int using_perfmon;
--int perfmon_init(struct oprofile_operations * ops)
-+STATIC_IF_NO_XEN
-+int __perfmon_init(void)
- {
-       int ret = pfm_register_buffer_fmt(&oprofile_fmt);
-       if (ret)
-               return -ENODEV;
-+      using_perfmon = 1;
-+      return 0;
-+}
-+
-+STATIC_IF_NO_XEN
-+void __perfmon_exit(void)
-+{
-+      if (!using_perfmon)
-+              return;
-+
-+      pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid);
-+}
-+
-+int perfmon_init(struct oprofile_operations * ops)
-+{
-+      int ret = __perfmon_init();
-+      if (ret)
-+              return -ENODEV;
-+
-       ops->cpu_type = get_cpu_type();
-       ops->start = perfmon_start;
-       ops->stop = perfmon_stop;
--      using_perfmon = 1;
-       printk(KERN_INFO "oprofile: using perfmon.\n");
-       return 0;
- }
-@@ -93,8 +115,5 @@
- void perfmon_exit(void)
- {
--      if (!using_perfmon)
--              return;
--
--      pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid);
-+      __perfmon_exit();
- }
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/oprofile/xenoprof.c linux-2.6.16.33/arch/ia64/oprofile/xenoprof.c
---- linux-2.6.16.33-noxen/arch/ia64/oprofile/xenoprof.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/oprofile/xenoprof.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,142 @@
-+/******************************************************************************
-+ * xenoprof ia64 specific part
-+ *
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+#include <linux/init.h>
-+#include <linux/oprofile.h>
-+#include <linux/ioport.h>
-+
-+#include <xen/driver_util.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/xenoprof.h>
-+#include <xen/xenoprof.h>
-+
-+#include "oprofile_perfmon.h"
-+
-+void __init xenoprof_arch_init_counter(struct xenoprof_init *init)
-+{
-+      init->num_events = 0; /* perfmon manages. */
-+}
-+
-+void xenoprof_arch_counter(void)
-+{
-+      /* nothing. perfmon does. */
-+}
-+
-+void xenoprof_arch_start(void) 
-+{
-+      perfmon_start();
-+}
-+
-+void xenoprof_arch_stop(void)
-+{
-+      perfmon_stop();
-+}
-+
-+/* XXX move them to an appropriate header file. */
-+struct resource* xen_ia64_allocate_resource(unsigned long size); 
-+void xen_ia64_release_resource(struct resource* res); 
-+void xen_ia64_unmap_resource(struct resource* res); 
-+
-+struct resource*
-+xenoprof_ia64_allocate_resource(int32_t max_samples)
-+{
-+      unsigned long bufsize;
-+
-+      /* XXX add hypercall to get bufsize? */
-+      /*     this value is taken from alloc_xenoprof_struct(). */
-+#if 0
-+      bufsize = NR_CPUS * (sizeof(struct xenoprof_buf) +
-+                           (max_samples - 1) * sizeof(struct event_log));
-+      bufsize = PAGE_ALIGN(bufsize) + PAGE_SIZE;
-+#else
-+#define MAX_OPROF_SHARED_PAGES 32
-+      bufsize = (MAX_OPROF_SHARED_PAGES + 1) * PAGE_SIZE;
-+#endif
-+      return xen_ia64_allocate_resource(bufsize);
-+}
-+
-+void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer* sbuf)
-+{
-+      if (sbuf->buffer) {
-+              xen_ia64_unmap_resource(sbuf->arch.res);
-+              sbuf->buffer = NULL;
-+              sbuf->arch.res = NULL;
-+      }
-+}
-+
-+int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer* get_buffer,
-+                                    struct xenoprof_shared_buffer* sbuf)
-+{
-+      int ret;
-+      struct resource* res;
-+
-+      sbuf->buffer = NULL;
-+      sbuf->arch.res = NULL;
-+
-+      res = xenoprof_ia64_allocate_resource(get_buffer->max_samples);
-+      if (IS_ERR(res))
-+              return PTR_ERR(res);
-+
-+      get_buffer->buf_gmaddr = res->start;
-+
-+      ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, get_buffer);
-+      if (ret) {
-+              xen_ia64_release_resource(res);
-+              return ret;
-+      }
-+
-+      BUG_ON((res->end - res->start + 1) <
-+             get_buffer->bufsize * get_buffer->nbuf);
-+
-+      sbuf->buffer = __va(res->start);
-+      sbuf->arch.res = res;
-+
-+      return ret;
-+}
-+
-+int xenoprof_arch_set_passive(struct xenoprof_passive* pdomain,
-+                              struct xenoprof_shared_buffer* sbuf)
-+{
-+      int ret;
-+      struct resource* res;
-+
-+      sbuf->buffer = NULL;
-+      sbuf->arch.res = NULL;
-+
-+      res = xenoprof_ia64_allocate_resource(pdomain->max_samples);
-+      if (IS_ERR(res))
-+              return PTR_ERR(res);
-+
-+      pdomain->buf_gmaddr = res->start;
-+
-+      ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, pdomain);
-+      if (ret) {
-+              xen_ia64_release_resource(res);
-+              return ret;
-+      }
-+
-+      BUG_ON((res->end - res->start + 1) < pdomain->bufsize * pdomain->nbuf);
-+
-+      sbuf->buffer = __va(res->start);
-+      sbuf->arch.res = res;
-+
-+      return ret;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/Makefile linux-2.6.16.33/arch/ia64/xen/Makefile
---- linux-2.6.16.33-noxen/arch/ia64/xen/Makefile       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/Makefile     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,9 @@
-+#
-+# Makefile for Xen components
-+#
-+
-+obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o \
-+       hypervisor.o pci-dma-xen.o util.o xencomm.o xcom_hcall.o \
-+       xcom_mini.o xcom_privcmd.o mem.o
-+
-+pci-dma-xen-y := ../../i386/kernel/pci-dma-xen.o
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/hypercall.S linux-2.6.16.33/arch/ia64/xen/hypercall.S
---- linux-2.6.16.33-noxen/arch/ia64/xen/hypercall.S    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/hypercall.S  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,412 @@
-+/*
-+ * Support routines for Xen hypercalls
-+ *
-+ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
-+ */
-+
-+#include <linux/config.h>
-+#include <asm/processor.h>
-+#include <asm/asmmacro.h>
-+
-+/* To clear vpsr.ic, vpsr.i needs to be cleared first */
-+#define XEN_CLEAR_PSR_IC                              \
-+      mov r14=1;                                      \
-+      movl r15=XSI_PSR_I_ADDR;                        \
-+      movl r2=XSI_PSR_IC;                             \
-+      ;;                                              \
-+      ld8 r15=[r15];                                  \
-+      ld4 r3=[r2];                                    \
-+      ;;                                              \
-+      ld1 r16=[r15];                                  \
-+      ;;                                              \
-+      st1 [r15]=r14;                                  \
-+      st4 [r2]=r0;                                    \
-+      ;;
-+
-+/* First restore vpsr.ic, and then vpsr.i */
-+#define XEN_RESTORE_PSR_IC                            \
-+      st4 [r2]=r3;                                    \
-+      st1 [r15]=r16;                                  \
-+      ;;
-+
-+GLOBAL_ENTRY(xen_get_ivr)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov r8=cr.ivr;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_GET_IVR
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_get_ivr)
-+
-+GLOBAL_ENTRY(xen_get_tpr)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov r8=cr.tpr;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_GET_TPR
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_get_tpr)
-+
-+GLOBAL_ENTRY(xen_set_tpr)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov cr.tpr=r32;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_SET_TPR
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_set_tpr)
-+
-+GLOBAL_ENTRY(xen_eoi)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov cr.eoi=r0;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_EOI
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_eoi)
-+
-+GLOBAL_ENTRY(xen_thash)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  thash r8=r32;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_THASH
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_thash)
-+
-+GLOBAL_ENTRY(xen_set_itm)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov cr.itm=r32;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_SET_ITM
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_set_itm)
-+
-+GLOBAL_ENTRY(xen_ptcga)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  ptc.ga r32,r33;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      mov r9=r33
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_PTC_GA
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_ptcga)
-+
-+GLOBAL_ENTRY(xen_get_rr)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov r8=rr[r32];;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_GET_RR
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_get_rr)
-+
-+GLOBAL_ENTRY(xen_set_rr)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov rr[r32]=r33;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      mov r9=r33
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_SET_RR
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+      ;;
-+END(xen_set_rr)
-+
-+GLOBAL_ENTRY(xen_set_kr)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.ne p7,p0=r8,r0;;
-+(p7)  br.cond.spnt.few 1f;
-+      ;;
-+      cmp.eq p7,p0=r8,r0
-+      adds r8=-1,r8;;
-+(p7)  mov ar0=r9
-+(p7)  br.ret.sptk.many rp;;
-+      cmp.eq p7,p0=r8,r0
-+      adds r8=-1,r8;;
-+(p7)  mov ar1=r9
-+(p7)  br.ret.sptk.many rp;;
-+      cmp.eq p7,p0=r8,r0
-+      adds r8=-1,r8;;
-+(p7)  mov ar2=r9
-+(p7)  br.ret.sptk.many rp;;
-+      cmp.eq p7,p0=r8,r0
-+      adds r8=-1,r8;;
-+(p7)  mov ar3=r9
-+(p7)  br.ret.sptk.many rp;;
-+      cmp.eq p7,p0=r8,r0
-+      adds r8=-1,r8;;
-+(p7)  mov ar4=r9
-+(p7)  br.ret.sptk.many rp;;
-+      cmp.eq p7,p0=r8,r0
-+      adds r8=-1,r8;;
-+(p7)  mov ar5=r9
-+(p7)  br.ret.sptk.many rp;;
-+      cmp.eq p7,p0=r8,r0
-+      adds r8=-1,r8;;
-+(p7)  mov ar6=r9
-+(p7)  br.ret.sptk.many rp;;
-+      cmp.eq p7,p0=r8,r0
-+      adds r8=-1,r8;;
-+(p7)  mov ar7=r9
-+(p7)  br.ret.sptk.many rp;;
-+
-+1:    mov r8=r32
-+      mov r9=r33
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_SET_KR
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+END(xen_set_kr)
-+
-+GLOBAL_ENTRY(xen_fc)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  fc r32;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_FC
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+END(xen_fc)
-+
-+GLOBAL_ENTRY(xen_get_cpuid)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov r8=cpuid[r32];;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_GET_CPUID
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+END(xen_get_cpuid)
-+
-+GLOBAL_ENTRY(xen_get_pmd)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov r8=pmd[r32];;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_GET_PMD
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+END(xen_get_pmd)
-+
-+#ifdef CONFIG_IA32_SUPPORT
-+GLOBAL_ENTRY(xen_get_eflag)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov r8=ar24;;
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_GET_EFLAG
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+END(xen_get_eflag)
-+      
-+// some bits aren't set if pl!=0, see SDM vol1 3.1.8
-+GLOBAL_ENTRY(xen_set_eflag)
-+      movl r8=running_on_xen;;
-+      ld4 r8=[r8];;
-+      cmp.eq p7,p0=r8,r0;;
-+(p7)  mov ar24=r32
-+(p7)  br.ret.sptk.many rp
-+      ;;
-+      mov r8=r32
-+      ;;
-+      XEN_CLEAR_PSR_IC
-+      ;;
-+      XEN_HYPER_SET_EFLAG
-+      ;;
-+      XEN_RESTORE_PSR_IC
-+      ;;
-+      br.ret.sptk.many rp
-+END(xen_set_eflag)
-+#endif
-+
-+GLOBAL_ENTRY(xen_send_ipi)
-+        mov r14=r32
-+        mov r15=r33
-+        mov r2=0x400
-+        break 0x1000
-+        ;;
-+        br.ret.sptk.many rp
-+        ;;
-+END(xen_send_ipi)
-+
-+#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
-+// Those are vdso specialized.
-+// In fsys mode, call, ret can't be used.
-+GLOBAL_ENTRY(xen_rsm_be_i)
-+      st1 [r22]=r20
-+      st4 [r23]=r0
-+      XEN_HYPER_RSM_BE
-+      st4 [r23]=r20
-+      brl.cond.sptk   .vdso_rsm_be_i_ret
-+      ;; 
-+END(xen_rsm_be_i)
-+
-+GLOBAL_ENTRY(xen_get_psr)
-+      mov r31=r8
-+      mov r25=IA64_PSR_IC
-+      st4 [r23]=r0
-+      XEN_HYPER_GET_PSR
-+      ;; 
-+      st4 [r23]=r20
-+      or r29=r8,r25 // vpsr.ic was cleared for hyperprivop
-+      mov r8=r31
-+      brl.cond.sptk   .vdso_get_psr_ret
-+      ;; 
-+END(xen_get_psr)
-+
-+      // see xen_ssm_i() in privop.h
-+      // r22 = &vcpu->vcpu_info->evtchn_upcall_mask
-+      // r23 = &vpsr.ic
-+      // r24 = &vcpu->vcpu_info->evtchn_upcall_pending
-+      // r25 = tmp
-+      // r31 = tmp
-+      // p11 = tmp
-+      // p14 = tmp
-+#define XEN_SET_PSR_I                 \
-+      ld1 r31=[r22];                  \
-+      ld1 r25=[r24];                  \
-+      ;;                              \
-+      st1 [r22]=r0;                   \
-+      cmp.ne.unc p14,p0=r0,r31;       \
-+      ;;                              \
-+(p14) cmp.ne.unc p11,p0=r0,r25;       \
-+      ;;                              \
-+(p11) st1 [r22]=r20;                  \
-+(p11) st4 [r23]=r0;                   \
-+(p11) XEN_HYPER_SSM_I;
-+              
-+GLOBAL_ENTRY(xen_ssm_i_0)
-+      XEN_SET_PSR_I
-+      brl.cond.sptk   .vdso_ssm_i_0_ret
-+      ;; 
-+END(xen_ssm_i_0)
-+
-+GLOBAL_ENTRY(xen_ssm_i_1)
-+      XEN_SET_PSR_I
-+      brl.cond.sptk   .vdso_ssm_i_1_ret
-+      ;; 
-+END(xen_ssm_i_1)
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/hypervisor.c linux-2.6.16.33/arch/ia64/xen/hypervisor.c
---- linux-2.6.16.33-noxen/arch/ia64/xen/hypervisor.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/hypervisor.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1104 @@
-+/******************************************************************************
-+ * include/asm-ia64/shadow.h
-+ *
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+
-+//#include <linux/kernel.h>
-+#include <linux/spinlock.h>
-+#include <linux/bootmem.h>
-+#include <linux/module.h>
-+#include <linux/vmalloc.h>
-+#include <asm/page.h>
-+#include <asm/hypervisor.h>
-+#include <asm/hypercall.h>
-+#include <xen/interface/memory.h>
-+#include <xen/balloon.h>
-+
-+shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)XSI_BASE;
-+EXPORT_SYMBOL(HYPERVISOR_shared_info);
-+
-+start_info_t *xen_start_info;
-+EXPORT_SYMBOL(xen_start_info);
-+
-+int running_on_xen;
-+EXPORT_SYMBOL(running_on_xen);
-+
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
-+static int p2m_expose_init(void);
-+#else
-+#define p2m_expose_init() (-ENOSYS)
-+#endif
-+
-+//XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
-+// move those to lib/contiguous_bitmap?
-+//XXX discontigmem/sparsemem
-+
-+/*
-+ * Bitmap is indexed by page number. If bit is set, the page is part of a
-+ * xen_create_contiguous_region() area of memory.
-+ */
-+unsigned long *contiguous_bitmap;
-+
-+void
-+contiguous_bitmap_init(unsigned long end_pfn)
-+{
-+      unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3;
-+      contiguous_bitmap = alloc_bootmem_low_pages(size);
-+      BUG_ON(!contiguous_bitmap);
-+      memset(contiguous_bitmap, 0, size);
-+}
-+
-+#if 0
-+int
-+contiguous_bitmap_test(void* p)
-+{
-+      return test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap);
-+}
-+#endif
-+
-+static void contiguous_bitmap_set(
-+      unsigned long first_page, unsigned long nr_pages)
-+{
-+      unsigned long start_off, end_off, curr_idx, end_idx;
-+
-+      curr_idx  = first_page / BITS_PER_LONG;
-+      start_off = first_page & (BITS_PER_LONG-1);
-+      end_idx   = (first_page + nr_pages) / BITS_PER_LONG;
-+      end_off   = (first_page + nr_pages) & (BITS_PER_LONG-1);
-+
-+      if (curr_idx == end_idx) {
-+              contiguous_bitmap[curr_idx] |=
-+                      ((1UL<<end_off)-1) & -(1UL<<start_off);
-+      } else {
-+              contiguous_bitmap[curr_idx] |= -(1UL<<start_off);
-+              while ( ++curr_idx < end_idx )
-+                      contiguous_bitmap[curr_idx] = ~0UL;
-+              contiguous_bitmap[curr_idx] |= (1UL<<end_off)-1;
-+      }
-+}
-+
-+static void contiguous_bitmap_clear(
-+      unsigned long first_page, unsigned long nr_pages)
-+{
-+      unsigned long start_off, end_off, curr_idx, end_idx;
-+
-+      curr_idx  = first_page / BITS_PER_LONG;
-+      start_off = first_page & (BITS_PER_LONG-1);
-+      end_idx   = (first_page + nr_pages) / BITS_PER_LONG;
-+      end_off   = (first_page + nr_pages) & (BITS_PER_LONG-1);
-+
-+      if (curr_idx == end_idx) {
-+              contiguous_bitmap[curr_idx] &=
-+                      -(1UL<<end_off) | ((1UL<<start_off)-1);
-+      } else {
-+              contiguous_bitmap[curr_idx] &= (1UL<<start_off)-1;
-+              while ( ++curr_idx != end_idx )
-+                      contiguous_bitmap[curr_idx] = 0;
-+              contiguous_bitmap[curr_idx] &= -(1UL<<end_off);
-+      }
-+}
-+
-+// __xen_create_contiguous_region(), __xen_destroy_contiguous_region()
-+// are based on i386 xen_create_contiguous_region(),
-+// xen_destroy_contiguous_region()
-+
-+/* Protected by balloon_lock. */
-+#define MAX_CONTIG_ORDER 7
-+static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
-+
-+/* Ensure multi-page extents are contiguous in machine memory. */
-+int
-+__xen_create_contiguous_region(unsigned long vstart,
-+                             unsigned int order, unsigned int address_bits)
-+{
-+      unsigned long error = 0;
-+      unsigned long gphys = __pa(vstart);
-+      unsigned long start_gpfn = gphys >> PAGE_SHIFT;
-+      unsigned long num_gpfn = 1 << order;
-+      unsigned long i;
-+      unsigned long flags;
-+
-+      unsigned long *in_frames = discontig_frames, out_frame;
-+      int success;
-+      struct xen_memory_exchange exchange = {
-+              .in = {
-+                      .nr_extents   = num_gpfn,
-+                      .extent_order = 0,
-+                      .domid        = DOMID_SELF
-+              },
-+              .out = {
-+                       .nr_extents   = 1,
-+                       .extent_order = order,
-+                       .address_bits = address_bits,
-+                       .domid        = DOMID_SELF
-+               },
-+              .nr_exchanged = 0
-+      };
-+
-+      if (unlikely(order > MAX_CONTIG_ORDER))
-+              return -ENOMEM;
-+      
-+      set_xen_guest_handle(exchange.in.extent_start, in_frames);
-+      set_xen_guest_handle(exchange.out.extent_start, &out_frame);
-+
-+      scrub_pages(vstart, num_gpfn);
-+
-+      balloon_lock(flags);
-+
-+      /* Get a new contiguous memory extent. */
-+      for (i = 0; i < num_gpfn; i++) {
-+              in_frames[i] = start_gpfn + i;
-+      }
-+      out_frame = start_gpfn;
-+      error = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
-+      success = (exchange.nr_exchanged == num_gpfn);
-+      BUG_ON(!success && ((exchange.nr_exchanged != 0) || (error == 0)));
-+      BUG_ON(success && (error != 0));
-+      if (unlikely(error == -ENOSYS)) {
-+              /* Compatibility when XENMEM_exchange is unsupported. */
-+              error = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-+                                           &exchange.in);
-+              BUG_ON(error != num_gpfn);
-+              error = HYPERVISOR_memory_op(XENMEM_populate_physmap,
-+                                           &exchange.out);
-+              if (error != 1) {
-+                      /* Couldn't get special memory: fall back to normal. */
-+                      for (i = 0; i < num_gpfn; i++) {
-+                              in_frames[i] = start_gpfn + i;
-+                      }
-+                      error = HYPERVISOR_memory_op(XENMEM_populate_physmap,
-+                                                   &exchange.in);
-+                      BUG_ON(error != num_gpfn);
-+                      success = 0;
-+              } else
-+                      success = 1;
-+      }
-+      if (success)
-+              contiguous_bitmap_set(start_gpfn, num_gpfn);
-+#if 0
-+      if (success) {
-+              unsigned long mfn;
-+              unsigned long mfn_prev = ~0UL;
-+              for (i = 0; i < num_gpfn; i++) {
-+                      mfn = pfn_to_mfn_for_dma(start_gpfn + i);
-+                      if (mfn_prev != ~0UL && mfn != mfn_prev + 1) {
-+                              xprintk("\n");
-+                              xprintk("%s:%d order %d "
-+                                      "start 0x%lx bus 0x%lx "
-+                                      "machine 0x%lx\n",
-+                                      __func__, __LINE__, order,
-+                                      vstart, virt_to_bus((void*)vstart),
-+                                      phys_to_machine_for_dma(gphys));
-+                              xprintk("mfn: ");
-+                              for (i = 0; i < num_gpfn; i++) {
-+                                      mfn = pfn_to_mfn_for_dma(
-+                                              start_gpfn + i);
-+                                      xprintk("0x%lx ", mfn);
-+                              }
-+                              xprintk("\n");
-+                              break;
-+                      }
-+                      mfn_prev = mfn;
-+              }
-+      }
-+#endif
-+      balloon_unlock(flags);
-+      return success? 0: -ENOMEM;
-+}
-+
-+void
-+__xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
-+{
-+      unsigned long flags;
-+      unsigned long error = 0;
-+      unsigned long start_gpfn = __pa(vstart) >> PAGE_SHIFT;
-+      unsigned long num_gpfn = 1UL << order;
-+      unsigned long i;
-+
-+      unsigned long *out_frames = discontig_frames, in_frame;
-+      int            success;
-+      struct xen_memory_exchange exchange = {
-+              .in = {
-+                      .nr_extents   = 1,
-+                      .extent_order = order,
-+                      .domid        = DOMID_SELF
-+              },
-+              .out = {
-+                       .nr_extents   = num_gpfn,
-+                       .extent_order = 0,
-+                       .address_bits = 0,
-+                       .domid        = DOMID_SELF
-+               },
-+              .nr_exchanged = 0
-+        };
-+      
-+
-+      if (!test_bit(start_gpfn, contiguous_bitmap))
-+              return;
-+
-+      if (unlikely(order > MAX_CONTIG_ORDER))
-+              return;
-+
-+      set_xen_guest_handle(exchange.in.extent_start, &in_frame);
-+      set_xen_guest_handle(exchange.out.extent_start, out_frames);
-+
-+      scrub_pages(vstart, num_gpfn);
-+
-+      balloon_lock(flags);
-+
-+      contiguous_bitmap_clear(start_gpfn, num_gpfn);
-+
-+        /* Do the exchange for non-contiguous MFNs. */
-+      in_frame = start_gpfn;
-+      for (i = 0; i < num_gpfn; i++) {
-+              out_frames[i] = start_gpfn + i;
-+      }
-+      error = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
-+      success = (exchange.nr_exchanged == 1);
-+      BUG_ON(!success && ((exchange.nr_exchanged != 0) || (error == 0)));
-+      BUG_ON(success && (error != 0));
-+      if (unlikely(error == -ENOSYS)) {
-+                /* Compatibility when XENMEM_exchange is unsupported. */
-+              error = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-+                                           &exchange.in);
-+              BUG_ON(error != 1);
-+
-+              error = HYPERVISOR_memory_op(XENMEM_populate_physmap,
-+                                           &exchange.out);
-+              BUG_ON(error != num_gpfn);
-+      }
-+      balloon_unlock(flags);
-+}
-+
-+
-+///////////////////////////////////////////////////////////////////////////
-+// grant table hack
-+// cmd: GNTTABOP_xxx
-+
-+#include <linux/mm.h>
-+#include <xen/interface/xen.h>
-+#include <xen/gnttab.h>
-+
-+static void
-+gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop)
-+{
-+      uint32_t flags;
-+
-+      flags = uop->flags;
-+
-+      if (flags & GNTMAP_host_map) {
-+              if (flags & GNTMAP_application_map) {
-+                      xprintd("GNTMAP_application_map is not supported yet: flags 0x%x\n", flags);
-+                      BUG();
-+              }
-+              if (flags & GNTMAP_contains_pte) {
-+                      xprintd("GNTMAP_contains_pte is not supported yet flags 0x%x\n", flags);
-+                      BUG();
-+              }
-+      } else if (flags & GNTMAP_device_map) {
-+              xprintd("GNTMAP_device_map is not supported yet 0x%x\n", flags);
-+              BUG();//XXX not yet. actually this flag is not used.
-+      } else {
-+              BUG();
-+      }
-+}
-+
-+int
-+HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
-+{
-+      if (cmd == GNTTABOP_map_grant_ref) {
-+              unsigned int i;
-+              for (i = 0; i < count; i++) {
-+                      gnttab_map_grant_ref_pre(
-+                              (struct gnttab_map_grant_ref*)uop + i);
-+              }
-+      }
-+      return xencomm_mini_hypercall_grant_table_op(cmd, uop, count);
-+}
-+EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
-+
-+///////////////////////////////////////////////////////////////////////////
-+// PageForeign(), SetPageForeign(), ClearPageForeign()
-+
-+struct address_space xen_ia64_foreign_dummy_mapping;
-+EXPORT_SYMBOL(xen_ia64_foreign_dummy_mapping);
-+
-+///////////////////////////////////////////////////////////////////////////
-+// foreign mapping
-+#include <linux/efi.h>
-+#include <asm/meminit.h> // for IA64_GRANULE_SIZE, GRANULEROUND{UP,DOWN}()
-+
-+static unsigned long privcmd_resource_min = 0;
-+// Xen/ia64 currently can handle pseudo physical address bits up to
-+// (PAGE_SHIFT * 3)
-+static unsigned long privcmd_resource_max = GRANULEROUNDDOWN((1UL << (PAGE_SHIFT * 3)) - 1);
-+static unsigned long privcmd_resource_align = IA64_GRANULE_SIZE;
-+
-+static unsigned long
-+md_end_addr(const efi_memory_desc_t *md)
-+{
-+      return md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
-+}
-+
-+#define XEN_IA64_PRIVCMD_LEAST_GAP_SIZE       (1024 * 1024 * 1024UL)
-+static int
-+xen_ia64_privcmd_check_size(unsigned long start, unsigned long end)
-+{
-+      return (start < end &&
-+              (end - start) > XEN_IA64_PRIVCMD_LEAST_GAP_SIZE);
-+}
-+
-+static int __init
-+xen_ia64_privcmd_init(void)
-+{
-+      void *efi_map_start, *efi_map_end, *p;
-+      u64 efi_desc_size;
-+      efi_memory_desc_t *md;
-+      unsigned long tmp_min;
-+      unsigned long tmp_max;
-+      unsigned long gap_size;
-+      unsigned long prev_end;
-+
-+      if (!is_running_on_xen())
-+              return -1;
-+
-+      efi_map_start = __va(ia64_boot_param->efi_memmap);
-+      efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
-+      efi_desc_size = ia64_boot_param->efi_memdesc_size;
-+
-+      // at first check the used highest address
-+      for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
-+              // nothing
-+      }
-+      md = p - efi_desc_size;
-+      privcmd_resource_min = GRANULEROUNDUP(md_end_addr(md));
-+      if (xen_ia64_privcmd_check_size(privcmd_resource_min,
-+                                      privcmd_resource_max)) {
-+              goto out;
-+      }
-+
-+      // the used highest address is too large. try to find the largest gap.
-+      tmp_min = privcmd_resource_max;
-+      tmp_max = 0;
-+      gap_size = 0;
-+      prev_end = 0;
-+      for (p = efi_map_start;
-+           p < efi_map_end - efi_desc_size;
-+           p += efi_desc_size) {
-+              unsigned long end;
-+              efi_memory_desc_t* next;
-+              unsigned long next_start;
-+
-+              md = p;
-+              end = md_end_addr(md);
-+              if (end > privcmd_resource_max) {
-+                      break;
-+              }
-+              if (end < prev_end) {
-+                      // work around. 
-+                      // Xen may pass incompletely sorted memory
-+                      // descriptors like
-+                      // [x, x + length]
-+                      // [x, x]
-+                      // this order should be reversed.
-+                      continue;
-+              }
-+              next = p + efi_desc_size;
-+              next_start = next->phys_addr;
-+              if (next_start > privcmd_resource_max) {
-+                      next_start = privcmd_resource_max;
-+              }
-+              if (end < next_start && gap_size < (next_start - end)) {
-+                      tmp_min = end;
-+                      tmp_max = next_start;
-+                      gap_size = tmp_max - tmp_min;
-+              }
-+              prev_end = end;
-+      }
-+
-+      privcmd_resource_min = GRANULEROUNDUP(tmp_min);
-+      if (xen_ia64_privcmd_check_size(privcmd_resource_min, tmp_max)) {
-+              privcmd_resource_max = tmp_max;
-+              goto out;
-+      }
-+
-+      privcmd_resource_min = tmp_min;
-+      privcmd_resource_max = tmp_max;
-+      if (!xen_ia64_privcmd_check_size(privcmd_resource_min,
-+                                       privcmd_resource_max)) {
-+              // Any large enough gap isn't found.
-+              // go ahead anyway with the warning hoping that large region
-+              // won't be requested.
-+              printk(KERN_WARNING "xen privcmd: large enough region for privcmd mmap is not found.\n");
-+      }
-+
-+out:
-+      printk(KERN_INFO "xen privcmd uses pseudo physical addr range [0x%lx, 0x%lx] (%ldMB)\n",
-+             privcmd_resource_min, privcmd_resource_max, 
-+             (privcmd_resource_max - privcmd_resource_min) >> 20);
-+      BUG_ON(privcmd_resource_min >= privcmd_resource_max);
-+
-+      // XXX this should be somewhere appropriate
-+      (void)p2m_expose_init();
-+
-+      return 0;
-+}
-+late_initcall(xen_ia64_privcmd_init);
-+
-+struct xen_ia64_privcmd_entry {
-+      atomic_t        map_count;
-+#define INVALID_GPFN  (~0UL)
-+      unsigned long   gpfn;
-+};
-+
-+struct xen_ia64_privcmd_range {
-+      atomic_t                        ref_count;
-+      unsigned long                   pgoff; // in PAGE_SIZE
-+      struct resource*                res;
-+
-+      unsigned long                   num_entries;
-+      struct xen_ia64_privcmd_entry   entries[0];
-+};
-+
-+struct xen_ia64_privcmd_vma {
-+      int                             is_privcmd_mmapped;
-+      struct xen_ia64_privcmd_range*  range;
-+
-+      unsigned long                   num_entries;
-+      struct xen_ia64_privcmd_entry*  entries;
-+};
-+
-+static void
-+xen_ia64_privcmd_init_entry(struct xen_ia64_privcmd_entry* entry)
-+{
-+      atomic_set(&entry->map_count, 0);
-+      entry->gpfn = INVALID_GPFN;
-+}
-+
-+static int
-+xen_ia64_privcmd_entry_mmap(struct vm_area_struct* vma,
-+                          unsigned long addr,
-+                          struct xen_ia64_privcmd_range* privcmd_range,
-+                          int i,
-+                          unsigned long gmfn,
-+                          pgprot_t prot,
-+                          domid_t domid)
-+{
-+      int error = 0;
-+      struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
-+      unsigned long gpfn;
-+      unsigned long flags;
-+
-+      if ((addr & ~PAGE_MASK) != 0 || gmfn == INVALID_MFN) {
-+              error = -EINVAL;
-+              goto out;
-+      }
-+
-+      if (entry->gpfn != INVALID_GPFN) {
-+              error = -EBUSY;
-+              goto out;
-+      }
-+      gpfn = (privcmd_range->res->start >> PAGE_SHIFT) + i;
-+
-+      flags = ASSIGN_writable;
-+      if (pgprot_val(prot) == PROT_READ) {
-+              flags = ASSIGN_readonly;
-+      }
-+      error = HYPERVISOR_add_physmap_with_gmfn(gpfn, gmfn, flags, domid);
-+      if (error != 0) {
-+              goto out;
-+      }
-+
-+      prot = vma->vm_page_prot;
-+      error = remap_pfn_range(vma, addr, gpfn, 1 << PAGE_SHIFT, prot);
-+      if (error != 0) {
-+              error = HYPERVISOR_zap_physmap(gpfn, 0);
-+              if (error) {
-+                      BUG();//XXX
-+              }
-+      } else {
-+              atomic_inc(&entry->map_count);
-+              entry->gpfn = gpfn;
-+      }
-+
-+out:
-+      return error;
-+}
-+
-+static void
-+xen_ia64_privcmd_entry_munmap(struct xen_ia64_privcmd_range* privcmd_range,
-+                            int i)
-+{
-+      struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
-+      unsigned long gpfn = entry->gpfn;
-+      //gpfn = (privcmd_range->res->start >> PAGE_SHIFT) +
-+      //      (vma->vm_pgoff - privcmd_range->pgoff);
-+      int error;
-+
-+      error = HYPERVISOR_zap_physmap(gpfn, 0);
-+      if (error) {
-+              BUG();//XXX
-+      }
-+      entry->gpfn = INVALID_GPFN;
-+}
-+
-+static void
-+xen_ia64_privcmd_entry_open(struct xen_ia64_privcmd_range* privcmd_range,
-+                          int i)
-+{
-+      struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
-+      if (entry->gpfn != INVALID_GPFN) {
-+              atomic_inc(&entry->map_count);
-+      } else {
-+              BUG_ON(atomic_read(&entry->map_count) != 0);
-+      }
-+}
-+
-+static void
-+xen_ia64_privcmd_entry_close(struct xen_ia64_privcmd_range* privcmd_range,
-+                           int i)
-+{
-+      struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
-+      if (entry->gpfn != INVALID_GPFN &&
-+          atomic_dec_and_test(&entry->map_count)) {
-+              xen_ia64_privcmd_entry_munmap(privcmd_range, i);
-+      }
-+}
-+
-+static void xen_ia64_privcmd_vma_open(struct vm_area_struct* vma);
-+static void xen_ia64_privcmd_vma_close(struct vm_area_struct* vma);
-+
-+struct vm_operations_struct xen_ia64_privcmd_vm_ops = {
-+      .open = &xen_ia64_privcmd_vma_open,
-+      .close = &xen_ia64_privcmd_vma_close,
-+};
-+
-+static void
-+__xen_ia64_privcmd_vma_open(struct vm_area_struct* vma,
-+                          struct xen_ia64_privcmd_vma* privcmd_vma,
-+                          struct xen_ia64_privcmd_range* privcmd_range)
-+{
-+      unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
-+      unsigned long num_entries = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-+      unsigned long i;
-+
-+      BUG_ON(entry_offset < 0);
-+      BUG_ON(entry_offset + num_entries > privcmd_range->num_entries);
-+
-+      privcmd_vma->range = privcmd_range;
-+      privcmd_vma->num_entries = num_entries;
-+      privcmd_vma->entries = &privcmd_range->entries[entry_offset];
-+      vma->vm_private_data = privcmd_vma;
-+      for (i = 0; i < privcmd_vma->num_entries; i++) {
-+              xen_ia64_privcmd_entry_open(privcmd_range, entry_offset + i);
-+      }
-+
-+      vma->vm_private_data = privcmd_vma;
-+      vma->vm_ops = &xen_ia64_privcmd_vm_ops;
-+}
-+
-+static void
-+xen_ia64_privcmd_vma_open(struct vm_area_struct* vma)
-+{
-+      struct xen_ia64_privcmd_vma* old_privcmd_vma = (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
-+      struct xen_ia64_privcmd_vma* privcmd_vma = (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
-+      struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
-+
-+      atomic_inc(&privcmd_range->ref_count);
-+      // vm_op->open() can't fail.
-+      privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL | __GFP_NOFAIL);
-+      // copy original value if necessary
-+      privcmd_vma->is_privcmd_mmapped = old_privcmd_vma->is_privcmd_mmapped;
-+
-+      __xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
-+}
-+
-+static void
-+xen_ia64_privcmd_vma_close(struct vm_area_struct* vma)
-+{
-+      struct xen_ia64_privcmd_vma* privcmd_vma =
-+              (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
-+      struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
-+      unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
-+      unsigned long i;
-+
-+      for (i = 0; i < privcmd_vma->num_entries; i++) {
-+              xen_ia64_privcmd_entry_close(privcmd_range, entry_offset + i);
-+      }
-+      vma->vm_private_data = NULL;
-+      kfree(privcmd_vma);
-+
-+      if (atomic_dec_and_test(&privcmd_range->ref_count)) {
-+#if 1
-+              for (i = 0; i < privcmd_range->num_entries; i++) {
-+                      struct xen_ia64_privcmd_entry* entry =
-+                              &privcmd_range->entries[i];
-+                      BUG_ON(atomic_read(&entry->map_count) != 0);
-+                      BUG_ON(entry->gpfn != INVALID_GPFN);
-+              }
-+#endif
-+              release_resource(privcmd_range->res);
-+              kfree(privcmd_range->res);
-+              vfree(privcmd_range);
-+      }
-+}
-+
-+int
-+privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
-+{
-+      struct xen_ia64_privcmd_vma* privcmd_vma =
-+              (struct xen_ia64_privcmd_vma *)vma->vm_private_data;
-+      return (xchg(&privcmd_vma->is_privcmd_mmapped, 1) == 0);
-+}
-+
-+int
-+privcmd_mmap(struct file * file, struct vm_area_struct * vma)
-+{
-+      int error;
-+      unsigned long size = vma->vm_end - vma->vm_start;
-+      unsigned long num_entries = size >> PAGE_SHIFT;
-+      struct xen_ia64_privcmd_range* privcmd_range = NULL;
-+      struct xen_ia64_privcmd_vma* privcmd_vma = NULL;
-+      struct resource* res = NULL;
-+      unsigned long i;
-+      BUG_ON(!is_running_on_xen());
-+
-+      BUG_ON(file->private_data != NULL);
-+
-+      error = -ENOMEM;
-+      privcmd_range =
-+              vmalloc(sizeof(*privcmd_range) +
-+                      sizeof(privcmd_range->entries[0]) * num_entries);
-+      if (privcmd_range == NULL) {
-+              goto out_enomem0;
-+      }
-+      privcmd_vma = kmalloc(sizeof(*privcmd_vma), GFP_KERNEL);
-+      if (privcmd_vma == NULL) {
-+              goto out_enomem1;
-+      }
-+      privcmd_vma->is_privcmd_mmapped = 0;
-+
-+      res = kzalloc(sizeof(*res), GFP_KERNEL);
-+      if (res == NULL) {
-+              goto out_enomem1;
-+      }
-+      res->name = "Xen privcmd mmap";
-+      error = allocate_resource(&iomem_resource, res, size,
-+                                privcmd_resource_min, privcmd_resource_max,
-+                                privcmd_resource_align, NULL, NULL);
-+      if (error) {
-+              goto out_enomem1;
-+      }
-+      privcmd_range->res = res;
-+
-+      /* DONTCOPY is essential for Xen as copy_page_range is broken. */
-+      vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
-+
-+      atomic_set(&privcmd_range->ref_count, 1);
-+      privcmd_range->pgoff = vma->vm_pgoff;
-+      privcmd_range->num_entries = num_entries;
-+      for (i = 0; i < privcmd_range->num_entries; i++) {
-+              xen_ia64_privcmd_init_entry(&privcmd_range->entries[i]);
-+      }
-+
-+      __xen_ia64_privcmd_vma_open(vma, privcmd_vma, privcmd_range);
-+      return 0;
-+
-+out_enomem1:
-+      kfree(res);
-+      kfree(privcmd_vma);
-+out_enomem0:
-+      vfree(privcmd_range);
-+      return error;
-+}
-+
-+int
-+direct_remap_pfn_range(struct vm_area_struct *vma,
-+                     unsigned long address,   // process virtual address
-+                     unsigned long gmfn,      // gmfn, gmfn + 1, ... gmfn + size/PAGE_SIZE
-+                     unsigned long size,
-+                     pgprot_t prot,
-+                     domid_t  domid)          // target domain
-+{
-+      struct xen_ia64_privcmd_vma* privcmd_vma =
-+              (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
-+      struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
-+      unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
-+
-+      unsigned long i;
-+      unsigned long offset;
-+      int error = 0;
-+      BUG_ON(!is_running_on_xen());
-+
-+#if 0
-+      if (prot != vm->vm_page_prot) {
-+              return -EINVAL;
-+      }
-+#endif
-+
-+      i = (address - vma->vm_start) >> PAGE_SHIFT;
-+      for (offset = 0; offset < size; offset += PAGE_SIZE) {
-+              error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & PAGE_MASK, privcmd_range, entry_offset + i, gmfn, prot, domid);
-+              if (error != 0) {
-+                      break;
-+              }
-+
-+              i++;
-+              gmfn++;
-+        }
-+
-+      return error;
-+}
-+
-+
-+/* Called after suspend, to resume time.  */
-+void
-+time_resume(void)
-+{
-+      extern void ia64_cpu_local_tick(void);
-+
-+      /* Just trigger a tick.  */
-+      ia64_cpu_local_tick();
-+}
-+
-+///////////////////////////////////////////////////////////////////////////
-+// expose p2m table
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
-+#include <linux/cpu.h>
-+#include <asm/uaccess.h>
-+
-+int p2m_initialized __read_mostly = 0;
-+
-+unsigned long p2m_min_low_pfn __read_mostly;
-+unsigned long p2m_max_low_pfn __read_mostly;
-+unsigned long p2m_convert_min_pfn __read_mostly;
-+unsigned long p2m_convert_max_pfn __read_mostly;
-+
-+static struct resource p2m_resource = {
-+      .name    = "Xen p2m table",
-+      .flags   = IORESOURCE_MEM,
-+};
-+static unsigned long p2m_assign_start_pfn __read_mostly;
-+static unsigned long p2m_assign_end_pfn __read_mostly;
-+volatile const pte_t* p2m_pte __read_mostly;
-+
-+#define GRNULE_PFN    PTRS_PER_PTE
-+static unsigned long p2m_granule_pfn __read_mostly = GRNULE_PFN;
-+
-+#define ROUNDDOWN(x, y)  ((x) & ~((y) - 1))
-+#define ROUNDUP(x, y)    (((x) + (y) - 1) & ~((y) - 1))
-+
-+#define P2M_PREFIX    "Xen p2m: "
-+
-+static int xen_ia64_p2m_expose __read_mostly = 1;
-+module_param(xen_ia64_p2m_expose, int, 0);
-+MODULE_PARM_DESC(xen_ia64_p2m_expose,
-+                 "enable/disable xen/ia64 p2m exposure optimization\n");
-+
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
-+static int xen_ia64_p2m_expose_use_dtr __read_mostly = 1;
-+module_param(xen_ia64_p2m_expose_use_dtr, int, 0);
-+MODULE_PARM_DESC(xen_ia64_p2m_expose_use_dtr,
-+                 "use/unuse dtr to map exposed p2m table\n");
-+
-+static const int p2m_page_shifts[] = {
-+      _PAGE_SIZE_4K,
-+      _PAGE_SIZE_8K,
-+      _PAGE_SIZE_16K,
-+      _PAGE_SIZE_64K,
-+      _PAGE_SIZE_256K,
-+      _PAGE_SIZE_1M,
-+      _PAGE_SIZE_4M,
-+      _PAGE_SIZE_16M,
-+      _PAGE_SIZE_64M,
-+      _PAGE_SIZE_256M,
-+};
-+
-+struct p2m_itr_arg {
-+      unsigned long vaddr;
-+      unsigned long pteval;
-+      unsigned long log_page_size;
-+};
-+static struct p2m_itr_arg p2m_itr_arg __read_mostly;
-+
-+// This should be in asm-ia64/kregs.h
-+#define IA64_TR_P2M_TABLE     3
-+
-+static void
-+p2m_itr(void* info)
-+{
-+      struct p2m_itr_arg* arg = (struct p2m_itr_arg*)info;
-+      ia64_itr(0x2, IA64_TR_P2M_TABLE,
-+               arg->vaddr, arg->pteval, arg->log_page_size);
-+      ia64_srlz_d();
-+}
-+
-+static int
-+p2m_expose_dtr_call(struct notifier_block *self,
-+                    unsigned long event, void* ptr)
-+{
-+      unsigned int cpu = (unsigned int)(long)ptr;
-+      if (event != CPU_ONLINE)
-+              return 0;
-+      if (!(p2m_initialized && xen_ia64_p2m_expose_use_dtr))
-+              smp_call_function_single(cpu, &p2m_itr, &p2m_itr_arg, 1, 1);
-+      return 0;
-+}
-+
-+static struct notifier_block p2m_expose_dtr_hotplug_notifier = {
-+      .notifier_call = p2m_expose_dtr_call,
-+      .next          = NULL,
-+      .priority      = 0
-+};
-+#endif
-+
-+static int
-+p2m_expose_init(void)
-+{
-+      unsigned long num_pfn;
-+      unsigned long size = 0;
-+      unsigned long p2m_size = 0;
-+      unsigned long align = ~0UL;
-+      int error = 0;
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
-+      int i;
-+      unsigned long page_size;
-+      unsigned long log_page_size = 0;
-+#endif
-+
-+      if (!xen_ia64_p2m_expose)
-+              return -ENOSYS;
-+      if (p2m_initialized)
-+              return 0;
-+
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
-+      error = register_cpu_notifier(&p2m_expose_dtr_hotplug_notifier);
-+      if (error < 0)
-+              return error;
-+#endif
-+
-+      lock_cpu_hotplug();
-+      if (p2m_initialized)
-+              goto out;
-+
-+#ifdef CONFIG_DISCONTIGMEM
-+      p2m_min_low_pfn = min_low_pfn;
-+      p2m_max_low_pfn = max_low_pfn;
-+#else
-+      p2m_min_low_pfn = 0;
-+      p2m_max_low_pfn = max_pfn;
-+#endif
-+
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
-+      if (xen_ia64_p2m_expose_use_dtr) {
-+              unsigned long granule_pfn = 0;
-+              p2m_size = p2m_max_low_pfn - p2m_min_low_pfn;
-+              for (i = 0;
-+                   i < sizeof(p2m_page_shifts)/sizeof(p2m_page_shifts[0]);
-+                   i++) {
-+                      log_page_size = p2m_page_shifts[i];
-+                      page_size = 1UL << log_page_size;
-+                      if (page_size < p2m_size)
-+                              continue;
-+
-+                      granule_pfn = max(page_size >> PAGE_SHIFT,
-+                                        p2m_granule_pfn);
-+                      p2m_convert_min_pfn = ROUNDDOWN(p2m_min_low_pfn,
-+                                                      granule_pfn);
-+                      p2m_convert_max_pfn = ROUNDUP(p2m_max_low_pfn,
-+                                                    granule_pfn);
-+                      num_pfn = p2m_convert_max_pfn - p2m_convert_min_pfn;
-+                      size = num_pfn << PAGE_SHIFT;
-+                      p2m_size = num_pfn / PTRS_PER_PTE;
-+                      p2m_size = ROUNDUP(p2m_size, granule_pfn << PAGE_SHIFT);
-+                      if (p2m_size == page_size)
-+                              break;
-+              }
-+              if (p2m_size != page_size) {
-+                      printk(KERN_ERR "p2m_size != page_size\n");
-+                      error = -EINVAL;
-+                      goto out;
-+              }
-+              align = max(privcmd_resource_align, granule_pfn << PAGE_SHIFT);
-+      } else
-+#endif
-+      {
-+              BUG_ON(p2m_granule_pfn & (p2m_granule_pfn - 1));
-+              p2m_convert_min_pfn = ROUNDDOWN(p2m_min_low_pfn,
-+                                              p2m_granule_pfn);
-+              p2m_convert_max_pfn = ROUNDUP(p2m_max_low_pfn, p2m_granule_pfn);
-+              num_pfn = p2m_convert_max_pfn - p2m_convert_min_pfn;
-+              size = num_pfn << PAGE_SHIFT;
-+              p2m_size = num_pfn / PTRS_PER_PTE;
-+              p2m_size = ROUNDUP(p2m_size, p2m_granule_pfn << PAGE_SHIFT);
-+              align = max(privcmd_resource_align,
-+                          p2m_granule_pfn << PAGE_SHIFT);
-+      }
-+      
-+      // use privcmd region
-+      error = allocate_resource(&iomem_resource, &p2m_resource, p2m_size,
-+                                privcmd_resource_min, privcmd_resource_max,
-+                                align, NULL, NULL);
-+      if (error) {
-+              printk(KERN_ERR P2M_PREFIX
-+                     "can't allocate region for p2m exposure "
-+                     "[0x%016lx, 0x%016lx) 0x%016lx\n",
-+                     p2m_convert_min_pfn, p2m_convert_max_pfn, p2m_size);
-+              goto out;
-+      }
-+
-+      p2m_assign_start_pfn = p2m_resource.start >> PAGE_SHIFT;
-+      p2m_assign_end_pfn = p2m_resource.end >> PAGE_SHIFT;
-+      
-+      error = HYPERVISOR_expose_p2m(p2m_convert_min_pfn,
-+                                    p2m_assign_start_pfn,
-+                                    size, p2m_granule_pfn);
-+      if (error) {
-+              printk(KERN_ERR P2M_PREFIX "failed expose p2m hypercall %d\n",
-+                     error);
-+              printk(KERN_ERR P2M_PREFIX "conv 0x%016lx assign 0x%016lx "
-+                     "size 0x%016lx granule 0x%016lx\n",
-+                     p2m_convert_min_pfn, p2m_assign_start_pfn,
-+                     size, p2m_granule_pfn);;
-+              release_resource(&p2m_resource);
-+              goto out;
-+      }
-+      p2m_pte = (volatile const pte_t*)pfn_to_kaddr(p2m_assign_start_pfn);
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
-+      if (xen_ia64_p2m_expose_use_dtr) {
-+              p2m_itr_arg.vaddr = (unsigned long)__va(p2m_assign_start_pfn
-+                                                      << PAGE_SHIFT);
-+              p2m_itr_arg.pteval = pte_val(pfn_pte(p2m_assign_start_pfn,
-+                                                   PAGE_KERNEL));
-+              p2m_itr_arg.log_page_size = log_page_size;
-+              smp_mb();
-+              smp_call_function(&p2m_itr, &p2m_itr_arg, 1, 1);
-+              p2m_itr(&p2m_itr_arg);
-+      }
-+#endif        
-+      smp_mb();
-+      p2m_initialized = 1;
-+      printk(P2M_PREFIX "assign p2m table of [0x%016lx, 0x%016lx)\n",
-+             p2m_convert_min_pfn << PAGE_SHIFT,
-+             p2m_convert_max_pfn << PAGE_SHIFT);
-+      printk(P2M_PREFIX "to [0x%016lx, 0x%016lx) (%ld KBytes)\n",
-+             p2m_assign_start_pfn << PAGE_SHIFT,
-+             p2m_assign_end_pfn << PAGE_SHIFT,
-+             p2m_size / 1024);
-+out:
-+      unlock_cpu_hotplug();
-+      return error;
-+}
-+
-+#ifdef notyet
-+void
-+p2m_expose_cleanup(void)
-+{
-+      BUG_ON(!p2m_initialized);
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
-+      unregister_cpu_notifier(&p2m_expose_dtr_hotplug_notifier);
-+#endif
-+      release_resource(&p2m_resource);
-+}
-+#endif
-+
-+//XXX inlinize?
-+unsigned long
-+p2m_phystomach(unsigned long gpfn)
-+{
-+      volatile const pte_t* pte;
-+      unsigned long mfn;
-+      unsigned long pteval;
-+      
-+      if (!p2m_initialized ||
-+          gpfn < p2m_min_low_pfn || gpfn > p2m_max_low_pfn
-+          /* || !pfn_valid(gpfn) */)
-+              return INVALID_MFN;
-+      pte = p2m_pte + (gpfn - p2m_convert_min_pfn);
-+
-+      mfn = INVALID_MFN;
-+      if (likely(__get_user(pteval, (unsigned long __user *)pte) == 0 &&
-+                 pte_present(__pte(pteval)) &&
-+                 pte_pfn(__pte(pteval)) != (INVALID_MFN >> PAGE_SHIFT)))
-+              mfn = (pteval & _PFN_MASK) >> PAGE_SHIFT;
-+
-+      return mfn;
-+}
-+
-+EXPORT_SYMBOL_GPL(p2m_initialized);
-+EXPORT_SYMBOL_GPL(p2m_min_low_pfn);
-+EXPORT_SYMBOL_GPL(p2m_max_low_pfn);
-+EXPORT_SYMBOL_GPL(p2m_convert_min_pfn);
-+EXPORT_SYMBOL_GPL(p2m_convert_max_pfn);
-+EXPORT_SYMBOL_GPL(p2m_pte);
-+EXPORT_SYMBOL_GPL(p2m_phystomach);
-+#endif
-+
-+///////////////////////////////////////////////////////////////////////////
-+// for xenoprof
-+
-+struct resource*
-+xen_ia64_allocate_resource(unsigned long size)
-+{
-+      struct resource* res;
-+      int error;
-+      
-+      res = kmalloc(sizeof(*res), GFP_KERNEL);
-+      if (res == NULL)
-+              return ERR_PTR(-ENOMEM);
-+
-+      res->name = "Xen";
-+      res->flags = IORESOURCE_MEM;
-+      error = allocate_resource(&iomem_resource, res, PAGE_ALIGN(size),
-+                                privcmd_resource_min, privcmd_resource_max,
-+                                IA64_GRANULE_SIZE, NULL, NULL);
-+      if (error) {
-+              kfree(res);
-+              return ERR_PTR(error);
-+      }
-+      return res;
-+}
-+EXPORT_SYMBOL_GPL(xen_ia64_allocate_resource);
-+
-+void
-+xen_ia64_release_resource(struct resource* res)
-+{
-+      release_resource(res);
-+      kfree(res);
-+}
-+EXPORT_SYMBOL_GPL(xen_ia64_release_resource);
-+
-+void
-+xen_ia64_unmap_resource(struct resource* res)
-+{
-+      unsigned long gpfn = res->start >> PAGE_SHIFT;
-+      unsigned long nr_pages = (res->end - res->start) >> PAGE_SHIFT;
-+      unsigned long i;
-+      
-+      for (i = 0; i < nr_pages; i++) {
-+              int error = HYPERVISOR_zap_physmap(gpfn + i, 0);
-+              if (error)
-+                      printk(KERN_ERR
-+                             "%s:%d zap_phsymap failed %d gpfn %lx\n",
-+                             __func__, __LINE__, error, gpfn + i);
-+      }
-+      xen_ia64_release_resource(res);
-+}
-+EXPORT_SYMBOL_GPL(xen_ia64_unmap_resource);
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/mem.c linux-2.6.16.33/arch/ia64/xen/mem.c
---- linux-2.6.16.33-noxen/arch/ia64/xen/mem.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/mem.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,76 @@
-+/*
-+ *  Originally from linux/drivers/char/mem.c
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ *
-+ *  Added devfs support. 
-+ *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
-+ *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
-+ */
-+/*
-+ * taken from
-+ * linux/drivers/char/mem.c and linux-2.6-xen-sparse/drivers/xen/char/mem.c.
-+ * adjusted for IA64 and made transparent.
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/mm.h>
-+#include <linux/efi.h>
-+
-+/*
-+ * Architectures vary in how they handle caching for addresses
-+ * outside of main memory.
-+ *
-+ */
-+static inline int uncached_access(struct file *file, unsigned long addr)
-+{
-+      /*
-+       * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
-+       */
-+      return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
-+}
-+
-+int xen_mmap_mem(struct file * file, struct vm_area_struct * vma)
-+{
-+      unsigned long addr = vma->vm_pgoff << PAGE_SHIFT;
-+      size_t size = vma->vm_end - vma->vm_start;
-+
-+
-+#if 0
-+      /*
-+       *XXX FIXME: linux-2.6.16.29, linux-2.6.17
-+       *    valid_mmap_phys_addr_range() in linux/arch/ia64/kernel/efi.c
-+       *    fails checks.
-+       *    linux-2.6.18.1's returns always 1. 
-+       *    Its comments says
-+       *
-+         * MMIO regions are often missing from the EFI memory map.
-+         * We must allow mmap of them for programs like X, so we
-+         * currently can't do any useful validation.
-+         */
-+      if (!valid_mmap_phys_addr_range(addr, &size))
-+              return -EINVAL;
-+      if (size < vma->vm_end - vma->vm_start)
-+              return -EINVAL;
-+#endif
-+
-+      if (is_running_on_xen()) {
-+              unsigned long offset = HYPERVISOR_ioremap(addr, size);
-+              if (IS_ERR_VALUE(offset))
-+                      return offset;
-+      }
-+
-+      if (uncached_access(file, vma->vm_pgoff << PAGE_SHIFT))
-+              vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+
-+        /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
-+        if (remap_pfn_range(vma,
-+                            vma->vm_start,
-+                            vma->vm_pgoff,
-+                            size,
-+                            vma->vm_page_prot))
-+                return -EAGAIN;
-+        return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/util.c linux-2.6.16.33/arch/ia64/xen/util.c
---- linux-2.6.16.33-noxen/arch/ia64/xen/util.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/util.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,118 @@
-+/******************************************************************************
-+ * arch/ia64/xen/util.c
-+ * This file is the ia64 counterpart of drivers/xen/util.c
-+ *
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <asm/uaccess.h>
-+#include <xen/driver_util.h>
-+#include <xen/interface/memory.h>
-+#include <asm/hypercall.h>
-+
-+struct vm_struct *alloc_vm_area(unsigned long size)
-+{
-+      int order;
-+      unsigned long virt;
-+      unsigned long nr_pages;
-+      struct vm_struct* area;
-+      
-+      order = get_order(size);
-+      virt = __get_free_pages(GFP_KERNEL, order);
-+      if (virt == 0) {
-+              goto err0;
-+      }
-+      nr_pages = 1 << order;
-+      scrub_pages(virt, nr_pages);
-+      
-+      area = kmalloc(sizeof(*area), GFP_KERNEL);
-+      if (area == NULL) {
-+              goto err1;
-+      }
-+      
-+        area->flags = VM_IOREMAP;//XXX
-+        area->addr = (void*)virt;
-+        area->size = size;
-+        area->pages = NULL; //XXX
-+        area->nr_pages = nr_pages;
-+        area->phys_addr = 0;  /* xenbus_map_ring_valloc uses this field!  */
-+
-+      return area;
-+
-+err1:
-+      free_pages(virt, order);
-+err0:
-+      return NULL;
-+      
-+}
-+EXPORT_SYMBOL_GPL(alloc_vm_area);
-+
-+void free_vm_area(struct vm_struct *area)
-+{
-+      unsigned int order = get_order(area->size);
-+      unsigned long i;
-+      unsigned long phys_addr = __pa(area->addr);
-+
-+      // This area is used for foreign page mappping.
-+      // So underlying machine page may not be assigned.
-+      for (i = 0; i < (1 << order); i++) {
-+              unsigned long ret;
-+              unsigned long gpfn = (phys_addr >> PAGE_SHIFT) + i;
-+              struct xen_memory_reservation reservation = {
-+                      .nr_extents   = 1,
-+                      .address_bits = 0,
-+                      .extent_order = 0,
-+                      .domid        = DOMID_SELF
-+              };
-+              set_xen_guest_handle(reservation.extent_start, &gpfn);
-+              ret = HYPERVISOR_memory_op(XENMEM_populate_physmap,
-+                                         &reservation);
-+              BUG_ON(ret != 1);
-+      }
-+      free_pages((unsigned long)area->addr, order);
-+      kfree(area);
-+}
-+EXPORT_SYMBOL_GPL(free_vm_area);
-+
-+void lock_vm_area(struct vm_struct *area)
-+{
-+      // nothing
-+}
-+EXPORT_SYMBOL_GPL(lock_vm_area);
-+
-+void unlock_vm_area(struct vm_struct *area)
-+{
-+      // nothing
-+}
-+EXPORT_SYMBOL_GPL(unlock_vm_area);
-+
-+/*
-+ * Local variables:
-+ *  c-file-style: "linux"
-+ *  indent-tabs-mode: t
-+ *  c-indent-level: 8
-+ *  c-basic-offset: 8
-+ *  tab-width: 8
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xcom_hcall.c linux-2.6.16.33/arch/ia64/xen/xcom_hcall.c
---- linux-2.6.16.33-noxen/arch/ia64/xen/xcom_hcall.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xcom_hcall.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,365 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-+ *
-+ *          Tristan Gingold <tristan.gingold@bull.net>
-+ */
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/gfp.h>
-+#include <linux/module.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/dom0_ops.h>
-+#include <xen/interface/memory.h>
-+#include <xen/interface/xencomm.h>
-+#include <xen/interface/version.h>
-+#include <xen/interface/sched.h>
-+#include <xen/interface/event_channel.h>
-+#include <xen/interface/physdev.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/interface/callback.h>
-+#include <xen/interface/acm_ops.h>
-+#include <xen/interface/hvm/params.h>
-+#include <xen/interface/xenoprof.h>
-+#include <asm/hypercall.h>
-+#include <asm/page.h>
-+#include <asm/uaccess.h>
-+#include <asm/xen/xencomm.h>
-+#include <asm/perfmon.h>
-+
-+/* Xencomm notes:
-+ * This file defines hypercalls to be used by xencomm.  The hypercalls simply
-+ * create inlines descriptors for pointers and then call the raw arch hypercall
-+ * xencomm_arch_hypercall_XXX
-+ *
-+ * If the arch wants to directly use these hypercalls, simply define macros
-+ * in asm/hypercall.h, eg:
-+ *  #define HYPERVISOR_sched_op xencomm_hypercall_sched_op
-+ * 
-+ * The arch may also define HYPERVISOR_xxx as a function and do more operations
-+ * before/after doing the hypercall.
-+ *
-+ * Note: because only inline descriptors are created these functions must only
-+ * be called with in kernel memory parameters.
-+ */
-+
-+int
-+xencomm_hypercall_console_io(int cmd, int count, char *str)
-+{
-+      return xencomm_arch_hypercall_console_io
-+              (cmd, count, xencomm_create_inline(str));
-+}
-+
-+int
-+xencomm_hypercall_event_channel_op(int cmd, void *op)
-+{
-+      return xencomm_arch_hypercall_event_channel_op
-+              (cmd, xencomm_create_inline(op));
-+}
-+
-+int
-+xencomm_hypercall_xen_version(int cmd, void *arg)
-+{
-+      switch (cmd) {
-+      case XENVER_version:
-+      case XENVER_extraversion:
-+      case XENVER_compile_info:
-+      case XENVER_capabilities:
-+      case XENVER_changeset:
-+      case XENVER_platform_parameters:
-+      case XENVER_pagesize:
-+      case XENVER_get_features:
-+              break;
-+      default:
-+              printk("%s: unknown version cmd %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+
-+      return xencomm_arch_hypercall_xen_version
-+              (cmd, xencomm_create_inline(arg));
-+}
-+
-+int
-+xencomm_hypercall_physdev_op(int cmd, void *op)
-+{
-+      return xencomm_arch_hypercall_physdev_op
-+              (cmd, xencomm_create_inline(op));
-+}
-+
-+static void *
-+xencommize_grant_table_op(unsigned int cmd, void *op, unsigned int count)
-+{
-+      switch (cmd) {
-+      case GNTTABOP_map_grant_ref:
-+      case GNTTABOP_unmap_grant_ref:
-+              break;
-+      case GNTTABOP_setup_table:
-+      {
-+              struct gnttab_setup_table *setup = op;
-+              struct xencomm_handle *frame_list;
-+
-+              frame_list = xencomm_create_inline
-+                      (xen_guest_handle(setup->frame_list));
-+
-+              set_xen_guest_handle(setup->frame_list, (void *)frame_list);
-+              break;
-+      }
-+      case GNTTABOP_dump_table:
-+      case GNTTABOP_transfer:
-+      case GNTTABOP_copy:
-+              break;
-+      default:
-+              printk("%s: unknown grant table op %d\n", __func__, cmd);
-+              BUG();
-+      }
-+
-+      return  xencomm_create_inline(op);
-+}
-+
-+int
-+xencomm_hypercall_grant_table_op(unsigned int cmd, void *op, unsigned int count)
-+{
-+      void *desc = xencommize_grant_table_op (cmd, op, count);
-+
-+      return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
-+}
-+
-+int
-+xencomm_hypercall_sched_op(int cmd, void *arg)
-+{
-+      switch (cmd) {
-+      case SCHEDOP_yield:
-+      case SCHEDOP_block:
-+      case SCHEDOP_shutdown:
-+      case SCHEDOP_remote_shutdown:
-+              break;
-+      case SCHEDOP_poll:
-+      {
-+              sched_poll_t *poll = arg;
-+              struct xencomm_handle *ports;
-+
-+              ports = xencomm_create_inline(xen_guest_handle(poll->ports));
-+
-+              set_xen_guest_handle(poll->ports, (void *)ports);
-+              break;
-+      }
-+      default:
-+              printk("%s: unknown sched op %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+      
-+      return xencomm_arch_hypercall_sched_op(cmd, xencomm_create_inline(arg));
-+}
-+
-+int
-+xencomm_hypercall_multicall(void *call_list, int nr_calls)
-+{
-+      int i;
-+      multicall_entry_t *mce;
-+
-+      for (i = 0; i < nr_calls; i++) {
-+              mce = (multicall_entry_t *)call_list + i;
-+
-+              switch (mce->op) {
-+              case __HYPERVISOR_update_va_mapping:
-+              case __HYPERVISOR_mmu_update:
-+                      /* No-op on ia64.  */
-+                      break;
-+              case __HYPERVISOR_grant_table_op:
-+                      mce->args[1] = (unsigned long)xencommize_grant_table_op
-+                              (mce->args[0], (void *)mce->args[1],
-+                               mce->args[2]);
-+                      break;
-+              case __HYPERVISOR_memory_op:
-+              default:
-+                      printk("%s: unhandled multicall op entry op %lu\n",
-+                             __func__, mce->op);
-+                      return -ENOSYS;
-+              }
-+      }
-+
-+      return xencomm_arch_hypercall_multicall
-+              (xencomm_create_inline(call_list), nr_calls);
-+}
-+
-+int
-+xencomm_hypercall_callback_op(int cmd, void *arg)
-+{
-+      switch (cmd)
-+      {
-+      case CALLBACKOP_register:
-+      case CALLBACKOP_unregister:
-+              break;
-+      default:
-+              printk("%s: unknown callback op %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+
-+      return xencomm_arch_hypercall_callback_op
-+              (cmd, xencomm_create_inline(arg));
-+}
-+
-+static void
-+xencommize_memory_reservation (xen_memory_reservation_t *mop)
-+{
-+      struct xencomm_handle *desc;
-+
-+      desc = xencomm_create_inline(xen_guest_handle(mop->extent_start));
-+      set_xen_guest_handle(mop->extent_start, (void *)desc);
-+}
-+
-+int
-+xencomm_hypercall_memory_op(unsigned int cmd, void *arg)
-+{
-+      XEN_GUEST_HANDLE(xen_pfn_t) extent_start_va[2];
-+      xen_memory_reservation_t *xmr = NULL, *xme_in = NULL, *xme_out = NULL;
-+      int rc;
-+
-+      switch (cmd) {
-+      case XENMEM_increase_reservation:
-+      case XENMEM_decrease_reservation:
-+      case XENMEM_populate_physmap:
-+              xmr = (xen_memory_reservation_t *)arg;
-+              xen_guest_handle(extent_start_va[0]) =
-+                      xen_guest_handle(xmr->extent_start);
-+              xencommize_memory_reservation((xen_memory_reservation_t *)arg);
-+              break;
-+              
-+      case XENMEM_maximum_ram_page:
-+              break;
-+
-+      case XENMEM_exchange:
-+              xme_in  = &((xen_memory_exchange_t *)arg)->in;
-+              xme_out = &((xen_memory_exchange_t *)arg)->out;
-+              xen_guest_handle(extent_start_va[0]) =
-+                      xen_guest_handle(xme_in->extent_start);
-+              xen_guest_handle(extent_start_va[1]) =
-+                      xen_guest_handle(xme_out->extent_start);
-+              xencommize_memory_reservation
-+                      (&((xen_memory_exchange_t *)arg)->in);
-+              xencommize_memory_reservation
-+                      (&((xen_memory_exchange_t *)arg)->out);
-+              break;
-+
-+      default:
-+              printk("%s: unknown memory op %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+
-+      rc =  xencomm_arch_hypercall_memory_op(cmd, xencomm_create_inline(arg));
-+
-+      switch (cmd) {
-+      case XENMEM_increase_reservation:
-+      case XENMEM_decrease_reservation:
-+      case XENMEM_populate_physmap:
-+              xen_guest_handle(xmr->extent_start) =
-+                      xen_guest_handle(extent_start_va[0]);
-+              break;
-+
-+      case XENMEM_exchange:
-+              xen_guest_handle(xme_in->extent_start) =
-+                      xen_guest_handle(extent_start_va[0]);
-+              xen_guest_handle(xme_out->extent_start) =
-+                      xen_guest_handle(extent_start_va[1]);
-+              break;
-+      }
-+
-+      return rc;
-+}
-+
-+unsigned long
-+xencomm_hypercall_hvm_op(int cmd, void *arg)
-+{
-+      switch (cmd) {
-+      case HVMOP_set_param:
-+      case HVMOP_get_param:
-+              break;
-+      default:
-+              printk("%s: unknown hvm op %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+
-+      return xencomm_arch_hypercall_hvm_op(cmd, xencomm_create_inline(arg));
-+}
-+
-+int
-+xencomm_hypercall_suspend(unsigned long srec)
-+{
-+      struct sched_shutdown arg;
-+
-+      arg.reason = SHUTDOWN_suspend;
-+
-+      return xencomm_arch_hypercall_suspend(xencomm_create_inline(&arg));
-+}
-+
-+int
-+xencomm_hypercall_xenoprof_op(int op, void *arg)
-+{
-+      switch (op) {
-+      case XENOPROF_init:
-+      case XENOPROF_set_active:
-+      case XENOPROF_set_passive:
-+      case XENOPROF_counter:
-+      case XENOPROF_get_buffer:
-+              break;
-+
-+      case XENOPROF_reset_active_list:
-+      case XENOPROF_reset_passive_list:
-+      case XENOPROF_reserve_counters:
-+      case XENOPROF_setup_events:
-+      case XENOPROF_enable_virq:
-+      case XENOPROF_start:
-+      case XENOPROF_stop:
-+      case XENOPROF_disable_virq:
-+      case XENOPROF_release_counters:
-+      case XENOPROF_shutdown:
-+              return xencomm_arch_hypercall_xenoprof_op(op, arg);
-+              break;
-+
-+      default:
-+              printk("%s: op %d isn't supported\n", __func__, op);
-+              return -ENOSYS;
-+      }
-+      return xencomm_arch_hypercall_xenoprof_op(op,
-+                                                xencomm_create_inline(arg));
-+}
-+
-+int
-+xencomm_hypercall_perfmon_op(unsigned long cmd, void* arg, unsigned long count)
-+{
-+      switch (cmd) {
-+      case PFM_GET_FEATURES:
-+      case PFM_CREATE_CONTEXT:
-+      case PFM_WRITE_PMCS:
-+      case PFM_WRITE_PMDS:
-+      case PFM_LOAD_CONTEXT:
-+              break;
-+
-+      case PFM_DESTROY_CONTEXT:
-+      case PFM_UNLOAD_CONTEXT:
-+      case PFM_START:
-+      case PFM_STOP:
-+              return xencomm_arch_hypercall_perfmon_op(cmd, arg, count);
-+
-+      default:
-+              printk("%s:%d cmd %ld isn't supported\n",
-+                     __func__,__LINE__, cmd);
-+              BUG();
-+      }
-+
-+      return xencomm_arch_hypercall_perfmon_op(cmd,
-+                                               xencomm_create_inline(arg),
-+                                               count);
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xcom_mini.c linux-2.6.16.33/arch/ia64/xen/xcom_mini.c
---- linux-2.6.16.33-noxen/arch/ia64/xen/xcom_mini.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xcom_mini.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,417 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-+ *
-+ *          Tristan Gingold <tristan.gingold@bull.net>
-+ */
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/dom0_ops.h>
-+#include <xen/interface/memory.h>
-+#include <xen/interface/xencomm.h>
-+#include <xen/interface/version.h>
-+#include <xen/interface/event_channel.h>
-+#include <xen/interface/physdev.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/interface/hvm/params.h>
-+#include <xen/interface/xenoprof.h>
-+#ifdef CONFIG_VMX_GUEST
-+#include <asm/hypervisor.h>
-+#else
-+#include <asm/hypercall.h>
-+#endif
-+#include <asm/xen/xencomm.h>
-+#include <asm/perfmon.h>
-+
-+int
-+xencomm_mini_hypercall_event_channel_op(int cmd, void *op)
-+{
-+      struct xencomm_mini xc_area[2];
-+      int nbr_area = 2;
-+      struct xencomm_handle *desc;
-+      int rc;
-+
-+      rc = xencomm_create_mini(xc_area, &nbr_area,
-+                               op, sizeof(evtchn_op_t), &desc);
-+      if (rc)
-+              return rc;
-+
-+      return xencomm_arch_hypercall_event_channel_op(cmd, desc);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_event_channel_op);
-+
-+static int
-+xencommize_mini_grant_table_op(struct xencomm_mini *xc_area, int *nbr_area,
-+                               unsigned int cmd, void *op, unsigned int count,
-+                               struct xencomm_handle **desc)
-+{
-+      struct xencomm_handle *desc1;
-+      unsigned int argsize;
-+      int rc;
-+
-+      switch (cmd) {
-+      case GNTTABOP_map_grant_ref:
-+              argsize = sizeof(struct gnttab_map_grant_ref);
-+              break;
-+      case GNTTABOP_unmap_grant_ref:
-+              argsize = sizeof(struct gnttab_unmap_grant_ref);
-+              break;
-+      case GNTTABOP_setup_table:
-+      {
-+              struct gnttab_setup_table *setup = op;
-+
-+              argsize = sizeof(*setup);
-+
-+              if (count != 1)
-+                      return -EINVAL;
-+              rc = xencomm_create_mini
-+                      (xc_area, nbr_area,
-+                       xen_guest_handle(setup->frame_list),
-+                       setup->nr_frames 
-+                       * sizeof(*xen_guest_handle(setup->frame_list)),
-+                       &desc1);
-+              if (rc)
-+                      return rc;
-+              set_xen_guest_handle(setup->frame_list, (void *)desc1);
-+              break;
-+      }
-+      case GNTTABOP_dump_table:
-+              argsize = sizeof(struct gnttab_dump_table);
-+              break;
-+      case GNTTABOP_transfer:
-+              argsize = sizeof(struct gnttab_transfer);
-+              break;
-+      case GNTTABOP_copy:
-+              argsize = sizeof(struct gnttab_copy);
-+              break;
-+      default:
-+              printk("%s: unknown mini grant table op %d\n", __func__, cmd);
-+              BUG();
-+      }
-+
-+      rc = xencomm_create_mini(xc_area, nbr_area, op, count * argsize, desc);
-+      if (rc)
-+              return rc;
-+
-+      return 0;
-+}
-+
-+int
-+xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op,
-+                                      unsigned int count)
-+{
-+      int rc;
-+      struct xencomm_handle *desc;
-+      int nbr_area = 2;
-+      struct xencomm_mini xc_area[2];
-+
-+      rc = xencommize_mini_grant_table_op(xc_area, &nbr_area,
-+                                          cmd, op, count, &desc);
-+      if (rc)
-+              return rc;
-+
-+      return xencomm_arch_hypercall_grant_table_op(cmd, desc, count);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_grant_table_op);
-+
-+int
-+xencomm_mini_hypercall_multicall(void *call_list, int nr_calls)
-+{
-+      int i;
-+      multicall_entry_t *mce;
-+      int nbr_area = 2 + nr_calls * 3;
-+      struct xencomm_mini xc_area[nbr_area];
-+      struct xencomm_handle *desc;
-+      int rc;
-+
-+      for (i = 0; i < nr_calls; i++) {
-+              mce = (multicall_entry_t *)call_list + i;
-+
-+              switch (mce->op) {
-+              case __HYPERVISOR_update_va_mapping:
-+              case __HYPERVISOR_mmu_update:
-+                      /* No-op on ia64.  */
-+                      break;
-+              case __HYPERVISOR_grant_table_op:
-+                      rc = xencommize_mini_grant_table_op
-+                              (xc_area, &nbr_area,
-+                               mce->args[0], (void *)mce->args[1],
-+                               mce->args[2], &desc);
-+                      if (rc)
-+                              return rc;
-+                      mce->args[1] = (unsigned long)desc;
-+                      break;
-+              case __HYPERVISOR_memory_op:
-+              default:
-+                      printk("%s: unhandled multicall op entry op %lu\n",
-+                             __func__, mce->op);
-+                      return -ENOSYS;
-+              }
-+      }
-+
-+      rc = xencomm_create_mini(xc_area, &nbr_area, call_list,
-+                               nr_calls * sizeof(multicall_entry_t), &desc);
-+      if (rc)
-+              return rc;
-+
-+      return xencomm_arch_hypercall_multicall(desc, nr_calls);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_multicall);
-+
-+static int
-+xencommize_mini_memory_reservation(struct xencomm_mini *area, int *nbr_area,
-+                                   xen_memory_reservation_t *mop)
-+{
-+      struct xencomm_handle *desc;
-+      int rc;
-+
-+      rc = xencomm_create_mini
-+              (area, nbr_area,
-+               xen_guest_handle(mop->extent_start),
-+               mop->nr_extents 
-+               * sizeof(*xen_guest_handle(mop->extent_start)),
-+               &desc);
-+      if (rc)
-+              return rc;
-+
-+      set_xen_guest_handle(mop->extent_start, (void *)desc);
-+
-+      return 0;
-+}
-+
-+int
-+xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg)
-+{
-+      int nbr_area = 4;
-+      struct xencomm_mini xc_area[4];
-+      struct xencomm_handle *desc;
-+      int rc;
-+      unsigned int argsize;
-+
-+      switch (cmd) {
-+      case XENMEM_increase_reservation:
-+      case XENMEM_decrease_reservation:
-+      case XENMEM_populate_physmap:
-+              argsize = sizeof(xen_memory_reservation_t);
-+              rc = xencommize_mini_memory_reservation
-+                      (xc_area, &nbr_area, (xen_memory_reservation_t *)arg);
-+              if (rc)
-+                      return rc;
-+              break;
-+              
-+      case XENMEM_maximum_ram_page:
-+              argsize = 0;
-+              break;
-+
-+      case XENMEM_exchange:
-+              argsize = sizeof(xen_memory_exchange_t);
-+              rc = xencommize_mini_memory_reservation
-+                      (xc_area, &nbr_area,
-+                       &((xen_memory_exchange_t *)arg)->in);
-+              if (rc)
-+                      return rc;
-+              rc = xencommize_mini_memory_reservation
-+                      (xc_area, &nbr_area,
-+                       &((xen_memory_exchange_t *)arg)->out);
-+              if (rc)
-+                      return rc;
-+              break;
-+
-+      case XENMEM_add_to_physmap:
-+              argsize = sizeof (xen_add_to_physmap_t);
-+              break;
-+
-+      default:
-+              printk("%s: unknown mini memory op %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+
-+      rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+      if (rc)
-+              return rc;
-+
-+      return xencomm_arch_hypercall_memory_op(cmd, desc);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_memory_op);
-+
-+unsigned long
-+xencomm_mini_hypercall_hvm_op(int cmd, void *arg)
-+{
-+      struct xencomm_handle *desc;
-+      int nbr_area = 2;
-+      struct xencomm_mini xc_area[2];
-+      unsigned int argsize;
-+      int rc;
-+
-+      switch (cmd) {
-+      case HVMOP_get_param:
-+      case HVMOP_set_param:
-+              argsize = sizeof(xen_hvm_param_t);
-+              break;
-+      default:
-+              printk("%s: unknown HVMOP %d\n", __func__, cmd);
-+              return -EINVAL;
-+      }
-+
-+      rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+      if (rc)
-+              return rc;
-+
-+      return xencomm_arch_hypercall_hvm_op(cmd, desc);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_hvm_op);
-+
-+int
-+xencomm_mini_hypercall_xen_version(int cmd, void *arg)
-+{
-+      struct xencomm_handle *desc;
-+      int nbr_area = 2;
-+      struct xencomm_mini xc_area[2];
-+      unsigned int argsize;
-+      int rc;
-+
-+      switch (cmd) {
-+      case XENVER_version:
-+              /* do not actually pass an argument */
-+              return xencomm_arch_hypercall_xen_version(cmd, 0);
-+      case XENVER_extraversion:
-+              argsize = sizeof(xen_extraversion_t);
-+              break;
-+      case XENVER_compile_info:
-+              argsize = sizeof(xen_compile_info_t);
-+              break;
-+      case XENVER_capabilities:
-+              argsize = sizeof(xen_capabilities_info_t);
-+              break;
-+      case XENVER_changeset:
-+              argsize = sizeof(xen_changeset_info_t);
-+              break;
-+      case XENVER_platform_parameters:
-+              argsize = sizeof(xen_platform_parameters_t);
-+              break;
-+      case XENVER_pagesize:
-+              argsize = (arg == NULL) ? 0 : sizeof(void *);
-+              break;
-+      case XENVER_get_features:
-+              argsize = (arg == NULL) ? 0 : sizeof(xen_feature_info_t);
-+              break;
-+
-+      default:
-+              printk("%s: unknown version op %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+
-+      rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+      if (rc)
-+              return rc;
-+
-+      return xencomm_arch_hypercall_xen_version(cmd, desc);
-+}
-+EXPORT_SYMBOL(xencomm_mini_hypercall_xen_version);
-+
-+int
-+xencomm_mini_hypercall_xenoprof_op(int op, void *arg)
-+{
-+      unsigned int argsize;
-+      struct xencomm_mini xc_area[2];
-+      int nbr_area = 2;
-+      struct xencomm_handle *desc;
-+      int rc;
-+
-+      switch (op) {
-+      case XENOPROF_init:
-+              argsize = sizeof(xenoprof_init_t);
-+              break;
-+      case XENOPROF_set_active:
-+              argsize = sizeof(domid_t);
-+              break;
-+      case XENOPROF_set_passive:
-+              argsize = sizeof(xenoprof_passive_t);
-+              break;
-+      case XENOPROF_counter:
-+              argsize = sizeof(xenoprof_counter_t);
-+              break;
-+      case XENOPROF_get_buffer:
-+              argsize = sizeof(xenoprof_get_buffer_t);
-+              break;
-+
-+      case XENOPROF_reset_active_list:
-+      case XENOPROF_reset_passive_list:
-+      case XENOPROF_reserve_counters:
-+      case XENOPROF_setup_events:
-+      case XENOPROF_enable_virq:
-+      case XENOPROF_start:
-+      case XENOPROF_stop:
-+      case XENOPROF_disable_virq:
-+      case XENOPROF_release_counters:
-+      case XENOPROF_shutdown:
-+              return xencomm_arch_hypercall_xenoprof_op(op, arg);
-+
-+      default:
-+              printk("%s: op %d isn't supported\n", __func__, op);
-+              return -ENOSYS;
-+      }
-+      rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+      if (rc)
-+              return rc;
-+      return xencomm_arch_hypercall_xenoprof_op(op, desc);
-+}
-+EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_xenoprof_op);
-+
-+int
-+xencomm_mini_hypercall_perfmon_op(unsigned long cmd, void* arg,
-+                                  unsigned long count)
-+{
-+      unsigned int argsize;
-+      struct xencomm_mini xc_area[2];
-+      int nbr_area = 2;
-+      struct xencomm_handle *desc;
-+      int rc;
-+
-+      switch (cmd) {
-+      case PFM_GET_FEATURES:
-+              argsize = sizeof(pfarg_features_t);
-+              break;
-+      case PFM_CREATE_CONTEXT:
-+              argsize = sizeof(pfarg_context_t);
-+              break;
-+      case PFM_LOAD_CONTEXT:
-+              argsize = sizeof(pfarg_load_t);
-+              break;
-+      case PFM_WRITE_PMCS:
-+      case PFM_WRITE_PMDS:
-+              argsize = sizeof(pfarg_reg_t) * count;
-+              break;
-+
-+      case PFM_DESTROY_CONTEXT:
-+      case PFM_UNLOAD_CONTEXT:
-+      case PFM_START:
-+      case PFM_STOP:
-+              return xencomm_arch_hypercall_perfmon_op(cmd, arg, count);
-+
-+      default:
-+              printk("%s:%d cmd %ld isn't supported\n",
-+                     __func__, __LINE__, cmd);
-+              BUG();
-+      }
-+
-+      rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc);
-+      if (rc)
-+              return rc;
-+      return xencomm_arch_hypercall_perfmon_op(cmd, desc, count);
-+}
-+EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_perfmon_op);
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xcom_privcmd.c linux-2.6.16.33/arch/ia64/xen/xcom_privcmd.c
---- linux-2.6.16.33-noxen/arch/ia64/xen/xcom_privcmd.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xcom_privcmd.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,663 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-+ *
-+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
-+ *          Tristan Gingold <tristan.gingold@bull.net>
-+ */
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/gfp.h>
-+#include <linux/module.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/dom0_ops.h>
-+#define __XEN__
-+#include <xen/interface/domctl.h>
-+#include <xen/interface/sysctl.h>
-+#include <xen/interface/memory.h>
-+#include <xen/interface/version.h>
-+#include <xen/interface/event_channel.h>
-+#include <xen/interface/acm_ops.h>
-+#include <xen/interface/hvm/params.h>
-+#include <xen/public/privcmd.h>
-+#include <asm/hypercall.h>
-+#include <asm/page.h>
-+#include <asm/uaccess.h>
-+#include <asm/xen/xencomm.h>
-+
-+#define ROUND_DIV(v,s) (((v) + (s) - 1) / (s))
-+
-+static int
-+xencomm_privcmd_dom0_op(privcmd_hypercall_t *hypercall)
-+{
-+      dom0_op_t kern_op;
-+      dom0_op_t __user *user_op = (dom0_op_t __user *)hypercall->arg[0];
-+      struct xencomm_handle *op_desc;
-+      struct xencomm_handle *desc = NULL;
-+      int ret = 0;
-+
-+      if (copy_from_user(&kern_op, user_op, sizeof(dom0_op_t)))
-+              return -EFAULT;
-+
-+      if (kern_op.interface_version != DOM0_INTERFACE_VERSION)
-+              return -EACCES;
-+
-+      op_desc = xencomm_create_inline(&kern_op);
-+
-+      switch (kern_op.cmd) {
-+      default:
-+              printk("%s: unknown dom0 cmd %d\n", __func__, kern_op.cmd);
-+              return -ENOSYS;
-+      }
-+
-+      if (ret) {
-+              /* error mapping the nested pointer */
-+              return ret;
-+      }
-+
-+      ret = xencomm_arch_hypercall_dom0_op(op_desc);
-+
-+      /* FIXME: should we restore the handle?  */
-+      if (copy_to_user(user_op, &kern_op, sizeof(dom0_op_t)))
-+              ret = -EFAULT;
-+
-+      if (desc)
-+              xencomm_free(desc);
-+      return ret;
-+}
-+
-+/*
-+ * Temporarily disable the NUMA PHYSINFO code until the rest of the
-+ * changes are upstream.
-+ */
-+#undef IA64_NUMA_PHYSINFO
-+
-+static int
-+xencomm_privcmd_sysctl(privcmd_hypercall_t *hypercall)
-+{
-+      xen_sysctl_t kern_op;
-+      xen_sysctl_t __user *user_op;
-+      struct xencomm_handle *op_desc;
-+      struct xencomm_handle *desc = NULL;
-+      struct xencomm_handle *desc1 = NULL;
-+      int ret = 0;
-+
-+      user_op = (xen_sysctl_t __user *)hypercall->arg[0];
-+
-+      if (copy_from_user(&kern_op, user_op, sizeof(xen_sysctl_t)))
-+              return -EFAULT;
-+
-+      if (kern_op.interface_version != XEN_SYSCTL_INTERFACE_VERSION)
-+              return -EACCES;
-+
-+      op_desc = xencomm_create_inline(&kern_op);
-+
-+      switch (kern_op.cmd) {
-+      case XEN_SYSCTL_readconsole:
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.readconsole.buffer),
-+                      kern_op.u.readconsole.count,
-+                      &desc, GFP_KERNEL);
-+              set_xen_guest_handle(kern_op.u.readconsole.buffer,
-+                                   (void *)desc);
-+              break;
-+      case XEN_SYSCTL_tbuf_op:
-+#ifndef IA64_NUMA_PHYSINFO
-+      case XEN_SYSCTL_physinfo:
-+#endif
-+      case XEN_SYSCTL_sched_id:
-+              break;
-+      case XEN_SYSCTL_perfc_op:
-+      {
-+              struct xencomm_handle *tmp_desc;
-+              xen_sysctl_t tmp_op = {
-+                      .cmd = XEN_SYSCTL_perfc_op,
-+                      .interface_version = XEN_SYSCTL_INTERFACE_VERSION,
-+                      .u.perfc_op = {
-+                              .cmd = XEN_SYSCTL_PERFCOP_query,
-+                              // .desc.p = NULL,
-+                              // .val.p = NULL,
-+                      },
-+              };
-+
-+              if (xen_guest_handle(kern_op.u.perfc_op.desc) == NULL) {
-+                      if (xen_guest_handle(kern_op.u.perfc_op.val) != NULL)
-+                              return -EINVAL;
-+                      break;
-+              }
-+
-+              /* query the buffer size for xencomm */
-+              tmp_desc = xencomm_create_inline(&tmp_op);
-+              ret = xencomm_arch_hypercall_sysctl(tmp_desc);
-+              if (ret)
-+                      return ret;
-+
-+              ret = xencomm_create(xen_guest_handle(kern_op.u.perfc_op.desc),
-+                                   tmp_op.u.perfc_op.nr_counters *
-+                                   sizeof(xen_sysctl_perfc_desc_t),
-+                                   &desc, GFP_KERNEL);
-+              if (ret)
-+                      return ret;
-+
-+              set_xen_guest_handle(kern_op.u.perfc_op.desc, (void *)desc);
-+
-+              ret = xencomm_create(xen_guest_handle(kern_op.u.perfc_op.val),
-+                                   tmp_op.u.perfc_op.nr_vals *
-+                                   sizeof(xen_sysctl_perfc_val_t),
-+                                   &desc1, GFP_KERNEL);
-+              if (ret)
-+                      xencomm_free(desc);
-+
-+              set_xen_guest_handle(kern_op.u.perfc_op.val, (void *)desc1);
-+              break;
-+      }
-+      case XEN_SYSCTL_getdomaininfolist:
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.getdomaininfolist.buffer),
-+                      kern_op.u.getdomaininfolist.max_domains *
-+                      sizeof(xen_domctl_getdomaininfo_t),
-+                      &desc, GFP_KERNEL);
-+              set_xen_guest_handle(kern_op.u.getdomaininfolist.buffer,
-+                                   (void *)desc);
-+              break;
-+#ifdef IA64_NUMA_PHYSINFO
-+      case XEN_SYSCTL_physinfo:
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.physinfo.memory_chunks),
-+                      PUBLIC_MAXCHUNKS * sizeof(node_data_t),
-+                      &desc, GFP_KERNEL);
-+              if (ret)
-+                      return ret;
-+              set_xen_guest_handle(kern_op.u.physinfo.memory_chunks,
-+                                   (void *)desc);
-+
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.physinfo.cpu_to_node),
-+                      PUBLIC_MAX_NUMNODES * sizeof(u64),
-+                      &desc1, GFP_KERNEL);
-+              if (ret)
-+                      xencomm_free(desc);
-+              set_xen_guest_handle(kern_op.u.physinfo.cpu_to_node,
-+                                   (void *)desc1);
-+              break;
-+#endif
-+      default:
-+              printk("%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
-+              return -ENOSYS;
-+      }
-+
-+      if (ret) {
-+              /* error mapping the nested pointer */
-+              return ret;
-+      }
-+
-+      ret = xencomm_arch_hypercall_sysctl(op_desc);
-+
-+      /* FIXME: should we restore the handles?  */
-+      if (copy_to_user(user_op, &kern_op, sizeof(xen_sysctl_t)))
-+              ret = -EFAULT;
-+
-+      if (desc)
-+              xencomm_free(desc);
-+      if (desc1)
-+              xencomm_free(desc1);
-+      return ret;
-+}
-+
-+static int
-+xencomm_privcmd_domctl(privcmd_hypercall_t *hypercall)
-+{
-+      xen_domctl_t kern_op;
-+      xen_domctl_t __user *user_op;
-+      struct xencomm_handle *op_desc;
-+      struct xencomm_handle *desc = NULL;
-+      int ret = 0;
-+
-+      user_op = (xen_domctl_t __user *)hypercall->arg[0];
-+
-+      if (copy_from_user(&kern_op, user_op, sizeof(xen_domctl_t)))
-+              return -EFAULT;
-+
-+      if (kern_op.interface_version != XEN_DOMCTL_INTERFACE_VERSION)
-+              return -EACCES;
-+
-+      op_desc = xencomm_create_inline(&kern_op);
-+
-+      switch (kern_op.cmd) {
-+      case XEN_DOMCTL_createdomain:
-+      case XEN_DOMCTL_destroydomain:
-+      case XEN_DOMCTL_pausedomain:
-+      case XEN_DOMCTL_unpausedomain:
-+      case XEN_DOMCTL_getdomaininfo:
-+              break;
-+      case XEN_DOMCTL_getmemlist:
-+      {
-+              unsigned long nr_pages = kern_op.u.getmemlist.max_pfns;
-+
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.getmemlist.buffer),
-+                      nr_pages * sizeof(unsigned long),
-+                      &desc, GFP_KERNEL);
-+              set_xen_guest_handle(kern_op.u.getmemlist.buffer,
-+                                   (void *)desc);
-+              break;
-+      }
-+      case XEN_DOMCTL_getpageframeinfo:
-+              break;
-+      case XEN_DOMCTL_getpageframeinfo2:
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.getpageframeinfo2.array),
-+                      kern_op.u.getpageframeinfo2.num,
-+                      &desc, GFP_KERNEL);
-+              set_xen_guest_handle(kern_op.u.getpageframeinfo2.array,
-+                                   (void *)desc);
-+              break;
-+      case XEN_DOMCTL_shadow_op:
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap),
-+                      ROUND_DIV(kern_op.u.shadow_op.pages, 8),
-+                      &desc, GFP_KERNEL);
-+              set_xen_guest_handle(kern_op.u.shadow_op.dirty_bitmap,
-+                                   (void *)desc);
-+              break;
-+      case XEN_DOMCTL_max_mem:
-+              break;
-+      case XEN_DOMCTL_setvcpucontext:
-+      case XEN_DOMCTL_getvcpucontext:
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.vcpucontext.ctxt),
-+                      sizeof(vcpu_guest_context_t),
-+                      &desc, GFP_KERNEL);
-+              set_xen_guest_handle(kern_op.u.vcpucontext.ctxt, (void *)desc);
-+              break;
-+      case XEN_DOMCTL_getvcpuinfo:
-+              break;
-+      case XEN_DOMCTL_setvcpuaffinity:
-+      case XEN_DOMCTL_getvcpuaffinity:
-+              ret = xencomm_create(
-+                      xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap),
-+                      ROUND_DIV(kern_op.u.vcpuaffinity.cpumap.nr_cpus, 8),
-+                      &desc, GFP_KERNEL);
-+              set_xen_guest_handle(kern_op.u.vcpuaffinity.cpumap.bitmap,
-+                                   (void *)desc);
-+              break;
-+      case XEN_DOMCTL_max_vcpus:
-+      case XEN_DOMCTL_scheduler_op:
-+      case XEN_DOMCTL_setdomainhandle:
-+      case XEN_DOMCTL_setdebugging:
-+      case XEN_DOMCTL_irq_permission:
-+      case XEN_DOMCTL_iomem_permission:
-+      case XEN_DOMCTL_ioport_permission:
-+      case XEN_DOMCTL_hypercall_init:
-+      case XEN_DOMCTL_arch_setup:
-+      case XEN_DOMCTL_settimeoffset:
-+              break;
-+      default:
-+              printk("%s: unknown domctl cmd %d\n", __func__, kern_op.cmd);
-+              return -ENOSYS;
-+      }
-+
-+      if (ret) {
-+              /* error mapping the nested pointer */
-+              return ret;
-+      }
-+
-+      ret = xencomm_arch_hypercall_domctl (op_desc);
-+
-+      /* FIXME: should we restore the handle?  */
-+      if (copy_to_user(user_op, &kern_op, sizeof(xen_domctl_t)))
-+              ret = -EFAULT;
-+
-+      if (desc)
-+              xencomm_free(desc);
-+      return ret;
-+}
-+
-+static int
-+xencomm_privcmd_acm_op(privcmd_hypercall_t *hypercall)
-+{
-+      int cmd = hypercall->arg[0];
-+      void __user *arg = (void __user *)hypercall->arg[1];
-+      struct xencomm_handle *op_desc;
-+      struct xencomm_handle *desc = NULL;
-+      int ret;
-+
-+      switch (cmd) {
-+      case ACMOP_getssid:
-+      {
-+              struct acm_getssid kern_arg;
-+
-+              if (copy_from_user(&kern_arg, arg, sizeof (kern_arg)))
-+                      return -EFAULT;
-+
-+              op_desc = xencomm_create_inline(&kern_arg);
-+
-+              ret = xencomm_create(xen_guest_handle(kern_arg.ssidbuf),
-+                                   kern_arg.ssidbuf_size, &desc, GFP_KERNEL);
-+              if (ret)
-+                      return ret;
-+
-+              set_xen_guest_handle(kern_arg.ssidbuf, (void *)desc);
-+
-+              ret = xencomm_arch_hypercall_acm_op(cmd, op_desc);
-+
-+              xencomm_free(desc);
-+
-+              if (copy_to_user(arg, &kern_arg, sizeof (kern_arg)))
-+                      return -EFAULT;
-+
-+              return ret;
-+      }
-+      default:
-+              printk("%s: unknown acm_op cmd %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+
-+      return ret;
-+}
-+
-+static int
-+xencomm_privcmd_memory_op(privcmd_hypercall_t *hypercall)
-+{
-+      const unsigned long cmd = hypercall->arg[0];
-+      int ret = 0;
-+
-+      switch (cmd) {
-+      case XENMEM_increase_reservation:
-+      case XENMEM_decrease_reservation:
-+      case XENMEM_populate_physmap:
-+      {
-+              xen_memory_reservation_t kern_op;
-+              xen_memory_reservation_t __user *user_op;
-+              struct xencomm_handle *desc = NULL;
-+              struct xencomm_handle *desc_op;
-+
-+              user_op = (xen_memory_reservation_t __user *)hypercall->arg[1];
-+              if (copy_from_user(&kern_op, user_op,
-+                                 sizeof(xen_memory_reservation_t)))
-+                      return -EFAULT;
-+              desc_op = xencomm_create_inline(&kern_op);
-+
-+              if (xen_guest_handle(kern_op.extent_start)) {
-+                      void * addr;
-+
-+                      addr = xen_guest_handle(kern_op.extent_start);
-+                      ret = xencomm_create
-+                              (addr,
-+                               kern_op.nr_extents *
-+                               sizeof(*xen_guest_handle
-+                                      (kern_op.extent_start)),
-+                               &desc, GFP_KERNEL);
-+                      if (ret)
-+                              return ret;
-+                      set_xen_guest_handle(kern_op.extent_start,
-+                                           (void *)desc);
-+              }
-+
-+              ret = xencomm_arch_hypercall_memory_op(cmd, desc_op);
-+
-+              if (desc)
-+                      xencomm_free(desc);
-+
-+              if (ret != 0)
-+                      return ret;
-+
-+              if (copy_to_user(user_op, &kern_op,
-+                               sizeof(xen_memory_reservation_t)))
-+                      return -EFAULT;
-+
-+              return ret;
-+      }
-+      case XENMEM_translate_gpfn_list:
-+      {
-+              xen_translate_gpfn_list_t kern_op;
-+              xen_translate_gpfn_list_t __user *user_op;
-+              struct xencomm_handle *desc_gpfn = NULL;
-+              struct xencomm_handle *desc_mfn = NULL;
-+              struct xencomm_handle *desc_op;
-+              void *addr;
-+
-+              user_op = (xen_translate_gpfn_list_t __user *)
-+                      hypercall->arg[1];
-+              if (copy_from_user(&kern_op, user_op,
-+                                 sizeof(xen_translate_gpfn_list_t)))
-+                      return -EFAULT;
-+              desc_op = xencomm_create_inline(&kern_op);
-+
-+              if (kern_op.nr_gpfns) {
-+                      /* gpfn_list.  */
-+                      addr = xen_guest_handle(kern_op.gpfn_list);
-+
-+                      ret = xencomm_create(addr, kern_op.nr_gpfns *
-+                                           sizeof(*xen_guest_handle
-+                                                  (kern_op.gpfn_list)),
-+                                           &desc_gpfn, GFP_KERNEL);
-+                      if (ret)
-+                              return ret;
-+                      set_xen_guest_handle(kern_op.gpfn_list,
-+                                           (void *)desc_gpfn);
-+
-+                      /* mfn_list.  */
-+                      addr = xen_guest_handle(kern_op.mfn_list);
-+
-+                      ret = xencomm_create(addr, kern_op.nr_gpfns *
-+                                           sizeof(*xen_guest_handle
-+                                                  (kern_op.mfn_list)),
-+                                           &desc_mfn, GFP_KERNEL);
-+                      if (ret)
-+                              return ret;
-+                      set_xen_guest_handle(kern_op.mfn_list,
-+                                           (void *)desc_mfn);
-+              }
-+
-+              ret = xencomm_arch_hypercall_memory_op(cmd, desc_op);
-+
-+              if (desc_gpfn)
-+                      xencomm_free(desc_gpfn);
-+
-+              if (desc_mfn)
-+                      xencomm_free(desc_mfn);
-+
-+              if (ret != 0)
-+                      return ret;
-+
-+              return ret;
-+      }
-+      default:
-+              printk("%s: unknown memory op %lu\n", __func__, cmd);
-+              ret = -ENOSYS;
-+      }
-+      return ret;
-+}
-+
-+static int
-+xencomm_privcmd_xen_version(privcmd_hypercall_t *hypercall)
-+{
-+      int cmd = hypercall->arg[0];
-+      void __user *arg = (void __user *)hypercall->arg[1];
-+      struct xencomm_handle *desc;
-+      size_t argsize;
-+      int rc;
-+
-+      switch (cmd) {
-+      case XENVER_version:
-+              /* do not actually pass an argument */
-+              return xencomm_arch_hypercall_xen_version(cmd, 0);
-+      case XENVER_extraversion:
-+              argsize = sizeof(xen_extraversion_t);
-+              break;
-+      case XENVER_compile_info:
-+              argsize = sizeof(xen_compile_info_t);
-+              break;
-+      case XENVER_capabilities:
-+              argsize = sizeof(xen_capabilities_info_t);
-+              break;
-+      case XENVER_changeset:
-+              argsize = sizeof(xen_changeset_info_t);
-+              break;
-+      case XENVER_platform_parameters:
-+              argsize = sizeof(xen_platform_parameters_t);
-+              break;
-+      case XENVER_pagesize:
-+              argsize = (arg == NULL) ? 0 : sizeof(void *);
-+              break;
-+      case XENVER_get_features:
-+              argsize = (arg == NULL) ? 0 : sizeof(xen_feature_info_t);
-+              break;
-+
-+      default:
-+              printk("%s: unknown version op %d\n", __func__, cmd);
-+              return -ENOSYS;
-+      }
-+
-+      rc = xencomm_create(arg, argsize, &desc, GFP_KERNEL);
-+      if (rc)
-+              return rc;
-+
-+      rc = xencomm_arch_hypercall_xen_version(cmd, desc);
-+
-+      xencomm_free(desc);
-+
-+      return rc;
-+}
-+
-+static int
-+xencomm_privcmd_event_channel_op(privcmd_hypercall_t *hypercall)
-+{
-+      int cmd = hypercall->arg[0];
-+      struct xencomm_handle *desc;
-+      unsigned int argsize;
-+      int ret;
-+
-+      switch (cmd) {
-+      case EVTCHNOP_alloc_unbound:
-+              argsize = sizeof(evtchn_alloc_unbound_t);
-+              break;
-+
-+      case EVTCHNOP_status:
-+              argsize = sizeof(evtchn_status_t);
-+              break;
-+
-+      default:
-+              printk("%s: unknown EVTCHNOP %d\n", __func__, cmd);
-+              return -EINVAL;
-+      }
-+
-+      ret = xencomm_create((void *)hypercall->arg[1], argsize,
-+                           &desc, GFP_KERNEL);
-+      if (ret)
-+              return ret;
-+
-+      ret = xencomm_arch_hypercall_event_channel_op(cmd, desc);
-+
-+      xencomm_free(desc);
-+      return ret;
-+}
-+
-+static int
-+xencomm_privcmd_hvm_op(privcmd_hypercall_t *hypercall)
-+{
-+      int cmd = hypercall->arg[0];
-+      struct xencomm_handle *desc;
-+      unsigned int argsize;
-+      int ret;
-+
-+      switch (cmd) {
-+      case HVMOP_get_param:
-+      case HVMOP_set_param:
-+              argsize = sizeof(xen_hvm_param_t);
-+              break;
-+      case HVMOP_set_pci_intx_level:
-+              argsize = sizeof(xen_hvm_set_pci_intx_level_t);
-+              break;
-+      case HVMOP_set_isa_irq_level:
-+              argsize = sizeof(xen_hvm_set_isa_irq_level_t);
-+              break;
-+      case HVMOP_set_pci_link_route:
-+              argsize = sizeof(xen_hvm_set_pci_link_route_t);
-+              break;
-+
-+      default:
-+              printk("%s: unknown HVMOP %d\n", __func__, cmd);
-+              return -EINVAL;
-+      }
-+
-+      ret = xencomm_create((void *)hypercall->arg[1], argsize,
-+                           &desc, GFP_KERNEL);
-+      if (ret)
-+              return ret;
-+
-+      ret = xencomm_arch_hypercall_hvm_op(cmd, desc);
-+
-+      xencomm_free(desc);
-+      return ret;
-+}
-+
-+static int
-+xencomm_privcmd_sched_op(privcmd_hypercall_t *hypercall)
-+{
-+      int cmd = hypercall->arg[0];
-+      struct xencomm_handle *desc;
-+      unsigned int argsize;
-+      int ret;
-+
-+      switch (cmd) {
-+      case SCHEDOP_remote_shutdown:
-+              argsize = sizeof(sched_remote_shutdown_t);
-+              break;
-+      default:
-+              printk("%s: unknown SCHEDOP %d\n", __func__, cmd);
-+              return -EINVAL;
-+      }
-+
-+      ret = xencomm_create((void *)hypercall->arg[1], argsize,
-+                           &desc, GFP_KERNEL);
-+      if (ret)
-+              return ret;
-+
-+      ret = xencomm_arch_hypercall_sched_op(cmd, desc);
-+
-+      xencomm_free(desc);
-+      return ret;
-+}
-+
-+int
-+privcmd_hypercall(privcmd_hypercall_t *hypercall)
-+{
-+      switch (hypercall->op) {
-+      case __HYPERVISOR_dom0_op:
-+              return xencomm_privcmd_dom0_op(hypercall);
-+      case __HYPERVISOR_domctl:
-+              return xencomm_privcmd_domctl(hypercall);
-+      case __HYPERVISOR_sysctl:
-+              return xencomm_privcmd_sysctl(hypercall);
-+        case __HYPERVISOR_acm_op:
-+              return xencomm_privcmd_acm_op(hypercall);
-+      case __HYPERVISOR_xen_version:
-+              return xencomm_privcmd_xen_version(hypercall);
-+      case __HYPERVISOR_memory_op:
-+              return xencomm_privcmd_memory_op(hypercall);
-+      case __HYPERVISOR_event_channel_op:
-+              return xencomm_privcmd_event_channel_op(hypercall);
-+      case __HYPERVISOR_hvm_op:
-+              return xencomm_privcmd_hvm_op(hypercall);
-+      case __HYPERVISOR_sched_op:
-+              return xencomm_privcmd_sched_op(hypercall);
-+      default:
-+              printk("%s: unknown hcall (%ld)\n", __func__, hypercall->op);
-+              return -ENOSYS;
-+      }
-+}
-+
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xencomm.c linux-2.6.16.33/arch/ia64/xen/xencomm.c
---- linux-2.6.16.33-noxen/arch/ia64/xen/xencomm.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xencomm.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,263 @@
-+/*
-+ * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ * 
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ * 
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-+ */
-+
-+#include <linux/gfp.h>
-+#include <linux/mm.h>
-+#include <xen/interface/xen.h>
-+#include <asm/page.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+#include <asm/xen/xencomm.h>
-+
-+static int xencomm_debug = 0;
-+
-+static unsigned long kernel_start_pa;
-+
-+void
-+xencomm_init (void)
-+{
-+      kernel_start_pa = KERNEL_START - ia64_tpa(KERNEL_START);
-+}
-+
-+/* Translate virtual address to physical address.  */
-+unsigned long
-+xencomm_vaddr_to_paddr(unsigned long vaddr)
-+{
-+#ifndef CONFIG_VMX_GUEST
-+      struct page *page;
-+      struct vm_area_struct *vma;
-+#endif
-+
-+      if (vaddr == 0)
-+              return 0;
-+
-+#ifdef __ia64__
-+      if (REGION_NUMBER(vaddr) == 5) {
-+              pgd_t *pgd;
-+              pud_t *pud;
-+              pmd_t *pmd;
-+              pte_t *ptep;
-+
-+              /* On ia64, TASK_SIZE refers to current.  It is not initialized
-+                 during boot.
-+                 Furthermore the kernel is relocatable and __pa() doesn't
-+                 work on  addresses.  */
-+              if (vaddr >= KERNEL_START
-+                  && vaddr < (KERNEL_START + KERNEL_TR_PAGE_SIZE)) {
-+                      return vaddr - kernel_start_pa;
-+              }
-+
-+              /* In kernel area -- virtually mapped.  */
-+              pgd = pgd_offset_k(vaddr);
-+              if (pgd_none(*pgd) || pgd_bad(*pgd))
-+                      return ~0UL;
-+
-+              pud = pud_offset(pgd, vaddr);
-+              if (pud_none(*pud) || pud_bad(*pud))
-+                      return ~0UL;
-+
-+              pmd = pmd_offset(pud, vaddr);
-+              if (pmd_none(*pmd) || pmd_bad(*pmd))
-+                      return ~0UL;
-+
-+              ptep = pte_offset_kernel(pmd, vaddr);
-+              if (!ptep)
-+                      return ~0UL;
-+
-+              return (pte_val(*ptep) & _PFN_MASK) | (vaddr & ~PAGE_MASK);
-+      }
-+#endif
-+
-+      if (vaddr > TASK_SIZE) {
-+              /* kernel address */
-+              return __pa(vaddr);
-+      }
-+
-+
-+#ifdef CONFIG_VMX_GUEST
-+      /* No privcmd within vmx guest.  */
-+      return ~0UL;
-+#else
-+      /* XXX double-check (lack of) locking */
-+      vma = find_extend_vma(current->mm, vaddr);
-+      if (!vma)
-+              return ~0UL;
-+
-+      /* We assume the page is modified.  */
-+      page = follow_page(vma, vaddr, FOLL_WRITE | FOLL_TOUCH);
-+      if (!page)
-+              return ~0UL;
-+
-+      return (page_to_pfn(page) << PAGE_SHIFT) | (vaddr & ~PAGE_MASK);
-+#endif
-+}
-+
-+static int
-+xencomm_init_desc(struct xencomm_desc *desc, void *buffer, unsigned long bytes)
-+{
-+      unsigned long recorded = 0;
-+      int i = 0;
-+
-+      BUG_ON((buffer == NULL) && (bytes > 0));
-+
-+      /* record the physical pages used */
-+      if (buffer == NULL)
-+              desc->nr_addrs = 0;
-+
-+      while ((recorded < bytes) && (i < desc->nr_addrs)) {
-+              unsigned long vaddr = (unsigned long)buffer + recorded;
-+              unsigned long paddr;
-+              int offset;
-+              int chunksz;
-+
-+              offset = vaddr % PAGE_SIZE; /* handle partial pages */
-+              chunksz = min(PAGE_SIZE - offset, bytes - recorded);
-+
-+              paddr = xencomm_vaddr_to_paddr(vaddr);
-+              if (paddr == ~0UL) {
-+                      printk("%s: couldn't translate vaddr %lx\n",
-+                             __func__, vaddr);
-+                      return -EINVAL;
-+              }
-+
-+              desc->address[i++] = paddr;
-+              recorded += chunksz;
-+      }
-+
-+      if (recorded < bytes) {
-+              printk("%s: could only translate %ld of %ld bytes\n",
-+                     __func__, recorded, bytes);
-+              return -ENOSPC;
-+      }
-+
-+      /* mark remaining addresses invalid (just for safety) */
-+      while (i < desc->nr_addrs)
-+              desc->address[i++] = XENCOMM_INVALID;
-+
-+      desc->magic = XENCOMM_MAGIC;
-+
-+      return 0;
-+}
-+
-+static struct xencomm_desc *
-+xencomm_alloc(gfp_t gfp_mask)
-+{
-+      struct xencomm_desc *desc;
-+
-+      desc = (struct xencomm_desc *)__get_free_page(gfp_mask);
-+      if (desc == NULL)
-+              panic("%s: page allocation failed\n", __func__);
-+
-+      desc->nr_addrs = (PAGE_SIZE - sizeof(struct xencomm_desc)) /
-+                       sizeof(*desc->address);
-+
-+      return desc;
-+}
-+
-+void
-+xencomm_free(struct xencomm_handle *desc)
-+{
-+      if (desc)
-+              free_page((unsigned long)__va(desc));
-+}
-+
-+int
-+xencomm_create(void *buffer, unsigned long bytes,
-+               struct xencomm_handle **ret, gfp_t gfp_mask)
-+{
-+      struct xencomm_desc *desc;
-+      struct xencomm_handle *handle;
-+      int rc;
-+
-+      if (xencomm_debug)
-+              printk("%s: %p[%ld]\n", __func__, buffer, bytes);
-+
-+      if (buffer == NULL || bytes == 0) {
-+              *ret = (struct xencomm_handle *)NULL;
-+              return 0;
-+      }
-+
-+      desc = xencomm_alloc(gfp_mask);
-+      if (!desc) {
-+              printk("%s failure\n", "xencomm_alloc");
-+              return -ENOMEM;
-+      }
-+      handle = (struct xencomm_handle *)__pa(desc);
-+
-+      rc = xencomm_init_desc(desc, buffer, bytes);
-+      if (rc) {
-+              printk("%s failure: %d\n", "xencomm_init_desc", rc);
-+              xencomm_free(handle);
-+              return rc;
-+      }
-+
-+      *ret = handle;
-+      return 0;
-+}
-+
-+/* "mini" routines, for stack-based communications: */
-+
-+static void *
-+xencomm_alloc_mini(struct xencomm_mini *area, int *nbr_area)
-+{
-+      unsigned long base;
-+      unsigned int pageoffset;
-+
-+      while (*nbr_area >= 0) {
-+              /* Allocate an area.  */
-+              (*nbr_area)--;
-+
-+              base = (unsigned long)(area + *nbr_area);
-+              pageoffset = base % PAGE_SIZE;
-+
-+              /* If the area does not cross a page, use it.  */
-+              if ((PAGE_SIZE - pageoffset) >= sizeof(struct xencomm_mini))
-+                      return &area[*nbr_area];
-+      }
-+      /* No more area.  */
-+      return NULL;
-+}
-+
-+int
-+xencomm_create_mini(struct xencomm_mini *area, int *nbr_area,
-+                    void *buffer, unsigned long bytes,
-+                    struct xencomm_handle **ret)
-+{
-+      struct xencomm_desc *desc;
-+      int rc;
-+      unsigned long res;
-+
-+      desc = xencomm_alloc_mini(area, nbr_area);
-+      if (!desc)
-+              return -ENOMEM;
-+      desc->nr_addrs = XENCOMM_MINI_ADDRS;
-+
-+      rc = xencomm_init_desc(desc, buffer, bytes);
-+      if (rc)
-+              return rc;
-+
-+      res = xencomm_vaddr_to_paddr((unsigned long)desc);
-+      if (res == ~0UL)
-+              return -EINVAL;
-+
-+      *ret = (struct xencomm_handle*)res;
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xenentry.S linux-2.6.16.33/arch/ia64/xen/xenentry.S
---- linux-2.6.16.33-noxen/arch/ia64/xen/xenentry.S     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xenentry.S   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,924 @@
-+/*
-+ * ia64/xen/entry.S
-+ *
-+ * Alternate kernel routines for Xen.  Heavily leveraged from
-+ *   ia64/kernel/entry.S
-+ *
-+ * Copyright (C) 2005 Hewlett-Packard Co
-+ *    Dan Magenheimer <dan.magenheimer@.hp.com>
-+ */
-+
-+#include <linux/config.h>
-+
-+#include <asm/asmmacro.h>
-+#include <asm/cache.h>
-+#include <asm/errno.h>
-+#include <asm/kregs.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/pgtable.h>
-+#include <asm/percpu.h>
-+#include <asm/processor.h>
-+#include <asm/thread_info.h>
-+#include <asm/unistd.h>
-+
-+#ifdef CONFIG_XEN
-+#include "xenminstate.h"
-+#else
-+#include "minstate.h"
-+#endif
-+
-+/*
-+ * prev_task <- ia64_switch_to(struct task_struct *next)
-+ *    With Ingo's new scheduler, interrupts are disabled when this routine gets
-+ *    called.  The code starting at .map relies on this.  The rest of the code
-+ *    doesn't care about the interrupt masking status.
-+ */
-+#ifdef CONFIG_XEN
-+GLOBAL_ENTRY(xen_switch_to)
-+      .prologue
-+      alloc r16=ar.pfs,1,0,0,0
-+      movl r22=running_on_xen;;
-+      ld4 r22=[r22];;
-+      cmp.eq p7,p0=r22,r0
-+(p7)  br.cond.sptk.many __ia64_switch_to;;
-+#else
-+GLOBAL_ENTRY(ia64_switch_to)
-+      .prologue
-+      alloc r16=ar.pfs,1,0,0,0
-+#endif
-+      DO_SAVE_SWITCH_STACK
-+      .body
-+
-+      adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
-+      movl r25=init_task
-+      mov r27=IA64_KR(CURRENT_STACK)
-+      adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
-+      dep r20=0,in0,61,3              // physical address of "next"
-+      ;;
-+      st8 [r22]=sp                    // save kernel stack pointer of old task
-+      shr.u r26=r20,IA64_GRANULE_SHIFT
-+      cmp.eq p7,p6=r25,in0
-+      ;;
-+#ifdef CONFIG_XEN
-+      movl r8=XSI_PSR_IC
-+      ;;
-+      st4 [r8]=r0     // force psr.ic off for hyperprivop(s)
-+      ;;
-+#endif
-+      /*
-+       * If we've already mapped this task's page, we can skip doing it again.
-+       */
-+(p6)  cmp.eq p7,p6=r26,r27
-+(p6)  br.cond.dpnt .map
-+      ;;
-+.done:
-+#ifdef CONFIG_XEN
-+      // psr.ic already off
-+      // update "current" application register
-+      mov r8=IA64_KR_CURRENT
-+      mov r9=in0;;
-+      XEN_HYPER_SET_KR
-+      ld8 sp=[r21]                    // load kernel stack pointer of new task
-+      movl r27=XSI_PSR_IC
-+      mov r8=1
-+      ;;
-+      st4 [r27]=r8                    // psr.ic back on
-+#else
-+      ld8 sp=[r21]                    // load kernel stack pointer of new task
-+      mov IA64_KR(CURRENT)=in0        // update "current" application register
-+#endif
-+      mov r8=r13                      // return pointer to previously running task
-+      mov r13=in0                     // set "current" pointer
-+      ;;
-+      DO_LOAD_SWITCH_STACK
-+
-+#ifdef CONFIG_SMP
-+      sync.i                          // ensure "fc"s done by this CPU are visible on other CPUs
-+#endif
-+      br.ret.sptk.many rp             // boogie on out in new context
-+
-+.map:
-+#ifdef CONFIG_XEN
-+      // psr.ic already off
-+#else
-+      rsm psr.ic                      // interrupts (psr.i) are already disabled here
-+#endif
-+      movl r25=PAGE_KERNEL
-+      ;;
-+      srlz.d
-+      or r23=r25,r20                  // construct PA | page properties
-+      mov r25=IA64_GRANULE_SHIFT<<2
-+      ;;
-+#ifdef CONFIG_XEN
-+      movl r8=XSI_ITIR
-+      ;;
-+      st8 [r8]=r25
-+      ;;
-+      movl r8=XSI_IFA
-+      ;;
-+      st8 [r8]=in0                     // VA of next task...
-+      ;;
-+      mov r25=IA64_TR_CURRENT_STACK
-+      // remember last page we mapped...
-+      mov r8=IA64_KR_CURRENT_STACK
-+      mov r9=r26;;
-+      XEN_HYPER_SET_KR;;
-+#else
-+      mov cr.itir=r25
-+      mov cr.ifa=in0                  // VA of next task...
-+      ;;
-+      mov r25=IA64_TR_CURRENT_STACK
-+      mov IA64_KR(CURRENT_STACK)=r26  // remember last page we mapped...
-+#endif
-+      ;;
-+      itr.d dtr[r25]=r23              // wire in new mapping...
-+#ifndef CONFIG_XEN
-+      ssm psr.ic                      // reenable the psr.ic bit
-+      ;;
-+      srlz.d
-+#endif
-+      br.cond.sptk .done
-+#ifdef CONFIG_XEN
-+END(xen_switch_to)
-+#else
-+END(ia64_switch_to)
-+#endif
-+
-+      /*
-+       * Invoke a system call, but do some tracing before and after the call.
-+       * We MUST preserve the current register frame throughout this routine
-+       * because some system calls (such as ia64_execve) directly
-+       * manipulate ar.pfs.
-+       */
-+#ifdef CONFIG_XEN
-+GLOBAL_ENTRY(xen_trace_syscall)
-+      PT_REGS_UNWIND_INFO(0)
-+      movl r16=running_on_xen;;
-+      ld4 r16=[r16];;
-+      cmp.eq p7,p0=r16,r0
-+(p7)  br.cond.sptk.many __ia64_trace_syscall;;
-+#else
-+GLOBAL_ENTRY(ia64_trace_syscall)
-+      PT_REGS_UNWIND_INFO(0)
-+#endif
-+      /*
-+       * We need to preserve the scratch registers f6-f11 in case the system
-+       * call is sigreturn.
-+       */
-+      adds r16=PT(F6)+16,sp
-+      adds r17=PT(F7)+16,sp
-+      ;;
-+      stf.spill [r16]=f6,32
-+      stf.spill [r17]=f7,32
-+      ;;
-+      stf.spill [r16]=f8,32
-+      stf.spill [r17]=f9,32
-+      ;;
-+      stf.spill [r16]=f10
-+      stf.spill [r17]=f11
-+      br.call.sptk.many rp=syscall_trace_enter // give parent a chance to catch syscall args
-+      adds r16=PT(F6)+16,sp
-+      adds r17=PT(F7)+16,sp
-+      ;;
-+      ldf.fill f6=[r16],32
-+      ldf.fill f7=[r17],32
-+      ;;
-+      ldf.fill f8=[r16],32
-+      ldf.fill f9=[r17],32
-+      ;;
-+      ldf.fill f10=[r16]
-+      ldf.fill f11=[r17]
-+      // the syscall number may have changed, so re-load it and re-calculate the
-+      // syscall entry-point:
-+      adds r15=PT(R15)+16,sp                  // r15 = &pt_regs.r15 (syscall #)
-+      ;;
-+      ld8 r15=[r15]
-+      mov r3=NR_syscalls - 1
-+      ;;
-+      adds r15=-1024,r15
-+      movl r16=sys_call_table
-+      ;;
-+      shladd r20=r15,3,r16                    // r20 = sys_call_table + 8*(syscall-1024)
-+      cmp.leu p6,p7=r15,r3
-+      ;;
-+(p6)  ld8 r20=[r20]                           // load address of syscall entry point
-+(p7)  movl r20=sys_ni_syscall
-+      ;;
-+      mov b6=r20
-+      br.call.sptk.many rp=b6                 // do the syscall
-+.strace_check_retval:
-+      cmp.lt p6,p0=r8,r0                      // syscall failed?
-+      adds r2=PT(R8)+16,sp                    // r2 = &pt_regs.r8
-+      adds r3=PT(R10)+16,sp                   // r3 = &pt_regs.r10
-+      mov r10=0
-+(p6)  br.cond.sptk strace_error               // syscall failed ->
-+      ;;                                      // avoid RAW on r10
-+.strace_save_retval:
-+.mem.offset 0,0; st8.spill [r2]=r8            // store return value in slot for r8
-+.mem.offset 8,0; st8.spill [r3]=r10           // clear error indication in slot for r10
-+      br.call.sptk.many rp=syscall_trace_leave // give parent a chance to catch return value
-+.ret3:
-+(pUStk)       cmp.eq.unc p6,p0=r0,r0                  // p6 <- pUStk
-+      br.cond.sptk .work_pending_syscall_end
-+
-+strace_error:
-+      ld8 r3=[r2]                             // load pt_regs.r8
-+      sub r9=0,r8                             // negate return value to get errno value
-+      ;;
-+      cmp.ne p6,p0=r3,r0                      // is pt_regs.r8!=0?
-+      adds r3=16,r2                           // r3=&pt_regs.r10
-+      ;;
-+(p6)  mov r10=-1
-+(p6)  mov r8=r9
-+      br.cond.sptk .strace_save_retval
-+#ifdef CONFIG_XEN
-+END(xen_trace_syscall)
-+#else
-+END(ia64_trace_syscall)
-+#endif
-+
-+#ifdef CONFIG_XEN
-+GLOBAL_ENTRY(xen_ret_from_clone)
-+      PT_REGS_UNWIND_INFO(0)
-+      movl r16=running_on_xen;;
-+      ld4 r16=[r16];;
-+      cmp.eq p7,p0=r16,r0
-+(p7)  br.cond.sptk.many __ia64_ret_from_clone;;
-+#else 
-+GLOBAL_ENTRY(ia64_ret_from_clone)
-+      PT_REGS_UNWIND_INFO(0)
-+#endif        
-+{     /*
-+       * Some versions of gas generate bad unwind info if the first instruction of a
-+       * procedure doesn't go into the first slot of a bundle.  This is a workaround.
-+       */
-+      nop.m 0
-+      nop.i 0
-+      /*
-+       * We need to call schedule_tail() to complete the scheduling process.
-+       * Called by ia64_switch_to() after do_fork()->copy_thread().  r8 contains the
-+       * address of the previously executing task.
-+       */
-+      br.call.sptk.many rp=ia64_invoke_schedule_tail
-+}
-+.ret8:
-+      adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
-+      ;;
-+      ld4 r2=[r2]
-+      ;;
-+      mov r8=0
-+      and r2=_TIF_SYSCALL_TRACEAUDIT,r2
-+      ;;
-+      cmp.ne p6,p0=r2,r0
-+(p6)  br.cond.spnt .strace_check_retval
-+      ;;                                      // added stop bits to prevent r8 dependency
-+#ifdef CONFIG_XEN
-+      br.cond.sptk ia64_ret_from_syscall
-+END(xen_ret_from_clone)
-+#else
-+END(ia64_ret_from_clone)
-+#endif                
-+/*
-+ * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
-+ *    need to switch to bank 0 and doesn't restore the scratch registers.
-+ *    To avoid leaking kernel bits, the scratch registers are set to
-+ *    the following known-to-be-safe values:
-+ *
-+ *              r1: restored (global pointer)
-+ *              r2: cleared
-+ *              r3: 1 (when returning to user-level)
-+ *          r8-r11: restored (syscall return value(s))
-+ *             r12: restored (user-level stack pointer)
-+ *             r13: restored (user-level thread pointer)
-+ *             r14: set to __kernel_syscall_via_epc
-+ *             r15: restored (syscall #)
-+ *         r16-r17: cleared
-+ *             r18: user-level b6
-+ *             r19: cleared
-+ *             r20: user-level ar.fpsr
-+ *             r21: user-level b0
-+ *             r22: cleared
-+ *             r23: user-level ar.bspstore
-+ *             r24: user-level ar.rnat
-+ *             r25: user-level ar.unat
-+ *             r26: user-level ar.pfs
-+ *             r27: user-level ar.rsc
-+ *             r28: user-level ip
-+ *             r29: user-level psr
-+ *             r30: user-level cfm
-+ *             r31: user-level pr
-+ *          f6-f11: cleared
-+ *              pr: restored (user-level pr)
-+ *              b0: restored (user-level rp)
-+ *              b6: restored
-+ *              b7: set to __kernel_syscall_via_epc
-+ *         ar.unat: restored (user-level ar.unat)
-+ *          ar.pfs: restored (user-level ar.pfs)
-+ *          ar.rsc: restored (user-level ar.rsc)
-+ *         ar.rnat: restored (user-level ar.rnat)
-+ *     ar.bspstore: restored (user-level ar.bspstore)
-+ *         ar.fpsr: restored (user-level ar.fpsr)
-+ *          ar.ccv: cleared
-+ *          ar.csd: cleared
-+ *          ar.ssd: cleared
-+ */
-+#ifdef CONFIG_XEN
-+GLOBAL_ENTRY(xen_leave_syscall)
-+      PT_REGS_UNWIND_INFO(0)
-+      movl r22=running_on_xen;;
-+      ld4 r22=[r22];;
-+      cmp.eq p7,p0=r22,r0
-+(p7)  br.cond.sptk.many __ia64_leave_syscall;;
-+#else
-+ENTRY(ia64_leave_syscall)
-+      PT_REGS_UNWIND_INFO(0)
-+#endif
-+      /*
-+       * work.need_resched etc. mustn't get changed by this CPU before it returns to
-+       * user- or fsys-mode, hence we disable interrupts early on.
-+       *
-+       * p6 controls whether current_thread_info()->flags needs to be check for
-+       * extra work.  We always check for extra work when returning to user-level.
-+       * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
-+       * is 0.  After extra work processing has been completed, execution
-+       * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
-+       * needs to be redone.
-+       */
-+#ifdef CONFIG_PREEMPT
-+      rsm psr.i                               // disable interrupts
-+      cmp.eq pLvSys,p0=r0,r0                  // pLvSys=1: leave from syscall
-+(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
-+      ;;
-+      .pred.rel.mutex pUStk,pKStk
-+(pKStk) ld4 r21=[r20]                 // r21 <- preempt_count
-+(pUStk)       mov r21=0                       // r21 <- 0
-+      ;;
-+      cmp.eq p6,p0=r21,r0             // p6 <- pUStk || (preempt_count == 0)
-+#else /* !CONFIG_PREEMPT */
-+#ifdef CONFIG_XEN
-+      movl r2=XSI_PSR_I_ADDR
-+      mov r18=1
-+      ;;
-+      ld8 r2=[r2]
-+      ;;
-+(pUStk)       st1 [r2]=r18
-+#else
-+(pUStk)       rsm psr.i
-+#endif
-+      cmp.eq pLvSys,p0=r0,r0          // pLvSys=1: leave from syscall
-+(pUStk)       cmp.eq.unc p6,p0=r0,r0          // p6 <- pUStk
-+#endif
-+.work_processed_syscall:
-+      adds r2=PT(LOADRS)+16,r12
-+      adds r3=PT(AR_BSPSTORE)+16,r12
-+      adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
-+      ;;
-+(p6)  ld4 r31=[r18]                           // load current_thread_info()->flags
-+      ld8 r19=[r2],PT(B6)-PT(LOADRS)          // load ar.rsc value for "loadrs"
-+      nop.i 0
-+      ;;
-+      mov r16=ar.bsp                          // M2  get existing backing store pointer
-+      ld8 r18=[r2],PT(R9)-PT(B6)              // load b6
-+(p6)  and r15=TIF_WORK_MASK,r31               // any work other than TIF_SYSCALL_TRACE?
-+      ;;
-+      ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)    // load ar.bspstore (may be garbage)
-+(p6)  cmp4.ne.unc p6,p0=r15, r0               // any special work pending?
-+(p6)  br.cond.spnt .work_pending_syscall
-+      ;;
-+      // start restoring the state saved on the kernel stack (struct pt_regs):
-+      ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
-+      ld8 r11=[r3],PT(CR_IIP)-PT(R11)
-+(pNonSys) break 0             //      bug check: we shouldn't be here if pNonSys is TRUE!
-+      ;;
-+      invala                  // M0|1 invalidate ALAT
-+#ifdef CONFIG_XEN
-+      movl r28=XSI_PSR_I_ADDR
-+      movl r29=XSI_PSR_IC
-+      ;;
-+      ld8 r28=[r28]
-+      mov r30=1
-+      ;;
-+      st1     [r28]=r30
-+      st4     [r29]=r0        // note: clears both vpsr.i and vpsr.ic!
-+      ;;
-+#else
-+      rsm psr.i | psr.ic      // M2   turn off interrupts and interruption collection
-+#endif
-+      cmp.eq p9,p0=r0,r0      // A    set p9 to indicate that we should restore cr.ifs
-+
-+      ld8 r29=[r2],16         // M0|1 load cr.ipsr
-+      ld8 r28=[r3],16         // M0|1 load cr.iip
-+      mov r22=r0              // A    clear r22
-+      ;;
-+      ld8 r30=[r2],16         // M0|1 load cr.ifs
-+      ld8 r25=[r3],16         // M0|1 load ar.unat
-+(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
-+      ;;
-+      ld8 r26=[r2],PT(B0)-PT(AR_PFS)  // M0|1 load ar.pfs
-+(pKStk)       mov r22=psr                     // M2   read PSR now that interrupts are disabled
-+      nop 0
-+      ;;
-+      ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
-+      ld8 r27=[r3],PT(PR)-PT(AR_RSC)  // M0|1 load ar.rsc
-+      mov f6=f0                       // F    clear f6
-+      ;;
-+      ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)    // M0|1 load ar.rnat (may be garbage)
-+      ld8 r31=[r3],PT(R1)-PT(PR)              // M0|1 load predicates
-+      mov f7=f0                               // F    clear f7
-+      ;;
-+      ld8 r20=[r2],PT(R12)-PT(AR_FPSR)        // M0|1 load ar.fpsr
-+      ld8.fill r1=[r3],16                     // M0|1 load r1
-+(pUStk) mov r17=1                             // A
-+      ;;
-+(pUStk) st1 [r14]=r17                         // M2|3
-+      ld8.fill r13=[r3],16                    // M0|1
-+      mov f8=f0                               // F    clear f8
-+      ;;
-+      ld8.fill r12=[r2]                       // M0|1 restore r12 (sp)
-+      ld8.fill r15=[r3]                       // M0|1 restore r15
-+      mov b6=r18                              // I0   restore b6
-+
-+      addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
-+      mov f9=f0                                       // F    clear f9
-+(pKStk) br.cond.dpnt.many skip_rbs_switch             // B
-+
-+      srlz.d                          // M0   ensure interruption collection is off (for cover)
-+      shr.u r18=r19,16                // I0|1 get byte size of existing "dirty" partition
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_COVER;
-+#else
-+      cover                           // B    add current frame into dirty partition & set cr.ifs
-+#endif
-+      ;;
-+(pUStk) ld4 r17=[r17]                 // M0|1 r17 = cpu_data->phys_stacked_size_p8
-+      mov r19=ar.bsp                  // M2   get new backing store pointer
-+      mov f10=f0                      // F    clear f10
-+
-+      nop.m 0
-+      movl r14=__kernel_syscall_via_epc // X
-+      ;;
-+      mov.m ar.csd=r0                 // M2   clear ar.csd
-+      mov.m ar.ccv=r0                 // M2   clear ar.ccv
-+      mov b7=r14                      // I0   clear b7 (hint with __kernel_syscall_via_epc)
-+
-+      mov.m ar.ssd=r0                 // M2   clear ar.ssd
-+      mov f11=f0                      // F    clear f11
-+      br.cond.sptk.many rbs_switch    // B
-+#ifdef CONFIG_XEN
-+END(xen_leave_syscall)
-+#else
-+END(ia64_leave_syscall)
-+#endif
-+
-+#ifdef CONFIG_XEN
-+GLOBAL_ENTRY(xen_leave_kernel)
-+      PT_REGS_UNWIND_INFO(0)
-+      movl r22=running_on_xen;;
-+      ld4 r22=[r22];;
-+      cmp.eq p7,p0=r22,r0
-+(p7)  br.cond.sptk.many __ia64_leave_kernel;;
-+#else
-+GLOBAL_ENTRY(ia64_leave_kernel)
-+      PT_REGS_UNWIND_INFO(0)
-+#endif
-+      /*
-+       * work.need_resched etc. mustn't get changed by this CPU before it returns to
-+       * user- or fsys-mode, hence we disable interrupts early on.
-+       *
-+       * p6 controls whether current_thread_info()->flags needs to be check for
-+       * extra work.  We always check for extra work when returning to user-level.
-+       * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
-+       * is 0.  After extra work processing has been completed, execution
-+       * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
-+       * needs to be redone.
-+       */
-+#ifdef CONFIG_PREEMPT
-+      rsm psr.i                               // disable interrupts
-+      cmp.eq p0,pLvSys=r0,r0                  // pLvSys=0: leave from kernel
-+(pKStk)       adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
-+      ;;
-+      .pred.rel.mutex pUStk,pKStk
-+(pKStk)       ld4 r21=[r20]                   // r21 <- preempt_count
-+(pUStk)       mov r21=0                       // r21 <- 0
-+      ;;
-+      cmp.eq p6,p0=r21,r0             // p6 <- pUStk || (preempt_count == 0)
-+#else
-+#ifdef CONFIG_XEN
-+(pUStk)       movl r17=XSI_PSR_I_ADDR
-+(pUStk)       mov r31=1
-+              ;;
-+(pUStk)       ld8 r17=[r17]
-+              ;;
-+(pUStk)       st1 [r17]=r31
-+      ;;
-+#else
-+(pUStk)       rsm psr.i
-+#endif
-+      cmp.eq p0,pLvSys=r0,r0          // pLvSys=0: leave from kernel
-+(pUStk)       cmp.eq.unc p6,p0=r0,r0          // p6 <- pUStk
-+#endif
-+.work_processed_kernel:
-+      adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
-+      ;;
-+(p6)  ld4 r31=[r17]                           // load current_thread_info()->flags
-+      adds r21=PT(PR)+16,r12
-+      ;;
-+
-+      lfetch [r21],PT(CR_IPSR)-PT(PR)
-+      adds r2=PT(B6)+16,r12
-+      adds r3=PT(R16)+16,r12
-+      ;;
-+      lfetch [r21]
-+      ld8 r28=[r2],8          // load b6
-+      adds r29=PT(R24)+16,r12
-+
-+      ld8.fill r16=[r3],PT(AR_CSD)-PT(R16)
-+      adds r30=PT(AR_CCV)+16,r12
-+(p6)  and r19=TIF_WORK_MASK,r31               // any work other than TIF_SYSCALL_TRACE?
-+      ;;
-+      ld8.fill r24=[r29]
-+      ld8 r15=[r30]           // load ar.ccv
-+(p6)  cmp4.ne.unc p6,p0=r19, r0               // any special work pending?
-+      ;;
-+      ld8 r29=[r2],16         // load b7
-+      ld8 r30=[r3],16         // load ar.csd
-+(p6)  br.cond.spnt .work_pending
-+      ;;
-+      ld8 r31=[r2],16         // load ar.ssd
-+      ld8.fill r8=[r3],16
-+      ;;
-+      ld8.fill r9=[r2],16
-+      ld8.fill r10=[r3],PT(R17)-PT(R10)
-+      ;;
-+      ld8.fill r11=[r2],PT(R18)-PT(R11)
-+      ld8.fill r17=[r3],16
-+      ;;
-+      ld8.fill r18=[r2],16
-+      ld8.fill r19=[r3],16
-+      ;;
-+      ld8.fill r20=[r2],16
-+      ld8.fill r21=[r3],16
-+      mov ar.csd=r30
-+      mov ar.ssd=r31
-+      ;;
-+#ifdef CONFIG_XEN
-+      movl r23=XSI_PSR_I_ADDR
-+      movl r22=XSI_PSR_IC
-+      ;;
-+      ld8 r23=[r23]
-+      mov r25=1
-+      ;;
-+      st1 [r23]=r25
-+      st4 [r22]=r0            // note: clears both vpsr.i and vpsr.ic!
-+      ;;
-+#else
-+      rsm psr.i | psr.ic      // initiate turning off of interrupt and interruption collection
-+#endif
-+      invala                  // invalidate ALAT
-+      ;;
-+      ld8.fill r22=[r2],24
-+      ld8.fill r23=[r3],24
-+      mov b6=r28
-+      ;;
-+      ld8.fill r25=[r2],16
-+      ld8.fill r26=[r3],16
-+      mov b7=r29
-+      ;;
-+      ld8.fill r27=[r2],16
-+      ld8.fill r28=[r3],16
-+      ;;
-+      ld8.fill r29=[r2],16
-+      ld8.fill r30=[r3],24
-+      ;;
-+      ld8.fill r31=[r2],PT(F9)-PT(R31)
-+      adds r3=PT(F10)-PT(F6),r3
-+      ;;
-+      ldf.fill f9=[r2],PT(F6)-PT(F9)
-+      ldf.fill f10=[r3],PT(F8)-PT(F10)
-+      ;;
-+      ldf.fill f6=[r2],PT(F7)-PT(F6)
-+      ;;
-+      ldf.fill f7=[r2],PT(F11)-PT(F7)
-+      ldf.fill f8=[r3],32
-+      ;;
-+      srlz.d  // ensure that inter. collection is off (VHPT is don't care, since text is pinned)
-+      mov ar.ccv=r15
-+      ;;
-+      ldf.fill f11=[r2]
-+#ifdef CONFIG_XEN
-+      ;;
-+      // r16-r31 all now hold bank1 values
-+      movl r2=XSI_BANK1_R16
-+      movl r3=XSI_BANK1_R16+8
-+      ;;
-+.mem.offset 0,0; st8.spill [r2]=r16,16
-+.mem.offset 8,0; st8.spill [r3]=r17,16
-+      ;;
-+.mem.offset 0,0; st8.spill [r2]=r18,16
-+.mem.offset 8,0; st8.spill [r3]=r19,16
-+      ;;
-+.mem.offset 0,0; st8.spill [r2]=r20,16
-+.mem.offset 8,0; st8.spill [r3]=r21,16
-+      ;;
-+.mem.offset 0,0; st8.spill [r2]=r22,16
-+.mem.offset 8,0; st8.spill [r3]=r23,16
-+      ;;
-+.mem.offset 0,0; st8.spill [r2]=r24,16
-+.mem.offset 8,0; st8.spill [r3]=r25,16
-+      ;;
-+.mem.offset 0,0; st8.spill [r2]=r26,16
-+.mem.offset 8,0; st8.spill [r3]=r27,16
-+      ;;
-+.mem.offset 0,0; st8.spill [r2]=r28,16
-+.mem.offset 8,0; st8.spill [r3]=r29,16
-+      ;;
-+.mem.offset 0,0; st8.spill [r2]=r30,16
-+.mem.offset 8,0; st8.spill [r3]=r31,16
-+      ;;
-+      movl r2=XSI_BANKNUM;;
-+      st4 [r2]=r0;
-+#else
-+      bsw.0                   // switch back to bank 0 (no stop bit required beforehand...)
-+#endif
-+      ;;
-+(pUStk)       mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
-+      adds r16=PT(CR_IPSR)+16,r12
-+      adds r17=PT(CR_IIP)+16,r12
-+
-+(pKStk)       mov r22=psr             // M2 read PSR now that interrupts are disabled
-+      nop.i 0
-+      nop.i 0
-+      ;;
-+      ld8 r29=[r16],16        // load cr.ipsr
-+      ld8 r28=[r17],16        // load cr.iip
-+      ;;
-+      ld8 r30=[r16],16        // load cr.ifs
-+      ld8 r25=[r17],16        // load ar.unat
-+      ;;
-+      ld8 r26=[r16],16        // load ar.pfs
-+      ld8 r27=[r17],16        // load ar.rsc
-+      cmp.eq p9,p0=r0,r0      // set p9 to indicate that we should restore cr.ifs
-+      ;;
-+      ld8 r24=[r16],16        // load ar.rnat (may be garbage)
-+      ld8 r23=[r17],16        // load ar.bspstore (may be garbage)
-+      ;;
-+      ld8 r31=[r16],16        // load predicates
-+      ld8 r21=[r17],16        // load b0
-+      ;;
-+      ld8 r19=[r16],16        // load ar.rsc value for "loadrs"
-+      ld8.fill r1=[r17],16    // load r1
-+      ;;
-+      ld8.fill r12=[r16],16
-+      ld8.fill r13=[r17],16
-+(pUStk)       adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
-+      ;;
-+      ld8 r20=[r16],16        // ar.fpsr
-+      ld8.fill r15=[r17],16
-+      ;;
-+      ld8.fill r14=[r16],16
-+      ld8.fill r2=[r17]
-+(pUStk)       mov r17=1
-+      ;;
-+      ld8.fill r3=[r16]
-+(pUStk)       st1 [r18]=r17           // restore current->thread.on_ustack
-+      shr.u r18=r19,16        // get byte size of existing "dirty" partition
-+      ;;
-+      mov r16=ar.bsp          // get existing backing store pointer
-+      addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
-+      ;;
-+      ld4 r17=[r17]           // r17 = cpu_data->phys_stacked_size_p8
-+(pKStk)       br.cond.dpnt skip_rbs_switch
-+
-+      /*
-+       * Restore user backing store.
-+       *
-+       * NOTE: alloc, loadrs, and cover can't be predicated.
-+       */
-+(pNonSys) br.cond.dpnt dont_preserve_current_frame
-+
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_COVER;
-+#else
-+      cover                           // add current frame into dirty partition and set cr.ifs
-+#endif
-+      ;;
-+      mov r19=ar.bsp                  // get new backing store pointer
-+rbs_switch:
-+      sub r16=r16,r18                 // krbs = old bsp - size of dirty partition
-+      cmp.ne p9,p0=r0,r0              // clear p9 to skip restore of cr.ifs
-+      ;;
-+      sub r19=r19,r16                 // calculate total byte size of dirty partition
-+      add r18=64,r18                  // don't force in0-in7 into memory...
-+      ;;
-+      shl r19=r19,16                  // shift size of dirty partition into loadrs position
-+      ;;
-+dont_preserve_current_frame:
-+      /*
-+       * To prevent leaking bits between the kernel and user-space,
-+       * we must clear the stacked registers in the "invalid" partition here.
-+       * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium,
-+       * 5 registers/cycle on McKinley).
-+       */
-+#     define pRecurse p6
-+#     define pReturn  p7
-+#ifdef CONFIG_ITANIUM
-+#     define Nregs    10
-+#else
-+#     define Nregs    14
-+#endif
-+      alloc loc0=ar.pfs,2,Nregs-2,2,0
-+      shr.u loc1=r18,9                // RNaTslots <= floor(dirtySize / (64*8))
-+      sub r17=r17,r18                 // r17 = (physStackedSize + 8) - dirtySize
-+      ;;
-+      mov ar.rsc=r19                  // load ar.rsc to be used for "loadrs"
-+      shladd in0=loc1,3,r17
-+      mov in1=0
-+      ;;
-+      TEXT_ALIGN(32)
-+rse_clear_invalid:
-+#ifdef CONFIG_ITANIUM
-+      // cycle 0
-+ { .mii
-+      alloc loc0=ar.pfs,2,Nregs-2,2,0
-+      cmp.lt pRecurse,p0=Nregs*8,in0  // if more than Nregs regs left to clear, (re)curse
-+      add out0=-Nregs*8,in0
-+}{ .mfb
-+      add out1=1,in1                  // increment recursion count
-+      nop.f 0
-+      nop.b 0                         // can't do br.call here because of alloc (WAW on CFM)
-+      ;;
-+}{ .mfi       // cycle 1
-+      mov loc1=0
-+      nop.f 0
-+      mov loc2=0
-+}{ .mib
-+      mov loc3=0
-+      mov loc4=0
-+(pRecurse) br.call.sptk.many b0=rse_clear_invalid
-+
-+}{ .mfi       // cycle 2
-+      mov loc5=0
-+      nop.f 0
-+      cmp.ne pReturn,p0=r0,in1        // if recursion count != 0, we need to do a br.ret
-+}{ .mib
-+      mov loc6=0
-+      mov loc7=0
-+(pReturn) br.ret.sptk.many b0
-+}
-+#else /* !CONFIG_ITANIUM */
-+      alloc loc0=ar.pfs,2,Nregs-2,2,0
-+      cmp.lt pRecurse,p0=Nregs*8,in0  // if more than Nregs regs left to clear, (re)curse
-+      add out0=-Nregs*8,in0
-+      add out1=1,in1                  // increment recursion count
-+      mov loc1=0
-+      mov loc2=0
-+      ;;
-+      mov loc3=0
-+      mov loc4=0
-+      mov loc5=0
-+      mov loc6=0
-+      mov loc7=0
-+(pRecurse) br.call.dptk.few b0=rse_clear_invalid
-+      ;;
-+      mov loc8=0
-+      mov loc9=0
-+      cmp.ne pReturn,p0=r0,in1        // if recursion count != 0, we need to do a br.ret
-+      mov loc10=0
-+      mov loc11=0
-+(pReturn) br.ret.dptk.many b0
-+#endif /* !CONFIG_ITANIUM */
-+#     undef pRecurse
-+#     undef pReturn
-+      ;;
-+      alloc r17=ar.pfs,0,0,0,0        // drop current register frame
-+      ;;
-+      loadrs
-+      ;;
-+skip_rbs_switch:
-+      mov ar.unat=r25         // M2
-+(pKStk)       extr.u r22=r22,21,1     // I0 extract current value of psr.pp from r22
-+(pLvSys)mov r19=r0            // A  clear r19 for leave_syscall, no-op otherwise
-+      ;;
-+(pUStk)       mov ar.bspstore=r23     // M2
-+(pKStk)       dep r29=r22,r29,21,1    // I0 update ipsr.pp with psr.pp
-+(pLvSys)mov r16=r0            // A  clear r16 for leave_syscall, no-op otherwise
-+      ;;
-+#ifdef CONFIG_XEN
-+      movl r25=XSI_IPSR
-+      ;;
-+      st8[r25]=r29,XSI_IFS_OFS-XSI_IPSR_OFS
-+      ;;
-+#else
-+      mov cr.ipsr=r29         // M2
-+#endif
-+      mov ar.pfs=r26          // I0
-+(pLvSys)mov r17=r0            // A  clear r17 for leave_syscall, no-op otherwise
-+
-+#ifdef CONFIG_XEN
-+(p9)  st8 [r25]=r30
-+      ;;
-+      adds r25=XSI_IIP_OFS-XSI_IFS_OFS,r25
-+      ;;
-+#else
-+(p9)  mov cr.ifs=r30          // M2
-+#endif
-+      mov b0=r21              // I0
-+(pLvSys)mov r18=r0            // A  clear r18 for leave_syscall, no-op otherwise
-+
-+      mov ar.fpsr=r20         // M2
-+#ifdef CONFIG_XEN
-+      st8     [r25]=r28
-+#else
-+      mov cr.iip=r28          // M2
-+#endif
-+      nop 0
-+      ;;
-+(pUStk)       mov ar.rnat=r24         // M2 must happen with RSE in lazy mode
-+      nop 0
-+(pLvSys)mov r2=r0
-+
-+      mov ar.rsc=r27          // M2
-+      mov pr=r31,-1           // I0
-+#ifdef CONFIG_XEN
-+      ;;
-+      XEN_HYPER_RFI;
-+#else
-+      rfi                     // B
-+#endif
-+
-+      /*
-+       * On entry:
-+       *      r20 = &current->thread_info->pre_count (if CONFIG_PREEMPT)
-+       *      r31 = current->thread_info->flags
-+       * On exit:
-+       *      p6 = TRUE if work-pending-check needs to be redone
-+       */
-+.work_pending_syscall:
-+      add r2=-8,r2
-+      add r3=-8,r3
-+      ;;
-+      st8 [r2]=r8
-+      st8 [r3]=r10
-+.work_pending:
-+      tbit.nz p6,p0=r31,TIF_SIGDELAYED                // signal delayed from  MCA/INIT/NMI/PMI context?
-+(p6)  br.cond.sptk.few .sigdelayed
-+      ;;
-+      tbit.z p6,p0=r31,TIF_NEED_RESCHED               // current_thread_info()->need_resched==0?
-+(p6)  br.cond.sptk.few .notify
-+#ifdef CONFIG_PREEMPT
-+(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1
-+      ;;
-+(pKStk) st4 [r20]=r21
-+      ssm psr.i               // enable interrupts
-+#endif
-+      br.call.spnt.many rp=schedule
-+.ret9:        cmp.eq p6,p0=r0,r0                              // p6 <- 1
-+#ifdef CONFIG_XEN
-+      movl r2=XSI_PSR_I_ADDR
-+      mov r20=1
-+      ;;
-+      ld8 r2=[r2]
-+      ;;
-+      st1 [r2]=r20
-+#else
-+      rsm psr.i               // disable interrupts
-+#endif
-+      ;;
-+#ifdef CONFIG_PREEMPT
-+(pKStk)       adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
-+      ;;
-+(pKStk)       st4 [r20]=r0            // preempt_count() <- 0
-+#endif
-+(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
-+      br.cond.sptk.many .work_processed_kernel        // re-check
-+
-+.notify:
-+(pUStk)       br.call.spnt.many rp=notify_resume_user
-+.ret10:       cmp.ne p6,p0=r0,r0                              // p6 <- 0
-+(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
-+      br.cond.sptk.many .work_processed_kernel        // don't re-check
-+
-+// There is a delayed signal that was detected in MCA/INIT/NMI/PMI context where
-+// it could not be delivered.  Deliver it now.  The signal might be for us and
-+// may set TIF_SIGPENDING, so redrive ia64_leave_* after processing the delayed
-+// signal.
-+
-+.sigdelayed:
-+      br.call.sptk.many rp=do_sigdelayed
-+      cmp.eq p6,p0=r0,r0                              // p6 <- 1, always re-check
-+(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
-+      br.cond.sptk.many .work_processed_kernel        // re-check
-+
-+.work_pending_syscall_end:
-+      adds r2=PT(R8)+16,r12
-+      adds r3=PT(R10)+16,r12
-+      ;;
-+      ld8 r8=[r2]
-+      ld8 r10=[r3]
-+      br.cond.sptk.many .work_processed_syscall       // re-check
-+
-+#ifdef CONFIG_XEN
-+END(xen_leave_kernel)
-+#else
-+END(ia64_leave_kernel)
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xenhpski.c linux-2.6.16.33/arch/ia64/xen/xenhpski.c
---- linux-2.6.16.33-noxen/arch/ia64/xen/xenhpski.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xenhpski.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,19 @@
-+
-+extern unsigned long xen_get_cpuid(int);
-+
-+int
-+running_on_sim(void)
-+{
-+      int i;
-+      long cpuid[6];
-+
-+      for (i = 0; i < 5; ++i)
-+              cpuid[i] = xen_get_cpuid(i);
-+      if ((cpuid[0] & 0xff) != 'H') return 0;
-+      if ((cpuid[3] & 0xff) != 0x4) return 0;
-+      if (((cpuid[3] >> 8) & 0xff) != 0x0) return 0;
-+      if (((cpuid[3] >> 16) & 0xff) != 0x0) return 0;
-+      if (((cpuid[3] >> 24) & 0x7) != 0x7) return 0;
-+      return 1;
-+}
-+
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xenivt.S linux-2.6.16.33/arch/ia64/xen/xenivt.S
---- linux-2.6.16.33-noxen/arch/ia64/xen/xenivt.S       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xenivt.S     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2180 @@
-+/*
-+ * arch/ia64/xen/ivt.S
-+ *
-+ * Copyright (C) 2005 Hewlett-Packard Co
-+ *    Dan Magenheimer <dan.magenheimer@hp.com>
-+ */
-+/*
-+ * This file defines the interruption vector table used by the CPU.
-+ * It does not include one entry per possible cause of interruption.
-+ *
-+ * The first 20 entries of the table contain 64 bundles each while the
-+ * remaining 48 entries contain only 16 bundles each.
-+ *
-+ * The 64 bundles are used to allow inlining the whole handler for critical
-+ * interruptions like TLB misses.
-+ *
-+ *  For each entry, the comment is as follows:
-+ *
-+ *            // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
-+ *  entry offset ----/     /         /                  /          /
-+ *  entry number ---------/         /                  /          /
-+ *  size of the entry -------------/                  /          /
-+ *  vector name -------------------------------------/          /
-+ *  interruptions triggering this vector ----------------------/
-+ *
-+ * The table is 32KB in size and must be aligned on 32KB boundary.
-+ * (The CPU ignores the 15 lower bits of the address)
-+ *
-+ * Table is based upon EAS2.6 (Oct 1999)
-+ */
-+
-+#include <linux/config.h>
-+
-+#include <asm/asmmacro.h>
-+#include <asm/break.h>
-+#include <asm/ia32.h>
-+#include <asm/kregs.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/pgtable.h>
-+#include <asm/processor.h>
-+#include <asm/ptrace.h>
-+#include <asm/system.h>
-+#include <asm/thread_info.h>
-+#include <asm/unistd.h>
-+#include <asm/errno.h>
-+
-+#ifdef CONFIG_XEN
-+#define ia64_ivt xen_ivt
-+#endif
-+
-+#if 1
-+# define PSR_DEFAULT_BITS     psr.ac
-+#else
-+# define PSR_DEFAULT_BITS     0
-+#endif
-+
-+#if 0
-+  /*
-+   * This lets you track the last eight faults that occurred on the CPU.  Make sure ar.k2 isn't
-+   * needed for something else before enabling this...
-+   */
-+# define DBG_FAULT(i) mov r16=ar.k2;; shl r16=r16,8;; add r16=(i),r16;;mov ar.k2=r16
-+#else
-+# define DBG_FAULT(i)
-+#endif
-+
-+#define MINSTATE_VIRT /* needed by minstate.h */
-+#include "xenminstate.h"
-+
-+#define FAULT(n)                                                                      \
-+      mov r31=pr;                                                                     \
-+      mov r19=n;;                     /* prepare to save predicates */                \
-+      br.sptk.many dispatch_to_fault_handler
-+
-+      .section .text.ivt,"ax"
-+
-+      .align 32768    // align on 32KB boundary
-+      .global ia64_ivt
-+ia64_ivt:
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
-+ENTRY(vhpt_miss)
-+      DBG_FAULT(0)
-+      /*
-+       * The VHPT vector is invoked when the TLB entry for the virtual page table
-+       * is missing.  This happens only as a result of a previous
-+       * (the "original") TLB miss, which may either be caused by an instruction
-+       * fetch or a data access (or non-access).
-+       *
-+       * What we do here is normal TLB miss handing for the _original_ miss,
-+       * followed by inserting the TLB entry for the virtual page table page
-+       * that the VHPT walker was attempting to access.  The latter gets
-+       * inserted as long as page table entry above pte level have valid
-+       * mappings for the faulting address.  The TLB entry for the original
-+       * miss gets inserted only if the pte entry indicates that the page is
-+       * present.
-+       *
-+       * do_page_fault gets invoked in the following cases:
-+       *      - the faulting virtual address uses unimplemented address bits
-+       *      - the faulting virtual address has no valid page table mapping
-+       */
-+#ifdef CONFIG_XEN
-+      movl r16=XSI_IFA
-+      ;;
-+      ld8 r16=[r16]
-+#ifdef CONFIG_HUGETLB_PAGE
-+      movl r18=PAGE_SHIFT
-+      movl r25=XSI_ITIR
-+      ;;
-+      ld8 r25=[r25]
-+#endif
-+      ;;
-+#else
-+      mov r16=cr.ifa                          // get address that caused the TLB miss
-+#ifdef CONFIG_HUGETLB_PAGE
-+      movl r18=PAGE_SHIFT
-+      mov r25=cr.itir
-+#endif
-+#endif
-+      ;;
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RSM_PSR_DT;
-+#else
-+      rsm psr.dt                              // use physical addressing for data
-+#endif
-+      mov r31=pr                              // save the predicate registers
-+      mov r19=IA64_KR(PT_BASE)                // get page table base address
-+      shl r21=r16,3                           // shift bit 60 into sign bit
-+      shr.u r17=r16,61                        // get the region number into r17
-+      ;;
-+      shr.u r22=r21,3
-+#ifdef CONFIG_HUGETLB_PAGE
-+      extr.u r26=r25,2,6
-+      ;;
-+      cmp.ne p8,p0=r18,r26
-+      sub r27=r26,r18
-+      ;;
-+(p8)  dep r25=r18,r25,2,6
-+(p8)  shr r22=r22,r27
-+#endif
-+      ;;
-+      cmp.eq p6,p7=5,r17                      // is IFA pointing into to region 5?
-+      shr.u r18=r22,PGDIR_SHIFT               // get bottom portion of pgd index bit
-+      ;;
-+(p7)  dep r17=r17,r19,(PAGE_SHIFT-3),3        // put region number bits in place
-+
-+      srlz.d
-+      LOAD_PHYSICAL(p6, r19, swapper_pg_dir)  // region 5 is rooted at swapper_pg_dir
-+
-+      .pred.rel "mutex", p6, p7
-+(p6)  shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
-+(p7)  shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
-+      ;;
-+(p6)  dep r17=r18,r19,3,(PAGE_SHIFT-3)        // r17=pgd_offset for region 5
-+(p7)  dep r17=r18,r17,3,(PAGE_SHIFT-6)        // r17=pgd_offset for region[0-4]
-+      cmp.eq p7,p6=0,r21                      // unused address bits all zeroes?
-+#ifdef CONFIG_PGTABLE_4
-+      shr.u r28=r22,PUD_SHIFT                 // shift pud index into position
-+#else
-+      shr.u r18=r22,PMD_SHIFT                 // shift pmd index into position
-+#endif
-+      ;;
-+      ld8 r17=[r17]                           // get *pgd (may be 0)
-+      ;;
-+(p7)  cmp.eq p6,p7=r17,r0                     // was pgd_present(*pgd) == NULL?
-+#ifdef CONFIG_PGTABLE_4
-+      dep r28=r28,r17,3,(PAGE_SHIFT-3)        // r28=pud_offset(pgd,addr)
-+      ;;
-+      shr.u r18=r22,PMD_SHIFT                 // shift pmd index into position
-+(p7)  ld8 r29=[r28]                           // get *pud (may be 0)
-+      ;;
-+(p7)  cmp.eq.or.andcm p6,p7=r29,r0            // was pud_present(*pud) == NULL?
-+      dep r17=r18,r29,3,(PAGE_SHIFT-3)        // r17=pmd_offset(pud,addr)
-+#else
-+      dep r17=r18,r17,3,(PAGE_SHIFT-3)        // r17=pmd_offset(pgd,addr)
-+#endif
-+      ;;
-+(p7)  ld8 r20=[r17]                           // get *pmd (may be 0)
-+      shr.u r19=r22,PAGE_SHIFT                // shift pte index into position
-+      ;;
-+(p7)  cmp.eq.or.andcm p6,p7=r20,r0            // was pmd_present(*pmd) == NULL?
-+      dep r21=r19,r20,3,(PAGE_SHIFT-3)        // r21=pte_offset(pmd,addr)
-+      ;;
-+(p7)  ld8 r18=[r21]                           // read *pte
-+#ifdef CONFIG_XEN
-+      movl r19=XSI_ISR
-+      ;;
-+      ld8 r19=[r19]
-+#else
-+      mov r19=cr.isr                          // cr.isr bit 32 tells us if this is an insn miss
-+#endif
-+      ;;
-+(p7)  tbit.z p6,p7=r18,_PAGE_P_BIT            // page present bit cleared?
-+#ifdef CONFIG_XEN
-+      movl r22=XSI_IHA
-+      ;;
-+      ld8 r22=[r22]
-+#else
-+      mov r22=cr.iha                          // get the VHPT address that caused the TLB miss
-+#endif
-+      ;;                                      // avoid RAW on p7
-+(p7)  tbit.nz.unc p10,p11=r19,32              // is it an instruction TLB miss?
-+      dep r23=0,r20,0,PAGE_SHIFT              // clear low bits to get page address
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r24=r8
-+      mov r8=r18
-+      ;;
-+(p10) XEN_HYPER_ITC_I
-+      ;;
-+(p11) XEN_HYPER_ITC_D
-+      ;;
-+      mov r8=r24
-+      ;;
-+#else
-+(p10) itc.i r18                               // insert the instruction TLB entry
-+(p11) itc.d r18                               // insert the data TLB entry
-+#endif
-+(p6)  br.cond.spnt.many page_fault            // handle bad address/page not present (page fault)
-+#ifdef CONFIG_XEN
-+      movl r24=XSI_IFA
-+      ;;
-+      st8 [r24]=r22
-+      ;;
-+#else
-+      mov cr.ifa=r22
-+#endif
-+
-+#ifdef CONFIG_HUGETLB_PAGE
-+(p8)  mov cr.itir=r25                         // change to default page-size for VHPT
-+#endif
-+
-+      /*
-+       * Now compute and insert the TLB entry for the virtual page table.  We never
-+       * execute in a page table page so there is no need to set the exception deferral
-+       * bit.
-+       */
-+      adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
-+      ;;
-+#ifdef CONFIG_XEN
-+(p7)  mov r25=r8
-+(p7)  mov r8=r24
-+      ;;
-+(p7)  XEN_HYPER_ITC_D
-+      ;;
-+(p7)  mov r8=r25
-+      ;;
-+#else
-+(p7)  itc.d r24
-+#endif
-+      ;;
-+#ifdef CONFIG_SMP
-+      /*
-+       * Tell the assemblers dependency-violation checker that the above "itc" instructions
-+       * cannot possibly affect the following loads:
-+       */
-+      dv_serialize_data
-+
-+      /*
-+       * Re-check pagetable entry.  If they changed, we may have received a ptc.g
-+       * between reading the pagetable and the "itc".  If so, flush the entry we
-+       * inserted and retry.  At this point, we have:
-+       *
-+       * r28 = equivalent of pud_offset(pgd, ifa)
-+       * r17 = equivalent of pmd_offset(pud, ifa)
-+       * r21 = equivalent of pte_offset(pmd, ifa)
-+       *
-+       * r29 = *pud
-+       * r20 = *pmd
-+       * r18 = *pte
-+       */
-+      ld8 r25=[r21]                           // read *pte again
-+      ld8 r26=[r17]                           // read *pmd again
-+#ifdef CONFIG_PGTABLE_4
-+      ld8 r19=[r28]                           // read *pud again
-+#endif
-+      cmp.ne p6,p7=r0,r0
-+      ;;
-+      cmp.ne.or.andcm p6,p7=r26,r20           // did *pmd change
-+#ifdef CONFIG_PGTABLE_4
-+      cmp.ne.or.andcm p6,p7=r19,r29           // did *pud change
-+#endif
-+      mov r27=PAGE_SHIFT<<2
-+      ;;
-+(p6)  ptc.l r22,r27                           // purge PTE page translation
-+(p7)  cmp.ne.or.andcm p6,p7=r25,r18           // did *pte change
-+      ;;
-+(p6)  ptc.l r16,r27                           // purge translation
-+#endif
-+
-+      mov pr=r31,-1                           // restore predicate registers
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RFI
-+      dv_serialize_data
-+#else
-+      rfi
-+#endif
-+END(vhpt_miss)
-+
-+      .org ia64_ivt+0x400
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x0400 Entry 1 (size 64 bundles) ITLB (21)
-+ENTRY(itlb_miss)
-+      DBG_FAULT(1)
-+      /*
-+       * The ITLB handler accesses the PTE via the virtually mapped linear
-+       * page table.  If a nested TLB miss occurs, we switch into physical
-+       * mode, walk the page table, and then re-execute the PTE read and
-+       * go on normally after that.
-+       */
-+#ifdef CONFIG_XEN
-+      movl r16=XSI_IFA
-+      ;;
-+      ld8 r16=[r16]
-+#else
-+      mov r16=cr.ifa                          // get virtual address
-+#endif
-+      mov r29=b0                              // save b0
-+      mov r31=pr                              // save predicates
-+.itlb_fault:
-+#ifdef CONFIG_XEN
-+      movl r17=XSI_IHA
-+      ;;
-+      ld8 r17=[r17]                           // get virtual address of L3 PTE
-+#else
-+      mov r17=cr.iha                          // get virtual address of PTE
-+#endif
-+      movl r30=1f                             // load nested fault continuation point
-+      ;;
-+1:    ld8 r18=[r17]                           // read *pte
-+      ;;
-+      mov b0=r29
-+      tbit.z p6,p0=r18,_PAGE_P_BIT            // page present bit cleared?
-+(p6)  br.cond.spnt page_fault
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r19=r8
-+      mov r8=r18
-+      ;;
-+      XEN_HYPER_ITC_I
-+      ;;
-+      mov r8=r19
-+#else
-+      itc.i r18
-+#endif
-+      ;;
-+#ifdef CONFIG_SMP
-+      /*
-+       * Tell the assemblers dependency-violation checker that the above "itc" instructions
-+       * cannot possibly affect the following loads:
-+       */
-+      dv_serialize_data
-+
-+      ld8 r19=[r17]                           // read *pte again and see if same
-+      mov r20=PAGE_SHIFT<<2                   // setup page size for purge
-+      ;;
-+      cmp.ne p7,p0=r18,r19
-+      ;;
-+(p7)  ptc.l r16,r20
-+#endif
-+      mov pr=r31,-1
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RFI
-+      dv_serialize_data
-+#else
-+      rfi
-+#endif
-+END(itlb_miss)
-+
-+      .org ia64_ivt+0x0800
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
-+ENTRY(dtlb_miss)
-+      DBG_FAULT(2)
-+      /*
-+       * The DTLB handler accesses the PTE via the virtually mapped linear
-+       * page table.  If a nested TLB miss occurs, we switch into physical
-+       * mode, walk the page table, and then re-execute the PTE read and
-+       * go on normally after that.
-+       */
-+#ifdef CONFIG_XEN
-+      movl r16=XSI_IFA
-+      ;;
-+      ld8 r16=[r16]
-+#else
-+      mov r16=cr.ifa                          // get virtual address
-+#endif
-+      mov r29=b0                              // save b0
-+      mov r31=pr                              // save predicates
-+dtlb_fault:
-+#ifdef CONFIG_XEN
-+      movl r17=XSI_IHA
-+      ;;
-+      ld8 r17=[r17]                           // get virtual address of L3 PTE
-+#else
-+      mov r17=cr.iha                          // get virtual address of PTE
-+#endif
-+      movl r30=1f                             // load nested fault continuation point
-+      ;;
-+1:    ld8 r18=[r17]                           // read *pte
-+      ;;
-+      mov b0=r29
-+      tbit.z p6,p0=r18,_PAGE_P_BIT            // page present bit cleared?
-+(p6)  br.cond.spnt page_fault
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r19=r8
-+      mov r8=r18
-+      ;;
-+      XEN_HYPER_ITC_D
-+      ;;
-+      mov r8=r19
-+      ;;
-+#else
-+      itc.d r18
-+#endif
-+      ;;
-+#ifdef CONFIG_SMP
-+      /*
-+       * Tell the assemblers dependency-violation checker that the above "itc" instructions
-+       * cannot possibly affect the following loads:
-+       */
-+      dv_serialize_data
-+
-+      ld8 r19=[r17]                           // read *pte again and see if same
-+      mov r20=PAGE_SHIFT<<2                   // setup page size for purge
-+      ;;
-+      cmp.ne p7,p0=r18,r19
-+      ;;
-+(p7)  ptc.l r16,r20
-+#endif
-+      mov pr=r31,-1
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RFI
-+      dv_serialize_data
-+#else
-+      rfi
-+#endif
-+END(dtlb_miss)
-+
-+      .org ia64_ivt+0x0c00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
-+ENTRY(alt_itlb_miss)
-+      DBG_FAULT(3)
-+#ifdef CONFIG_XEN
-+      movl r31=XSI_IPSR
-+      ;;
-+      ld8 r21=[r31],XSI_IFA_OFS-XSI_IPSR_OFS  // get ipsr, point to ifa
-+      movl r17=PAGE_KERNEL
-+      ;;
-+      ld8 r16=[r31]           // get ifa
-+#else
-+      mov r16=cr.ifa          // get address that caused the TLB miss
-+      movl r17=PAGE_KERNEL
-+      mov r21=cr.ipsr
-+#endif
-+      movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-+      mov r31=pr
-+      ;;
-+#ifdef CONFIG_DISABLE_VHPT
-+      shr.u r22=r16,61                        // get the region number into r21
-+      ;;
-+      cmp.gt p8,p0=6,r22                      // user mode
-+      ;;
-+#ifndef CONFIG_XEN
-+(p8)  thash r17=r16
-+      ;;
-+(p8)  mov cr.iha=r17
-+#endif
-+(p8)  mov r29=b0                              // save b0
-+(p8)  br.cond.dptk .itlb_fault
-+#endif
-+      extr.u r23=r21,IA64_PSR_CPL0_BIT,2      // extract psr.cpl
-+      and r19=r19,r16         // clear ed, reserved bits, and PTE control bits
-+      shr.u r18=r16,57        // move address bit 61 to bit 4
-+      ;;
-+      andcm r18=0x10,r18      // bit 4=~address-bit(61)
-+      cmp.ne p8,p0=r0,r23     // psr.cpl != 0?
-+      or r19=r17,r19          // insert PTE control bits into r19
-+      ;;
-+      or r19=r19,r18          // set bit 4 (uncached) if the access was to region 6
-+(p8)  br.cond.spnt page_fault
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r18=r8
-+      mov r8=r19
-+      ;;
-+      XEN_HYPER_ITC_I
-+      ;;
-+      mov r8=r18
-+      ;;
-+      mov pr=r31,-1
-+      ;;
-+      XEN_HYPER_RFI;
-+#else
-+      itc.i r19               // insert the TLB entry
-+      mov pr=r31,-1
-+      rfi
-+#endif
-+END(alt_itlb_miss)
-+
-+      .org ia64_ivt+0x1000
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
-+ENTRY(alt_dtlb_miss)
-+      DBG_FAULT(4)
-+#ifdef CONFIG_XEN
-+      movl r31=XSI_IPSR
-+      ;;
-+      ld8 r21=[r31],XSI_ISR_OFS-XSI_IPSR_OFS  // get ipsr, point to isr
-+      movl r17=PAGE_KERNEL
-+      ;;
-+      ld8 r20=[r31],XSI_IFA_OFS-XSI_ISR_OFS   // get isr, point to ifa
-+      movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-+      ;;
-+      ld8 r16=[r31]           // get ifa
-+#else
-+      mov r16=cr.ifa          // get address that caused the TLB miss
-+      movl r17=PAGE_KERNEL
-+      mov r20=cr.isr
-+      movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-+      mov r21=cr.ipsr
-+#endif
-+      mov r31=pr
-+      ;;
-+#ifdef CONFIG_DISABLE_VHPT
-+      shr.u r22=r16,61                        // get the region number into r21
-+      ;;
-+      cmp.gt p8,p0=6,r22                      // access to region 0-5
-+      ;;
-+#ifndef CONFIG_XEN
-+(p8)  thash r17=r16
-+      ;;
-+(p8)  mov cr.iha=r17
-+#endif
-+(p8)  mov r29=b0                              // save b0
-+(p8)  br.cond.dptk dtlb_fault
-+#endif
-+      extr.u r23=r21,IA64_PSR_CPL0_BIT,2      // extract psr.cpl
-+      and r22=IA64_ISR_CODE_MASK,r20          // get the isr.code field
-+      tbit.nz p6,p7=r20,IA64_ISR_SP_BIT       // is speculation bit on?
-+      shr.u r18=r16,57                        // move address bit 61 to bit 4
-+      and r19=r19,r16                         // clear ed, reserved bits, and PTE control bits
-+      tbit.nz p9,p0=r20,IA64_ISR_NA_BIT       // is non-access bit on?
-+      ;;
-+      andcm r18=0x10,r18      // bit 4=~address-bit(61)
-+      cmp.ne p8,p0=r0,r23
-+(p9)  cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22  // check isr.code field
-+(p8)  br.cond.spnt page_fault
-+
-+      dep r21=-1,r21,IA64_PSR_ED_BIT,1
-+      or r19=r19,r17          // insert PTE control bits into r19
-+      ;;
-+      or r19=r19,r18          // set bit 4 (uncached) if the access was to region 6
-+(p6)  mov cr.ipsr=r21
-+      ;;
-+#ifdef CONFIG_XEN
-+(p7)  mov r18=r8
-+(p7)  mov r8=r19
-+      ;;
-+(p7)  XEN_HYPER_ITC_D
-+      ;;
-+(p7)  mov r8=r18
-+      ;;
-+      mov pr=r31,-1
-+      ;;
-+      XEN_HYPER_RFI;
-+#else
-+(p7)  itc.d r19               // insert the TLB entry
-+      mov pr=r31,-1
-+      rfi
-+#endif
-+END(alt_dtlb_miss)
-+
-+      .org ia64_ivt+0x1400
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
-+ENTRY(nested_dtlb_miss)
-+      /*
-+       * In the absence of kernel bugs, we get here when the virtually mapped linear
-+       * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction
-+       * Access-bit, or Data Access-bit faults).  If the DTLB entry for the virtual page
-+       * table is missing, a nested TLB miss fault is triggered and control is
-+       * transferred to this point.  When this happens, we lookup the pte for the
-+       * faulting address by walking the page table in physical mode and return to the
-+       * continuation point passed in register r30 (or call page_fault if the address is
-+       * not mapped).
-+       *
-+       * Input:       r16:    faulting address
-+       *              r29:    saved b0
-+       *              r30:    continuation address
-+       *              r31:    saved pr
-+       *
-+       * Output:      r17:    physical address of PTE of faulting address
-+       *              r29:    saved b0
-+       *              r30:    continuation address
-+       *              r31:    saved pr
-+       *
-+       * Clobbered:   b0, r18, r19, r21, r22, psr.dt (cleared)
-+       */
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RSM_PSR_DT;
-+#else
-+      rsm psr.dt                              // switch to using physical data addressing
-+#endif
-+      mov r19=IA64_KR(PT_BASE)                // get the page table base address
-+      shl r21=r16,3                           // shift bit 60 into sign bit
-+#ifdef CONFIG_XEN
-+      movl r18=XSI_ITIR
-+      ;;
-+      ld8 r18=[r18]
-+#else
-+      mov r18=cr.itir
-+#endif
-+      ;;
-+      shr.u r17=r16,61                        // get the region number into r17
-+      extr.u r18=r18,2,6                      // get the faulting page size
-+      ;;
-+      cmp.eq p6,p7=5,r17                      // is faulting address in region 5?
-+      add r22=-PAGE_SHIFT,r18                 // adjustment for hugetlb address
-+      add r18=PGDIR_SHIFT-PAGE_SHIFT,r18
-+      ;;
-+      shr.u r22=r16,r22
-+      shr.u r18=r16,r18
-+(p7)  dep r17=r17,r19,(PAGE_SHIFT-3),3        // put region number bits in place
-+
-+      srlz.d
-+      LOAD_PHYSICAL(p6, r19, swapper_pg_dir)  // region 5 is rooted at swapper_pg_dir
-+
-+      .pred.rel "mutex", p6, p7
-+(p6)  shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
-+(p7)  shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
-+      ;;
-+(p6)  dep r17=r18,r19,3,(PAGE_SHIFT-3)        // r17=pgd_offset for region 5
-+(p7)  dep r17=r18,r17,3,(PAGE_SHIFT-6)        // r17=pgd_offset for region[0-4]
-+      cmp.eq p7,p6=0,r21                      // unused address bits all zeroes?
-+#ifdef CONFIG_PGTABLE_4
-+      shr.u r18=r22,PUD_SHIFT                 // shift pud index into position
-+#else
-+      shr.u r18=r22,PMD_SHIFT                 // shift pmd index into position
-+#endif
-+      ;;
-+      ld8 r17=[r17]                           // get *pgd (may be 0)
-+      ;;
-+(p7)  cmp.eq p6,p7=r17,r0                     // was pgd_present(*pgd) == NULL?
-+      dep r17=r18,r17,3,(PAGE_SHIFT-3)        // r17=p[u|m]d_offset(pgd,addr)
-+      ;;
-+#ifdef CONFIG_PGTABLE_4
-+(p7)  ld8 r17=[r17]                           // get *pud (may be 0)
-+      shr.u r18=r22,PMD_SHIFT                 // shift pmd index into position
-+      ;;
-+(p7)  cmp.eq.or.andcm p6,p7=r17,r0            // was pud_present(*pud) == NULL?
-+      dep r17=r18,r17,3,(PAGE_SHIFT-3)        // r17=pmd_offset(pud,addr)
-+      ;;
-+#endif
-+(p7)  ld8 r17=[r17]                           // get *pmd (may be 0)
-+      shr.u r19=r22,PAGE_SHIFT                // shift pte index into position
-+      ;;
-+(p7)  cmp.eq.or.andcm p6,p7=r17,r0            // was pmd_present(*pmd) == NULL?
-+      dep r17=r19,r17,3,(PAGE_SHIFT-3)        // r17=pte_offset(pmd,addr);
-+(p6)  br.cond.spnt page_fault
-+      mov b0=r30
-+      br.sptk.many b0                         // return to continuation point
-+END(nested_dtlb_miss)
-+
-+      .org ia64_ivt+0x1800
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
-+ENTRY(ikey_miss)
-+      DBG_FAULT(6)
-+      FAULT(6)
-+END(ikey_miss)
-+
-+      //-----------------------------------------------------------------------------------
-+      // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
-+ENTRY(page_fault)
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_SSM_PSR_DT
-+#else
-+      ssm psr.dt
-+      ;;
-+      srlz.i
-+#endif
-+      ;;
-+      SAVE_MIN_WITH_COVER
-+      alloc r15=ar.pfs,0,0,3,0
-+#ifdef CONFIG_XEN
-+      movl r3=XSI_ISR
-+      ;;
-+      ld8 out1=[r3],XSI_IFA_OFS-XSI_ISR_OFS   // get vcr.isr, point to ifa
-+      ;;
-+      ld8 out0=[r3]                           // get vcr.ifa
-+      mov r14=1
-+      ;;
-+      add r3=XSI_PSR_IC_OFS-XSI_IFA_OFS, r3   // point to vpsr.ic
-+      ;;
-+      st4 [r3]=r14                            // vpsr.ic = 1
-+      adds r3=8,r2                            // set up second base pointer
-+      ;;
-+#else
-+      mov out0=cr.ifa
-+      mov out1=cr.isr
-+      adds r3=8,r2                            // set up second base pointer
-+      ;;
-+      ssm psr.ic | PSR_DEFAULT_BITS
-+      ;;
-+      srlz.i                                  // guarantee that interruption collectin is on
-+      ;;
-+#endif
-+#ifdef CONFIG_XEN
-+      br.cond.sptk.many       xen_page_fault
-+      ;;
-+done_xen_page_fault:
-+#endif
-+(p15) ssm psr.i                               // restore psr.i
-+      movl r14=ia64_leave_kernel
-+      ;;
-+      SAVE_REST
-+      mov rp=r14
-+      ;;
-+      adds out2=16,r12                        // out2 = pointer to pt_regs
-+      br.call.sptk.many b6=ia64_do_page_fault // ignore return address
-+END(page_fault)
-+
-+      .org ia64_ivt+0x1c00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
-+ENTRY(dkey_miss)
-+      DBG_FAULT(7)
-+      FAULT(7)
-+#ifdef CONFIG_XEN
-+      // Leaving this code inline above results in an IVT section overflow
-+      // There is no particular reason for this code to be here...
-+xen_page_fault:
-+(p15) movl r3=XSI_PSR_I_ADDR
-+      ;;
-+(p15) ld8 r3=[r3]
-+      ;;
-+(p15) st1 [r3]=r0,-1  // if (p15) vpsr.i = 1
-+      mov r14=r0
-+      ;;
-+(p15) ld1 r14=[r3]                            // if (pending_events)
-+      adds r3=8,r2                            // re-set up second base pointer
-+      ;;
-+(p15) cmp.ne  p15,p0=r14,r0
-+      ;;
-+      br.cond.sptk.many done_xen_page_fault
-+      ;;
-+#endif
-+END(dkey_miss)
-+
-+      .org ia64_ivt+0x2000
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
-+ENTRY(dirty_bit)
-+      DBG_FAULT(8)
-+      /*
-+       * What we do here is to simply turn on the dirty bit in the PTE.  We need to
-+       * update both the page-table and the TLB entry.  To efficiently access the PTE,
-+       * we address it through the virtual page table.  Most likely, the TLB entry for
-+       * the relevant virtual page table page is still present in the TLB so we can
-+       * normally do this without additional TLB misses.  In case the necessary virtual
-+       * page table TLB entry isn't present, we take a nested TLB miss hit where we look
-+       * up the physical address of the L3 PTE and then continue at label 1 below.
-+       */
-+#ifdef CONFIG_XEN
-+      movl r16=XSI_IFA
-+      ;;
-+      ld8 r16=[r16]
-+      ;;
-+#else
-+      mov r16=cr.ifa                          // get the address that caused the fault
-+#endif
-+      movl r30=1f                             // load continuation point in case of nested fault
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r18=r8;
-+      mov r8=r16;
-+      XEN_HYPER_THASH;;
-+      mov r17=r8;
-+      mov r8=r18;;
-+#else
-+      thash r17=r16                           // compute virtual address of L3 PTE
-+#endif
-+      mov r29=b0                              // save b0 in case of nested fault
-+      mov r31=pr                              // save pr
-+#ifdef CONFIG_SMP
-+      mov r28=ar.ccv                          // save ar.ccv
-+      ;;
-+1:    ld8 r18=[r17]
-+      ;;                                      // avoid RAW on r18
-+      mov ar.ccv=r18                          // set compare value for cmpxchg
-+      or r25=_PAGE_D|_PAGE_A,r18              // set the dirty and accessed bits
-+      tbit.z p7,p6 = r18,_PAGE_P_BIT          // Check present bit
-+      ;;
-+(p6)  cmpxchg8.acq r26=[r17],r25,ar.ccv       // Only update if page is present
-+      mov r24=PAGE_SHIFT<<2
-+      ;;
-+(p6)  cmp.eq p6,p7=r26,r18                    // Only compare if page is present
-+      ;;
-+#ifdef CONFIG_XEN
-+(p6)  mov r18=r8
-+(p6)  mov r8=r25
-+      ;;
-+(p6)  XEN_HYPER_ITC_D
-+      ;;
-+(p6)  mov r8=r18
-+#else
-+(p6)  itc.d r25                               // install updated PTE
-+#endif        
-+      ;;
-+      /*
-+       * Tell the assemblers dependency-violation checker that the above "itc" instructions
-+       * cannot possibly affect the following loads:
-+       */
-+      dv_serialize_data
-+
-+      ld8 r18=[r17]                           // read PTE again
-+      ;;
-+      cmp.eq p6,p7=r18,r25                    // is it same as the newly installed
-+      ;;
-+(p7)  ptc.l r16,r24
-+      mov b0=r29                              // restore b0
-+      mov ar.ccv=r28
-+#else
-+      ;;
-+1:    ld8 r18=[r17]
-+      ;;                                      // avoid RAW on r18
-+      or r18=_PAGE_D|_PAGE_A,r18              // set the dirty and accessed bits
-+      mov b0=r29                              // restore b0
-+      ;;
-+      st8 [r17]=r18                           // store back updated PTE
-+      itc.d r18                               // install updated PTE
-+#endif
-+      mov pr=r31,-1                           // restore pr
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RFI
-+      dv_serialize_data
-+#else
-+      rfi
-+#endif
-+END(dirty_bit)
-+
-+      .org ia64_ivt+0x2400
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
-+ENTRY(iaccess_bit)
-+      DBG_FAULT(9)
-+      // Like Entry 8, except for instruction access
-+#ifdef CONFIG_XEN
-+      movl r16=XSI_IFA
-+      ;;
-+      ld8 r16=[r16]
-+      ;;
-+#else
-+      mov r16=cr.ifa                          // get the address that caused the fault
-+#endif
-+      movl r30=1f                             // load continuation point in case of nested fault
-+      mov r31=pr                              // save predicates
-+#ifdef CONFIG_ITANIUM
-+      /*
-+       * Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
-+       */
-+      mov r17=cr.ipsr
-+      ;;
-+      mov r18=cr.iip
-+      tbit.z p6,p0=r17,IA64_PSR_IS_BIT        // IA64 instruction set?
-+      ;;
-+(p6)  mov r16=r18                             // if so, use cr.iip instead of cr.ifa
-+#endif /* CONFIG_ITANIUM */
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r18=r8;
-+      mov r8=r16;
-+      XEN_HYPER_THASH;;
-+      mov r17=r8;
-+      mov r8=r18;;
-+#else
-+      thash r17=r16                           // compute virtual address of L3 PTE
-+#endif
-+      mov r29=b0                              // save b0 in case of nested fault)
-+#ifdef CONFIG_SMP
-+      mov r28=ar.ccv                          // save ar.ccv
-+      ;;
-+1:    ld8 r18=[r17]
-+      ;;
-+      mov ar.ccv=r18                          // set compare value for cmpxchg
-+      or r25=_PAGE_A,r18                      // set the accessed bit
-+      tbit.z p7,p6 = r18,_PAGE_P_BIT          // Check present bit
-+      ;;
-+(p6)  cmpxchg8.acq r26=[r17],r25,ar.ccv       // Only if page present
-+      mov r24=PAGE_SHIFT<<2
-+      ;;
-+(p6)  cmp.eq p6,p7=r26,r18                    // Only if page present
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r26=r8
-+      mov r8=r25
-+      ;;
-+(p6)  XEN_HYPER_ITC_I
-+      ;;
-+      mov r8=r26
-+      ;;
-+#else
-+(p6)  itc.i r25                               // install updated PTE
-+#endif
-+      ;;
-+      /*
-+       * Tell the assemblers dependency-violation checker that the above "itc" instructions
-+       * cannot possibly affect the following loads:
-+       */
-+      dv_serialize_data
-+
-+      ld8 r18=[r17]                           // read PTE again
-+      ;;
-+      cmp.eq p6,p7=r18,r25                    // is it same as the newly installed
-+      ;;
-+(p7)  ptc.l r16,r24
-+      mov b0=r29                              // restore b0
-+      mov ar.ccv=r28
-+#else /* !CONFIG_SMP */
-+      ;;
-+1:    ld8 r18=[r17]
-+      ;;
-+      or r18=_PAGE_A,r18                      // set the accessed bit
-+      mov b0=r29                              // restore b0
-+      ;;
-+      st8 [r17]=r18                           // store back updated PTE
-+      itc.i r18                               // install updated PTE
-+#endif /* !CONFIG_SMP */
-+      mov pr=r31,-1
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RFI
-+      dv_serialize_data
-+#else
-+      rfi
-+#endif
-+END(iaccess_bit)
-+
-+      .org ia64_ivt+0x2800
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
-+ENTRY(daccess_bit)
-+      DBG_FAULT(10)
-+      // Like Entry 8, except for data access
-+#ifdef CONFIG_XEN
-+      movl r16=XSI_IFA
-+      ;;
-+      ld8 r16=[r16]
-+      ;;
-+#else
-+      mov r16=cr.ifa                          // get the address that caused the fault
-+#endif
-+      movl r30=1f                             // load continuation point in case of nested fault
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r18=r8
-+      mov r8=r16
-+      XEN_HYPER_THASH
-+      ;;
-+      mov r17=r8
-+      mov r8=r18
-+      ;;
-+#else
-+      thash r17=r16                           // compute virtual address of L3 PTE
-+#endif
-+      mov r31=pr
-+      mov r29=b0                              // save b0 in case of nested fault)
-+#ifdef CONFIG_SMP
-+      mov r28=ar.ccv                          // save ar.ccv
-+      ;;
-+1:    ld8 r18=[r17]
-+      ;;                                      // avoid RAW on r18
-+      mov ar.ccv=r18                          // set compare value for cmpxchg
-+      or r25=_PAGE_A,r18                      // set the dirty bit
-+      tbit.z p7,p6 = r18,_PAGE_P_BIT          // Check present bit
-+      ;;
-+(p6)  cmpxchg8.acq r26=[r17],r25,ar.ccv       // Only if page is present
-+      mov r24=PAGE_SHIFT<<2
-+      ;;
-+(p6)  cmp.eq p6,p7=r26,r18                    // Only if page is present
-+      ;;
-+#ifdef CONFIG_XEN
-+      mov r26=r8
-+      mov r8=r25
-+      ;;
-+(p6)  XEN_HYPER_ITC_D
-+      ;;
-+      mov r8=r26
-+      ;;
-+#else
-+(p6)  itc.d r25                               // install updated PTE
-+#endif
-+      /*
-+       * Tell the assemblers dependency-violation checker that the above "itc" instructions
-+       * cannot possibly affect the following loads:
-+       */
-+      dv_serialize_data
-+      ;;
-+      ld8 r18=[r17]                           // read PTE again
-+      ;;
-+      cmp.eq p6,p7=r18,r25                    // is it same as the newly installed
-+      ;;
-+(p7)  ptc.l r16,r24
-+      mov ar.ccv=r28
-+#else
-+      ;;
-+1:    ld8 r18=[r17]
-+      ;;                                      // avoid RAW on r18
-+      or r18=_PAGE_A,r18                      // set the accessed bit
-+      ;;
-+      st8 [r17]=r18                           // store back updated PTE
-+      itc.d r18                               // install updated PTE
-+#endif
-+      mov b0=r29                              // restore b0
-+      mov pr=r31,-1
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RFI
-+      dv_serialize_data
-+#else
-+      rfi
-+#endif
-+END(daccess_bit)
-+
-+      .org ia64_ivt+0x2c00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
-+ENTRY(break_fault)
-+      /*
-+       * The streamlined system call entry/exit paths only save/restore the initial part
-+       * of pt_regs.  This implies that the callers of system-calls must adhere to the
-+       * normal procedure calling conventions.
-+       *
-+       *   Registers to be saved & restored:
-+       *      CR registers: cr.ipsr, cr.iip, cr.ifs
-+       *      AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
-+       *      others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
-+       *   Registers to be restored only:
-+       *      r8-r11: output value from the system call.
-+       *
-+       * During system call exit, scratch registers (including r15) are modified/cleared
-+       * to prevent leaking bits from kernel to user level.
-+       */
-+      DBG_FAULT(11)
-+      mov.m r16=IA64_KR(CURRENT)              // M2 r16 <- current task (12 cyc)
-+#ifdef CONFIG_XEN
-+      movl r22=XSI_IPSR
-+      ;;
-+      ld8 r29=[r22],XSI_IIM_OFS-XSI_IPSR_OFS  // get ipsr, point to iip
-+#else
-+      mov r29=cr.ipsr                         // M2 (12 cyc)
-+#endif
-+      mov r31=pr                              // I0 (2 cyc)
-+
-+#ifdef CONFIG_XEN
-+      ;;
-+      ld8 r17=[r22],XSI_IIP_OFS-XSI_IIM_OFS
-+#else
-+      mov r17=cr.iim                          // M2 (2 cyc)
-+#endif
-+      mov.m r27=ar.rsc                        // M2 (12 cyc)
-+      mov r18=__IA64_BREAK_SYSCALL            // A
-+
-+      mov.m ar.rsc=0                          // M2
-+      mov.m r21=ar.fpsr                       // M2 (12 cyc)
-+      mov r19=b6                              // I0 (2 cyc)
-+      ;;
-+      mov.m r23=ar.bspstore                   // M2 (12 cyc)
-+      mov.m r24=ar.rnat                       // M2 (5 cyc)
-+      mov.i r26=ar.pfs                        // I0 (2 cyc)
-+
-+      invala                                  // M0|1
-+      nop.m 0                                 // M
-+      mov r20=r1                              // A                    save r1
-+
-+      nop.m 0
-+      movl r30=sys_call_table                 // X
-+
-+#ifdef CONFIG_XEN
-+      ld8 r28=[r22]
-+#else
-+      mov r28=cr.iip                          // M2 (2 cyc)
-+#endif
-+      cmp.eq p0,p7=r18,r17                    // I0 is this a system call?
-+(p7)  br.cond.spnt non_syscall                // B  no ->
-+      //
-+      // From this point on, we are definitely on the syscall-path
-+      // and we can use (non-banked) scratch registers.
-+      //
-+///////////////////////////////////////////////////////////////////////
-+      mov r1=r16                              // A    move task-pointer to "addl"-addressable reg
-+      mov r2=r16                              // A    setup r2 for ia64_syscall_setup
-+      add r9=TI_FLAGS+IA64_TASK_SIZE,r16      // A    r9 = &current_thread_info()->flags
-+
-+      adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
-+      adds r15=-1024,r15                      // A    subtract 1024 from syscall number
-+      mov r3=NR_syscalls - 1
-+      ;;
-+      ld1.bias r17=[r16]                      // M0|1 r17 = current->thread.on_ustack flag
-+      ld4 r9=[r9]                             // M0|1 r9 = current_thread_info()->flags
-+      extr.u r8=r29,41,2                      // I0   extract ei field from cr.ipsr
-+
-+      shladd r30=r15,3,r30                    // A    r30 = sys_call_table + 8*(syscall-1024)
-+      addl r22=IA64_RBS_OFFSET,r1             // A    compute base of RBS
-+      cmp.leu p6,p7=r15,r3                    // A    syscall number in range?
-+      ;;
-+
-+      lfetch.fault.excl.nt1 [r22]             // M0|1 prefetch RBS
-+(p6)  ld8 r30=[r30]                           // M0|1 load address of syscall entry point
-+      tnat.nz.or p7,p0=r15                    // I0   is syscall nr a NaT?
-+
-+      mov.m ar.bspstore=r22                   // M2   switch to kernel RBS
-+      cmp.eq p8,p9=2,r8                       // A    isr.ei==2?
-+      ;;
-+
-+(p8)  mov r8=0                                // A    clear ei to 0
-+(p7)  movl r30=sys_ni_syscall                 // X
-+
-+(p8)  adds r28=16,r28                         // A    switch cr.iip to next bundle
-+(p9)  adds r8=1,r8                            // A    increment ei to next slot
-+      nop.i 0
-+      ;;
-+
-+      mov.m r25=ar.unat                       // M2 (5 cyc)
-+      dep r29=r8,r29,41,2                     // I0   insert new ei into cr.ipsr
-+      adds r15=1024,r15                       // A    restore original syscall number
-+      //
-+      // If any of the above loads miss in L1D, we'll stall here until
-+      // the data arrives.
-+      //
-+///////////////////////////////////////////////////////////////////////
-+      st1 [r16]=r0                            // M2|3 clear current->thread.on_ustack flag
-+      mov b6=r30                              // I0   setup syscall handler branch reg early
-+      cmp.eq pKStk,pUStk=r0,r17               // A    were we on kernel stacks already?
-+
-+      and r9=_TIF_SYSCALL_TRACEAUDIT,r9       // A    mask trace or audit
-+      mov r18=ar.bsp                          // M2 (12 cyc)
-+(pKStk)       br.cond.spnt .break_fixup               // B    we're already in kernel-mode -- fix up RBS
-+      ;;
-+.back_from_break_fixup:
-+(pUStk)       addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute base of memory stack
-+      cmp.eq p14,p0=r9,r0                     // A    are syscalls being traced/audited?
-+      br.call.sptk.many b7=ia64_syscall_setup // B
-+1:
-+      mov ar.rsc=0x3                          // M2   set eager mode, pl 0, LE, loadrs=0
-+      nop 0
-+#ifdef CONFIG_XEN
-+      mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;;
-+#else
-+      bsw.1                                   // B (6 cyc) regs are saved, switch to bank 1
-+#endif
-+      ;;
-+
-+#ifdef CONFIG_XEN
-+      movl r16=XSI_PSR_IC
-+      mov r3=1
-+      ;;
-+      st4 [r16]=r3,XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS  // vpsr.ic = 1
-+#else
-+      ssm psr.ic | PSR_DEFAULT_BITS           // M2   now it's safe to re-enable intr.-collection
-+#endif
-+      movl r3=ia64_ret_from_syscall           // X
-+      ;;
-+
-+      srlz.i                                  // M0   ensure interruption collection is on
-+      mov rp=r3                               // I0   set the real return addr
-+(p10) br.cond.spnt.many ia64_ret_from_syscall // B    return if bad call-frame or r15 is a NaT
-+
-+#ifdef CONFIG_XEN
-+(p15) ld8 r16=[r16]                           // vpsr.i
-+      ;;
-+(p15) st1 [r16]=r0,-1         // if (p15) vpsr.i = 1
-+      mov r2=r0
-+      ;;
-+(p15) ld1 r2=[r16]                            // if (pending_events)
-+      ;;
-+      cmp.ne  p6,p0=r2,r0
-+      ;;
-+(p6)  ssm     psr.i                           //   do a real ssm psr.i
-+#else
-+(p15) ssm psr.i                               // M2   restore psr.i
-+#endif
-+(p14) br.call.sptk.many b6=b6                 // B    invoke syscall-handker (ignore return addr)
-+      br.cond.spnt.many ia64_trace_syscall    // B    do syscall-tracing thingamagic
-+      // NOT REACHED
-+///////////////////////////////////////////////////////////////////////
-+      // On entry, we optimistically assumed that we're coming from user-space.
-+      // For the rare cases where a system-call is done from within the kernel,
-+      // we fix things up at this point:
-+.break_fixup:
-+      add r1=-IA64_PT_REGS_SIZE,sp            // A    allocate space for pt_regs structure
-+      mov ar.rnat=r24                         // M2   restore kernel's AR.RNAT
-+      ;;
-+      mov ar.bspstore=r23                     // M2   restore kernel's AR.BSPSTORE
-+      br.cond.sptk .back_from_break_fixup
-+END(break_fault)
-+
-+      .org ia64_ivt+0x3000
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
-+ENTRY(interrupt)
-+      DBG_FAULT(12)
-+      mov r31=pr              // prepare to save predicates
-+      ;;
-+      SAVE_MIN_WITH_COVER     // uses r31; defines r2 and r3
-+#ifdef CONFIG_XEN
-+      movl r3=XSI_PSR_IC
-+      mov r14=1
-+      ;;
-+      st4 [r3]=r14
-+#else
-+      ssm psr.ic | PSR_DEFAULT_BITS
-+#endif
-+      ;;
-+      adds r3=8,r2            // set up second base pointer for SAVE_REST
-+      srlz.i                  // ensure everybody knows psr.ic is back on
-+      ;;
-+      SAVE_REST
-+      ;;
-+      alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
-+#ifdef CONFIG_XEN
-+      ;;
-+      br.call.sptk.many rp=xen_get_ivr
-+      ;;
-+      mov out0=r8             // pass cr.ivr as first arg
-+#else
-+      mov out0=cr.ivr         // pass cr.ivr as first arg
-+#endif
-+      add out1=16,sp          // pass pointer to pt_regs as second arg
-+      ;;
-+      srlz.d                  // make sure we see the effect of cr.ivr
-+      movl r14=ia64_leave_kernel
-+      ;;
-+      mov rp=r14
-+      br.call.sptk.many b6=ia64_handle_irq
-+END(interrupt)
-+
-+      .org ia64_ivt+0x3400
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x3400 Entry 13 (size 64 bundles) Reserved
-+      DBG_FAULT(13)
-+      FAULT(13)
-+
-+      .org ia64_ivt+0x3800
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x3800 Entry 14 (size 64 bundles) Reserved
-+      DBG_FAULT(14)
-+      FAULT(14)
-+
-+      /*
-+       * There is no particular reason for this code to be here, other than that
-+       * there happens to be space here that would go unused otherwise.  If this
-+       * fault ever gets "unreserved", simply moved the following code to a more
-+       * suitable spot...
-+       *
-+       * ia64_syscall_setup() is a separate subroutine so that it can
-+       *      allocate stacked registers so it can safely demine any
-+       *      potential NaT values from the input registers.
-+       *
-+       * On entry:
-+       *      - executing on bank 0 or bank 1 register set (doesn't matter)
-+       *      -  r1: stack pointer
-+       *      -  r2: current task pointer
-+       *      -  r3: preserved
-+       *      - r11: original contents (saved ar.pfs to be saved)
-+       *      - r12: original contents (sp to be saved)
-+       *      - r13: original contents (tp to be saved)
-+       *      - r15: original contents (syscall # to be saved)
-+       *      - r18: saved bsp (after switching to kernel stack)
-+       *      - r19: saved b6
-+       *      - r20: saved r1 (gp)
-+       *      - r21: saved ar.fpsr
-+       *      - r22: kernel's register backing store base (krbs_base)
-+       *      - r23: saved ar.bspstore
-+       *      - r24: saved ar.rnat
-+       *      - r25: saved ar.unat
-+       *      - r26: saved ar.pfs
-+       *      - r27: saved ar.rsc
-+       *      - r28: saved cr.iip
-+       *      - r29: saved cr.ipsr
-+       *      - r31: saved pr
-+       *      -  b0: original contents (to be saved)
-+       * On exit:
-+       *      -  p10: TRUE if syscall is invoked with more than 8 out
-+       *              registers or r15's Nat is true
-+       *      -  r1: kernel's gp
-+       *      -  r3: preserved (same as on entry)
-+       *      -  r8: -EINVAL if p10 is true
-+       *      - r12: points to kernel stack
-+       *      - r13: points to current task
-+       *      - r14: preserved (same as on entry)
-+       *      - p13: preserved
-+       *      - p15: TRUE if interrupts need to be re-enabled
-+       *      - ar.fpsr: set to kernel settings
-+       *      -  b6: preserved (same as on entry)
-+       */
-+#ifndef CONFIG_XEN
-+GLOBAL_ENTRY(ia64_syscall_setup)
-+#if PT(B6) != 0
-+# error This code assumes that b6 is the first field in pt_regs.
-+#endif
-+      st8 [r1]=r19                            // save b6
-+      add r16=PT(CR_IPSR),r1                  // initialize first base pointer
-+      add r17=PT(R11),r1                      // initialize second base pointer
-+      ;;
-+      alloc r19=ar.pfs,8,0,0,0                // ensure in0-in7 are writable
-+      st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)    // save cr.ipsr
-+      tnat.nz p8,p0=in0
-+
-+      st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)  // save r11
-+      tnat.nz p9,p0=in1
-+(pKStk)       mov r18=r0                              // make sure r18 isn't NaT
-+      ;;
-+
-+      st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)     // save ar.pfs
-+      st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)    // save cr.iip
-+      mov r28=b0                              // save b0 (2 cyc)
-+      ;;
-+
-+      st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)    // save ar.unat
-+      dep r19=0,r19,38,26                     // clear all bits but 0..37 [I0]
-+(p8)  mov in0=-1
-+      ;;
-+
-+      st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)    // store ar.pfs.pfm in cr.ifs
-+      extr.u r11=r19,7,7      // I0           // get sol of ar.pfs
-+      and r8=0x7f,r19         // A            // get sof of ar.pfs
-+
-+      st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
-+      tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
-+(p9)  mov in1=-1
-+      ;;
-+
-+(pUStk) sub r18=r18,r22                               // r18=RSE.ndirty*8
-+      tnat.nz p10,p0=in2
-+      add r11=8,r11
-+      ;;
-+(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16               // skip over ar_rnat field
-+(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17   // skip over ar_bspstore field
-+      tnat.nz p11,p0=in3
-+      ;;
-+(p10) mov in2=-1
-+      tnat.nz p12,p0=in4                              // [I0]
-+(p11) mov in3=-1
-+      ;;
-+(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)      // save ar.rnat
-+(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)  // save ar.bspstore
-+      shl r18=r18,16                          // compute ar.rsc to be used for "loadrs"
-+      ;;
-+      st8 [r16]=r31,PT(LOADRS)-PT(PR)         // save predicates
-+      st8 [r17]=r28,PT(R1)-PT(B0)             // save b0
-+      tnat.nz p13,p0=in5                              // [I0]
-+      ;;
-+      st8 [r16]=r18,PT(R12)-PT(LOADRS)        // save ar.rsc value for "loadrs"
-+      st8.spill [r17]=r20,PT(R13)-PT(R1)      // save original r1
-+(p12) mov in4=-1
-+      ;;
-+
-+.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)      // save r12
-+.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)          // save r13
-+(p13) mov in5=-1
-+      ;;
-+      st8 [r16]=r21,PT(R8)-PT(AR_FPSR)        // save ar.fpsr
-+      tnat.nz p13,p0=in6
-+      cmp.lt p10,p9=r11,r8    // frame size can't be more than local+8
-+      ;;
-+      mov r8=1
-+(p9)  tnat.nz p10,p0=r15
-+      adds r12=-16,r1         // switch to kernel memory stack (with 16 bytes of scratch)
-+
-+      st8.spill [r17]=r15                     // save r15
-+      tnat.nz p8,p0=in7
-+      nop.i 0
-+
-+      mov r13=r2                              // establish `current'
-+      movl r1=__gp                            // establish kernel global pointer
-+      ;;
-+      st8 [r16]=r8            // ensure pt_regs.r8 != 0 (see handle_syscall_error)
-+(p13) mov in6=-1
-+(p8)  mov in7=-1
-+
-+      cmp.eq pSys,pNonSys=r0,r0               // set pSys=1, pNonSys=0
-+      movl r17=FPSR_DEFAULT
-+      ;;
-+      mov.m ar.fpsr=r17                       // set ar.fpsr to kernel default value
-+(p10) mov r8=-EINVAL
-+      br.ret.sptk.many b7
-+END(ia64_syscall_setup)
-+#endif
-+
-+      .org ia64_ivt+0x3c00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x3c00 Entry 15 (size 64 bundles) Reserved
-+      DBG_FAULT(15)
-+      FAULT(15)
-+
-+      /*
-+       * Squatting in this space ...
-+       *
-+       * This special case dispatcher for illegal operation faults allows preserved
-+       * registers to be modified through a callback function (asm only) that is handed
-+       * back from the fault handler in r8. Up to three arguments can be passed to the
-+       * callback function by returning an aggregate with the callback as its first
-+       * element, followed by the arguments.
-+       */
-+ENTRY(dispatch_illegal_op_fault)
-+      .prologue
-+      .body
-+      SAVE_MIN_WITH_COVER
-+      ssm psr.ic | PSR_DEFAULT_BITS
-+      ;;
-+      srlz.i          // guarantee that interruption collection is on
-+      ;;
-+(p15) ssm psr.i       // restore psr.i
-+      adds r3=8,r2    // set up second base pointer for SAVE_REST
-+      ;;
-+      alloc r14=ar.pfs,0,0,1,0        // must be first in insn group
-+      mov out0=ar.ec
-+      ;;
-+      SAVE_REST
-+      PT_REGS_UNWIND_INFO(0)
-+      ;;
-+      br.call.sptk.many rp=ia64_illegal_op_fault
-+.ret0:        ;;
-+      alloc r14=ar.pfs,0,0,3,0        // must be first in insn group
-+      mov out0=r9
-+      mov out1=r10
-+      mov out2=r11
-+      movl r15=ia64_leave_kernel
-+      ;;
-+      mov rp=r15
-+      mov b6=r8
-+      ;;
-+      cmp.ne p6,p0=0,r8
-+(p6)  br.call.dpnt.many b6=b6         // call returns to ia64_leave_kernel
-+      br.sptk.many ia64_leave_kernel
-+END(dispatch_illegal_op_fault)
-+
-+      .org ia64_ivt+0x4000
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x4000 Entry 16 (size 64 bundles) Reserved
-+      DBG_FAULT(16)
-+      FAULT(16)
-+
-+      .org ia64_ivt+0x4400
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x4400 Entry 17 (size 64 bundles) Reserved
-+      DBG_FAULT(17)
-+      FAULT(17)
-+
-+ENTRY(non_syscall)
-+      mov ar.rsc=r27                  // restore ar.rsc before SAVE_MIN_WITH_COVER
-+      ;;
-+      SAVE_MIN_WITH_COVER
-+
-+      // There is no particular reason for this code to be here, other than that
-+      // there happens to be space here that would go unused otherwise.  If this
-+      // fault ever gets "unreserved", simply moved the following code to a more
-+      // suitable spot...
-+
-+      alloc r14=ar.pfs,0,0,2,0
-+      mov out0=cr.iim
-+      add out1=16,sp
-+      adds r3=8,r2                    // set up second base pointer for SAVE_REST
-+
-+      ssm psr.ic | PSR_DEFAULT_BITS
-+      ;;
-+      srlz.i                          // guarantee that interruption collection is on
-+      ;;
-+(p15) ssm psr.i                       // restore psr.i
-+      movl r15=ia64_leave_kernel
-+      ;;
-+      SAVE_REST
-+      mov rp=r15
-+      ;;
-+      br.call.sptk.many b6=ia64_bad_break     // avoid WAW on CFM and ignore return addr
-+END(non_syscall)
-+
-+      .org ia64_ivt+0x4800
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x4800 Entry 18 (size 64 bundles) Reserved
-+      DBG_FAULT(18)
-+      FAULT(18)
-+
-+      /*
-+       * There is no particular reason for this code to be here, other than that
-+       * there happens to be space here that would go unused otherwise.  If this
-+       * fault ever gets "unreserved", simply moved the following code to a more
-+       * suitable spot...
-+       */
-+
-+ENTRY(dispatch_unaligned_handler)
-+      SAVE_MIN_WITH_COVER
-+      ;;
-+      alloc r14=ar.pfs,0,0,2,0                // now it's safe (must be first in insn group!)
-+      mov out0=cr.ifa
-+      adds out1=16,sp
-+
-+      ssm psr.ic | PSR_DEFAULT_BITS
-+      ;;
-+      srlz.i                                  // guarantee that interruption collection is on
-+      ;;
-+(p15) ssm psr.i                               // restore psr.i
-+      adds r3=8,r2                            // set up second base pointer
-+      ;;
-+      SAVE_REST
-+      movl r14=ia64_leave_kernel
-+      ;;
-+      mov rp=r14
-+      br.sptk.many ia64_prepare_handle_unaligned
-+END(dispatch_unaligned_handler)
-+
-+      .org ia64_ivt+0x4c00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x4c00 Entry 19 (size 64 bundles) Reserved
-+      DBG_FAULT(19)
-+      FAULT(19)
-+
-+      /*
-+       * There is no particular reason for this code to be here, other than that
-+       * there happens to be space here that would go unused otherwise.  If this
-+       * fault ever gets "unreserved", simply moved the following code to a more
-+       * suitable spot...
-+       */
-+
-+ENTRY(dispatch_to_fault_handler)
-+      /*
-+       * Input:
-+       *      psr.ic: off
-+       *      r19:    fault vector number (e.g., 24 for General Exception)
-+       *      r31:    contains saved predicates (pr)
-+       */
-+      SAVE_MIN_WITH_COVER_R19
-+      alloc r14=ar.pfs,0,0,5,0
-+      mov out0=r15
-+#ifdef CONFIG_XEN
-+      movl out1=XSI_ISR
-+      ;;
-+      adds out2=XSI_IFA-XSI_ISR,out1
-+      adds out3=XSI_IIM-XSI_ISR,out1
-+      adds out4=XSI_ITIR-XSI_ISR,out1
-+      ;;
-+      ld8 out1=[out1]
-+      ld8 out2=[out2]
-+      ld8 out3=[out4]
-+      ld8 out4=[out4]
-+      ;;
-+#else
-+      mov out1=cr.isr
-+      mov out2=cr.ifa
-+      mov out3=cr.iim
-+      mov out4=cr.itir
-+      ;;
-+#endif
-+      ssm psr.ic | PSR_DEFAULT_BITS
-+      ;;
-+      srlz.i                                  // guarantee that interruption collection is on
-+      ;;
-+(p15) ssm psr.i                               // restore psr.i
-+      adds r3=8,r2                            // set up second base pointer for SAVE_REST
-+      ;;
-+      SAVE_REST
-+      movl r14=ia64_leave_kernel
-+      ;;
-+      mov rp=r14
-+      br.call.sptk.many b6=ia64_fault
-+END(dispatch_to_fault_handler)
-+
-+//
-+// --- End of long entries, Beginning of short entries
-+//
-+
-+      .org ia64_ivt+0x5000
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
-+ENTRY(page_not_present)
-+      DBG_FAULT(20)
-+      mov r16=cr.ifa
-+      rsm psr.dt
-+      /*
-+       * The Linux page fault handler doesn't expect non-present pages to be in
-+       * the TLB.  Flush the existing entry now, so we meet that expectation.
-+       */
-+      mov r17=PAGE_SHIFT<<2
-+      ;;
-+      ptc.l r16,r17
-+      ;;
-+      mov r31=pr
-+      srlz.d
-+      br.sptk.many page_fault
-+END(page_not_present)
-+
-+      .org ia64_ivt+0x5100
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
-+ENTRY(key_permission)
-+      DBG_FAULT(21)
-+      mov r16=cr.ifa
-+      rsm psr.dt
-+      mov r31=pr
-+      ;;
-+      srlz.d
-+      br.sptk.many page_fault
-+END(key_permission)
-+
-+      .org ia64_ivt+0x5200
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
-+ENTRY(iaccess_rights)
-+      DBG_FAULT(22)
-+      mov r16=cr.ifa
-+      rsm psr.dt
-+      mov r31=pr
-+      ;;
-+      srlz.d
-+      br.sptk.many page_fault
-+END(iaccess_rights)
-+
-+      .org ia64_ivt+0x5300
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
-+ENTRY(daccess_rights)
-+      DBG_FAULT(23)
-+#ifdef CONFIG_XEN
-+      movl r16=XSI_IFA
-+      ;;
-+      ld8 r16=[r16]
-+      ;;
-+      XEN_HYPER_RSM_PSR_DT
-+#else
-+      mov r16=cr.ifa
-+      rsm psr.dt
-+#endif
-+      mov r31=pr
-+      ;;
-+      srlz.d
-+      br.sptk.many page_fault
-+END(daccess_rights)
-+
-+      .org ia64_ivt+0x5400
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
-+ENTRY(general_exception)
-+      DBG_FAULT(24)
-+      mov r16=cr.isr
-+      mov r31=pr
-+      ;;
-+      cmp4.eq p6,p0=0,r16
-+(p6)  br.sptk.many dispatch_illegal_op_fault
-+      ;;
-+      mov r19=24              // fault number
-+      br.sptk.many dispatch_to_fault_handler
-+END(general_exception)
-+
-+      .org ia64_ivt+0x5500
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
-+ENTRY(disabled_fp_reg)
-+      DBG_FAULT(25)
-+      rsm psr.dfh             // ensure we can access fph
-+      ;;
-+      srlz.d
-+      mov r31=pr
-+      mov r19=25
-+      br.sptk.many dispatch_to_fault_handler
-+END(disabled_fp_reg)
-+
-+      .org ia64_ivt+0x5600
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
-+ENTRY(nat_consumption)
-+      DBG_FAULT(26)
-+
-+      mov r16=cr.ipsr
-+      mov r17=cr.isr
-+      mov r31=pr                              // save PR
-+      ;;
-+      and r18=0xf,r17                         // r18 = cr.ipsr.code{3:0}
-+      tbit.z p6,p0=r17,IA64_ISR_NA_BIT
-+      ;;
-+      cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18
-+      dep r16=-1,r16,IA64_PSR_ED_BIT,1
-+(p6)  br.cond.spnt 1f         // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
-+      ;;
-+      mov cr.ipsr=r16         // set cr.ipsr.na
-+      mov pr=r31,-1
-+      ;;
-+      rfi
-+
-+1:    mov pr=r31,-1
-+      ;;
-+      FAULT(26)
-+END(nat_consumption)
-+
-+      .org ia64_ivt+0x5700
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5700 Entry 27 (size 16 bundles) Speculation (40)
-+ENTRY(speculation_vector)
-+      DBG_FAULT(27)
-+      /*
-+       * A [f]chk.[as] instruction needs to take the branch to the recovery code but
-+       * this part of the architecture is not implemented in hardware on some CPUs, such
-+       * as Itanium.  Thus, in general we need to emulate the behavior.  IIM contains
-+       * the relative target (not yet sign extended).  So after sign extending it we
-+       * simply add it to IIP.  We also need to reset the EI field of the IPSR to zero,
-+       * i.e., the slot to restart into.
-+       *
-+       * cr.imm contains zero_ext(imm21)
-+       */
-+      mov r18=cr.iim
-+      ;;
-+      mov r17=cr.iip
-+      shl r18=r18,43                  // put sign bit in position (43=64-21)
-+      ;;
-+
-+      mov r16=cr.ipsr
-+      shr r18=r18,39                  // sign extend (39=43-4)
-+      ;;
-+
-+      add r17=r17,r18                 // now add the offset
-+      ;;
-+      mov cr.iip=r17
-+      dep r16=0,r16,41,2              // clear EI
-+      ;;
-+
-+      mov cr.ipsr=r16
-+      ;;
-+
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RFI;
-+#else
-+      rfi                             // and go back
-+#endif
-+END(speculation_vector)
-+
-+      .org ia64_ivt+0x5800
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5800 Entry 28 (size 16 bundles) Reserved
-+      DBG_FAULT(28)
-+      FAULT(28)
-+
-+      .org ia64_ivt+0x5900
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
-+ENTRY(debug_vector)
-+      DBG_FAULT(29)
-+      FAULT(29)
-+END(debug_vector)
-+
-+      .org ia64_ivt+0x5a00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
-+ENTRY(unaligned_access)
-+      DBG_FAULT(30)
-+      mov r31=pr              // prepare to save predicates
-+      ;;
-+      br.sptk.many dispatch_unaligned_handler
-+END(unaligned_access)
-+
-+      .org ia64_ivt+0x5b00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
-+ENTRY(unsupported_data_reference)
-+      DBG_FAULT(31)
-+      FAULT(31)
-+END(unsupported_data_reference)
-+
-+      .org ia64_ivt+0x5c00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
-+ENTRY(floating_point_fault)
-+      DBG_FAULT(32)
-+      FAULT(32)
-+END(floating_point_fault)
-+
-+      .org ia64_ivt+0x5d00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
-+ENTRY(floating_point_trap)
-+      DBG_FAULT(33)
-+      FAULT(33)
-+END(floating_point_trap)
-+
-+      .org ia64_ivt+0x5e00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
-+ENTRY(lower_privilege_trap)
-+      DBG_FAULT(34)
-+      FAULT(34)
-+END(lower_privilege_trap)
-+
-+      .org ia64_ivt+0x5f00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
-+ENTRY(taken_branch_trap)
-+      DBG_FAULT(35)
-+      FAULT(35)
-+END(taken_branch_trap)
-+
-+      .org ia64_ivt+0x6000
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
-+ENTRY(single_step_trap)
-+      DBG_FAULT(36)
-+      FAULT(36)
-+END(single_step_trap)
-+
-+      .org ia64_ivt+0x6100
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6100 Entry 37 (size 16 bundles) Reserved
-+      DBG_FAULT(37)
-+      FAULT(37)
-+
-+      .org ia64_ivt+0x6200
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6200 Entry 38 (size 16 bundles) Reserved
-+      DBG_FAULT(38)
-+      FAULT(38)
-+
-+      .org ia64_ivt+0x6300
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6300 Entry 39 (size 16 bundles) Reserved
-+      DBG_FAULT(39)
-+      FAULT(39)
-+
-+      .org ia64_ivt+0x6400
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6400 Entry 40 (size 16 bundles) Reserved
-+      DBG_FAULT(40)
-+      FAULT(40)
-+
-+      .org ia64_ivt+0x6500
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6500 Entry 41 (size 16 bundles) Reserved
-+      DBG_FAULT(41)
-+      FAULT(41)
-+
-+      .org ia64_ivt+0x6600
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6600 Entry 42 (size 16 bundles) Reserved
-+      DBG_FAULT(42)
-+      FAULT(42)
-+
-+      .org ia64_ivt+0x6700
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6700 Entry 43 (size 16 bundles) Reserved
-+      DBG_FAULT(43)
-+      FAULT(43)
-+
-+      .org ia64_ivt+0x6800
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6800 Entry 44 (size 16 bundles) Reserved
-+      DBG_FAULT(44)
-+      FAULT(44)
-+
-+      .org ia64_ivt+0x6900
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77)
-+ENTRY(ia32_exception)
-+      DBG_FAULT(45)
-+      FAULT(45)
-+END(ia32_exception)
-+
-+      .org ia64_ivt+0x6a00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
-+ENTRY(ia32_intercept)
-+      DBG_FAULT(46)
-+#ifdef        CONFIG_IA32_SUPPORT
-+      mov r31=pr
-+      mov r16=cr.isr
-+      ;;
-+      extr.u r17=r16,16,8     // get ISR.code
-+      mov r18=ar.eflag
-+      mov r19=cr.iim          // old eflag value
-+      ;;
-+      cmp.ne p6,p0=2,r17
-+(p6)  br.cond.spnt 1f         // not a system flag fault
-+      xor r16=r18,r19
-+      ;;
-+      extr.u r17=r16,18,1     // get the eflags.ac bit
-+      ;;
-+      cmp.eq p6,p0=0,r17
-+(p6)  br.cond.spnt 1f         // eflags.ac bit didn't change
-+      ;;
-+      mov pr=r31,-1           // restore predicate registers
-+#ifdef CONFIG_XEN
-+      XEN_HYPER_RFI;
-+#else
-+      rfi
-+#endif
-+
-+1:
-+#endif        // CONFIG_IA32_SUPPORT
-+      FAULT(46)
-+END(ia32_intercept)
-+
-+      .org ia64_ivt+0x6b00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
-+ENTRY(ia32_interrupt)
-+      DBG_FAULT(47)
-+#ifdef CONFIG_IA32_SUPPORT
-+      mov r31=pr
-+      br.sptk.many dispatch_to_ia32_handler
-+#else
-+      FAULT(47)
-+#endif
-+END(ia32_interrupt)
-+
-+      .org ia64_ivt+0x6c00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6c00 Entry 48 (size 16 bundles) Reserved
-+      DBG_FAULT(48)
-+      FAULT(48)
-+
-+      .org ia64_ivt+0x6d00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6d00 Entry 49 (size 16 bundles) Reserved
-+      DBG_FAULT(49)
-+      FAULT(49)
-+
-+      .org ia64_ivt+0x6e00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6e00 Entry 50 (size 16 bundles) Reserved
-+      DBG_FAULT(50)
-+      FAULT(50)
-+
-+      .org ia64_ivt+0x6f00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x6f00 Entry 51 (size 16 bundles) Reserved
-+      DBG_FAULT(51)
-+      FAULT(51)
-+
-+      .org ia64_ivt+0x7000
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7000 Entry 52 (size 16 bundles) Reserved
-+      DBG_FAULT(52)
-+      FAULT(52)
-+
-+      .org ia64_ivt+0x7100
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7100 Entry 53 (size 16 bundles) Reserved
-+      DBG_FAULT(53)
-+      FAULT(53)
-+
-+      .org ia64_ivt+0x7200
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7200 Entry 54 (size 16 bundles) Reserved
-+      DBG_FAULT(54)
-+      FAULT(54)
-+
-+      .org ia64_ivt+0x7300
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7300 Entry 55 (size 16 bundles) Reserved
-+      DBG_FAULT(55)
-+      FAULT(55)
-+
-+      .org ia64_ivt+0x7400
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7400 Entry 56 (size 16 bundles) Reserved
-+      DBG_FAULT(56)
-+      FAULT(56)
-+
-+      .org ia64_ivt+0x7500
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7500 Entry 57 (size 16 bundles) Reserved
-+      DBG_FAULT(57)
-+      FAULT(57)
-+
-+      .org ia64_ivt+0x7600
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7600 Entry 58 (size 16 bundles) Reserved
-+      DBG_FAULT(58)
-+      FAULT(58)
-+
-+      .org ia64_ivt+0x7700
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7700 Entry 59 (size 16 bundles) Reserved
-+      DBG_FAULT(59)
-+      FAULT(59)
-+
-+      .org ia64_ivt+0x7800
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7800 Entry 60 (size 16 bundles) Reserved
-+      DBG_FAULT(60)
-+      FAULT(60)
-+
-+      .org ia64_ivt+0x7900
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7900 Entry 61 (size 16 bundles) Reserved
-+      DBG_FAULT(61)
-+      FAULT(61)
-+
-+      .org ia64_ivt+0x7a00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7a00 Entry 62 (size 16 bundles) Reserved
-+      DBG_FAULT(62)
-+      FAULT(62)
-+
-+      .org ia64_ivt+0x7b00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7b00 Entry 63 (size 16 bundles) Reserved
-+      DBG_FAULT(63)
-+      FAULT(63)
-+
-+      .org ia64_ivt+0x7c00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7c00 Entry 64 (size 16 bundles) Reserved
-+      DBG_FAULT(64)
-+      FAULT(64)
-+
-+      .org ia64_ivt+0x7d00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7d00 Entry 65 (size 16 bundles) Reserved
-+      DBG_FAULT(65)
-+      FAULT(65)
-+
-+      .org ia64_ivt+0x7e00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7e00 Entry 66 (size 16 bundles) Reserved
-+      DBG_FAULT(66)
-+      FAULT(66)
-+
-+#ifdef CONFIG_XEN
-+      /*
-+       * There is no particular reason for this code to be here, other than that
-+       * there happens to be space here that would go unused otherwise.  If this
-+       * fault ever gets "unreserved", simply moved the following code to a more
-+       * suitable spot...
-+       */
-+
-+GLOBAL_ENTRY(xen_bsw1)
-+      /* FIXME: THIS CODE IS NOT NaT SAFE! */
-+      movl r30=XSI_BANKNUM;
-+      mov r31=1;;
-+      st4 [r30]=r31;
-+      movl r30=XSI_BANK1_R16;
-+      movl r31=XSI_BANK1_R16+8;;
-+      ld8 r16=[r30],16; ld8 r17=[r31],16;;
-+      ld8 r18=[r30],16; ld8 r19=[r31],16;;
-+      ld8 r20=[r30],16; ld8 r21=[r31],16;;
-+      ld8 r22=[r30],16; ld8 r23=[r31],16;;
-+      ld8 r24=[r30],16; ld8 r25=[r31],16;;
-+      ld8 r26=[r30],16; ld8 r27=[r31],16;;
-+      ld8 r28=[r30],16; ld8 r29=[r31],16;;
-+      ld8 r30=[r30]; ld8 r31=[r31];;
-+      br.ret.sptk.many b0
-+END(xen_bsw1)
-+#endif
-+
-+      .org ia64_ivt+0x7f00
-+/////////////////////////////////////////////////////////////////////////////////////////
-+// 0x7f00 Entry 67 (size 16 bundles) Reserved
-+      DBG_FAULT(67)
-+      FAULT(67)
-+
-+#ifdef CONFIG_IA32_SUPPORT
-+
-+      /*
-+       * There is no particular reason for this code to be here, other than that
-+       * there happens to be space here that would go unused otherwise.  If this
-+       * fault ever gets "unreserved", simply moved the following code to a more
-+       * suitable spot...
-+       */
-+
-+      // IA32 interrupt entry point
-+
-+ENTRY(dispatch_to_ia32_handler)
-+      SAVE_MIN
-+      ;;
-+      mov r14=cr.isr
-+      ssm psr.ic | PSR_DEFAULT_BITS
-+      ;;
-+      srlz.i                                  // guarantee that interruption collection is on
-+      ;;
-+(p15) ssm psr.i
-+      adds r3=8,r2            // Base pointer for SAVE_REST
-+      ;;
-+      SAVE_REST
-+      ;;
-+      mov r15=0x80
-+      shr r14=r14,16          // Get interrupt number
-+      ;;
-+      cmp.ne p6,p0=r14,r15
-+(p6)  br.call.dpnt.many b6=non_ia32_syscall
-+
-+      adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp // 16 byte hole per SW conventions
-+      adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
-+      ;;
-+      cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
-+      ld8 r8=[r14]            // get r8
-+      ;;
-+      st8 [r15]=r8            // save original EAX in r1 (IA32 procs don't use the GP)
-+      ;;
-+      alloc r15=ar.pfs,0,0,6,0        // must first in an insn group
-+      ;;
-+      ld4 r8=[r14],8          // r8 == eax (syscall number)
-+      mov r15=IA32_NR_syscalls
-+      ;;
-+      cmp.ltu.unc p6,p7=r8,r15
-+      ld4 out1=[r14],8        // r9 == ecx
-+      ;;
-+      ld4 out2=[r14],8        // r10 == edx
-+      ;;
-+      ld4 out0=[r14]          // r11 == ebx
-+      adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp
-+      ;;
-+      ld4 out5=[r14],PT(R14)-PT(R13)  // r13 == ebp
-+      ;;
-+      ld4 out3=[r14],PT(R15)-PT(R14)  // r14 == esi
-+      adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
-+      ;;
-+      ld4 out4=[r14]          // r15 == edi
-+      movl r16=ia32_syscall_table
-+      ;;
-+(p6)  shladd r16=r8,3,r16     // force ni_syscall if not valid syscall number
-+      ld4 r2=[r2]             // r2 = current_thread_info()->flags
-+      ;;
-+      ld8 r16=[r16]
-+      and r2=_TIF_SYSCALL_TRACEAUDIT,r2       // mask trace or audit
-+      ;;
-+      mov b6=r16
-+      movl r15=ia32_ret_from_syscall
-+      cmp.eq p8,p0=r2,r0
-+      ;;
-+      mov rp=r15
-+(p8)  br.call.sptk.many b6=b6
-+      br.cond.sptk ia32_trace_syscall
-+
-+non_ia32_syscall:
-+      alloc r15=ar.pfs,0,0,2,0
-+      mov out0=r14                            // interrupt #
-+      add out1=16,sp                          // pointer to pt_regs
-+      ;;                      // avoid WAW on CFM
-+      br.call.sptk.many rp=ia32_bad_interrupt
-+.ret1:        movl r15=ia64_leave_kernel
-+      ;;
-+      mov rp=r15
-+      br.ret.sptk.many rp
-+END(dispatch_to_ia32_handler)
-+#endif /* CONFIG_IA32_SUPPORT */
-+
-+#ifdef CONFIG_XEN
-+      .section .text,"ax"
-+GLOBAL_ENTRY(xen_event_callback)
-+      mov r31=pr              // prepare to save predicates
-+      ;;
-+      SAVE_MIN_WITH_COVER     // uses r31; defines r2 and r3
-+      ;;
-+      movl r3=XSI_PSR_IC
-+      mov r14=1
-+      ;;
-+      st4 [r3]=r14
-+      ;;
-+      adds r3=8,r2            // set up second base pointer for SAVE_REST
-+      srlz.i                  // ensure everybody knows psr.ic is back on
-+      ;;
-+      SAVE_REST
-+      ;;
-+1:
-+      alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group
-+      add out0=16,sp          // pass pointer to pt_regs as first arg
-+      ;;
-+      br.call.sptk.many b0=evtchn_do_upcall
-+      ;;
-+      movl r20=XSI_PSR_I_ADDR
-+      ;;
-+      ld8 r20=[r20]
-+      ;;
-+      adds r20=-1,r20         // vcpu_info->evtchn_upcall_pending
-+      ;;
-+      ld1 r20=[r20]
-+      ;;
-+      cmp.ne p6,p0=r20,r0     // if there are pending events, 
-+      (p6) br.spnt.few 1b     // call evtchn_do_upcall again.
-+      br.sptk.many ia64_leave_kernel   
-+END(xen_event_callback)
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xenminstate.h linux-2.6.16.33/arch/ia64/xen/xenminstate.h
---- linux-2.6.16.33-noxen/arch/ia64/xen/xenminstate.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xenminstate.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,369 @@
-+#include <linux/config.h>
-+
-+#include <asm/cache.h>
-+
-+#ifdef CONFIG_XEN
-+#include "../kernel/entry.h"
-+#else
-+#include "entry.h"
-+#endif
-+
-+/*
-+ * For ivt.s we want to access the stack virtually so we don't have to disable translation
-+ * on interrupts.
-+ *
-+ *  On entry:
-+ *    r1:     pointer to current task (ar.k6)
-+ */
-+#define MINSTATE_START_SAVE_MIN_VIRT                                                          \
-+(pUStk)       mov ar.rsc=0;           /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */     \
-+      ;;                                                                                      \
-+(pUStk)       mov.m r24=ar.rnat;                                                                      \
-+(pUStk)       addl r22=IA64_RBS_OFFSET,r1;                    /* compute base of RBS */               \
-+(pKStk) mov r1=sp;                                    /* get sp  */                           \
-+      ;;                                                                                      \
-+(pUStk) lfetch.fault.excl.nt1 [r22];                                                          \
-+(pUStk)       addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;   /* compute base of memory stack */      \
-+(pUStk)       mov r23=ar.bspstore;                            /* save ar.bspstore */                  \
-+      ;;                                                                                      \
-+(pUStk)       mov ar.bspstore=r22;                            /* switch to kernel RBS */              \
-+(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;                        /* if in kernel mode, use sp (r12) */   \
-+      ;;                                                                                      \
-+(pUStk)       mov r18=ar.bsp;                                                                         \
-+(pUStk)       mov ar.rsc=0x3;         /* set eager mode, pl 0, little-endian, loadrs=0 */             \
-+
-+#define MINSTATE_END_SAVE_MIN_VIRT                                                            \
-+      bsw.1;                  /* switch back to bank 1 (must be last in insn group) */        \
-+      ;;
-+
-+/*
-+ * For mca_asm.S we want to access the stack physically since the state is saved before we
-+ * go virtual and don't want to destroy the iip or ipsr.
-+ */
-+#define MINSTATE_START_SAVE_MIN_PHYS                                                          \
-+(pKStk) mov r3=IA64_KR(PER_CPU_DATA);;                                                                \
-+(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;                                                  \
-+(pKStk) ld8 r3 = [r3];;                                                                               \
-+(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;                                           \
-+(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;                                         \
-+(pUStk)       mov ar.rsc=0;           /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */     \
-+(pUStk)       addl r22=IA64_RBS_OFFSET,r1;            /* compute base of register backing store */    \
-+      ;;                                                                                      \
-+(pUStk)       mov r24=ar.rnat;                                                                        \
-+(pUStk)       addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;   /* compute base of memory stack */      \
-+(pUStk)       mov r23=ar.bspstore;                            /* save ar.bspstore */                  \
-+(pUStk)       dep r22=-1,r22,61,3;                    /* compute kernel virtual addr of RBS */        \
-+      ;;                                                                                      \
-+(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;                /* if in kernel mode, use sp (r12) */           \
-+(pUStk)       mov ar.bspstore=r22;                    /* switch to kernel RBS */                      \
-+      ;;                                                                                      \
-+(pUStk)       mov r18=ar.bsp;                                                                         \
-+(pUStk)       mov ar.rsc=0x3;         /* set eager mode, pl 0, little-endian, loadrs=0 */             \
-+
-+#define MINSTATE_END_SAVE_MIN_PHYS                                                            \
-+      dep r12=-1,r12,61,3;            /* make sp a kernel virtual address */                  \
-+      ;;
-+
-+#ifdef MINSTATE_VIRT
-+# define MINSTATE_GET_CURRENT(reg)    mov reg=IA64_KR(CURRENT)
-+# define MINSTATE_START_SAVE_MIN      MINSTATE_START_SAVE_MIN_VIRT
-+# define MINSTATE_END_SAVE_MIN                MINSTATE_END_SAVE_MIN_VIRT
-+#endif
-+
-+#ifdef MINSTATE_PHYS
-+# define MINSTATE_GET_CURRENT(reg)    mov reg=IA64_KR(CURRENT);; tpa reg=reg
-+# define MINSTATE_START_SAVE_MIN      MINSTATE_START_SAVE_MIN_PHYS
-+# define MINSTATE_END_SAVE_MIN                MINSTATE_END_SAVE_MIN_PHYS
-+#endif
-+
-+/*
-+ * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
-+ * the minimum state necessary that allows us to turn psr.ic back
-+ * on.
-+ *
-+ * Assumed state upon entry:
-+ *    psr.ic: off
-+ *    r31:    contains saved predicates (pr)
-+ *
-+ * Upon exit, the state is as follows:
-+ *    psr.ic: off
-+ *     r2 = points to &pt_regs.r16
-+ *     r8 = contents of ar.ccv
-+ *     r9 = contents of ar.csd
-+ *    r10 = contents of ar.ssd
-+ *    r11 = FPSR_DEFAULT
-+ *    r12 = kernel sp (kernel virtual address)
-+ *    r13 = points to current task_struct (kernel virtual address)
-+ *    p15 = TRUE if psr.i is set in cr.ipsr
-+ *    predicate registers (other than p2, p3, and p15), b6, r3, r14, r15:
-+ *            preserved
-+ * CONFIG_XEN note: p6/p7 are not preserved
-+ *
-+ * Note that psr.ic is NOT turned on by this macro.  This is so that
-+ * we can pass interruption state as arguments to a handler.
-+ */
-+#ifdef CONFIG_XEN
-+#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)                                                     \
-+      MINSTATE_GET_CURRENT(r16);      /* M (or M;;I) */                                       \
-+      mov r27=ar.rsc;                 /* M */                                                 \
-+      mov r20=r1;                     /* A */                                                 \
-+      mov r25=ar.unat;                /* M */                                                 \
-+      /* mov r29=cr.ipsr;             /* M */                                                 \
-+      movl r29=XSI_IPSR;;                                                                     \
-+      ld8 r29=[r29];;                                                                         \
-+      mov r26=ar.pfs;                 /* I */                                                 \
-+      /* mov r28=cr.iip;              /* M */                                                 \
-+      movl r28=XSI_IIP;;                                                                      \
-+      ld8 r28=[r28];;                                                                         \
-+      mov r21=ar.fpsr;                /* M */                                                 \
-+      COVER;                  /* B;; (or nothing) */                                  \
-+      ;;                                                                                      \
-+      adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;                                         \
-+      ;;                                                                                      \
-+      ld1 r17=[r16];                          /* load current->thread.on_ustack flag */       \
-+      st1 [r16]=r0;                           /* clear current->thread.on_ustack flag */      \
-+      adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16                                          \
-+      /* switch from user to kernel RBS: */                                                   \
-+      ;;                                                                                      \
-+      invala;                         /* M */                                                 \
-+      /* SAVE_IFS; /* see xen special handling below */                                               \
-+      cmp.eq pKStk,pUStk=r0,r17;              /* are we in kernel mode already? */            \
-+      ;;                                                                                      \
-+      MINSTATE_START_SAVE_MIN                                                                 \
-+      adds r17=2*L1_CACHE_BYTES,r1;           /* really: biggest cache-line size */           \
-+      adds r16=PT(CR_IPSR),r1;                                                                \
-+      ;;                                                                                      \
-+      lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;                                             \
-+      st8 [r16]=r29;          /* save cr.ipsr */                                              \
-+      ;;                                                                                      \
-+      lfetch.fault.excl.nt1 [r17];                                                            \
-+      tbit.nz p15,p0=r29,IA64_PSR_I_BIT;                                                      \
-+      mov r29=b0                                                                              \
-+      ;;                                                                                      \
-+      adds r16=PT(R8),r1;     /* initialize first base pointer */                             \
-+      adds r17=PT(R9),r1;     /* initialize second base pointer */                            \
-+(pKStk)       mov r18=r0;             /* make sure r18 isn't NaT */                                   \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r8,16;                                                               \
-+.mem.offset 8,0; st8.spill [r17]=r9,16;                                                               \
-+        ;;                                                                                    \
-+.mem.offset 0,0; st8.spill [r16]=r10,24;                                                      \
-+.mem.offset 8,0; st8.spill [r17]=r11,24;                                                      \
-+        ;;                                                                                    \
-+      /* xen special handling for possibly lazy cover */                                      \
-+      movl r8=XSI_INCOMPL_REGFR;                                                              \
-+      ;;                                                                                      \
-+      ld4 r30=[r8];                                                                           \
-+      ;;                                                                                      \
-+      /* set XSI_INCOMPL_REGFR 0 */                                                           \
-+      st4 [r8]=r0;                                                                            \
-+      cmp.eq  p6,p7=r30,r0;                                                                   \
-+      ;; /* not sure if this stop bit is necessary */                                         \
-+(p6)  adds r8=XSI_PRECOVER_IFS-XSI_INCOMPL_REGFR,r8;                                          \
-+(p7)  adds r8=XSI_IFS-XSI_INCOMPL_REGFR,r8;                                                   \
-+      ;;                                                                                      \
-+      ld8 r30=[r8];                                                                           \
-+      ;;                                                                                      \
-+      st8 [r16]=r28,16;       /* save cr.iip */                                               \
-+      st8 [r17]=r30,16;       /* save cr.ifs */                                               \
-+(pUStk)       sub r18=r18,r22;        /* r18=RSE.ndirty*8 */                                          \
-+      mov r8=ar.ccv;                                                                          \
-+      mov r9=ar.csd;                                                                          \
-+      mov r10=ar.ssd;                                                                         \
-+      movl r11=FPSR_DEFAULT;   /* L-unit */                                                   \
-+      ;;                                                                                      \
-+      st8 [r16]=r25,16;       /* save ar.unat */                                              \
-+      st8 [r17]=r26,16;       /* save ar.pfs */                                               \
-+      shl r18=r18,16;         /* compute ar.rsc to be used for "loadrs" */                    \
-+      ;;                                                                                      \
-+      st8 [r16]=r27,16;       /* save ar.rsc */                                               \
-+(pUStk)       st8 [r17]=r24,16;       /* save ar.rnat */                                              \
-+(pKStk)       adds r17=16,r17;        /* skip over ar_rnat field */                                   \
-+      ;;                      /* avoid RAW on r16 & r17 */                                    \
-+(pUStk)       st8 [r16]=r23,16;       /* save ar.bspstore */                                          \
-+      st8 [r17]=r31,16;       /* save predicates */                                           \
-+(pKStk)       adds r16=16,r16;        /* skip over ar_bspstore field */                               \
-+      ;;                                                                                      \
-+      st8 [r16]=r29,16;       /* save b0 */                                                   \
-+      st8 [r17]=r18,16;       /* save ar.rsc value for "loadrs" */                            \
-+      cmp.eq pNonSys,pSys=r0,r0       /* initialize pSys=0, pNonSys=1 */                      \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r20,16;      /* save original r1 */                          \
-+.mem.offset 8,0; st8.spill [r17]=r12,16;                                                      \
-+      adds r12=-16,r1;        /* switch to kernel memory stack (with 16 bytes of scratch) */  \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r13,16;                                                      \
-+.mem.offset 8,0; st8.spill [r17]=r21,16;      /* save ar.fpsr */                              \
-+      mov r13=IA64_KR(CURRENT);       /* establish `current' */                               \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r15,16;                                                      \
-+.mem.offset 8,0; st8.spill [r17]=r14,16;                                                      \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r2,16;                                                               \
-+.mem.offset 8,0; st8.spill [r17]=r3,16;                                                               \
-+      ;;                                                                                      \
-+      EXTRA;                                                                                  \
-+      mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;                                        \
-+      adds r2=IA64_PT_REGS_R16_OFFSET,r1;                                                     \
-+      ;;                                                                                      \
-+      movl r1=__gp;           /* establish kernel global pointer */                           \
-+      ;;                                                                                      \
-+      /* MINSTATE_END_SAVE_MIN */
-+#else
-+#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)                                                     \
-+      MINSTATE_GET_CURRENT(r16);      /* M (or M;;I) */                                       \
-+      mov r27=ar.rsc;                 /* M */                                                 \
-+      mov r20=r1;                     /* A */                                                 \
-+      mov r25=ar.unat;                /* M */                                                 \
-+      mov r29=cr.ipsr;                /* M */                                                 \
-+      mov r26=ar.pfs;                 /* I */                                                 \
-+      mov r28=cr.iip;                 /* M */                                                 \
-+      mov r21=ar.fpsr;                /* M */                                                 \
-+      COVER;                          /* B;; (or nothing) */                                  \
-+      ;;                                                                                      \
-+      adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;                                         \
-+      ;;                                                                                      \
-+      ld1 r17=[r16];                          /* load current->thread.on_ustack flag */       \
-+      st1 [r16]=r0;                           /* clear current->thread.on_ustack flag */      \
-+      adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16                                          \
-+      /* switch from user to kernel RBS: */                                                   \
-+      ;;                                                                                      \
-+      invala;                         /* M */                                                 \
-+      SAVE_IFS;                                                                               \
-+      cmp.eq pKStk,pUStk=r0,r17;              /* are we in kernel mode already? */            \
-+      ;;                                                                                      \
-+      MINSTATE_START_SAVE_MIN                                                                 \
-+      adds r17=2*L1_CACHE_BYTES,r1;           /* really: biggest cache-line size */           \
-+      adds r16=PT(CR_IPSR),r1;                                                                \
-+      ;;                                                                                      \
-+      lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;                                             \
-+      st8 [r16]=r29;          /* save cr.ipsr */                                              \
-+      ;;                                                                                      \
-+      lfetch.fault.excl.nt1 [r17];                                                            \
-+      tbit.nz p15,p0=r29,IA64_PSR_I_BIT;                                                      \
-+      mov r29=b0                                                                              \
-+      ;;                                                                                      \
-+      adds r16=PT(R8),r1;     /* initialize first base pointer */                             \
-+      adds r17=PT(R9),r1;     /* initialize second base pointer */                            \
-+(pKStk)       mov r18=r0;             /* make sure r18 isn't NaT */                                   \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r8,16;                                                               \
-+.mem.offset 8,0; st8.spill [r17]=r9,16;                                                               \
-+        ;;                                                                                    \
-+.mem.offset 0,0; st8.spill [r16]=r10,24;                                                      \
-+.mem.offset 8,0; st8.spill [r17]=r11,24;                                                      \
-+        ;;                                                                                    \
-+      st8 [r16]=r28,16;       /* save cr.iip */                                               \
-+      st8 [r17]=r30,16;       /* save cr.ifs */                                               \
-+(pUStk)       sub r18=r18,r22;        /* r18=RSE.ndirty*8 */                                          \
-+      mov r8=ar.ccv;                                                                          \
-+      mov r9=ar.csd;                                                                          \
-+      mov r10=ar.ssd;                                                                         \
-+      movl r11=FPSR_DEFAULT;   /* L-unit */                                                   \
-+      ;;                                                                                      \
-+      st8 [r16]=r25,16;       /* save ar.unat */                                              \
-+      st8 [r17]=r26,16;       /* save ar.pfs */                                               \
-+      shl r18=r18,16;         /* compute ar.rsc to be used for "loadrs" */                    \
-+      ;;                                                                                      \
-+      st8 [r16]=r27,16;       /* save ar.rsc */                                               \
-+(pUStk)       st8 [r17]=r24,16;       /* save ar.rnat */                                              \
-+(pKStk)       adds r17=16,r17;        /* skip over ar_rnat field */                                   \
-+      ;;                      /* avoid RAW on r16 & r17 */                                    \
-+(pUStk)       st8 [r16]=r23,16;       /* save ar.bspstore */                                          \
-+      st8 [r17]=r31,16;       /* save predicates */                                           \
-+(pKStk)       adds r16=16,r16;        /* skip over ar_bspstore field */                               \
-+      ;;                                                                                      \
-+      st8 [r16]=r29,16;       /* save b0 */                                                   \
-+      st8 [r17]=r18,16;       /* save ar.rsc value for "loadrs" */                            \
-+      cmp.eq pNonSys,pSys=r0,r0       /* initialize pSys=0, pNonSys=1 */                      \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r20,16;      /* save original r1 */                          \
-+.mem.offset 8,0; st8.spill [r17]=r12,16;                                                      \
-+      adds r12=-16,r1;        /* switch to kernel memory stack (with 16 bytes of scratch) */  \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r13,16;                                                      \
-+.mem.offset 8,0; st8.spill [r17]=r21,16;      /* save ar.fpsr */                              \
-+      mov r13=IA64_KR(CURRENT);       /* establish `current' */                               \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r15,16;                                                      \
-+.mem.offset 8,0; st8.spill [r17]=r14,16;                                                      \
-+      ;;                                                                                      \
-+.mem.offset 0,0; st8.spill [r16]=r2,16;                                                               \
-+.mem.offset 8,0; st8.spill [r17]=r3,16;                                                               \
-+      adds r2=IA64_PT_REGS_R16_OFFSET,r1;                                                     \
-+      ;;                                                                                      \
-+      EXTRA;                                                                                  \
-+      movl r1=__gp;           /* establish kernel global pointer */                           \
-+      ;;                                                                                      \
-+      MINSTATE_END_SAVE_MIN
-+#endif
-+
-+/*
-+ * SAVE_REST saves the remainder of pt_regs (with psr.ic on).
-+ *
-+ * Assumed state upon entry:
-+ *    psr.ic: on
-+ *    r2:     points to &pt_regs.r16
-+ *    r3:     points to &pt_regs.r17
-+ *    r8:     contents of ar.ccv
-+ *    r9:     contents of ar.csd
-+ *    r10:    contents of ar.ssd
-+ *    r11:    FPSR_DEFAULT
-+ *
-+ * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST.
-+ */
-+#define SAVE_REST                             \
-+.mem.offset 0,0; st8.spill [r2]=r16,16;               \
-+.mem.offset 8,0; st8.spill [r3]=r17,16;               \
-+      ;;                                      \
-+.mem.offset 0,0; st8.spill [r2]=r18,16;               \
-+.mem.offset 8,0; st8.spill [r3]=r19,16;               \
-+      ;;                                      \
-+.mem.offset 0,0; st8.spill [r2]=r20,16;               \
-+.mem.offset 8,0; st8.spill [r3]=r21,16;               \
-+      mov r18=b6;                             \
-+      ;;                                      \
-+.mem.offset 0,0; st8.spill [r2]=r22,16;               \
-+.mem.offset 8,0; st8.spill [r3]=r23,16;               \
-+      mov r19=b7;                             \
-+      ;;                                      \
-+.mem.offset 0,0; st8.spill [r2]=r24,16;               \
-+.mem.offset 8,0; st8.spill [r3]=r25,16;               \
-+      ;;                                      \
-+.mem.offset 0,0; st8.spill [r2]=r26,16;               \
-+.mem.offset 8,0; st8.spill [r3]=r27,16;               \
-+      ;;                                      \
-+.mem.offset 0,0; st8.spill [r2]=r28,16;               \
-+.mem.offset 8,0; st8.spill [r3]=r29,16;               \
-+      ;;                                      \
-+.mem.offset 0,0; st8.spill [r2]=r30,16;               \
-+.mem.offset 8,0; st8.spill [r3]=r31,32;               \
-+      ;;                                      \
-+      mov ar.fpsr=r11;        /* M-unit */    \
-+      st8 [r2]=r8,8;          /* ar.ccv */    \
-+      adds r24=PT(B6)-PT(F7),r3;              \
-+      ;;                                      \
-+      stf.spill [r2]=f6,32;                   \
-+      stf.spill [r3]=f7,32;                   \
-+      ;;                                      \
-+      stf.spill [r2]=f8,32;                   \
-+      stf.spill [r3]=f9,32;                   \
-+      ;;                                      \
-+      stf.spill [r2]=f10;                     \
-+      stf.spill [r3]=f11;                     \
-+      adds r25=PT(B7)-PT(F11),r3;             \
-+      ;;                                      \
-+      st8 [r24]=r18,16;       /* b6 */        \
-+      st8 [r25]=r19,16;       /* b7 */        \
-+      ;;                                      \
-+      st8 [r24]=r9;           /* ar.csd */    \
-+      st8 [r25]=r10;          /* ar.ssd */    \
-+      ;;
-+
-+#define SAVE_MIN_WITH_COVER   DO_SAVE_MIN(cover, mov r30=cr.ifs,)
-+#define SAVE_MIN_WITH_COVER_R19       DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19)
-+#ifdef CONFIG_XEN
-+#define SAVE_MIN              break 0;; /* FIXME: non-cover version only for ia32 support? */
-+#else
-+#define SAVE_MIN              DO_SAVE_MIN(     , mov r30=r0, )
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xenpal.S linux-2.6.16.33/arch/ia64/xen/xenpal.S
---- linux-2.6.16.33-noxen/arch/ia64/xen/xenpal.S       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xenpal.S     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,76 @@
-+/*
-+ * ia64/xen/xenpal.S
-+ *
-+ * Alternate PAL  routines for Xen.  Heavily leveraged from
-+ *   ia64/kernel/pal.S
-+ *
-+ * Copyright (C) 2005 Hewlett-Packard Co
-+ *    Dan Magenheimer <dan.magenheimer@.hp.com>
-+ */
-+
-+#include <asm/asmmacro.h>
-+#include <asm/processor.h>
-+
-+GLOBAL_ENTRY(xen_pal_call_static)
-+      .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
-+      alloc loc1 = ar.pfs,5,5,0,0
-+#ifdef CONFIG_XEN
-+      movl r22=running_on_xen;;
-+      ld4 r22=[r22];;
-+      cmp.eq p7,p0=r22,r0
-+(p7)  br.cond.spnt.many __ia64_pal_call_static;;
-+#endif
-+      movl loc2 = pal_entry_point
-+1:    {
-+        mov r28 = in0
-+        mov r29 = in1
-+        mov r8 = ip
-+      }
-+      ;;
-+      ld8 loc2 = [loc2]               // loc2 <- entry point
-+      tbit.nz p6,p7 = in4, 0
-+      adds r8 = 1f-1b,r8
-+      mov loc4=ar.rsc                 // save RSE configuration
-+      ;;
-+      mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
-+      mov loc3 = psr
-+      mov loc0 = rp
-+      .body
-+      mov r30 = in2
-+
-+#ifdef CONFIG_XEN
-+      // this is low priority for paravirtualization, but is called
-+      // from the idle loop so confuses privop counting
-+      movl r31=XSI_PSR_IC
-+      ;;
-+(p6)  st4 [r31]=r0
-+      ;;
-+(p7)  adds r31=XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS,r31
-+(p7)  mov r22=1
-+      ;;
-+(p7)  ld8 r31=[r31]
-+      ;;
-+(p7)  st1 [r31]=r22
-+      ;;
-+      mov r31 = in3
-+      mov b7 = loc2
-+      ;;
-+#else
-+(p6)  rsm psr.i | psr.ic
-+      mov r31 = in3
-+      mov b7 = loc2
-+
-+(p7)  rsm psr.i
-+      ;;
-+(p6)  srlz.i
-+#endif
-+      mov rp = r8
-+      br.cond.sptk.many b7
-+1:    mov psr.l = loc3
-+      mov ar.rsc = loc4               // restore RSE configuration
-+      mov ar.pfs = loc1
-+      mov rp = loc0
-+      ;;
-+      srlz.d                          // seralize restoration of psr.l
-+      br.ret.sptk.many b0
-+END(xen_pal_call_static)
-diff -Nur linux-2.6.16.33-noxen/arch/ia64/xen/xensetup.S linux-2.6.16.33/arch/ia64/xen/xensetup.S
---- linux-2.6.16.33-noxen/arch/ia64/xen/xensetup.S     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/ia64/xen/xensetup.S   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,54 @@
-+/*
-+ * Support routines for Xen
-+ *
-+ * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
-+ */
-+
-+#include <linux/config.h>
-+#include <asm/processor.h>
-+#include <asm/asmmacro.h>
-+
-+#define isBP  p3      // are we the Bootstrap Processor?
-+
-+      .text
-+GLOBAL_ENTRY(early_xen_setup)
-+      mov r8=ar.rsc           // Initialized in head.S
-+(isBP)        movl r9=running_on_xen;;
-+      extr.u r8=r8,2,2;;      // Extract pl fields
-+      cmp.eq p7,p0=r8,r0      // p7: !running on xen
-+      mov r8=1                // booleanize.
-+(p7)  br.ret.sptk.many rp;;
-+(isBP)        st4 [r9]=r8
-+      movl r10=xen_ivt;;
-+      
-+      mov cr.iva=r10
-+
-+      /* Set xsi base.  */
-+#define FW_HYPERCALL_SET_SHARED_INFO_VA                       0x600
-+(isBP)        mov r2=FW_HYPERCALL_SET_SHARED_INFO_VA
-+(isBP)        movl r28=XSI_BASE;;
-+(isBP)        break 0x1000;;
-+
-+      br.ret.sptk.many rp
-+      ;;
-+END(early_xen_setup)
-+
-+#include <xen/interface/xen.h>
-+
-+/* Stub for suspend.
-+   Just force the stacked registers to be written in memory.  */      
-+GLOBAL_ENTRY(xencomm_arch_hypercall_suspend)
-+      mov r15=r32
-+      ;; 
-+      alloc r20=ar.pfs,0,0,0,0
-+      mov r2=__HYPERVISOR_sched_op
-+      ;; 
-+      /* We don't want to deal with RSE.  */
-+      flushrs
-+      mov r14=2 // SCHEDOP_shutdown
-+      ;;
-+      break 0x1000
-+      ;; 
-+      mov ar.pfs=r20
-+      br.ret.sptk.many b0
-+END(xencomm_arch_hypercall_suspend)
-diff -Nur linux-2.6.16.33-noxen/arch/powerpc/kernel/machine_kexec_32.c linux-2.6.16.33/arch/powerpc/kernel/machine_kexec_32.c
---- linux-2.6.16.33-noxen/arch/powerpc/kernel/machine_kexec_32.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/powerpc/kernel/machine_kexec_32.c     2007-05-23 21:00:01.000000000 +0000
-@@ -30,8 +30,8 @@
-  */
- void default_machine_kexec(struct kimage *image)
- {
--      const extern unsigned char relocate_new_kernel[];
--      const extern unsigned int relocate_new_kernel_size;
-+      extern const unsigned char relocate_new_kernel[];
-+      extern const unsigned int relocate_new_kernel_size;
-       unsigned long page_list;
-       unsigned long reboot_code_buffer, reboot_code_buffer_phys;
-       relocate_new_kernel_t rnk;
-diff -Nur linux-2.6.16.33-noxen/arch/ppc/kernel/machine_kexec.c linux-2.6.16.33/arch/ppc/kernel/machine_kexec.c
---- linux-2.6.16.33-noxen/arch/ppc/kernel/machine_kexec.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/ppc/kernel/machine_kexec.c    2007-05-23 21:00:01.000000000 +0000
-@@ -25,8 +25,8 @@
-                               unsigned long reboot_code_buffer,
-                               unsigned long start_address) ATTRIB_NORET;
--const extern unsigned char relocate_new_kernel[];
--const extern unsigned int relocate_new_kernel_size;
-+extern const unsigned char relocate_new_kernel[];
-+extern const unsigned int relocate_new_kernel_size;
- void machine_shutdown(void)
- {
-diff -Nur linux-2.6.16.33-noxen/arch/s390/kernel/machine_kexec.c linux-2.6.16.33/arch/s390/kernel/machine_kexec.c
---- linux-2.6.16.33-noxen/arch/s390/kernel/machine_kexec.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/s390/kernel/machine_kexec.c   2007-05-23 21:00:01.000000000 +0000
-@@ -27,8 +27,8 @@
- typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
--const extern unsigned char relocate_kernel[];
--const extern unsigned long long relocate_kernel_len;
-+extern const unsigned char relocate_kernel[];
-+extern const unsigned long long relocate_kernel_len;
- int
- machine_kexec_prepare(struct kimage *image)
-diff -Nur linux-2.6.16.33-noxen/arch/sh/kernel/machine_kexec.c linux-2.6.16.33/arch/sh/kernel/machine_kexec.c
---- linux-2.6.16.33-noxen/arch/sh/kernel/machine_kexec.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/sh/kernel/machine_kexec.c     2007-05-23 21:00:01.000000000 +0000
-@@ -25,8 +25,8 @@
-                               unsigned long start_address,
-                               unsigned long vbr_reg) ATTRIB_NORET;
--const extern unsigned char relocate_new_kernel[];
--const extern unsigned int relocate_new_kernel_size;
-+extern const unsigned char relocate_new_kernel[];
-+extern const unsigned int relocate_new_kernel_size;
- extern void *gdb_vbr_vector;
- /*
-diff -Nur linux-2.6.16.33-noxen/arch/um/kernel/physmem.c linux-2.6.16.33/arch/um/kernel/physmem.c
---- linux-2.6.16.33-noxen/arch/um/kernel/physmem.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/um/kernel/physmem.c   2007-01-08 15:00:45.000000000 +0000
-@@ -225,7 +225,7 @@
- EXPORT_SYMBOL(physmem_remove_mapping);
- EXPORT_SYMBOL(physmem_subst_mapping);
--void arch_free_page(struct page *page, int order)
-+int arch_free_page(struct page *page, int order)
- {
-       void *virt;
-       int i;
-@@ -234,6 +234,8 @@
-               virt = __va(page_to_phys(page + i));
-               physmem_remove_mapping(virt);
-       }
-+
-+      return 0;
- }
- int is_remapped(void *virt)
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/Kconfig linux-2.6.16.33/arch/x86_64/Kconfig
---- linux-2.6.16.33-noxen/arch/x86_64/Kconfig  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/Kconfig        2007-01-08 15:00:45.000000000 +0000
-@@ -119,6 +119,22 @@
- endchoice
-+config X86_64_XEN
-+      bool "Enable Xen compatible kernel"
-+      select SWIOTLB
-+      help
-+        This option will compile a kernel compatible with Xen hypervisor
-+
-+config X86_NO_TSS
-+      bool
-+      depends on X86_64_XEN
-+      default y
-+
-+config X86_NO_IDT
-+      bool
-+      depends on X86_64_XEN
-+      default y
-+
- #
- # Define implied options from the CPU selection here
- #
-@@ -134,6 +150,7 @@
- config X86_TSC
-       bool
-+      depends on !X86_64_XEN
-       default y
- config X86_GOOD_APIC
-@@ -176,7 +193,7 @@
- config X86_HT
-       bool
--      depends on SMP && !MK8
-+      depends on SMP && !MK8 && !X86_64_XEN
-       default y
- config MATH_EMULATION
-@@ -190,14 +207,22 @@
- config X86_IO_APIC
-       bool
-+      depends !XEN_UNPRIVILEGED_GUEST
-       default y
-+config X86_XEN_GENAPIC
-+      bool
-+      depends X86_64_XEN
-+      default XEN_PRIVILEGED_GUEST || SMP
-+
- config X86_LOCAL_APIC
-       bool
-+      depends !XEN_UNPRIVILEGED_GUEST
-       default y
- config MTRR
-       bool "MTRR (Memory Type Range Register) support"
-+      depends on !XEN_UNPRIVILEGED_GUEST
-       ---help---
-         On Intel P6 family processors (Pentium Pro, Pentium II and later)
-         the Memory Type Range Registers (MTRRs) may be used to control
-@@ -238,7 +263,7 @@
- config SCHED_SMT
-       bool "SMT (Hyperthreading) scheduler support"
--      depends on SMP
-+      depends on SMP && !X86_64_XEN
-       default n
-       help
-         SMT scheduler support improves the CPU scheduler's decision making
-@@ -250,7 +275,7 @@
- config NUMA
-        bool "Non Uniform Memory Access (NUMA) Support"
--       depends on SMP
-+       depends on SMP && !X86_64_XEN
-        help
-        Enable NUMA (Non Uniform Memory Access) support. The kernel 
-        will try to allocate memory used by a CPU on the local memory 
-@@ -305,7 +330,7 @@
- config ARCH_SPARSEMEM_ENABLE
-       def_bool y
--      depends on (NUMA || EXPERIMENTAL)
-+      depends on (NUMA || EXPERIMENTAL) && !X86_64_XEN
- config ARCH_MEMORY_PROBE
-       def_bool y
-@@ -325,6 +350,7 @@
-       int "Maximum number of CPUs (2-256)"
-       range 2 256
-       depends on SMP
-+      default "16" if X86_64_XEN
-       default "8"
-       help
-         This allows you to specify the maximum number of CPUs which this
-@@ -347,6 +373,7 @@
- config HPET_TIMER
-       bool
-+      depends on !X86_64_XEN
-       default y
-       help
-         Use the IA-PC HPET (High Precision Event Timer) to manage
-@@ -364,7 +391,7 @@
-       bool "K8 GART IOMMU support"
-       default y
-       select SWIOTLB
--      depends on PCI
-+      depends on PCI && !X86_64_XEN
-       help
-         Support the IOMMU. Needed to run systems with more than 3GB of memory
-         properly with 32-bit PCI devices that do not support DAC (Double Address
-@@ -382,6 +409,7 @@
- config X86_MCE
-       bool "Machine check support" if EMBEDDED
-+      depends on !X86_64_XEN
-       default y
-       help
-          Include a machine check error handler to report hardware errors.
-@@ -407,7 +435,7 @@
- config KEXEC
-       bool "kexec system call (EXPERIMENTAL)"
--      depends on EXPERIMENTAL
-+      depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST
-       help
-         kexec is a system call that implements the ability to shutdown your
-         current kernel, and to start another kernel.  It is like a reboot
-@@ -490,8 +518,11 @@
-       default y
- menu "Power management options"
-+      depends on !XEN_UNPRIVILEGED_GUEST
-+if !X86_64_XEN
- source kernel/power/Kconfig
-+endif
- source "drivers/acpi/Kconfig"
-@@ -514,6 +545,21 @@
-       bool "Support mmconfig PCI config space access"
-       depends on PCI && ACPI
-+config XEN_PCIDEV_FRONTEND
-+      bool "Xen PCI Frontend"
-+      depends on PCI && X86_64_XEN
-+      default y
-+      help
-+        The PCI device frontend driver allows the kernel to import arbitrary
-+        PCI devices from a PCI backend to support PCI driver domains.
-+
-+config XEN_PCIDEV_FE_DEBUG
-+      bool "Xen PCI Frontend Debugging"
-+      depends on XEN_PCIDEV_FRONTEND
-+      default n
-+      help
-+        Enables some debug statements within the PCI Frontend.
-+
- config UNORDERED_IO
-        bool "Unordered IO mapping access"
-        depends on EXPERIMENTAL
-@@ -594,4 +640,6 @@
- source "crypto/Kconfig"
-+source "drivers/xen/Kconfig"
-+
- source "lib/Kconfig"
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/Makefile linux-2.6.16.33/arch/x86_64/Makefile
---- linux-2.6.16.33-noxen/arch/x86_64/Makefile 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -31,6 +31,10 @@
- cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
- CFLAGS += $(cflags-y)
-+cppflags-$(CONFIG_XEN) += \
-+      -D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION)
-+CPPFLAGS += $(cppflags-y)
-+
- CFLAGS += -m64
- CFLAGS += -mno-red-zone
- CFLAGS += -mcmodel=kernel
-@@ -70,6 +74,21 @@
- .PHONY: bzImage bzlilo install archmrproper \
-       fdimage fdimage144 fdimage288 archclean
-+ifdef CONFIG_XEN
-+CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS)
-+head-y := arch/x86_64/kernel/head-xen.o arch/x86_64/kernel/head64-xen.o arch/x86_64/kernel/init_task.o
-+LDFLAGS_vmlinux := -e _start
-+boot := arch/i386/boot-xen
-+.PHONY: vmlinuz
-+#Default target when executing "make"
-+all: vmlinuz
-+
-+vmlinuz: vmlinux
-+      $(Q)$(MAKE) $(build)=$(boot) $@
-+
-+install:
-+      $(Q)$(MAKE) $(build)=$(boot) XENGUEST=$(XENGUEST) $@
-+else
- #Default target when executing "make"
- all: bzImage
-@@ -90,6 +109,7 @@
- install:
-       $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ 
-+endif
- archclean:
-       $(Q)$(MAKE) $(clean)=$(boot)
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/ia32/Makefile linux-2.6.16.33/arch/x86_64/ia32/Makefile
---- linux-2.6.16.33-noxen/arch/x86_64/ia32/Makefile    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/ia32/Makefile  2007-01-08 15:00:45.000000000 +0000
-@@ -23,9 +23,25 @@
-                          -Wl,-soname=linux-gate.so.1 -o $@ \
-                          -Wl,-T,$(filter-out FORCE,$^)
-+$(obj)/vsyscall-int80.so \
- $(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \
- $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
-       $(call if_changed,syscall)
--AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
--AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
-+AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 -Iarch/i386/kernel
-+AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 -Iarch/i386/kernel
-+
-+ifdef CONFIG_XEN
-+AFLAGS_vsyscall-int80.o = -m32 -Wa,-32 -Iarch/i386/kernel
-+CFLAGS_syscall32-xen.o += -DUSE_INT80
-+AFLAGS_syscall32_syscall-xen.o += -DUSE_INT80
-+
-+$(obj)/syscall32_syscall-xen.o: \
-+      $(foreach F,int80 sysenter syscall,$(obj)/vsyscall-$F.so)
-+
-+targets := $(foreach F,int80 sysenter syscall,vsyscall-$F.o vsyscall-$F.so)
-+
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/ia32/ia32entry-xen.S linux-2.6.16.33/arch/x86_64/ia32/ia32entry-xen.S
---- linux-2.6.16.33-noxen/arch/x86_64/ia32/ia32entry-xen.S     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/ia32/ia32entry-xen.S   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,721 @@
-+/*
-+ * Compatibility mode system call entry point for x86-64. 
-+ *            
-+ * Copyright 2000-2002 Andi Kleen, SuSE Labs.
-+ */            
-+
-+#include <asm/dwarf2.h>
-+#include <asm/calling.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/current.h>
-+#include <asm/errno.h>
-+#include <asm/ia32_unistd.h>  
-+#include <asm/thread_info.h>  
-+#include <asm/segment.h>
-+#include <asm/vsyscall32.h>
-+#include <linux/linkage.h>
-+
-+#define __XEN_X86_64 1
-+      
-+      .macro IA32_ARG_FIXUP noebp=0
-+      movl    %edi,%r8d
-+      .if \noebp
-+      .else
-+      movl    %ebp,%r9d
-+      .endif
-+      xchg    %ecx,%esi
-+      movl    %ebx,%edi
-+      movl    %edx,%edx       /* zero extension */
-+      .endm 
-+
-+      /* clobbers %eax */     
-+      .macro  CLEAR_RREGS
-+      xorl    %eax,%eax
-+      movq    %rax,R11(%rsp)
-+      movq    %rax,R10(%rsp)
-+      movq    %rax,R9(%rsp)
-+      movq    %rax,R8(%rsp)
-+      .endm
-+
-+#if defined (__XEN_X86_64)
-+#include "../kernel/xen_entry.S"
-+              
-+#define       __swapgs
-+#define __cli
-+#define __sti 
-+#else
-+/*
-+ * Use the native instructions
-+ */   
-+#define       __swapgs        swapgs
-+#define __cli         cli
-+#define __sti         sti     
-+#endif                        
-+
-+      .macro CFI_STARTPROC32 simple
-+      CFI_STARTPROC   \simple
-+      CFI_UNDEFINED   r8
-+      CFI_UNDEFINED   r9
-+      CFI_UNDEFINED   r10
-+      CFI_UNDEFINED   r11
-+      CFI_UNDEFINED   r12
-+      CFI_UNDEFINED   r13
-+      CFI_UNDEFINED   r14
-+      CFI_UNDEFINED   r15
-+      .endm
-+
-+/*
-+ * 32bit SYSENTER instruction entry.
-+ *
-+ * Arguments:
-+ * %eax       System call number.
-+ * %ebx Arg1
-+ * %ecx Arg2
-+ * %edx Arg3
-+ * %esi Arg4
-+ * %edi Arg5
-+ * %ebp user stack
-+ * 0(%ebp) Arg6       
-+ *    
-+ * Interrupts off.
-+ *    
-+ * This is purely a fast path. For anything complicated we use the int 0x80
-+ * path below.        Set up a complete hardware stack frame to share code
-+ * with the int 0x80 path.
-+ */   
-+ENTRY(ia32_sysenter_target)
-+      CFI_STARTPROC32 simple
-+      CFI_DEF_CFA     rsp,0
-+      CFI_REGISTER    rsp,rbp
-+      __swapgs 
-+      movq    %gs:pda_kernelstack, %rsp
-+      addq    $(PDA_STACKOFFSET),%rsp
-+      XEN_UNBLOCK_EVENTS(%r11)        
-+      __sti
-+      movl    %ebp,%ebp               /* zero extension */
-+      pushq   $__USER32_DS
-+      CFI_ADJUST_CFA_OFFSET 8
-+      /*CFI_REL_OFFSET ss,0*/
-+      pushq   %rbp
-+      CFI_ADJUST_CFA_OFFSET 8
-+      CFI_REL_OFFSET rsp,0
-+      pushfq
-+      CFI_ADJUST_CFA_OFFSET 8
-+      /*CFI_REL_OFFSET rflags,0*/
-+      movl    $VSYSCALL32_SYSEXIT, %r10d
-+      CFI_REGISTER rip,r10
-+      pushq   $__USER32_CS
-+      CFI_ADJUST_CFA_OFFSET 8
-+      /*CFI_REL_OFFSET cs,0*/
-+      movl    %eax, %eax
-+      pushq   %r10
-+      CFI_ADJUST_CFA_OFFSET 8
-+      CFI_REL_OFFSET rip,0
-+      pushq   %rax
-+      CFI_ADJUST_CFA_OFFSET 8
-+      cld
-+      SAVE_ARGS 0,0,1
-+      /* no need to do an access_ok check here because rbp has been
-+         32bit zero extended */ 
-+1:    movl    (%rbp),%r9d
-+      .section __ex_table,"a"
-+      .quad 1b,ia32_badarg
-+      .previous       
-+      GET_THREAD_INFO(%r10)
-+      orl    $TS_COMPAT,threadinfo_status(%r10)
-+      testl  $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
-+      CFI_REMEMBER_STATE
-+      jnz  sysenter_tracesys
-+sysenter_do_call:     
-+      cmpl    $(IA32_NR_syscalls),%eax
-+      jae     ia32_badsys
-+      IA32_ARG_FIXUP 1
-+      call    *ia32_sys_call_table(,%rax,8)
-+      movq    %rax,RAX-ARGOFFSET(%rsp)
-+      GET_THREAD_INFO(%r10)
-+      XEN_BLOCK_EVENTS(%r11)  
-+      __cli
-+      testl   $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
-+      jnz     int_ret_from_sys_call
-+      andl    $~TS_COMPAT,threadinfo_status(%r10)
-+      /* clear IF, that popfq doesn't enable interrupts early */
-+      andl  $~0x200,EFLAGS-R11(%rsp) 
-+      RESTORE_ARGS 1,24,1,1,1,1
-+      popfq
-+      CFI_ADJUST_CFA_OFFSET -8
-+      /*CFI_RESTORE rflags*/
-+      popq    %rcx                            /* User %esp */
-+      CFI_ADJUST_CFA_OFFSET -8
-+      CFI_REGISTER rsp,rcx
-+      movl    $VSYSCALL32_SYSEXIT,%edx        /* User %eip */
-+      CFI_REGISTER rip,rdx
-+      __swapgs
-+      XEN_UNBLOCK_EVENTS(%r11)                
-+      __sti           /* sti only takes effect after the next instruction */
-+      /* sysexit */
-+      .byte   0xf, 0x35  /* TBD */
-+
-+sysenter_tracesys:
-+      CFI_RESTORE_STATE
-+      SAVE_REST
-+      CLEAR_RREGS
-+      movq    $-ENOSYS,RAX(%rsp)      /* really needed? */
-+      movq    %rsp,%rdi        /* &pt_regs -> arg1 */
-+      call    syscall_trace_enter
-+      LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
-+      RESTORE_REST
-+      movl    %ebp, %ebp
-+      /* no need to do an access_ok check here because rbp has been
-+         32bit zero extended */ 
-+1:    movl    (%rbp),%r9d
-+      .section __ex_table,"a"
-+      .quad 1b,ia32_badarg
-+      .previous
-+      jmp     sysenter_do_call
-+      CFI_ENDPROC
-+
-+/*
-+ * 32bit SYSCALL instruction entry.
-+ *
-+ * Arguments:
-+ * %eax       System call number.
-+ * %ebx Arg1
-+ * %ecx return EIP 
-+ * %edx Arg3
-+ * %esi Arg4
-+ * %edi Arg5
-+ * %ebp Arg2    [note: not saved in the stack frame, should not be touched]
-+ * %esp user stack 
-+ * 0(%esp) Arg6
-+ *    
-+ * Interrupts off.
-+ *    
-+ * This is purely a fast path. For anything complicated we use the int 0x80
-+ * path below.        Set up a complete hardware stack frame to share code
-+ * with the int 0x80 path.    
-+ */   
-+ENTRY(ia32_cstar_target)
-+      CFI_STARTPROC32 simple
-+      CFI_DEF_CFA     rsp,0
-+      CFI_REGISTER    rip,rcx
-+      /*CFI_REGISTER  rflags,r11*/
-+      __swapgs
-+      movl    %esp,%r8d
-+      CFI_REGISTER    rsp,r8
-+      movq    %gs:pda_kernelstack,%rsp
-+      XEN_UNBLOCK_EVENTS(%r11)        
-+      __sti
-+      SAVE_ARGS 8,1,1
-+      movl    %eax,%eax       /* zero extension */
-+      movq    %rax,ORIG_RAX-ARGOFFSET(%rsp)
-+      movq    %rcx,RIP-ARGOFFSET(%rsp)
-+      CFI_REL_OFFSET rip,RIP-ARGOFFSET
-+      movq    %rbp,RCX-ARGOFFSET(%rsp) /* this lies slightly to ptrace */
-+      movl    %ebp,%ecx
-+      movq    $__USER32_CS,CS-ARGOFFSET(%rsp)
-+      movq    $__USER32_DS,SS-ARGOFFSET(%rsp)
-+      movq    %r11,EFLAGS-ARGOFFSET(%rsp)
-+      /*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/
-+      movq    %r8,RSP-ARGOFFSET(%rsp) 
-+      CFI_REL_OFFSET rsp,RSP-ARGOFFSET
-+      /* no need to do an access_ok check here because r8 has been
-+         32bit zero extended */ 
-+      /* hardware stack frame is complete now */      
-+1:    movl    (%r8),%r9d
-+      .section __ex_table,"a"
-+      .quad 1b,ia32_badarg
-+      .previous       
-+      GET_THREAD_INFO(%r10)
-+      orl   $TS_COMPAT,threadinfo_status(%r10)
-+      testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
-+      CFI_REMEMBER_STATE
-+      jnz   cstar_tracesys
-+cstar_do_call:        
-+      cmpl $IA32_NR_syscalls,%eax
-+      jae  ia32_badsys
-+      IA32_ARG_FIXUP 1
-+      call *ia32_sys_call_table(,%rax,8)
-+      movq %rax,RAX-ARGOFFSET(%rsp)
-+      GET_THREAD_INFO(%r10)
-+      XEN_BLOCK_EVENTS(%r11)          
-+      __cli
-+      testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
-+      jnz  int_ret_from_sys_call
-+      andl $~TS_COMPAT,threadinfo_status(%r10)
-+      RESTORE_ARGS 1,-ARG_SKIP,1,1,1
-+      movl RIP-ARGOFFSET(%rsp),%ecx
-+      CFI_REGISTER rip,rcx
-+      movl EFLAGS-ARGOFFSET(%rsp),%r11d       
-+      /*CFI_REGISTER rflags,r11*/
-+      movl RSP-ARGOFFSET(%rsp),%esp
-+      CFI_RESTORE rsp
-+      __swapgs
-+      sysretl  /* TBD */
-+      
-+cstar_tracesys:       
-+      CFI_RESTORE_STATE
-+      SAVE_REST
-+      CLEAR_RREGS
-+      movq $-ENOSYS,RAX(%rsp) /* really needed? */
-+      movq %rsp,%rdi        /* &pt_regs -> arg1 */
-+      call syscall_trace_enter
-+      LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
-+      RESTORE_REST
-+      movl RSP-ARGOFFSET(%rsp), %r8d
-+      /* no need to do an access_ok check here because r8 has been
-+         32bit zero extended */ 
-+1:    movl    (%r8),%r9d
-+      .section __ex_table,"a"
-+      .quad 1b,ia32_badarg
-+      .previous
-+      jmp cstar_do_call
-+                              
-+ia32_badarg:
-+      movq $-EFAULT,%rax
-+      jmp ia32_sysret
-+      CFI_ENDPROC
-+
-+/* 
-+ * Emulated IA32 system calls via int 0x80. 
-+ *
-+ * Arguments:  
-+ * %eax       System call number.
-+ * %ebx Arg1
-+ * %ecx Arg2
-+ * %edx Arg3
-+ * %esi Arg4
-+ * %edi Arg5
-+ * %ebp Arg6    [note: not saved in the stack frame, should not be touched]
-+ *
-+ * Notes:
-+ * Uses the same stack frame as the x86-64 version.   
-+ * All registers except %eax must be saved (but ptrace may violate that)
-+ * Arguments are zero extended. For system calls that want sign extension and
-+ * take long arguments a wrapper is needed. Most calls can just be called
-+ * directly.
-+ * Assumes it is only called from user space and entered with interrupts off. 
-+ */                           
-+
-+ENTRY(ia32_syscall)
-+      CFI_STARTPROC   simple
-+      CFI_DEF_CFA     rsp,SS+8-RIP
-+      /*CFI_REL_OFFSET        ss,SS-RIP*/
-+      CFI_REL_OFFSET  rsp,RSP-RIP
-+      /*CFI_REL_OFFSET        rflags,EFLAGS-RIP*/
-+      /*CFI_REL_OFFSET        cs,CS-RIP*/
-+      CFI_REL_OFFSET  rip,RIP-RIP
-+      __swapgs
-+      XEN_UNBLOCK_EVENTS(%r11)
-+      __sti
-+      movq (%rsp),%rcx
-+      movq 8(%rsp),%r11
-+        addq $0x10,%rsp /* skip rcx and r11 */
-+      movl %eax,%eax
-+      pushq %rax
-+      CFI_ADJUST_CFA_OFFSET 8
-+      cld
-+/* 1: jmp 1b   */
-+      /* note the registers are not zero extended to the sf.
-+         this could be a problem. */
-+      SAVE_ARGS 0,0,1
-+      GET_THREAD_INFO(%r10)
-+      orl   $TS_COMPAT,threadinfo_status(%r10)
-+      testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
-+      jnz ia32_tracesys
-+ia32_do_syscall:      
-+      cmpl $(IA32_NR_syscalls),%eax
-+      jae  ia32_badsys
-+      IA32_ARG_FIXUP
-+      call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
-+ia32_sysret:
-+      movq %rax,RAX-ARGOFFSET(%rsp)
-+      jmp int_ret_from_sys_call 
-+
-+ia32_tracesys:                         
-+      SAVE_REST
-+      movq $-ENOSYS,RAX(%rsp) /* really needed? */
-+      movq %rsp,%rdi        /* &pt_regs -> arg1 */
-+      call syscall_trace_enter
-+      LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
-+      RESTORE_REST
-+      jmp ia32_do_syscall
-+
-+ia32_badsys:
-+      movq $0,ORIG_RAX-ARGOFFSET(%rsp)
-+      movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
-+      jmp int_ret_from_sys_call
-+
-+ni_syscall:
-+      movq %rax,%rdi
-+      jmp  sys32_ni_syscall                   
-+
-+quiet_ni_syscall:
-+      movq $-ENOSYS,%rax
-+      ret
-+      CFI_ENDPROC
-+      
-+      .macro PTREGSCALL label, func, arg
-+      .globl \label
-+\label:
-+      leaq \func(%rip),%rax
-+      leaq -ARGOFFSET+8(%rsp),\arg    /* 8 for return address */
-+      jmp  ia32_ptregs_common 
-+      .endm
-+
-+      CFI_STARTPROC32
-+
-+      PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
-+      PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
-+      PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
-+      PTREGSCALL stub32_sigsuspend, sys32_sigsuspend, %rcx
-+      PTREGSCALL stub32_execve, sys32_execve, %rcx
-+      PTREGSCALL stub32_fork, sys_fork, %rdi
-+      PTREGSCALL stub32_clone, sys32_clone, %rdx
-+      PTREGSCALL stub32_vfork, sys_vfork, %rdi
-+      PTREGSCALL stub32_iopl, sys_iopl, %rsi
-+      PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend, %rdx
-+
-+ENTRY(ia32_ptregs_common)
-+      popq %r11
-+      CFI_ENDPROC
-+      CFI_STARTPROC32 simple
-+      CFI_DEF_CFA     rsp,SS+8-ARGOFFSET
-+      CFI_REL_OFFSET  rax,RAX-ARGOFFSET
-+      CFI_REL_OFFSET  rcx,RCX-ARGOFFSET
-+      CFI_REL_OFFSET  rdx,RDX-ARGOFFSET
-+      CFI_REL_OFFSET  rsi,RSI-ARGOFFSET
-+      CFI_REL_OFFSET  rdi,RDI-ARGOFFSET
-+      CFI_REL_OFFSET  rip,RIP-ARGOFFSET
-+/*    CFI_REL_OFFSET  cs,CS-ARGOFFSET*/
-+/*    CFI_REL_OFFSET  rflags,EFLAGS-ARGOFFSET*/
-+      CFI_REL_OFFSET  rsp,RSP-ARGOFFSET
-+/*    CFI_REL_OFFSET  ss,SS-ARGOFFSET*/
-+      SAVE_REST
-+      call *%rax
-+      RESTORE_REST
-+      jmp  ia32_sysret        /* misbalances the return cache */
-+      CFI_ENDPROC
-+
-+      .section .rodata,"a"
-+      .align 8
-+      .globl ia32_sys_call_table
-+ia32_sys_call_table:
-+      .quad sys_restart_syscall
-+      .quad sys_exit
-+      .quad stub32_fork
-+      .quad sys_read
-+      .quad sys_write
-+      .quad compat_sys_open           /* 5 */
-+      .quad sys_close
-+      .quad sys32_waitpid
-+      .quad sys_creat
-+      .quad sys_link
-+      .quad sys_unlink                /* 10 */
-+      .quad stub32_execve
-+      .quad sys_chdir
-+      .quad compat_sys_time
-+      .quad sys_mknod
-+      .quad sys_chmod         /* 15 */
-+      .quad sys_lchown16
-+      .quad quiet_ni_syscall                  /* old break syscall holder */
-+      .quad sys_stat
-+      .quad sys32_lseek
-+      .quad sys_getpid                /* 20 */
-+      .quad compat_sys_mount  /* mount  */
-+      .quad sys_oldumount     /* old_umount  */
-+      .quad sys_setuid16
-+      .quad sys_getuid16
-+      .quad compat_sys_stime  /* stime */             /* 25 */
-+      .quad sys32_ptrace      /* ptrace */
-+      .quad sys_alarm
-+      .quad sys_fstat /* (old)fstat */
-+      .quad sys_pause
-+      .quad compat_sys_utime  /* 30 */
-+      .quad quiet_ni_syscall  /* old stty syscall holder */
-+      .quad quiet_ni_syscall  /* old gtty syscall holder */
-+      .quad sys_access
-+      .quad sys_nice  
-+      .quad quiet_ni_syscall  /* 35 */        /* old ftime syscall holder */
-+      .quad sys_sync
-+      .quad sys32_kill
-+      .quad sys_rename
-+      .quad sys_mkdir
-+      .quad sys_rmdir         /* 40 */
-+      .quad sys_dup
-+      .quad sys32_pipe
-+      .quad compat_sys_times
-+      .quad quiet_ni_syscall                  /* old prof syscall holder */
-+      .quad sys_brk           /* 45 */
-+      .quad sys_setgid16
-+      .quad sys_getgid16
-+      .quad sys_signal
-+      .quad sys_geteuid16
-+      .quad sys_getegid16     /* 50 */
-+      .quad sys_acct
-+      .quad sys_umount                        /* new_umount */
-+      .quad quiet_ni_syscall                  /* old lock syscall holder */
-+      .quad compat_sys_ioctl
-+      .quad compat_sys_fcntl64                /* 55 */
-+      .quad quiet_ni_syscall                  /* old mpx syscall holder */
-+      .quad sys_setpgid
-+      .quad quiet_ni_syscall                  /* old ulimit syscall holder */
-+      .quad sys32_olduname
-+      .quad sys_umask         /* 60 */
-+      .quad sys_chroot
-+      .quad sys32_ustat
-+      .quad sys_dup2
-+      .quad sys_getppid
-+      .quad sys_getpgrp               /* 65 */
-+      .quad sys_setsid
-+      .quad sys32_sigaction
-+      .quad sys_sgetmask
-+      .quad sys_ssetmask
-+      .quad sys_setreuid16    /* 70 */
-+      .quad sys_setregid16
-+      .quad stub32_sigsuspend
-+      .quad compat_sys_sigpending
-+      .quad sys_sethostname
-+      .quad compat_sys_setrlimit      /* 75 */
-+      .quad compat_sys_old_getrlimit  /* old_getrlimit */
-+      .quad compat_sys_getrusage
-+      .quad sys32_gettimeofday
-+      .quad sys32_settimeofday
-+      .quad sys_getgroups16   /* 80 */
-+      .quad sys_setgroups16
-+      .quad sys32_old_select
-+      .quad sys_symlink
-+      .quad sys_lstat
-+      .quad sys_readlink              /* 85 */
-+#ifdef CONFIG_IA32_AOUT
-+      .quad sys_uselib
-+#else
-+      .quad quiet_ni_syscall
-+#endif
-+      .quad sys_swapon
-+      .quad sys_reboot
-+      .quad compat_sys_old_readdir
-+      .quad sys32_mmap                /* 90 */
-+      .quad sys_munmap
-+      .quad sys_truncate
-+      .quad sys_ftruncate
-+      .quad sys_fchmod
-+      .quad sys_fchown16              /* 95 */
-+      .quad sys_getpriority
-+      .quad sys_setpriority
-+      .quad quiet_ni_syscall                  /* old profil syscall holder */
-+      .quad compat_sys_statfs
-+      .quad compat_sys_fstatfs                /* 100 */
-+      .quad sys_ioperm
-+      .quad compat_sys_socketcall
-+      .quad sys_syslog
-+      .quad compat_sys_setitimer
-+      .quad compat_sys_getitimer      /* 105 */
-+      .quad compat_sys_newstat
-+      .quad compat_sys_newlstat
-+      .quad compat_sys_newfstat
-+      .quad sys32_uname
-+      .quad stub32_iopl               /* 110 */
-+      .quad sys_vhangup
-+      .quad quiet_ni_syscall  /* old "idle" system call */
-+      .quad sys32_vm86_warning        /* vm86old */ 
-+      .quad compat_sys_wait4
-+      .quad sys_swapoff               /* 115 */
-+      .quad sys32_sysinfo
-+      .quad sys32_ipc
-+      .quad sys_fsync
-+      .quad stub32_sigreturn
-+      .quad stub32_clone              /* 120 */
-+      .quad sys_setdomainname
-+      .quad sys_uname
-+      .quad sys_modify_ldt
-+      .quad sys32_adjtimex
-+      .quad sys32_mprotect            /* 125 */
-+      .quad compat_sys_sigprocmask
-+      .quad quiet_ni_syscall          /* create_module */
-+      .quad sys_init_module
-+      .quad sys_delete_module
-+      .quad quiet_ni_syscall          /* 130  get_kernel_syms */
-+      .quad sys_quotactl
-+      .quad sys_getpgid
-+      .quad sys_fchdir
-+      .quad quiet_ni_syscall  /* bdflush */
-+      .quad sys_sysfs         /* 135 */
-+      .quad sys_personality
-+      .quad quiet_ni_syscall  /* for afs_syscall */
-+      .quad sys_setfsuid16
-+      .quad sys_setfsgid16
-+      .quad sys_llseek                /* 140 */
-+      .quad compat_sys_getdents
-+      .quad compat_sys_select
-+      .quad sys_flock
-+      .quad sys_msync
-+      .quad compat_sys_readv          /* 145 */
-+      .quad compat_sys_writev
-+      .quad sys_getsid
-+      .quad sys_fdatasync
-+      .quad sys32_sysctl      /* sysctl */
-+      .quad sys_mlock         /* 150 */
-+      .quad sys_munlock
-+      .quad sys_mlockall
-+      .quad sys_munlockall
-+      .quad sys_sched_setparam
-+      .quad sys_sched_getparam   /* 155 */
-+      .quad sys_sched_setscheduler
-+      .quad sys_sched_getscheduler
-+      .quad sys_sched_yield
-+      .quad sys_sched_get_priority_max
-+      .quad sys_sched_get_priority_min  /* 160 */
-+      .quad sys_sched_rr_get_interval
-+      .quad compat_sys_nanosleep
-+      .quad sys_mremap
-+      .quad sys_setresuid16
-+      .quad sys_getresuid16   /* 165 */
-+      .quad sys32_vm86_warning        /* vm86 */ 
-+      .quad quiet_ni_syscall  /* query_module */
-+      .quad sys_poll
-+      .quad compat_sys_nfsservctl
-+      .quad sys_setresgid16   /* 170 */
-+      .quad sys_getresgid16
-+      .quad sys_prctl
-+      .quad stub32_rt_sigreturn
-+      .quad sys32_rt_sigaction
-+      .quad sys32_rt_sigprocmask      /* 175 */
-+      .quad sys32_rt_sigpending
-+      .quad compat_sys_rt_sigtimedwait
-+      .quad sys32_rt_sigqueueinfo
-+      .quad stub32_rt_sigsuspend
-+      .quad sys32_pread               /* 180 */
-+      .quad sys32_pwrite
-+      .quad sys_chown16
-+      .quad sys_getcwd
-+      .quad sys_capget
-+      .quad sys_capset
-+      .quad stub32_sigaltstack
-+      .quad sys32_sendfile
-+      .quad quiet_ni_syscall          /* streams1 */
-+      .quad quiet_ni_syscall          /* streams2 */
-+      .quad stub32_vfork            /* 190 */
-+      .quad compat_sys_getrlimit
-+      .quad sys32_mmap2
-+      .quad sys32_truncate64
-+      .quad sys32_ftruncate64
-+      .quad sys32_stat64              /* 195 */
-+      .quad sys32_lstat64
-+      .quad sys32_fstat64
-+      .quad sys_lchown
-+      .quad sys_getuid
-+      .quad sys_getgid                /* 200 */
-+      .quad sys_geteuid
-+      .quad sys_getegid
-+      .quad sys_setreuid
-+      .quad sys_setregid
-+      .quad sys_getgroups     /* 205 */
-+      .quad sys_setgroups
-+      .quad sys_fchown
-+      .quad sys_setresuid
-+      .quad sys_getresuid
-+      .quad sys_setresgid     /* 210 */
-+      .quad sys_getresgid
-+      .quad sys_chown
-+      .quad sys_setuid
-+      .quad sys_setgid
-+      .quad sys_setfsuid              /* 215 */
-+      .quad sys_setfsgid
-+      .quad sys_pivot_root
-+      .quad sys_mincore
-+      .quad sys_madvise
-+      .quad compat_sys_getdents64     /* 220 getdents64 */
-+      .quad compat_sys_fcntl64        
-+      .quad quiet_ni_syscall          /* tux */
-+      .quad quiet_ni_syscall          /* security */
-+      .quad sys_gettid        
-+      .quad sys_readahead     /* 225 */
-+      .quad sys_setxattr
-+      .quad sys_lsetxattr
-+      .quad sys_fsetxattr
-+      .quad sys_getxattr
-+      .quad sys_lgetxattr     /* 230 */
-+      .quad sys_fgetxattr
-+      .quad sys_listxattr
-+      .quad sys_llistxattr
-+      .quad sys_flistxattr
-+      .quad sys_removexattr   /* 235 */
-+      .quad sys_lremovexattr
-+      .quad sys_fremovexattr
-+      .quad sys_tkill
-+      .quad sys_sendfile64 
-+      .quad compat_sys_futex          /* 240 */
-+      .quad compat_sys_sched_setaffinity
-+      .quad compat_sys_sched_getaffinity
-+      .quad sys32_set_thread_area
-+      .quad sys32_get_thread_area
-+      .quad compat_sys_io_setup       /* 245 */
-+      .quad sys_io_destroy
-+      .quad compat_sys_io_getevents
-+      .quad compat_sys_io_submit
-+      .quad sys_io_cancel
-+      .quad sys_fadvise64             /* 250 */
-+      .quad quiet_ni_syscall  /* free_huge_pages */
-+      .quad sys_exit_group
-+      .quad sys32_lookup_dcookie
-+      .quad sys_epoll_create
-+      .quad sys_epoll_ctl             /* 255 */
-+      .quad sys_epoll_wait
-+      .quad sys_remap_file_pages
-+      .quad sys_set_tid_address
-+      .quad compat_sys_timer_create
-+      .quad compat_sys_timer_settime  /* 260 */
-+      .quad compat_sys_timer_gettime
-+      .quad sys_timer_getoverrun
-+      .quad sys_timer_delete
-+      .quad compat_sys_clock_settime
-+      .quad compat_sys_clock_gettime  /* 265 */
-+      .quad compat_sys_clock_getres
-+      .quad compat_sys_clock_nanosleep
-+      .quad compat_sys_statfs64
-+      .quad compat_sys_fstatfs64
-+      .quad sys_tgkill                /* 270 */
-+      .quad compat_sys_utimes
-+      .quad sys32_fadvise64_64
-+      .quad quiet_ni_syscall  /* sys_vserver */
-+      .quad sys_mbind
-+      .quad compat_sys_get_mempolicy  /* 275 */
-+      .quad sys_set_mempolicy
-+      .quad compat_sys_mq_open
-+      .quad sys_mq_unlink
-+      .quad compat_sys_mq_timedsend
-+      .quad compat_sys_mq_timedreceive        /* 280 */
-+      .quad compat_sys_mq_notify
-+      .quad compat_sys_mq_getsetattr
-+      .quad compat_sys_kexec_load     /* reserved for kexec */
-+      .quad compat_sys_waitid
-+      .quad quiet_ni_syscall          /* 285: sys_altroot */
-+      .quad sys_add_key
-+      .quad sys_request_key
-+      .quad sys_keyctl
-+      .quad sys_ioprio_set
-+      .quad sys_ioprio_get            /* 290 */
-+      .quad sys_inotify_init
-+      .quad sys_inotify_add_watch
-+      .quad sys_inotify_rm_watch
-+      .quad sys_migrate_pages
-+      .quad compat_sys_openat         /* 295 */
-+      .quad sys_mkdirat
-+      .quad sys_mknodat
-+      .quad sys_fchownat
-+      .quad compat_sys_futimesat
-+      .quad sys32_fstatat             /* 300 */
-+      .quad sys_unlinkat
-+      .quad sys_renameat
-+      .quad sys_linkat
-+      .quad sys_symlinkat
-+      .quad sys_readlinkat            /* 305 */
-+      .quad sys_fchmodat
-+      .quad sys_faccessat
-+      .quad sys_ni_syscall            /* pselect6 for now */
-+      .quad sys_ni_syscall            /* ppoll for now */
-+      .quad sys_unshare               /* 310 */
-+ia32_syscall_end:             
-+      .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
-+              .quad ni_syscall
-+      .endr
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/ia32/syscall32-xen.c linux-2.6.16.33/arch/x86_64/ia32/syscall32-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/ia32/syscall32-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/ia32/syscall32-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,128 @@
-+/* Copyright 2002,2003 Andi Kleen, SuSE Labs */
-+
-+/* vsyscall handling for 32bit processes. Map a stub page into it 
-+   on demand because 32bit cannot reach the kernel's fixmaps */
-+
-+#include <linux/mm.h>
-+#include <linux/string.h>
-+#include <linux/kernel.h>
-+#include <linux/gfp.h>
-+#include <linux/init.h>
-+#include <linux/stringify.h>
-+#include <linux/security.h>
-+#include <asm/proto.h>
-+#include <asm/tlbflush.h>
-+#include <asm/ia32_unistd.h>
-+
-+#ifdef USE_INT80
-+extern unsigned char syscall32_int80[], syscall32_int80_end[];
-+#endif
-+extern unsigned char syscall32_syscall[], syscall32_syscall_end[];
-+extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
-+extern int sysctl_vsyscall32;
-+
-+char *syscall32_page; 
-+#ifndef USE_INT80
-+static int use_sysenter = -1;
-+#endif
-+
-+static struct page *
-+syscall32_nopage(struct vm_area_struct *vma, unsigned long adr, int *type)
-+{
-+      struct page *p = virt_to_page(adr - vma->vm_start + syscall32_page);
-+      get_page(p);
-+      return p;
-+}
-+
-+/* Prevent VMA merging */
-+static void syscall32_vma_close(struct vm_area_struct *vma)
-+{
-+}
-+
-+static struct vm_operations_struct syscall32_vm_ops = {
-+      .close = syscall32_vma_close,
-+      .nopage = syscall32_nopage,
-+};
-+
-+struct linux_binprm;
-+
-+/* Setup a VMA at program startup for the vsyscall page */
-+int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
-+{
-+      int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT;
-+      struct vm_area_struct *vma;
-+      struct mm_struct *mm = current->mm;
-+      int ret;
-+
-+      vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-+      if (!vma)
-+              return -ENOMEM;
-+
-+      memset(vma, 0, sizeof(struct vm_area_struct));
-+      /* Could randomize here */
-+      vma->vm_start = VSYSCALL32_BASE;
-+      vma->vm_end = VSYSCALL32_END;
-+      /* MAYWRITE to allow gdb to COW and set breakpoints */
-+      vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
-+      vma->vm_flags |= mm->def_flags;
-+      vma->vm_page_prot = protection_map[vma->vm_flags & 7];
-+      vma->vm_ops = &syscall32_vm_ops;
-+      vma->vm_mm = mm;
-+
-+      down_write(&mm->mmap_sem);
-+      if ((ret = insert_vm_struct(mm, vma))) {
-+              up_write(&mm->mmap_sem);
-+              kmem_cache_free(vm_area_cachep, vma);
-+              return ret;
-+      }
-+      mm->total_vm += npages;
-+      up_write(&mm->mmap_sem);
-+      return 0;
-+}
-+
-+static int __init init_syscall32(void)
-+{ 
-+      syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); 
-+      if (!syscall32_page) 
-+              panic("Cannot allocate syscall32 page"); 
-+
-+#ifdef USE_INT80
-+      /*
-+       * At this point we use int 0x80.
-+       */
-+      memcpy(syscall32_page, syscall32_int80,
-+             syscall32_int80_end - syscall32_int80);
-+#else
-+      if (use_sysenter > 0) {
-+              memcpy(syscall32_page, syscall32_sysenter,
-+                     syscall32_sysenter_end - syscall32_sysenter);
-+      } else {
-+              memcpy(syscall32_page, syscall32_syscall,
-+                     syscall32_syscall_end - syscall32_syscall);
-+      }       
-+#endif
-+      return 0;
-+} 
-+
-+/*
-+ * This must be done early in case we have an initrd containing 32-bit
-+ * binaries (e.g., hotplug). This could be pushed upstream to arch/x86_64.
-+ */   
-+core_initcall(init_syscall32); 
-+
-+/* May not be __init: called during resume */
-+void syscall32_cpu_init(void)
-+{
-+#ifndef USE_INT80
-+      if (use_sysenter < 0)
-+              use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
-+
-+      /* Load these always in case some future AMD CPU supports
-+         SYSENTER from compat mode too. */
-+      checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
-+      checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
-+      checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
-+
-+      wrmsrl(MSR_CSTAR, ia32_cstar_target);
-+#endif
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/ia32/syscall32_syscall-xen.S linux-2.6.16.33/arch/x86_64/ia32/syscall32_syscall-xen.S
---- linux-2.6.16.33-noxen/arch/x86_64/ia32/syscall32_syscall-xen.S     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/ia32/syscall32_syscall-xen.S   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,28 @@
-+/* 32bit VDSOs mapped into user space. */
-+
-+      .section ".init.data","aw"
-+
-+#ifdef USE_INT80
-+
-+      .globl syscall32_int80
-+      .globl syscall32_int80_end
-+
-+syscall32_int80:
-+      .incbin "arch/x86_64/ia32/vsyscall-int80.so"
-+syscall32_int80_end:
-+
-+#endif
-+
-+      .globl syscall32_syscall
-+      .globl syscall32_syscall_end
-+
-+syscall32_syscall:
-+      .incbin "arch/x86_64/ia32/vsyscall-syscall.so"
-+syscall32_syscall_end:
-+
-+      .globl syscall32_sysenter
-+      .globl syscall32_sysenter_end
-+
-+syscall32_sysenter:
-+      .incbin "arch/x86_64/ia32/vsyscall-sysenter.so"
-+syscall32_sysenter_end:
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/ia32/vsyscall-int80.S linux-2.6.16.33/arch/x86_64/ia32/vsyscall-int80.S
---- linux-2.6.16.33-noxen/arch/x86_64/ia32/vsyscall-int80.S    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/ia32/vsyscall-int80.S  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,58 @@
-+/*
-+ * Code for the vsyscall page.  This version uses the old int $0x80 method.
-+ *
-+ * NOTE:
-+ * 1) __kernel_vsyscall _must_ be first in this page.
-+ * 2) there are alignment constraints on this stub, see vsyscall-sigreturn.S
-+ *    for details.
-+ */
-+#include <asm/ia32_unistd.h>
-+#include <asm/asm-offsets.h>
-+
-+      .code32
-+      .text
-+      .section .text.vsyscall,"ax"
-+      .globl __kernel_vsyscall
-+      .type __kernel_vsyscall,@function
-+__kernel_vsyscall:
-+.LSTART_vsyscall:
-+      int $0x80
-+      ret
-+.LEND_vsyscall:
-+      .size __kernel_vsyscall,.-.LSTART_vsyscall
-+      .previous
-+
-+      .section .eh_frame,"a",@progbits
-+.LSTARTFRAME:
-+      .long .LENDCIE-.LSTARTCIE
-+.LSTARTCIE:
-+      .long 0                 /* CIE ID */
-+      .byte 1                 /* Version number */
-+      .string "zR"            /* NUL-terminated augmentation string */
-+      .uleb128 1              /* Code alignment factor */
-+      .sleb128 -4             /* Data alignment factor */
-+      .byte 8                 /* Return address register column */
-+      .uleb128 1              /* Augmentation value length */
-+      .byte 0x1b              /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
-+      .byte 0x0c              /* DW_CFA_def_cfa */
-+      .uleb128 4
-+      .uleb128 4
-+      .byte 0x88              /* DW_CFA_offset, column 0x8 */
-+      .uleb128 1
-+      .align 4
-+.LENDCIE:
-+
-+      .long .LENDFDE1-.LSTARTFDE1     /* Length FDE */
-+.LSTARTFDE1:
-+      .long .LSTARTFDE1-.LSTARTFRAME  /* CIE pointer */
-+      .long .LSTART_vsyscall-.        /* PC-relative start address */
-+      .long .LEND_vsyscall-.LSTART_vsyscall
-+      .uleb128 0                      /* Augmentation length */
-+      .align 4
-+.LENDFDE1:
-+              
-+/*
-+ * Get the common code for the sigreturn entry points.
-+ */
-+#define SYSCALL_ENTER_KERNEL    int $0x80
-+#include "vsyscall-sigreturn.S"
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/ia32/vsyscall-sigreturn.S linux-2.6.16.33/arch/x86_64/ia32/vsyscall-sigreturn.S
---- linux-2.6.16.33-noxen/arch/x86_64/ia32/vsyscall-sigreturn.S        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/ia32/vsyscall-sigreturn.S      2007-01-08 15:00:45.000000000 +0000
-@@ -120,5 +120,5 @@
-       .align 4
- .LENDFDE3:
--#include "../../i386/kernel/vsyscall-note.S"
-+#include <vsyscall-note.S>
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/Makefile linux-2.6.16.33/arch/x86_64/kernel/Makefile
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/Makefile  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/Makefile        2007-01-08 15:00:45.000000000 +0000
-@@ -20,11 +20,13 @@
- obj-$(CONFIG_X86_CPUID)               += cpuid.o
- obj-$(CONFIG_SMP)             += smp.o smpboot.o trampoline.o
- obj-$(CONFIG_X86_LOCAL_APIC)  += apic.o  nmi.o
-+obj-$(CONFIG_X86_XEN_GENAPIC) += genapic.o genapic_xen.o
- obj-$(CONFIG_X86_IO_APIC)     += io_apic.o mpparse.o \
-               genapic.o genapic_cluster.o genapic_flat.o
- obj-$(CONFIG_KEXEC)           += machine_kexec.o relocate_kernel.o crash.o
- obj-$(CONFIG_CRASH_DUMP)      += crash_dump.o
--obj-$(CONFIG_PM)              += suspend.o
-+obj-$(CONFIG_SOFTWARE_SUSPEND)        += suspend.o
-+obj-$(CONFIG_ACPI_SLEEP)      += suspend.o
- obj-$(CONFIG_SOFTWARE_SUSPEND)        += suspend_asm.o
- obj-$(CONFIG_CPU_FREQ)                += cpufreq/
- obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
-@@ -51,3 +53,17 @@
- msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
- dmi_scan-y                    += ../../i386/kernel/dmi_scan.o
-+ifdef CONFIG_XEN
-+time-y                                += ../../i386/kernel/time-xen.o
-+pci-dma-y                     += ../../i386/kernel/pci-dma-xen.o
-+microcode-$(subst m,y,$(CONFIG_MICROCODE))  := ../../i386/kernel/microcode-xen.o
-+quirks-y                      := ../../i386/kernel/quirks-xen.o
-+
-+n-obj-xen := i8259.o reboot.o i8237.o smpboot.o trampoline.o
-+
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
-+obj-y := $(call cherrypickxen, $(obj-y))
-+extra-y := $(call cherrypickxen, $(extra-y))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/acpi/Makefile linux-2.6.16.33/arch/x86_64/kernel/acpi/Makefile
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/acpi/Makefile     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/acpi/Makefile   2007-01-08 15:00:45.000000000 +0000
-@@ -7,3 +7,4 @@
- processor-y           := ../../../i386/kernel/acpi/processor.o ../../../i386/kernel/acpi/cstate.o
- endif
-+boot-$(CONFIG_XEN)            := ../../../i386/kernel/acpi/boot-xen.o
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/apic-xen.c linux-2.6.16.33/arch/x86_64/kernel/apic-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/apic-xen.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/apic-xen.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,198 @@
-+/*
-+ *    Local APIC handling, local APIC timers
-+ *
-+ *    (c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
-+ *
-+ *    Fixes
-+ *    Maciej W. Rozycki       :       Bits for genuine 82489DX APICs;
-+ *                                    thanks to Eric Gilmore
-+ *                                    and Rolf G. Tews
-+ *                                    for testing these extensively.
-+ *    Maciej W. Rozycki       :       Various updates and fixes.
-+ *    Mikael Pettersson       :       Power Management for UP-APIC.
-+ *    Pavel Machek and
-+ *    Mikael Pettersson       :       PM converted to driver model.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+
-+#include <linux/mm.h>
-+#include <linux/delay.h>
-+#include <linux/bootmem.h>
-+#include <linux/smp_lock.h>
-+#include <linux/interrupt.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/sysdev.h>
-+#include <linux/module.h>
-+
-+#include <asm/atomic.h>
-+#include <asm/smp.h>
-+#include <asm/mtrr.h>
-+#include <asm/mpspec.h>
-+#include <asm/desc.h>
-+#include <asm/arch_hooks.h>
-+#include <asm/hpet.h>
-+#include <asm/idle.h>
-+
-+int apic_verbosity;
-+
-+/*
-+ * 'what should we do if we get a hw irq event on an illegal vector'.
-+ * each architecture has to answer this themselves.
-+ */
-+void ack_bad_irq(unsigned int irq)
-+{
-+      printk("unexpected IRQ trap at vector %02x\n", irq);
-+      /*
-+       * Currently unexpected vectors happen only on SMP and APIC.
-+       * We _must_ ack these because every local APIC has only N
-+       * irq slots per priority level, and a 'hanging, unacked' IRQ
-+       * holds up an irq slot - in excessive cases (when multiple
-+       * unexpected vectors occur) that might lock up the APIC
-+       * completely.
-+       * But don't ack when the APIC is disabled. -AK
-+       */
-+      if (!disable_apic)
-+              ack_APIC_irq();
-+}
-+
-+int setup_profiling_timer(unsigned int multiplier)
-+{
-+      return -EINVAL;
-+}
-+
-+void smp_local_timer_interrupt(struct pt_regs *regs)
-+{
-+      profile_tick(CPU_PROFILING, regs);
-+#ifndef CONFIG_XEN
-+#ifdef CONFIG_SMP
-+              update_process_times(user_mode(regs));
-+#endif
-+#endif
-+      /*
-+       * We take the 'long' return path, and there every subsystem
-+       * grabs the appropriate locks (kernel lock/ irq lock).
-+       *
-+       * we might want to decouple profiling from the 'long path',
-+       * and do the profiling totally in assembly.
-+       *
-+       * Currently this isn't too much of an issue (performance wise),
-+       * we can take more than 100K local irqs per second on a 100 MHz P5.
-+       */
-+}
-+
-+/*
-+ * Local APIC timer interrupt. This is the most natural way for doing
-+ * local interrupts, but local timer interrupts can be emulated by
-+ * broadcast interrupts too. [in case the hw doesn't support APIC timers]
-+ *
-+ * [ if a single-CPU system runs an SMP kernel then we call the local
-+ *   interrupt as well. Thus we cannot inline the local irq ... ]
-+ */
-+void smp_apic_timer_interrupt(struct pt_regs *regs)
-+{
-+      /*
-+       * the NMI deadlock-detector uses this.
-+       */
-+      add_pda(apic_timer_irqs, 1);
-+
-+      /*
-+       * NOTE! We'd better ACK the irq immediately,
-+       * because timer handling can be slow.
-+       */
-+      ack_APIC_irq();
-+      /*
-+       * update_process_times() expects us to have done irq_enter().
-+       * Besides, if we don't timer interrupts ignore the global
-+       * interrupt lock, which is the WrongThing (tm) to do.
-+       */
-+      exit_idle();
-+      irq_enter();
-+      smp_local_timer_interrupt(regs);
-+      irq_exit();
-+}
-+
-+/*
-+ * This interrupt should _never_ happen with our APIC/SMP architecture
-+ */
-+asmlinkage void smp_spurious_interrupt(void)
-+{
-+      unsigned int v;
-+      exit_idle();
-+      irq_enter();
-+      /*
-+       * Check if this really is a spurious interrupt and ACK it
-+       * if it is a vectored one.  Just in case...
-+       * Spurious interrupts should not be ACKed.
-+       */
-+      v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
-+      if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
-+              ack_APIC_irq();
-+
-+#if 0
-+      static unsigned long last_warning; 
-+      static unsigned long skipped; 
-+
-+      /* see sw-dev-man vol 3, chapter 7.4.13.5 */
-+      if (time_before(last_warning+30*HZ,jiffies)) { 
-+              printk(KERN_INFO "spurious APIC interrupt on CPU#%d, %ld skipped.\n",
-+                     smp_processor_id(), skipped);
-+              last_warning = jiffies; 
-+              skipped = 0;
-+      } else { 
-+              skipped++; 
-+      } 
-+#endif 
-+      irq_exit();
-+}
-+
-+/*
-+ * This interrupt should never happen with our APIC/SMP architecture
-+ */
-+
-+asmlinkage void smp_error_interrupt(void)
-+{
-+      unsigned int v, v1;
-+
-+      exit_idle();
-+      irq_enter();
-+      /* First tickle the hardware, only then report what went on. -- REW */
-+      v = apic_read(APIC_ESR);
-+      apic_write(APIC_ESR, 0);
-+      v1 = apic_read(APIC_ESR);
-+      ack_APIC_irq();
-+      atomic_inc(&irq_err_count);
-+
-+      /* Here is what the APIC error bits mean:
-+         0: Send CS error
-+         1: Receive CS error
-+         2: Send accept error
-+         3: Receive accept error
-+         4: Reserved
-+         5: Send illegal vector
-+         6: Received illegal vector
-+         7: Illegal register address
-+      */
-+      printk (KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
-+              smp_processor_id(), v , v1);
-+      irq_exit();
-+}
-+
-+int disable_apic;
-+
-+/*
-+ * This initializes the IO-APIC and APIC hardware if this is
-+ * a UP kernel.
-+ */
-+int __init APIC_init_uniprocessor (void)
-+{
-+#ifdef CONFIG_X86_IO_APIC
-+      if (smp_found_config)
-+              if (!skip_ioapic_setup && nr_ioapics)
-+                      setup_IO_APIC();
-+#endif
-+
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/asm-offsets.c linux-2.6.16.33/arch/x86_64/kernel/asm-offsets.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/asm-offsets.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/asm-offsets.c   2007-01-08 15:00:45.000000000 +0000
-@@ -66,7 +66,9 @@
-       DEFINE(pbe_address, offsetof(struct pbe, address));
-       DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
-       DEFINE(pbe_next, offsetof(struct pbe, next));
-+#ifndef CONFIG_X86_NO_TSS
-       BLANK();
-       DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
-+#endif
-       return 0;
- }
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/crash.c linux-2.6.16.33/arch/x86_64/kernel/crash.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/crash.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/crash.c 2007-01-08 15:00:45.000000000 +0000
-@@ -92,6 +92,7 @@
-       crash_save_this_cpu(regs, cpu);
- }
-+#ifndef CONFIG_XEN
- #ifdef CONFIG_SMP
- static atomic_t waiting_for_crash_ipi;
-@@ -156,6 +157,7 @@
-       /* There are no cpus to shootdown */
- }
- #endif
-+#endif /* CONFIG_XEN */
- void machine_crash_shutdown(struct pt_regs *regs)
- {
-@@ -173,6 +175,8 @@
-       /* Make a note of crashing cpu. Will be used in NMI callback.*/
-       crashing_cpu = smp_processor_id();
-+
-+#ifndef CONFIG_XEN
-       nmi_shootdown_cpus();
-       if(cpu_has_apic)
-@@ -181,6 +185,6 @@
- #if defined(CONFIG_X86_IO_APIC)
-       disable_IO_APIC();
- #endif
--
-+#endif /* CONFIG_XEN */
-       crash_save_self(regs);
- }
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/e820-xen.c linux-2.6.16.33/arch/x86_64/kernel/e820-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/e820-xen.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/e820-xen.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,719 @@
-+/* 
-+ * Handle the memory map.
-+ * The functions here do the job until bootmem takes over.
-+ * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $
-+ *
-+ *  Getting sanitize_e820_map() in sync with i386 version by applying change:
-+ *  -  Provisions for empty E820 memory regions (reported by certain BIOSes).
-+ *     Alex Achenbach <xela@slit.de>, December 2002.
-+ *  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/bootmem.h>
-+#include <linux/ioport.h>
-+#include <linux/string.h>
-+#include <linux/kexec.h>
-+#include <linux/module.h>
-+
-+#include <asm/page.h>
-+#include <asm/e820.h>
-+#include <asm/proto.h>
-+#include <asm/bootsetup.h>
-+#include <asm/sections.h>
-+#include <xen/interface/memory.h>
-+
-+/* 
-+ * PFN of last memory page.
-+ */
-+unsigned long end_pfn; 
-+EXPORT_SYMBOL(end_pfn);
-+
-+/* 
-+ * end_pfn only includes RAM, while end_pfn_map includes all e820 entries.
-+ * The direct mapping extends to end_pfn_map, so that we can directly access
-+ * apertures, ACPI and other tables without having to play with fixmaps.
-+ */ 
-+unsigned long end_pfn_map; 
-+
-+/* 
-+ * Last pfn which the user wants to use.
-+ */
-+unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;  
-+
-+extern struct resource code_resource, data_resource;
-+
-+/* Check for some hardcoded bad areas that early boot is not allowed to touch */ 
-+static inline int bad_addr(unsigned long *addrp, unsigned long size)
-+{ 
-+      unsigned long addr = *addrp, last = addr + size; 
-+
-+#ifndef CONFIG_XEN
-+      /* various gunk below that needed for SMP startup */
-+      if (addr < 0x8000) { 
-+              *addrp = 0x8000;
-+              return 1; 
-+      }
-+
-+      /* direct mapping tables of the kernel */
-+      if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) { 
-+              *addrp = table_end << PAGE_SHIFT; 
-+              return 1;
-+      } 
-+
-+      /* initrd */ 
-+#ifdef CONFIG_BLK_DEV_INITRD
-+      if (LOADER_TYPE && INITRD_START && last >= INITRD_START && 
-+          addr < INITRD_START+INITRD_SIZE) { 
-+              *addrp = INITRD_START + INITRD_SIZE; 
-+              return 1;
-+      } 
-+#endif
-+      /* kernel code + 640k memory hole (later should not be needed, but 
-+         be paranoid for now) */
-+      if (last >= 640*1024 && addr < __pa_symbol(&_end)) { 
-+              *addrp = __pa_symbol(&_end);
-+              return 1;
-+      }
-+      /* XXX ramdisk image here? */ 
-+#else
-+      if (last < (table_end<<PAGE_SHIFT)) {
-+              *addrp = table_end << PAGE_SHIFT;
-+              return 1;
-+      }
-+#endif
-+      return 0;
-+} 
-+
-+#ifndef CONFIG_XEN
-+int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) 
-+{ 
-+      int i;
-+      for (i = 0; i < e820.nr_map; i++) { 
-+              struct e820entry *ei = &e820.map[i]; 
-+              if (type && ei->type != type) 
-+                      continue;
-+              if (ei->addr >= end || ei->addr + ei->size <= start)
-+                      continue; 
-+              return 1; 
-+      } 
-+      return 0;
-+}
-+#endif
-+
-+/* 
-+ * Find a free area in a specific range. 
-+ */ 
-+unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsigned size) 
-+{ 
-+      int i; 
-+      for (i = 0; i < e820.nr_map; i++) { 
-+              struct e820entry *ei = &e820.map[i]; 
-+              unsigned long addr = ei->addr, last; 
-+              if (ei->type != E820_RAM) 
-+                      continue; 
-+              if (addr < start) 
-+                      addr = start;
-+              if (addr > ei->addr + ei->size) 
-+                      continue; 
-+              while (bad_addr(&addr, size) && addr+size < ei->addr + ei->size)
-+                      ;
-+              last = addr + size;
-+              if (last > ei->addr + ei->size)
-+                      continue;
-+              if (last > end) 
-+                      continue;
-+              return addr; 
-+      } 
-+      return -1UL;            
-+} 
-+
-+/* 
-+ * Free bootmem based on the e820 table for a node.
-+ */
-+void __init e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end)
-+{
-+      int i;
-+      for (i = 0; i < e820.nr_map; i++) {
-+              struct e820entry *ei = &e820.map[i]; 
-+              unsigned long last, addr;
-+
-+              if (ei->type != E820_RAM || 
-+                  ei->addr+ei->size <= start || 
-+                  ei->addr >= end)
-+                      continue;
-+
-+              addr = round_up(ei->addr, PAGE_SIZE);
-+              if (addr < start) 
-+                      addr = start;
-+
-+              last = round_down(ei->addr + ei->size, PAGE_SIZE); 
-+              if (last >= end)
-+                      last = end; 
-+
-+              if (last > addr && last-addr >= PAGE_SIZE)
-+                      free_bootmem_node(pgdat, addr, last-addr);
-+      }
-+}
-+
-+/*
-+ * Find the highest page frame number we have available
-+ */
-+unsigned long __init e820_end_of_ram(void)
-+{
-+      int i;
-+      unsigned long end_pfn = 0;
-+      
-+      for (i = 0; i < e820.nr_map; i++) {
-+              struct e820entry *ei = &e820.map[i]; 
-+              unsigned long start, end;
-+
-+              start = round_up(ei->addr, PAGE_SIZE); 
-+              end = round_down(ei->addr + ei->size, PAGE_SIZE); 
-+              if (start >= end)
-+                      continue;
-+              if (ei->type == E820_RAM) { 
-+              if (end > end_pfn<<PAGE_SHIFT)
-+                      end_pfn = end>>PAGE_SHIFT;
-+              } else { 
-+                      if (end > end_pfn_map<<PAGE_SHIFT) 
-+                              end_pfn_map = end>>PAGE_SHIFT;
-+              } 
-+      }
-+
-+      if (end_pfn > end_pfn_map) 
-+              end_pfn_map = end_pfn;
-+      if (end_pfn_map > MAXMEM>>PAGE_SHIFT)
-+              end_pfn_map = MAXMEM>>PAGE_SHIFT;
-+      if (end_pfn > end_user_pfn)
-+              end_pfn = end_user_pfn;
-+      if (end_pfn > end_pfn_map) 
-+              end_pfn = end_pfn_map; 
-+
-+      return end_pfn; 
-+}
-+
-+/* 
-+ * Compute how much memory is missing in a range.
-+ * Unlike the other functions in this file the arguments are in page numbers.
-+ */
-+unsigned long __init
-+e820_hole_size(unsigned long start_pfn, unsigned long end_pfn)
-+{
-+      unsigned long ram = 0;
-+      unsigned long start = start_pfn << PAGE_SHIFT;
-+      unsigned long end = end_pfn << PAGE_SHIFT;
-+      int i;
-+      for (i = 0; i < e820.nr_map; i++) {
-+              struct e820entry *ei = &e820.map[i];
-+              unsigned long last, addr;
-+
-+              if (ei->type != E820_RAM ||
-+                  ei->addr+ei->size <= start ||
-+                  ei->addr >= end)
-+                      continue;
-+
-+              addr = round_up(ei->addr, PAGE_SIZE);
-+              if (addr < start)
-+                      addr = start;
-+
-+              last = round_down(ei->addr + ei->size, PAGE_SIZE);
-+              if (last >= end)
-+                      last = end;
-+
-+              if (last > addr)
-+                      ram += last - addr;
-+      }
-+      return ((end - start) - ram) >> PAGE_SHIFT;
-+}
-+
-+/*
-+ * Mark e820 reserved areas as busy for the resource manager.
-+ */
-+void __init e820_reserve_resources(struct e820entry *e820, int nr_map)
-+{
-+      int i;
-+      for (i = 0; i < nr_map; i++) {
-+              struct resource *res;
-+              res = alloc_bootmem_low(sizeof(struct resource));
-+              switch (e820[i].type) {
-+              case E820_RAM:  res->name = "System RAM"; break;
-+              case E820_ACPI: res->name = "ACPI Tables"; break;
-+              case E820_NVS:  res->name = "ACPI Non-volatile Storage"; break;
-+              default:        res->name = "reserved";
-+              }
-+              res->start = e820[i].addr;
-+              res->end = res->start + e820[i].size - 1;
-+              res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+              request_resource(&iomem_resource, res);
-+              if (e820[i].type == E820_RAM) {
-+                      /*
-+                       *  We don't know which RAM region contains kernel data,
-+                       *  so we try it repeatedly and let the resource manager
-+                       *  test it.
-+                       */
-+#ifndef CONFIG_XEN
-+                      request_resource(res, &code_resource);
-+                      request_resource(res, &data_resource);
-+#endif
-+#ifdef CONFIG_KEXEC
-+                      if (crashk_res.start != crashk_res.end)
-+                              request_resource(res, &crashk_res);
-+#ifdef CONFIG_XEN
-+                      xen_machine_kexec_register_resources(res);
-+#endif
-+#endif
-+              }
-+      }
-+}
-+
-+/* 
-+ * Add a memory region to the kernel e820 map.
-+ */ 
-+void __init add_memory_region(unsigned long start, unsigned long size, int type)
-+{
-+      int x = e820.nr_map;
-+
-+      if (x == E820MAX) {
-+              printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
-+              return;
-+      }
-+
-+      e820.map[x].addr = start;
-+      e820.map[x].size = size;
-+      e820.map[x].type = type;
-+      e820.nr_map++;
-+}
-+
-+void __init e820_print_map(char *who)
-+{
-+      int i;
-+
-+      for (i = 0; i < e820.nr_map; i++) {
-+              printk(" %s: %016Lx - %016Lx ", who,
-+                      (unsigned long long) e820.map[i].addr,
-+                      (unsigned long long) (e820.map[i].addr + e820.map[i].size));
-+              switch (e820.map[i].type) {
-+              case E820_RAM:  printk("(usable)\n");
-+                              break;
-+              case E820_RESERVED:
-+                              printk("(reserved)\n");
-+                              break;
-+              case E820_ACPI:
-+                              printk("(ACPI data)\n");
-+                              break;
-+              case E820_NVS:
-+                              printk("(ACPI NVS)\n");
-+                              break;
-+              default:        printk("type %u\n", e820.map[i].type);
-+                              break;
-+              }
-+      }
-+}
-+
-+/*
-+ * Sanitize the BIOS e820 map.
-+ *
-+ * Some e820 responses include overlapping entries.  The following 
-+ * replaces the original e820 map with a new one, removing overlaps.
-+ *
-+ */
-+static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
-+{
-+      struct change_member {
-+              struct e820entry *pbios; /* pointer to original bios entry */
-+              unsigned long long addr; /* address for this change point */
-+      };
-+      static struct change_member change_point_list[2*E820MAX] __initdata;
-+      static struct change_member *change_point[2*E820MAX] __initdata;
-+      static struct e820entry *overlap_list[E820MAX] __initdata;
-+      static struct e820entry new_bios[E820MAX] __initdata;
-+      struct change_member *change_tmp;
-+      unsigned long current_type, last_type;
-+      unsigned long long last_addr;
-+      int chgidx, still_changing;
-+      int overlap_entries;
-+      int new_bios_entry;
-+      int old_nr, new_nr, chg_nr;
-+      int i;
-+
-+      /*
-+              Visually we're performing the following (1,2,3,4 = memory types)...
-+
-+              Sample memory map (w/overlaps):
-+                 ____22__________________
-+                 ______________________4_
-+                 ____1111________________
-+                 _44_____________________
-+                 11111111________________
-+                 ____________________33__
-+                 ___________44___________
-+                 __________33333_________
-+                 ______________22________
-+                 ___________________2222_
-+                 _________111111111______
-+                 _____________________11_
-+                 _________________4______
-+
-+              Sanitized equivalent (no overlap):
-+                 1_______________________
-+                 _44_____________________
-+                 ___1____________________
-+                 ____22__________________
-+                 ______11________________
-+                 _________1______________
-+                 __________3_____________
-+                 ___________44___________
-+                 _____________33_________
-+                 _______________2________
-+                 ________________1_______
-+                 _________________4______
-+                 ___________________2____
-+                 ____________________33__
-+                 ______________________4_
-+      */
-+
-+      /* if there's only one memory region, don't bother */
-+      if (*pnr_map < 2)
-+              return -1;
-+
-+      old_nr = *pnr_map;
-+
-+      /* bail out if we find any unreasonable addresses in bios map */
-+      for (i=0; i<old_nr; i++)
-+              if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
-+                      return -1;
-+
-+      /* create pointers for initial change-point information (for sorting) */
-+      for (i=0; i < 2*old_nr; i++)
-+              change_point[i] = &change_point_list[i];
-+
-+      /* record all known change-points (starting and ending addresses),
-+         omitting those that are for empty memory regions */
-+      chgidx = 0;
-+      for (i=0; i < old_nr; i++)      {
-+              if (biosmap[i].size != 0) {
-+                      change_point[chgidx]->addr = biosmap[i].addr;
-+                      change_point[chgidx++]->pbios = &biosmap[i];
-+                      change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
-+                      change_point[chgidx++]->pbios = &biosmap[i];
-+              }
-+      }
-+      chg_nr = chgidx;
-+
-+      /* sort change-point list by memory addresses (low -> high) */
-+      still_changing = 1;
-+      while (still_changing)  {
-+              still_changing = 0;
-+              for (i=1; i < chg_nr; i++)  {
-+                      /* if <current_addr> > <last_addr>, swap */
-+                      /* or, if current=<start_addr> & last=<end_addr>, swap */
-+                      if ((change_point[i]->addr < change_point[i-1]->addr) ||
-+                              ((change_point[i]->addr == change_point[i-1]->addr) &&
-+                               (change_point[i]->addr == change_point[i]->pbios->addr) &&
-+                               (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
-+                         )
-+                      {
-+                              change_tmp = change_point[i];
-+                              change_point[i] = change_point[i-1];
-+                              change_point[i-1] = change_tmp;
-+                              still_changing=1;
-+                      }
-+              }
-+      }
-+
-+      /* create a new bios memory map, removing overlaps */
-+      overlap_entries=0;       /* number of entries in the overlap table */
-+      new_bios_entry=0;        /* index for creating new bios map entries */
-+      last_type = 0;           /* start with undefined memory type */
-+      last_addr = 0;           /* start with 0 as last starting address */
-+      /* loop through change-points, determining affect on the new bios map */
-+      for (chgidx=0; chgidx < chg_nr; chgidx++)
-+      {
-+              /* keep track of all overlapping bios entries */
-+              if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
-+              {
-+                      /* add map entry to overlap list (> 1 entry implies an overlap) */
-+                      overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
-+              }
-+              else
-+              {
-+                      /* remove entry from list (order independent, so swap with last) */
-+                      for (i=0; i<overlap_entries; i++)
-+                      {
-+                              if (overlap_list[i] == change_point[chgidx]->pbios)
-+                                      overlap_list[i] = overlap_list[overlap_entries-1];
-+                      }
-+                      overlap_entries--;
-+              }
-+              /* if there are overlapping entries, decide which "type" to use */
-+              /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
-+              current_type = 0;
-+              for (i=0; i<overlap_entries; i++)
-+                      if (overlap_list[i]->type > current_type)
-+                              current_type = overlap_list[i]->type;
-+              /* continue building up new bios map based on this information */
-+              if (current_type != last_type)  {
-+                      if (last_type != 0)      {
-+                              new_bios[new_bios_entry].size =
-+                                      change_point[chgidx]->addr - last_addr;
-+                              /* move forward only if the new size was non-zero */
-+                              if (new_bios[new_bios_entry].size != 0)
-+                                      if (++new_bios_entry >= E820MAX)
-+                                              break;  /* no more space left for new bios entries */
-+                      }
-+                      if (current_type != 0)  {
-+                              new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
-+                              new_bios[new_bios_entry].type = current_type;
-+                              last_addr=change_point[chgidx]->addr;
-+                      }
-+                      last_type = current_type;
-+              }
-+      }
-+      new_nr = new_bios_entry;   /* retain count for new bios entries */
-+
-+      /* copy new bios mapping into original location */
-+      memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
-+      *pnr_map = new_nr;
-+
-+      return 0;
-+}
-+
-+/*
-+ * Copy the BIOS e820 map into a safe place.
-+ *
-+ * Sanity-check it while we're at it..
-+ *
-+ * If we're lucky and live on a modern system, the setup code
-+ * will have given us a memory map that we can use to properly
-+ * set up memory.  If we aren't, we'll fake a memory map.
-+ *
-+ * We check to see that the memory map contains at least 2 elements
-+ * before we'll use it, because the detection code in setup.S may
-+ * not be perfect and most every PC known to man has two memory
-+ * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
-+ * thinkpad 560x, for example, does not cooperate with the memory
-+ * detection code.)
-+ */
-+static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
-+{
-+#ifndef CONFIG_XEN
-+      /* Only one memory region (or negative)? Ignore it */
-+      if (nr_map < 2)
-+              return -1;
-+#else
-+      BUG_ON(nr_map < 1);
-+#endif
-+
-+      do {
-+              unsigned long start = biosmap->addr;
-+              unsigned long size = biosmap->size;
-+              unsigned long end = start + size;
-+              unsigned long type = biosmap->type;
-+
-+              /* Overflow in 64 bits? Ignore the memory map. */
-+              if (start > end)
-+                      return -1;
-+
-+#ifndef CONFIG_XEN
-+              /*
-+               * Some BIOSes claim RAM in the 640k - 1M region.
-+               * Not right. Fix it up.
-+               * 
-+               * This should be removed on Hammer which is supposed to not
-+               * have non e820 covered ISA mappings there, but I had some strange
-+               * problems so it stays for now.  -AK
-+               */
-+              if (type == E820_RAM) {
-+                      if (start < 0x100000ULL && end > 0xA0000ULL) {
-+                              if (start < 0xA0000ULL)
-+                                      add_memory_region(start, 0xA0000ULL-start, type);
-+                              if (end <= 0x100000ULL)
-+                                      continue;
-+                              start = 0x100000ULL;
-+                              size = end - start;
-+                      }
-+              }
-+#endif
-+
-+              add_memory_region(start, size, type);
-+      } while (biosmap++,--nr_map);
-+      return 0;
-+}
-+
-+#ifndef CONFIG_XEN
-+void __init setup_memory_region(void)
-+{
-+      char *who = "BIOS-e820";
-+
-+      /*
-+       * Try to copy the BIOS-supplied E820-map.
-+       *
-+       * Otherwise fake a memory map; one section from 0k->640k,
-+       * the next section from 1mb->appropriate_mem_k
-+       */
-+      sanitize_e820_map(E820_MAP, &E820_MAP_NR);
-+      if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
-+              unsigned long mem_size;
-+
-+              /* compare results from other methods and take the greater */
-+              if (ALT_MEM_K < EXT_MEM_K) {
-+                      mem_size = EXT_MEM_K;
-+                      who = "BIOS-88";
-+              } else {
-+                      mem_size = ALT_MEM_K;
-+                      who = "BIOS-e801";
-+              }
-+
-+              e820.nr_map = 0;
-+              add_memory_region(0, LOWMEMSIZE(), E820_RAM);
-+              add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
-+      }
-+      printk(KERN_INFO "BIOS-provided physical RAM map:\n");
-+      e820_print_map(who);
-+}
-+
-+#else  /* CONFIG_XEN */
-+
-+void __init setup_memory_region(void)
-+{
-+      int rc;
-+      struct xen_memory_map memmap;
-+      /*
-+       * This is rather large for a stack variable but this early in
-+       * the boot process we know we have plenty slack space.
-+       */
-+      struct e820entry map[E820MAX];
-+
-+      memmap.nr_entries = E820MAX;
-+      set_xen_guest_handle(memmap.buffer, map);
-+
-+      rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
-+      if ( rc == -ENOSYS ) {
-+              memmap.nr_entries = 1;
-+              map[0].addr = 0ULL;
-+              map[0].size = xen_start_info->nr_pages << PAGE_SHIFT;
-+              /* 8MB slack (to balance backend allocations). */
-+              map[0].size += 8 << 20;
-+              map[0].type = E820_RAM;
-+              rc = 0;
-+      }
-+      BUG_ON(rc);
-+
-+      sanitize_e820_map(map, (char *)&memmap.nr_entries);
-+
-+      BUG_ON(copy_e820_map(map, (char)memmap.nr_entries) < 0);
-+
-+      printk(KERN_INFO "BIOS-provided physical RAM map:\n");
-+      e820_print_map("Xen");
-+}
-+#endif
-+
-+void __init parse_memopt(char *p, char **from) 
-+{ 
-+      int i;
-+      unsigned long current_end;
-+      unsigned long end;
-+
-+      end_user_pfn = memparse(p, from);
-+      end_user_pfn >>= PAGE_SHIFT;    
-+
-+      end = end_user_pfn<<PAGE_SHIFT;
-+      i = e820.nr_map-1;
-+      current_end = e820.map[i].addr + e820.map[i].size;
-+
-+      if (current_end < end) {
-+              /*
-+                 * The e820 map ends before our requested size so
-+                 * extend the final entry to the requested address.
-+                 */
-+              if (e820.map[i].type == E820_RAM)
-+                      e820.map[i].size = end - e820.map[i].addr;
-+              else
-+                      add_memory_region(current_end, end - current_end, E820_RAM);
-+      }
-+} 
-+
-+void __init parse_memmapopt(char *p, char **from)
-+{
-+      unsigned long long start_at, mem_size;
-+
-+      mem_size = memparse(p, from);
-+      p = *from;
-+      if (*p == '@') {
-+              start_at = memparse(p+1, from);
-+              add_memory_region(start_at, mem_size, E820_RAM);
-+      } else if (*p == '#') {
-+              start_at = memparse(p+1, from);
-+              add_memory_region(start_at, mem_size, E820_ACPI);
-+      } else if (*p == '$') {
-+              start_at = memparse(p+1, from);
-+              add_memory_region(start_at, mem_size, E820_RESERVED);
-+      } else {
-+              end_user_pfn = (mem_size >> PAGE_SHIFT);
-+      }
-+      p = *from;
-+}
-+
-+unsigned long pci_mem_start = 0xaeedbabe;
-+
-+/*
-+ * Search for the biggest gap in the low 32 bits of the e820
-+ * memory space.  We pass this space to PCI to assign MMIO resources
-+ * for hotplug or unconfigured devices in.
-+ * Hopefully the BIOS let enough space left.
-+ */
-+__init void e820_setup_gap(struct e820entry *e820, int nr_map)
-+{
-+      unsigned long gapstart, gapsize, round;
-+      unsigned long last;
-+      int i;
-+      int found = 0;
-+
-+      last = 0x100000000ull;
-+      gapstart = 0x10000000;
-+      gapsize = 0x400000;
-+      i = nr_map;
-+      while (--i >= 0) {
-+              unsigned long long start = e820[i].addr;
-+              unsigned long long end = start + e820[i].size;
-+
-+              /*
-+               * Since "last" is at most 4GB, we know we'll
-+               * fit in 32 bits if this condition is true
-+               */
-+              if (last > end) {
-+                      unsigned long gap = last - end;
-+
-+                      if (gap > gapsize) {
-+                              gapsize = gap;
-+                              gapstart = end;
-+                              found = 1;
-+                      }
-+              }
-+              if (start < last)
-+                      last = start;
-+      }
-+
-+      if (!found) {
-+              gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024;
-+              printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n"
-+                     KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n");
-+      }
-+
-+      /*
-+       * See how much we want to round up: start off with
-+       * rounding to the next 1MB area.
-+       */
-+      round = 0x100000;
-+      while ((gapsize >> 4) > round)
-+              round += round;
-+      /* Fun with two's complement */
-+      pci_mem_start = (gapstart + round) & -round;
-+
-+      printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
-+              pci_mem_start, gapstart, gapsize);
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/early_printk-xen.c linux-2.6.16.33/arch/x86_64/kernel/early_printk-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/early_printk-xen.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/early_printk-xen.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,306 @@
-+#include <linux/config.h>
-+#include <linux/console.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/string.h>
-+#include <linux/tty.h>
-+#include <asm/io.h>
-+#include <asm/processor.h>
-+#include <asm/fcntl.h>
-+
-+/* Simple VGA output */
-+
-+#ifdef __i386__
-+#include <asm/setup.h>
-+#define VGABASE               (__ISA_IO_base + 0xb8000)
-+#else
-+#include <asm/bootsetup.h>
-+#define VGABASE               ((void __iomem *)0xffffffff800b8000UL)
-+#endif
-+
-+#define MAX_YPOS      max_ypos
-+#define MAX_XPOS      max_xpos
-+
-+static int max_ypos = 25, max_xpos = 80;
-+
-+#ifndef CONFIG_XEN
-+static int current_ypos = 1, current_xpos = 0; 
-+
-+static void early_vga_write(struct console *con, const char *str, unsigned n)
-+{
-+      char c;
-+      int  i, k, j;
-+
-+      while ((c = *str++) != '\0' && n-- > 0) {
-+              if (current_ypos >= MAX_YPOS) {
-+                      /* scroll 1 line up */
-+                      for (k = 1, j = 0; k < MAX_YPOS; k++, j++) {
-+                              for (i = 0; i < MAX_XPOS; i++) {
-+                                      writew(readw(VGABASE + 2*(MAX_XPOS*k + i)),
-+                                             VGABASE + 2*(MAX_XPOS*j + i));
-+                              }
-+                      }
-+                      for (i = 0; i < MAX_XPOS; i++)
-+                              writew(0x720, VGABASE + 2*(MAX_XPOS*j + i));
-+                      current_ypos = MAX_YPOS-1;
-+              }
-+              if (c == '\n') {
-+                      current_xpos = 0;
-+                      current_ypos++;
-+              } else if (c != '\r')  {
-+                      writew(((0x7 << 8) | (unsigned short) c),
-+                             VGABASE + 2*(MAX_XPOS*current_ypos +
-+                                              current_xpos++));
-+                      if (current_xpos >= MAX_XPOS) {
-+                              current_xpos = 0;
-+                              current_ypos++;
-+                      }
-+              }
-+      }
-+}
-+
-+static struct console early_vga_console = {
-+      .name =         "earlyvga",
-+      .write =        early_vga_write,
-+      .flags =        CON_PRINTBUFFER,
-+      .index =        -1,
-+};
-+
-+/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ 
-+
-+static int early_serial_base = 0x3f8;  /* ttyS0 */
-+
-+#define XMTRDY          0x20
-+
-+#define DLAB          0x80
-+
-+#define TXR             0       /*  Transmit register (WRITE) */
-+#define RXR             0       /*  Receive register  (READ)  */
-+#define IER             1       /*  Interrupt Enable          */
-+#define IIR             2       /*  Interrupt ID              */
-+#define FCR             2       /*  FIFO control              */
-+#define LCR             3       /*  Line control              */
-+#define MCR             4       /*  Modem control             */
-+#define LSR             5       /*  Line Status               */
-+#define MSR             6       /*  Modem Status              */
-+#define DLL             0       /*  Divisor Latch Low         */
-+#define DLH             1       /*  Divisor latch High        */
-+
-+static int early_serial_putc(unsigned char ch) 
-+{ 
-+      unsigned timeout = 0xffff; 
-+      while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout) 
-+              cpu_relax();
-+      outb(ch, early_serial_base + TXR);
-+      return timeout ? 0 : -1;
-+} 
-+
-+static void early_serial_write(struct console *con, const char *s, unsigned n)
-+{
-+      while (*s && n-- > 0) { 
-+              early_serial_putc(*s); 
-+              if (*s == '\n') 
-+                      early_serial_putc('\r'); 
-+              s++; 
-+      } 
-+} 
-+
-+#define DEFAULT_BAUD 9600
-+
-+static __init void early_serial_init(char *s)
-+{
-+      unsigned char c; 
-+      unsigned divisor;
-+      unsigned baud = DEFAULT_BAUD;
-+      char *e;
-+
-+      if (*s == ',')
-+              ++s;
-+
-+      if (*s) {
-+              unsigned port; 
-+              if (!strncmp(s,"0x",2)) {
-+                      early_serial_base = simple_strtoul(s, &e, 16);
-+              } else {
-+                      static int bases[] = { 0x3f8, 0x2f8 };
-+
-+                      if (!strncmp(s,"ttyS",4))
-+                              s += 4;
-+                      port = simple_strtoul(s, &e, 10);
-+                      if (port > 1 || s == e)
-+                              port = 0;
-+                      early_serial_base = bases[port];
-+              }
-+              s += strcspn(s, ",");
-+              if (*s == ',')
-+                      s++;
-+      }
-+
-+      outb(0x3, early_serial_base + LCR);     /* 8n1 */
-+      outb(0, early_serial_base + IER);       /* no interrupt */
-+      outb(0, early_serial_base + FCR);       /* no fifo */
-+      outb(0x3, early_serial_base + MCR);     /* DTR + RTS */
-+
-+      if (*s) {
-+              baud = simple_strtoul(s, &e, 0); 
-+              if (baud == 0 || s == e) 
-+                      baud = DEFAULT_BAUD;
-+      } 
-+      
-+      divisor = 115200 / baud; 
-+      c = inb(early_serial_base + LCR); 
-+      outb(c | DLAB, early_serial_base + LCR); 
-+      outb(divisor & 0xff, early_serial_base + DLL); 
-+      outb((divisor >> 8) & 0xff, early_serial_base + DLH); 
-+      outb(c & ~DLAB, early_serial_base + LCR);
-+}
-+
-+#else /* CONFIG_XEN */
-+
-+#undef SCREEN_INFO
-+#define SCREEN_INFO screen_info
-+extern struct screen_info screen_info;
-+
-+static void
-+early_serial_write(struct console *con, const char *s, unsigned count)
-+{
-+      int n;
-+
-+      while (count > 0) {
-+              n = HYPERVISOR_console_io(CONSOLEIO_write, count, (char *)s);
-+              if (n <= 0)
-+                      break;
-+              count -= n;
-+              s += n;
-+      }
-+} 
-+
-+static __init void early_serial_init(char *s)
-+{
-+}
-+
-+/*
-+ * No early VGA console on Xen, as we do not have convenient ISA-space
-+ * mappings. Someone should fix this for domain 0. For now, use fake serial.
-+ */
-+#define early_vga_console early_serial_console
-+
-+#endif
-+
-+static struct console early_serial_console = {
-+      .name =         "earlyser",
-+      .write =        early_serial_write,
-+      .flags =        CON_PRINTBUFFER,
-+      .index =        -1,
-+};
-+
-+/* Console interface to a host file on AMD's SimNow! */
-+
-+static int simnow_fd;
-+
-+enum {
-+      MAGIC1 = 0xBACCD00A,
-+      MAGIC2 = 0xCA110000,
-+      XOPEN = 5,
-+      XWRITE = 4,
-+};
-+
-+static noinline long simnow(long cmd, long a, long b, long c)
-+{
-+      long ret;
-+      asm volatile("cpuid" :
-+                   "=a" (ret) :
-+                   "b" (a), "c" (b), "d" (c), "0" (MAGIC1), "D" (cmd + MAGIC2));
-+      return ret;
-+}
-+
-+void __init simnow_init(char *str)
-+{
-+      char *fn = "klog";
-+      if (*str == '=')
-+              fn = ++str;
-+      /* error ignored */
-+      simnow_fd = simnow(XOPEN, (unsigned long)fn, O_WRONLY|O_APPEND|O_CREAT, 0644);
-+}
-+
-+static void simnow_write(struct console *con, const char *s, unsigned n)
-+{
-+      simnow(XWRITE, simnow_fd, (unsigned long)s, n);
-+}
-+
-+static struct console simnow_console = {
-+      .name =         "simnow",
-+      .write =        simnow_write,
-+      .flags =        CON_PRINTBUFFER,
-+      .index =        -1,
-+};
-+
-+/* Direct interface for emergencies */
-+struct console *early_console = &early_vga_console;
-+static int early_console_initialized = 0;
-+
-+void early_printk(const char *fmt, ...)
-+{ 
-+      char buf[512]; 
-+      int n; 
-+      va_list ap;
-+
-+      va_start(ap,fmt); 
-+      n = vscnprintf(buf,512,fmt,ap);
-+      early_console->write(early_console,buf,n);
-+      va_end(ap); 
-+} 
-+
-+static int __initdata keep_early;
-+
-+int __init setup_early_printk(char *opt) 
-+{  
-+      char *space;
-+      char buf[256]; 
-+
-+      if (early_console_initialized)
-+              return -1;
-+
-+      strlcpy(buf,opt,sizeof(buf)); 
-+      space = strchr(buf, ' '); 
-+      if (space)
-+              *space = 0; 
-+
-+      if (strstr(buf,"keep"))
-+              keep_early = 1; 
-+
-+      if (!strncmp(buf, "serial", 6)) { 
-+              early_serial_init(buf + 6);
-+              early_console = &early_serial_console;
-+      } else if (!strncmp(buf, "ttyS", 4)) { 
-+              early_serial_init(buf);
-+              early_console = &early_serial_console;          
-+      } else if (!strncmp(buf, "vga", 3)
-+                 && SCREEN_INFO.orig_video_isVGA == 1) {
-+              max_xpos = SCREEN_INFO.orig_video_cols;
-+              max_ypos = SCREEN_INFO.orig_video_lines;
-+              early_console = &early_vga_console; 
-+      } else if (!strncmp(buf, "simnow", 6)) {
-+              simnow_init(buf + 6);
-+              early_console = &simnow_console;
-+              keep_early = 1;
-+      }
-+      early_console_initialized = 1;
-+      register_console(early_console);       
-+      return 0;
-+}
-+
-+void __init disable_early_printk(void)
-+{ 
-+      if (!early_console_initialized || !early_console)
-+              return;
-+      if (!keep_early) {
-+              printk("disabling early console\n");
-+              unregister_console(early_console);
-+              early_console_initialized = 0;
-+      } else { 
-+              printk("keeping early console\n");
-+      }
-+} 
-+
-+__setup("earlyprintk=", setup_early_printk);
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/entry-xen.S linux-2.6.16.33/arch/x86_64/kernel/entry-xen.S
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/entry-xen.S       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/entry-xen.S     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1136 @@
-+/*
-+ *  linux/arch/x86_64/entry.S
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ *  Copyright (C) 2000, 2001, 2002  Andi Kleen SuSE Labs
-+ *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
-+ * 
-+ *  $Id$
-+ *
-+ *  Jun Nakajima <jun.nakajima@intel.com>
-+ *  Asit Mallick <asit.k.mallick@intel.com>
-+ *      Modified for Xen
-+ */
-+
-+/*
-+ * entry.S contains the system-call and fault low-level handling routines.
-+ *
-+ * NOTE: This code handles signal-recognition, which happens every time
-+ * after an interrupt and after each system call.
-+ * 
-+ * Normal syscalls and interrupts don't save a full stack frame, this is 
-+ * only done for syscall tracing, signals or fork/exec et.al.
-+ * 
-+ * A note on terminology:      
-+ * - top of stack: Architecture defined interrupt frame from SS to RIP 
-+ * at the top of the kernel process stack.    
-+ * - partial stack frame: partially saved registers upto R11.
-+ * - full stack frame: Like partial stack frame, but all register saved. 
-+ *    
-+ * TODO:       
-+ * - schedule it carefully for the final hardware.
-+ */
-+
-+#define ASSEMBLY 1
-+#include <linux/config.h>
-+#ifdef CONFIG_DEBUG_INFO
-+#undef CONFIG_DEBUG_INFO
-+#endif
-+#include <linux/linkage.h>
-+#include <asm/segment.h>
-+#include <asm/smp.h>
-+#include <asm/cache.h>
-+#include <asm/errno.h>
-+#include <asm/dwarf2.h>
-+#include <asm/calling.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/msr.h>
-+#include <asm/unistd.h>
-+#include <asm/thread_info.h>
-+#include <asm/hw_irq.h>
-+#include <asm/page.h>
-+#include <asm/errno.h>
-+#include <xen/interface/arch-x86_64.h>
-+#include <xen/interface/features.h>
-+
-+#include "irq_vectors.h"
-+
-+#include "xen_entry.S"
-+      
-+      .code64
-+
-+#ifndef CONFIG_PREEMPT
-+#define retint_kernel retint_restore_args
-+#endif        
-+
-+NMI_MASK = 0x80000000
-+      
-+/*
-+ * C code is not supposed to know about undefined top of stack. Every time 
-+ * a C function with an pt_regs argument is called from the SYSCALL based 
-+ * fast path FIXUP_TOP_OF_STACK is needed.
-+ * RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs
-+ * manipulation.
-+ */           
-+              
-+      /* %rsp:at FRAMEEND */ 
-+      .macro FIXUP_TOP_OF_STACK tmp
-+      movq    $__USER_CS,CS(%rsp)
-+      movq    $-1,RCX(%rsp)
-+      .endm
-+
-+      .macro RESTORE_TOP_OF_STACK tmp,offset=0
-+      .endm
-+
-+      .macro FAKE_STACK_FRAME child_rip
-+      /* push in order ss, rsp, eflags, cs, rip */
-+      xorl %eax, %eax
-+      pushq %rax /* ss */
-+      CFI_ADJUST_CFA_OFFSET   8
-+      /*CFI_REL_OFFSET        ss,0*/
-+      pushq %rax /* rsp */
-+      CFI_ADJUST_CFA_OFFSET   8
-+      CFI_REL_OFFSET  rsp,0
-+      pushq $(1<<9) /* eflags - interrupts on */
-+      CFI_ADJUST_CFA_OFFSET   8
-+      /*CFI_REL_OFFSET        rflags,0*/
-+      pushq $__KERNEL_CS /* cs */
-+      CFI_ADJUST_CFA_OFFSET   8
-+      /*CFI_REL_OFFSET        cs,0*/
-+      pushq \child_rip /* rip */
-+      CFI_ADJUST_CFA_OFFSET   8
-+      CFI_REL_OFFSET  rip,0
-+      pushq   %rax /* orig rax */
-+      CFI_ADJUST_CFA_OFFSET   8
-+      .endm
-+
-+      .macro UNFAKE_STACK_FRAME
-+      addq $8*6, %rsp
-+      CFI_ADJUST_CFA_OFFSET   -(6*8)
-+      .endm
-+
-+      .macro  CFI_DEFAULT_STACK start=1
-+      .if \start
-+      CFI_STARTPROC   simple
-+      CFI_DEF_CFA     rsp,SS+8
-+      .else
-+      CFI_DEF_CFA_OFFSET SS+8
-+      .endif
-+      CFI_REL_OFFSET  r15,R15
-+      CFI_REL_OFFSET  r14,R14
-+      CFI_REL_OFFSET  r13,R13
-+      CFI_REL_OFFSET  r12,R12
-+      CFI_REL_OFFSET  rbp,RBP
-+      CFI_REL_OFFSET  rbx,RBX
-+      CFI_REL_OFFSET  r11,R11
-+      CFI_REL_OFFSET  r10,R10
-+      CFI_REL_OFFSET  r9,R9
-+      CFI_REL_OFFSET  r8,R8
-+      CFI_REL_OFFSET  rax,RAX
-+      CFI_REL_OFFSET  rcx,RCX
-+      CFI_REL_OFFSET  rdx,RDX
-+      CFI_REL_OFFSET  rsi,RSI
-+      CFI_REL_OFFSET  rdi,RDI
-+      CFI_REL_OFFSET  rip,RIP
-+      /*CFI_REL_OFFSET        cs,CS*/
-+      /*CFI_REL_OFFSET        rflags,EFLAGS*/
-+      CFI_REL_OFFSET  rsp,RSP
-+      /*CFI_REL_OFFSET        ss,SS*/
-+      .endm
-+
-+        /*
-+         * Must be consistent with the definition in arch-x86_64.h:    
-+         *     struct iret_context {
-+         *        u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
-+         *     };
-+         * #define VGCF_IN_SYSCALL (1<<8) 
-+         */
-+      .macro HYPERVISOR_IRET flag
-+      testb $3,1*8(%rsp)
-+      jnz   2f
-+      testl $NMI_MASK,2*8(%rsp)
-+      jnz   2f
-+
-+      testb $1,(xen_features+XENFEAT_supervisor_mode_kernel)
-+      jnz   1f
-+
-+      /* Direct iret to kernel space. Correct CS and SS. */
-+      orb   $3,1*8(%rsp)
-+      orb   $3,4*8(%rsp)
-+1:    iretq
-+
-+2:    /* Slow iret via hypervisor. */
-+      andl  $~NMI_MASK, 16(%rsp)
-+      pushq $\flag
-+      jmp  hypercall_page + (__HYPERVISOR_iret * 32)
-+      .endm
-+
-+        .macro SWITCH_TO_KERNEL ssoff,adjust=0
-+      jc  1f
-+      orb  $1,\ssoff-\adjust+4(%rsp)
-+1:
-+        .endm
-+
-+/*
-+ * A newly forked process directly context switches into this.
-+ */   
-+/* rdi:       prev */ 
-+ENTRY(ret_from_fork)
-+      CFI_DEFAULT_STACK
-+      call schedule_tail
-+      GET_THREAD_INFO(%rcx)
-+      testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
-+      jnz rff_trace
-+rff_action:   
-+      RESTORE_REST
-+      testl $3,CS-ARGOFFSET(%rsp)     # from kernel_thread?
-+      je   int_ret_from_sys_call
-+      testl $_TIF_IA32,threadinfo_flags(%rcx)
-+      jnz  int_ret_from_sys_call
-+      RESTORE_TOP_OF_STACK %rdi,ARGOFFSET
-+      jmp ret_from_sys_call
-+rff_trace:
-+      movq %rsp,%rdi
-+      call syscall_trace_leave
-+      GET_THREAD_INFO(%rcx)   
-+      jmp rff_action
-+      CFI_ENDPROC
-+
-+/*
-+ * System call entry. Upto 6 arguments in registers are supported.
-+ *
-+ * SYSCALL does not save anything on the stack and does not change the
-+ * stack pointer.
-+ */
-+              
-+/*
-+ * Register setup:    
-+ * rax  system call number
-+ * rdi  arg0
-+ * rcx  return address for syscall/sysret, C arg3 
-+ * rsi  arg1
-+ * rdx  arg2  
-+ * r10  arg3  (--> moved to rcx for C)
-+ * r8   arg4
-+ * r9   arg5
-+ * r11  eflags for syscall/sysret, temporary for C
-+ * r12-r15,rbp,rbx saved by C code, not touched.              
-+ * 
-+ * Interrupts are off on entry.
-+ * Only called from user space.
-+ *
-+ * XXX        if we had a free scratch register we could save the RSP into the stack frame
-+ *      and report it properly in ps. Unfortunately we haven't.
-+ *
-+ * When user can change the frames always force IRET. That is because
-+ * it deals with uncanonical addresses better. SYSRET has trouble
-+ * with them due to bugs in both AMD and Intel CPUs.
-+ */                                   
-+
-+ENTRY(system_call)
-+      CFI_STARTPROC   simple
-+      CFI_DEF_CFA     rsp,0
-+      CFI_REGISTER    rip,rcx
-+      /*CFI_REGISTER  rflags,r11*/
-+      SAVE_ARGS -8,0
-+      movq  %rax,ORIG_RAX-ARGOFFSET(%rsp) 
-+        XEN_UNBLOCK_EVENTS(%r11)        
-+      GET_THREAD_INFO(%rcx)
-+      testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
-+      CFI_REMEMBER_STATE
-+      jnz tracesys
-+      cmpq $__NR_syscall_max,%rax
-+      ja badsys
-+      movq %r10,%rcx
-+      call *sys_call_table(,%rax,8)  # XXX:    rip relative
-+      movq %rax,RAX-ARGOFFSET(%rsp)
-+/*
-+ * Syscall return path ending with SYSRET (fast path)
-+ * Has incomplete stack frame and undefined top of stack. 
-+ */           
-+      .globl ret_from_sys_call
-+ret_from_sys_call:
-+      movl $_TIF_ALLWORK_MASK,%edi
-+      /* edi: flagmask */
-+sysret_check:         
-+      GET_THREAD_INFO(%rcx)
-+        XEN_BLOCK_EVENTS(%rsi)        
-+      movl threadinfo_flags(%rcx),%edx
-+      andl %edi,%edx
-+      CFI_REMEMBER_STATE
-+      jnz  sysret_careful 
-+        XEN_UNBLOCK_EVENTS(%rsi)                
-+      CFI_REGISTER    rip,rcx
-+      RESTORE_ARGS 0,8,0
-+      /*CFI_REGISTER  rflags,r11*/
-+        HYPERVISOR_IRET VGCF_IN_SYSCALL
-+
-+      /* Handle reschedules */
-+      /* edx: work, edi: workmask */  
-+sysret_careful:
-+      CFI_RESTORE_STATE
-+      bt $TIF_NEED_RESCHED,%edx
-+      jnc sysret_signal
-+      XEN_UNBLOCK_EVENTS(%rsi)
-+      pushq %rdi
-+      CFI_ADJUST_CFA_OFFSET 8
-+      call schedule
-+      popq  %rdi
-+      CFI_ADJUST_CFA_OFFSET -8
-+      jmp sysret_check
-+
-+      /* Handle a signal */ 
-+sysret_signal:
-+/*    sti */
-+        XEN_UNBLOCK_EVENTS(%rsi)        
-+      testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
-+      jz    1f
-+
-+      /* Really a signal */
-+      /* edx: work flags (arg3) */
-+      leaq do_notify_resume(%rip),%rax
-+      leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
-+      xorl %esi,%esi # oldset -> arg2
-+      call ptregscall_common
-+1:    movl $_TIF_NEED_RESCHED,%edi
-+      /* Use IRET because user could have changed frame. This
-+         works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
-+      XEN_BLOCK_EVENTS(%rsi)
-+      jmp int_with_check
-+      
-+badsys:
-+      movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
-+      jmp ret_from_sys_call
-+
-+      /* Do syscall tracing */
-+tracesys:                      
-+      CFI_RESTORE_STATE
-+      SAVE_REST
-+      movq $-ENOSYS,RAX(%rsp)
-+      FIXUP_TOP_OF_STACK %rdi
-+      movq %rsp,%rdi
-+      call syscall_trace_enter
-+      LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
-+      RESTORE_REST
-+      cmpq $__NR_syscall_max,%rax
-+      ja  1f
-+      movq %r10,%rcx  /* fixup for C */
-+      call *sys_call_table(,%rax,8)
-+1:    movq %rax,RAX-ARGOFFSET(%rsp)
-+      /* Use IRET because user could have changed frame */
-+      jmp int_ret_from_sys_call
-+      CFI_ENDPROC
-+              
-+/* 
-+ * Syscall return path ending with IRET.
-+ * Has correct top of stack, but partial stack frame.
-+ */   
-+ENTRY(int_ret_from_sys_call)
-+      CFI_STARTPROC   simple
-+      CFI_DEF_CFA     rsp,SS+8-ARGOFFSET
-+      /*CFI_REL_OFFSET        ss,SS-ARGOFFSET*/
-+      CFI_REL_OFFSET  rsp,RSP-ARGOFFSET
-+      /*CFI_REL_OFFSET        rflags,EFLAGS-ARGOFFSET*/
-+      /*CFI_REL_OFFSET        cs,CS-ARGOFFSET*/
-+      CFI_REL_OFFSET  rip,RIP-ARGOFFSET
-+      CFI_REL_OFFSET  rdx,RDX-ARGOFFSET
-+      CFI_REL_OFFSET  rcx,RCX-ARGOFFSET
-+      CFI_REL_OFFSET  rax,RAX-ARGOFFSET
-+      CFI_REL_OFFSET  rdi,RDI-ARGOFFSET
-+      CFI_REL_OFFSET  rsi,RSI-ARGOFFSET
-+      CFI_REL_OFFSET  r8,R8-ARGOFFSET
-+      CFI_REL_OFFSET  r9,R9-ARGOFFSET
-+      CFI_REL_OFFSET  r10,R10-ARGOFFSET
-+      CFI_REL_OFFSET  r11,R11-ARGOFFSET
-+        XEN_BLOCK_EVENTS(%rsi)
-+      testb $3,CS-ARGOFFSET(%rsp)
-+        jnz 1f
-+        /* Need to set the proper %ss (not NULL) for ring 3 iretq */
-+        movl $__KERNEL_DS,SS-ARGOFFSET(%rsp)
-+        jmp retint_restore_args   # retrun from ring3 kernel
-+1:              
-+      movl $_TIF_ALLWORK_MASK,%edi
-+      /* edi: mask to check */
-+int_with_check:
-+      GET_THREAD_INFO(%rcx)
-+      movl threadinfo_flags(%rcx),%edx
-+      andl %edi,%edx
-+      jnz   int_careful
-+      andl    $~TS_COMPAT,threadinfo_status(%rcx)
-+      jmp   retint_restore_args
-+
-+      /* Either reschedule or signal or syscall exit tracking needed. */
-+      /* First do a reschedule test. */
-+      /* edx: work, edi: workmask */
-+int_careful:
-+      bt $TIF_NEED_RESCHED,%edx
-+      jnc  int_very_careful
-+/*    sti */
-+        XEN_UNBLOCK_EVENTS(%rsi)
-+      pushq %rdi
-+      CFI_ADJUST_CFA_OFFSET 8
-+      call schedule
-+      popq %rdi
-+      CFI_ADJUST_CFA_OFFSET -8
-+      XEN_BLOCK_EVENTS(%rsi)
-+      jmp int_with_check
-+
-+      /* handle signals and tracing -- both require a full stack frame */
-+int_very_careful:
-+/*    sti */
-+        XEN_UNBLOCK_EVENTS(%rsi)
-+      SAVE_REST
-+      /* Check for syscall exit trace */      
-+      testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx
-+      jz int_signal
-+      pushq %rdi
-+      CFI_ADJUST_CFA_OFFSET 8
-+      leaq 8(%rsp),%rdi       # &ptregs -> arg1       
-+      call syscall_trace_leave
-+      popq %rdi
-+      CFI_ADJUST_CFA_OFFSET -8
-+      andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
-+      XEN_BLOCK_EVENTS(%rsi)
-+      jmp int_restore_rest
-+      
-+int_signal:
-+      testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_SINGLESTEP),%edx
-+      jz 1f
-+      movq %rsp,%rdi          # &ptregs -> arg1
-+      xorl %esi,%esi          # oldset -> arg2
-+      call do_notify_resume
-+1:    movl $_TIF_NEED_RESCHED,%edi    
-+int_restore_rest:
-+      RESTORE_REST
-+      XEN_BLOCK_EVENTS(%rsi)
-+      jmp int_with_check
-+      CFI_ENDPROC
-+              
-+/* 
-+ * Certain special system calls that need to save a complete full stack frame.
-+ */                                                           
-+      
-+      .macro PTREGSCALL label,func,arg
-+      .globl \label
-+\label:
-+      leaq    \func(%rip),%rax
-+      leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
-+      jmp     ptregscall_common
-+      .endm
-+
-+      CFI_STARTPROC
-+
-+      PTREGSCALL stub_clone, sys_clone, %r8
-+      PTREGSCALL stub_fork, sys_fork, %rdi
-+      PTREGSCALL stub_vfork, sys_vfork, %rdi
-+      PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend, %rdx
-+      PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
-+      PTREGSCALL stub_iopl, sys_iopl, %rsi
-+
-+ENTRY(ptregscall_common)
-+      popq %r11
-+      CFI_ADJUST_CFA_OFFSET -8
-+      CFI_REGISTER rip, r11
-+      SAVE_REST
-+      movq %r11, %r15
-+      CFI_REGISTER rip, r15
-+      FIXUP_TOP_OF_STACK %r11
-+      call *%rax
-+      RESTORE_TOP_OF_STACK %r11
-+      movq %r15, %r11
-+      CFI_REGISTER rip, r11
-+      RESTORE_REST
-+      pushq %r11
-+      CFI_ADJUST_CFA_OFFSET 8
-+      CFI_REL_OFFSET rip, 0
-+      ret
-+      CFI_ENDPROC
-+      
-+ENTRY(stub_execve)
-+      CFI_STARTPROC
-+      popq %r11
-+      CFI_ADJUST_CFA_OFFSET -8
-+      CFI_REGISTER rip, r11
-+      SAVE_REST
-+      FIXUP_TOP_OF_STACK %r11
-+      call sys_execve
-+      RESTORE_TOP_OF_STACK %r11
-+      movq %rax,RAX(%rsp)
-+      RESTORE_REST
-+      jmp int_ret_from_sys_call
-+      CFI_ENDPROC
-+      
-+/*
-+ * sigreturn is special because it needs to restore all registers on return.
-+ * This cannot be done with SYSRET, so use the IRET return path instead.
-+ */                
-+ENTRY(stub_rt_sigreturn)
-+      CFI_STARTPROC
-+      addq $8, %rsp
-+      CFI_ADJUST_CFA_OFFSET   -8
-+      SAVE_REST
-+      movq %rsp,%rdi
-+      FIXUP_TOP_OF_STACK %r11
-+      call sys_rt_sigreturn
-+      movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
-+      RESTORE_REST
-+      jmp int_ret_from_sys_call
-+      CFI_ENDPROC
-+
-+/*
-+ * initial frame state for interrupts and exceptions
-+ */
-+      .macro _frame ref
-+      CFI_STARTPROC simple
-+      CFI_DEF_CFA rsp,SS+8-\ref
-+      /*CFI_REL_OFFSET ss,SS-\ref*/
-+      CFI_REL_OFFSET rsp,RSP-\ref
-+      /*CFI_REL_OFFSET rflags,EFLAGS-\ref*/
-+      /*CFI_REL_OFFSET cs,CS-\ref*/
-+      CFI_REL_OFFSET rip,RIP-\ref
-+      .endm
-+
-+/* initial frame state for interrupts (and exceptions without error code) */
-+#define INTR_FRAME _frame RIP
-+/* initial frame state for exceptions with error code (and interrupts with
-+   vector already pushed) */
-+#define XCPT_FRAME _frame ORIG_RAX
-+
-+/* 
-+ * Interrupt exit.
-+ *
-+ */ 
-+
-+retint_check:
-+      movl threadinfo_flags(%rcx),%edx
-+      andl %edi,%edx
-+      CFI_REMEMBER_STATE
-+      jnz  retint_careful
-+retint_restore_args:
-+      movl EFLAGS-REST_SKIP(%rsp), %eax
-+      shr $9, %eax                    # EAX[0] == IRET_EFLAGS.IF
-+      XEN_GET_VCPU_INFO(%rsi)
-+      andb evtchn_upcall_mask(%rsi),%al
-+      andb $1,%al                     # EAX[0] == IRET_EFLAGS.IF & event_mask
-+      jnz restore_all_enable_events   #        != 0 => enable event delivery
-+      XEN_PUT_VCPU_INFO(%rsi)
-+              
-+      RESTORE_ARGS 0,8,0
-+      HYPERVISOR_IRET 0
-+      
-+      /* edi: workmask, edx: work */
-+retint_careful:
-+      CFI_RESTORE_STATE
-+      bt    $TIF_NEED_RESCHED,%edx
-+      jnc   retint_signal
-+      XEN_UNBLOCK_EVENTS(%rsi)
-+/*    sti */        
-+      pushq %rdi
-+      CFI_ADJUST_CFA_OFFSET   8
-+      call  schedule
-+      popq %rdi               
-+      CFI_ADJUST_CFA_OFFSET   -8
-+      GET_THREAD_INFO(%rcx)
-+      XEN_BLOCK_EVENTS(%rsi)          
-+/*    cli */
-+      jmp retint_check
-+      
-+retint_signal:
-+      testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
-+      jz    retint_restore_args
-+        XEN_UNBLOCK_EVENTS(%rsi)
-+      SAVE_REST
-+      movq $-1,ORIG_RAX(%rsp)                         
-+      xorl %esi,%esi          # oldset
-+      movq %rsp,%rdi          # &pt_regs
-+      call do_notify_resume
-+      RESTORE_REST
-+        XEN_BLOCK_EVENTS(%rsi)                
-+      movl $_TIF_NEED_RESCHED,%edi
-+      GET_THREAD_INFO(%rcx)
-+      jmp retint_check
-+
-+#ifdef CONFIG_PREEMPT
-+      /* Returning to kernel space. Check if we need preemption */
-+      /* rcx:  threadinfo. interrupts off. */
-+      .p2align
-+retint_kernel:        
-+      cmpl $0,threadinfo_preempt_count(%rcx)
-+      jnz  retint_restore_args
-+      bt  $TIF_NEED_RESCHED,threadinfo_flags(%rcx)
-+      jnc  retint_restore_args
-+      bt   $9,EFLAGS-ARGOFFSET(%rsp)  /* interrupts off? */
-+      jnc  retint_restore_args
-+      call preempt_schedule_irq
-+      jmp retint_kernel       /* check again */
-+#endif        
-+      CFI_ENDPROC
-+      
-+/*
-+ * APIC interrupts.
-+ */           
-+      .macro apicinterrupt num,func
-+      INTR_FRAME
-+      pushq $~(\num)
-+      CFI_ADJUST_CFA_OFFSET 8
-+      interrupt \func
-+      jmp error_entry
-+      CFI_ENDPROC
-+      .endm
-+
-+#ifndef CONFIG_XEN
-+ENTRY(thermal_interrupt)
-+      apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
-+
-+ENTRY(threshold_interrupt)
-+      apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt
-+
-+#ifdef CONFIG_SMP     
-+ENTRY(reschedule_interrupt)
-+      apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
-+
-+      .macro INVALIDATE_ENTRY num
-+ENTRY(invalidate_interrupt\num)
-+      apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt 
-+      .endm
-+
-+      INVALIDATE_ENTRY 0
-+      INVALIDATE_ENTRY 1
-+      INVALIDATE_ENTRY 2
-+      INVALIDATE_ENTRY 3
-+      INVALIDATE_ENTRY 4
-+      INVALIDATE_ENTRY 5
-+      INVALIDATE_ENTRY 6
-+      INVALIDATE_ENTRY 7
-+
-+ENTRY(call_function_interrupt)
-+      apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
-+#endif
-+
-+#ifdef CONFIG_X86_LOCAL_APIC  
-+ENTRY(apic_timer_interrupt)
-+      apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
-+
-+ENTRY(error_interrupt)
-+      apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
-+
-+ENTRY(spurious_interrupt)
-+      apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
-+#endif
-+#endif /* !CONFIG_XEN */
-+                              
-+/*
-+ * Exception entry points.
-+ */           
-+      .macro zeroentry sym
-+      INTR_FRAME
-+        movq (%rsp),%rcx
-+        movq 8(%rsp),%r11
-+        addq $0x10,%rsp /* skip rcx and r11 */
-+      pushq $0        /* push error code/oldrax */ 
-+      CFI_ADJUST_CFA_OFFSET 8
-+      pushq %rax      /* push real oldrax to the rdi slot */ 
-+      CFI_ADJUST_CFA_OFFSET 8
-+      leaq  \sym(%rip),%rax
-+      jmp error_entry
-+      CFI_ENDPROC
-+      .endm   
-+
-+      .macro errorentry sym
-+      XCPT_FRAME
-+        movq (%rsp),%rcx
-+        movq 8(%rsp),%r11
-+        addq $0x10,%rsp /* rsp points to the error code */
-+      pushq %rax
-+      CFI_ADJUST_CFA_OFFSET 8
-+      leaq  \sym(%rip),%rax
-+      jmp error_entry
-+      CFI_ENDPROC
-+      .endm
-+
-+#if 0 /* not XEN */
-+      /* error code is on the stack already */
-+      /* handle NMI like exceptions that can happen everywhere */
-+      .macro paranoidentry sym, ist=0
-+        movq (%rsp),%rcx
-+        movq 8(%rsp),%r11
-+        addq $0x10,%rsp /* skip rcx and r11 */        
-+      SAVE_ALL
-+      cld
-+#if 0 /* not XEN */
-+      movl $1,%ebx
-+      movl  $MSR_GS_BASE,%ecx
-+      rdmsr
-+      testl %edx,%edx
-+      js    1f
-+      swapgs
-+      xorl  %ebx,%ebx
-+1:
-+#endif
-+      .if \ist
-+      movq    %gs:pda_data_offset, %rbp
-+      .endif
-+      movq %rsp,%rdi
-+      movq ORIG_RAX(%rsp),%rsi
-+      movq $-1,ORIG_RAX(%rsp)
-+      .if \ist
-+      subq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
-+      .endif
-+      call \sym
-+      .if \ist
-+      addq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
-+      .endif
-+/*    cli */
-+      XEN_BLOCK_EVENTS(%rsi)          
-+      .endm
-+#endif
-+      
-+/*
-+ * Exception entry point. This expects an error code/orig_rax on the stack
-+ * and the exception handler in %rax. 
-+ */                                           
-+ENTRY(error_entry)
-+      _frame RDI
-+      /* rdi slot contains rax, oldrax contains error code */
-+      cld     
-+      subq  $14*8,%rsp
-+      CFI_ADJUST_CFA_OFFSET   (14*8)
-+      movq %rsi,13*8(%rsp)
-+      CFI_REL_OFFSET  rsi,RSI
-+      movq 14*8(%rsp),%rsi    /* load rax from rdi slot */
-+      movq %rdx,12*8(%rsp)
-+      CFI_REL_OFFSET  rdx,RDX
-+      movq %rcx,11*8(%rsp)
-+      CFI_REL_OFFSET  rcx,RCX
-+      movq %rsi,10*8(%rsp)    /* store rax */ 
-+      CFI_REL_OFFSET  rax,RAX
-+      movq %r8, 9*8(%rsp)
-+      CFI_REL_OFFSET  r8,R8
-+      movq %r9, 8*8(%rsp)
-+      CFI_REL_OFFSET  r9,R9
-+      movq %r10,7*8(%rsp)
-+      CFI_REL_OFFSET  r10,R10
-+      movq %r11,6*8(%rsp)
-+      CFI_REL_OFFSET  r11,R11
-+      movq %rbx,5*8(%rsp) 
-+      CFI_REL_OFFSET  rbx,RBX
-+      movq %rbp,4*8(%rsp) 
-+      CFI_REL_OFFSET  rbp,RBP
-+      movq %r12,3*8(%rsp) 
-+      CFI_REL_OFFSET  r12,R12
-+      movq %r13,2*8(%rsp) 
-+      CFI_REL_OFFSET  r13,R13
-+      movq %r14,1*8(%rsp) 
-+      CFI_REL_OFFSET  r14,R14
-+      movq %r15,(%rsp) 
-+      CFI_REL_OFFSET  r15,R15
-+#if 0        
-+      cmpl $__KERNEL_CS,CS(%rsp)
-+      je  error_kernelspace
-+#endif        
-+error_call_handler:
-+      movq %rdi, RDI(%rsp)            
-+      movq %rsp,%rdi
-+      movq ORIG_RAX(%rsp),%rsi        # get error code 
-+      movq $-1,ORIG_RAX(%rsp)
-+      call *%rax
-+error_exit:           
-+      RESTORE_REST
-+/*    cli */
-+      XEN_BLOCK_EVENTS(%rsi)          
-+      GET_THREAD_INFO(%rcx)   
-+      testb $3,CS-ARGOFFSET(%rsp)
-+      jz retint_kernel
-+      movl  threadinfo_flags(%rcx),%edx
-+      movl  $_TIF_WORK_MASK,%edi      
-+      andl  %edi,%edx
-+      jnz   retint_careful
-+      jmp   retint_restore_args
-+
-+error_kernelspace:
-+         /*
-+         * We need to re-write the logic here because we don't do iretq to 
-+         * to return to user mode. It's still possible that we get trap/fault
-+         * in the kernel (when accessing buffers pointed to by system calls, 
-+         * for example).
-+         *
-+         */           
-+#if 0
-+      incl %ebx
-+       /* There are two places in the kernel that can potentially fault with
-+          usergs. Handle them here. The exception handlers after
-+         iret run with kernel gs again, so don't set the user space flag.
-+         B stepping K8s sometimes report an truncated RIP for IRET 
-+         exceptions returning to compat mode. Check for these here too. */
-+      leaq iret_label(%rip),%rbp
-+      cmpq %rbp,RIP(%rsp) 
-+      je   error_swapgs
-+      movl %ebp,%ebp  /* zero extend */
-+      cmpq %rbp,RIP(%rsp) 
-+      je   error_swapgs
-+      cmpq $gs_change,RIP(%rsp)
-+        je   error_swapgs
-+      jmp  error_sti
-+#endif        
-+      
-+ENTRY(hypervisor_callback)
-+      zeroentry do_hypervisor_callback
-+        
-+/*
-+ * Copied from arch/xen/i386/kernel/entry.S
-+ */               
-+# A note on the "critical region" in our callback handler.
-+# We want to avoid stacking callback handlers due to events occurring
-+# during handling of the last event. To do this, we keep events disabled
-+# until we've done all processing. HOWEVER, we must enable events before
-+# popping the stack frame (can't be done atomically) and so it would still
-+# be possible to get enough handler activations to overflow the stack.
-+# Although unlikely, bugs of that kind are hard to track down, so we'd
-+# like to avoid the possibility.
-+# So, on entry to the handler we detect whether we interrupted an
-+# existing activation in its critical region -- if so, we pop the current
-+# activation and restart the handler using the previous one.
-+ENTRY(do_hypervisor_callback)   # do_hypervisor_callback(struct *pt_regs)
-+# Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will
-+# see the correct pointer to the pt_regs
-+      movq %rdi, %rsp            # we don't return, adjust the stack frame
-+11:   movq %gs:pda_irqstackptr,%rax
-+      incl %gs:pda_irqcount
-+      cmovzq %rax,%rsp
-+      pushq %rdi
-+      call evtchn_do_upcall
-+      popq %rsp
-+      decl %gs:pda_irqcount
-+      jmp  error_exit
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+KPROBE_ENTRY(nmi)
-+      zeroentry do_nmi_callback
-+ENTRY(do_nmi_callback)
-+        addq $8, %rsp
-+        call do_nmi
-+        orl  $NMI_MASK,EFLAGS(%rsp)
-+        RESTORE_REST
-+        XEN_BLOCK_EVENTS(%rsi)
-+        GET_THREAD_INFO(%rcx)
-+        jmp  retint_restore_args
-+      .previous .text
-+#endif
-+
-+        ALIGN
-+restore_all_enable_events:  
-+      XEN_UNBLOCK_EVENTS(%rsi)        # %rsi is already set up...
-+
-+scrit:        /**** START OF CRITICAL REGION ****/
-+      XEN_TEST_PENDING(%rsi)
-+      jnz  14f                        # process more events if necessary...
-+      XEN_PUT_VCPU_INFO(%rsi)
-+        RESTORE_ARGS 0,8,0
-+        HYPERVISOR_IRET 0
-+        
-+14:   XEN_LOCKED_BLOCK_EVENTS(%rsi)
-+      XEN_PUT_VCPU_INFO(%rsi)
-+      SAVE_REST
-+        movq %rsp,%rdi                  # set the argument again
-+      jmp  11b
-+ecrit:  /**** END OF CRITICAL REGION ****/
-+# At this point, unlike on x86-32, we don't do the fixup to simplify the 
-+# code and the stack frame is more complex on x86-64.
-+# When the kernel is interrupted in the critical section, the kernel 
-+# will do IRET in that case, and everything will be restored at that point, 
-+# i.e. it just resumes from the next instruction interrupted with the same context. 
-+
-+# Hypervisor uses this for application faults while it executes.
-+# We get here for two reasons:
-+#  1. Fault while reloading DS, ES, FS or GS
-+#  2. Fault while executing IRET
-+# Category 1 we do not need to fix up as Xen has already reloaded all segment
-+# registers that could be reloaded and zeroed the others.
-+# Category 2 we fix up by killing the current process. We cannot use the
-+# normal Linux return path in this case because if we use the IRET hypercall
-+# to pop the stack frame we end up in an infinite loop of failsafe callbacks.
-+# We distinguish between categories by comparing each saved segment register
-+# with its current contents: any discrepancy means we in category 1.
-+ENTRY(failsafe_callback)
-+      movw %ds,%cx
-+      cmpw %cx,0x10(%rsp)
-+      jne 1f
-+      movw %es,%cx
-+      cmpw %cx,0x18(%rsp)
-+      jne 1f
-+      movw %fs,%cx
-+      cmpw %cx,0x20(%rsp)
-+      jne 1f
-+      movw %gs,%cx
-+      cmpw %cx,0x28(%rsp)
-+      jne 1f
-+      /* All segments match their saved values => Category 2 (Bad IRET). */
-+      movq (%rsp),%rcx
-+      movq 8(%rsp),%r11
-+      addq $0x30,%rsp
-+      movq $-9999,%rdi        /* better code? */
-+      jmp do_exit                     
-+1:    /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */
-+      movq (%rsp),%rcx
-+      movq 8(%rsp),%r11
-+      addq $0x30,%rsp
-+      pushq $0
-+      SAVE_ALL
-+      jmp error_exit
-+#if 0       
-+        .section __ex_table,"a"
-+        .align 8
-+        .quad gs_change,bad_gs
-+        .previous
-+        .section .fixup,"ax"
-+      /* running with kernelgs */
-+bad_gs: 
-+/*    swapgs          */      /* switch back to user gs */
-+      xorl %eax,%eax
-+        movl %eax,%gs
-+        jmp  2b
-+        .previous       
-+#endif
-+      
-+/*
-+ * Create a kernel thread.
-+ *
-+ * C extern interface:
-+ *    extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+ *
-+ * asm input arguments:
-+ *    rdi: fn, rsi: arg, rdx: flags
-+ */
-+ENTRY(kernel_thread)
-+      CFI_STARTPROC
-+      FAKE_STACK_FRAME $child_rip
-+      SAVE_ALL
-+
-+      # rdi: flags, rsi: usp, rdx: will be &pt_regs
-+      movq %rdx,%rdi
-+      orq  kernel_thread_flags(%rip),%rdi
-+      movq $-1, %rsi
-+      movq %rsp, %rdx
-+
-+      xorl %r8d,%r8d
-+      xorl %r9d,%r9d
-+      
-+      # clone now
-+      call do_fork
-+      movq %rax,RAX(%rsp)
-+      xorl %edi,%edi
-+
-+      /*
-+       * It isn't worth to check for reschedule here,
-+       * so internally to the x86_64 port you can rely on kernel_thread()
-+       * not to reschedule the child before returning, this avoids the need
-+       * of hacks for example to fork off the per-CPU idle tasks.
-+         * [Hopefully no generic code relies on the reschedule -AK]   
-+       */
-+      RESTORE_ALL
-+      UNFAKE_STACK_FRAME
-+      ret
-+      CFI_ENDPROC
-+
-+      
-+child_rip:
-+      /*
-+       * Here we are in the child and the registers are set as they were
-+       * at kernel_thread() invocation in the parent.
-+       */
-+      movq %rdi, %rax
-+      movq %rsi, %rdi
-+      call *%rax
-+      # exit
-+      xorl %edi, %edi
-+      call do_exit
-+
-+/*
-+ * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
-+ *
-+ * C extern interface:
-+ *     extern long execve(char *name, char **argv, char **envp)
-+ *
-+ * asm input arguments:
-+ *    rdi: name, rsi: argv, rdx: envp
-+ *
-+ * We want to fallback into:
-+ *    extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
-+ *
-+ * do_sys_execve asm fallback arguments:
-+ *    rdi: name, rsi: argv, rdx: envp, fake frame on the stack
-+ */
-+ENTRY(execve)
-+      CFI_STARTPROC
-+      FAKE_STACK_FRAME $0
-+      SAVE_ALL        
-+      call sys_execve
-+      movq %rax, RAX(%rsp)    
-+      RESTORE_REST
-+      testq %rax,%rax
-+      jne 1f
-+        jmp int_ret_from_sys_call
-+1:      RESTORE_ARGS
-+      UNFAKE_STACK_FRAME
-+      ret
-+      CFI_ENDPROC
-+
-+KPROBE_ENTRY(page_fault)
-+      errorentry do_page_fault
-+      .previous .text
-+
-+ENTRY(coprocessor_error)
-+      zeroentry do_coprocessor_error
-+
-+ENTRY(simd_coprocessor_error)
-+      zeroentry do_simd_coprocessor_error     
-+
-+ENTRY(device_not_available)
-+      zeroentry math_state_restore
-+
-+      /* runs on exception stack */
-+KPROBE_ENTRY(debug)
-+      INTR_FRAME
-+/*    pushq $0
-+      CFI_ADJUST_CFA_OFFSET 8 */
-+      zeroentry do_debug
-+/*    jmp paranoid_exit */
-+      CFI_ENDPROC
-+      .previous .text
-+
-+#if 0
-+      /* runs on exception stack */   
-+KPROBE_ENTRY(nmi)
-+      INTR_FRAME
-+      pushq $-1
-+      CFI_ADJUST_CFA_OFFSET 8
-+      paranoidentry do_nmi
-+      /*
-+       * "Paranoid" exit path from exception stack.
-+       * Paranoid because this is used by NMIs and cannot take
-+       * any kernel state for granted.
-+       * We don't do kernel preemption checks here, because only
-+       * NMI should be common and it does not enable IRQs and
-+       * cannot get reschedule ticks.
-+       */
-+      /* ebx: no swapgs flag */
-+paranoid_exit:
-+      testl %ebx,%ebx                         /* swapgs needed? */
-+      jnz paranoid_restore
-+      testl $3,CS(%rsp)
-+      jnz   paranoid_userspace
-+paranoid_swapgs:      
-+      swapgs
-+paranoid_restore:     
-+      RESTORE_ALL 8
-+      iretq
-+paranoid_userspace:   
-+      GET_THREAD_INFO(%rcx)
-+      movl threadinfo_flags(%rcx),%ebx
-+      andl $_TIF_WORK_MASK,%ebx
-+      jz paranoid_swapgs
-+      movq %rsp,%rdi                  /* &pt_regs */
-+      call sync_regs
-+      movq %rax,%rsp                  /* switch stack for scheduling */
-+      testl $_TIF_NEED_RESCHED,%ebx
-+      jnz paranoid_schedule
-+      movl %ebx,%edx                  /* arg3: thread flags */
-+      sti
-+      xorl %esi,%esi                  /* arg2: oldset */
-+      movq %rsp,%rdi                  /* arg1: &pt_regs */
-+      call do_notify_resume
-+      cli
-+      jmp paranoid_userspace
-+paranoid_schedule:
-+      sti
-+      call schedule
-+      cli
-+      jmp paranoid_userspace
-+      CFI_ENDPROC
-+      .previous .text
-+#endif        
-+
-+KPROBE_ENTRY(int3)
-+      INTR_FRAME
-+/*    pushq $0
-+      CFI_ADJUST_CFA_OFFSET 8 */
-+      zeroentry do_int3
-+/*    jmp paranoid_exit */
-+      CFI_ENDPROC
-+      .previous .text
-+
-+ENTRY(overflow)
-+      zeroentry do_overflow
-+
-+ENTRY(bounds)
-+      zeroentry do_bounds
-+
-+ENTRY(invalid_op)
-+      zeroentry do_invalid_op 
-+
-+ENTRY(coprocessor_segment_overrun)
-+      zeroentry do_coprocessor_segment_overrun
-+
-+ENTRY(reserved)
-+      zeroentry do_reserved
-+
-+#if 0
-+      /* runs on exception stack */
-+ENTRY(double_fault)
-+      XCPT_FRAME
-+      paranoidentry do_double_fault
-+      jmp paranoid_exit
-+      CFI_ENDPROC
-+#endif
-+
-+ENTRY(invalid_TSS)
-+      errorentry do_invalid_TSS
-+
-+ENTRY(segment_not_present)
-+      errorentry do_segment_not_present
-+
-+      /* runs on exception stack */
-+ENTRY(stack_segment)
-+      XCPT_FRAME
-+      errorentry do_stack_segment
-+      CFI_ENDPROC
-+
-+KPROBE_ENTRY(general_protection)
-+      errorentry do_general_protection
-+      .previous .text
-+
-+ENTRY(alignment_check)
-+      errorentry do_alignment_check
-+
-+ENTRY(divide_error)
-+      zeroentry do_divide_error
-+
-+ENTRY(spurious_interrupt_bug)
-+      zeroentry do_spurious_interrupt_bug
-+
-+#ifdef CONFIG_X86_MCE
-+      /* runs on exception stack */
-+ENTRY(machine_check)
-+      INTR_FRAME
-+      pushq $0
-+      CFI_ADJUST_CFA_OFFSET 8 
-+      paranoidentry do_machine_check
-+      jmp paranoid_exit
-+      CFI_ENDPROC
-+#endif
-+
-+ENTRY(call_softirq)
-+      CFI_STARTPROC
-+      movq %gs:pda_irqstackptr,%rax
-+      movq %rsp,%rdx
-+      CFI_DEF_CFA_REGISTER    rdx
-+      incl %gs:pda_irqcount
-+      cmove %rax,%rsp
-+      pushq %rdx
-+      /*todo CFI_DEF_CFA_EXPRESSION ...*/
-+      call __do_softirq
-+      popq %rsp
-+      CFI_DEF_CFA_REGISTER    rsp
-+      decl %gs:pda_irqcount
-+      ret
-+      CFI_ENDPROC
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/entry.S linux-2.6.16.33/arch/x86_64/kernel/entry.S
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/entry.S   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/entry.S 2007-05-23 21:00:01.000000000 +0000
-@@ -596,7 +596,7 @@
-  */           
-       .macro apicinterrupt num,func
-       INTR_FRAME
--      pushq $\num-256
-+      pushq $~(\num)
-       CFI_ADJUST_CFA_OFFSET 8
-       interrupt \func
-       jmp ret_from_intr
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/genapic-xen.c linux-2.6.16.33/arch/x86_64/kernel/genapic-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/genapic-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/genapic-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,144 @@
-+/*
-+ * Copyright 2004 James Cleverdon, IBM.
-+ * Subject to the GNU Public License, v.2
-+ *
-+ * Generic APIC sub-arch probe layer.
-+ *
-+ * Hacked for x86-64 by James Cleverdon from i386 architecture code by
-+ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
-+ * James Cleverdon.
-+ */
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <linux/cpumask.h>
-+#include <linux/string.h>
-+#include <linux/kernel.h>
-+#include <linux/ctype.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+
-+#include <asm/smp.h>
-+#include <asm/ipi.h>
-+
-+#if defined(CONFIG_ACPI)
-+#include <acpi/acpi_bus.h>
-+#endif
-+
-+/* which logical CPU number maps to which CPU (physical APIC ID) */
-+u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
-+EXPORT_SYMBOL(x86_cpu_to_apicid);
-+u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-+
-+extern struct genapic apic_cluster;
-+extern struct genapic apic_flat;
-+extern struct genapic apic_physflat;
-+
-+#ifndef CONFIG_XEN
-+struct genapic *genapic = &apic_flat;
-+#else
-+extern struct genapic apic_xen;
-+struct genapic *genapic = &apic_xen;
-+#endif
-+
-+
-+/*
-+ * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
-+ */
-+void __init clustered_apic_check(void)
-+{
-+#ifndef CONFIG_XEN
-+      long i;
-+      u8 clusters, max_cluster;
-+      u8 id;
-+      u8 cluster_cnt[NUM_APIC_CLUSTERS];
-+      int max_apic = 0;
-+
-+#if defined(CONFIG_ACPI)
-+      /*
-+       * Some x86_64 machines use physical APIC mode regardless of how many
-+       * procs/clusters are present (x86_64 ES7000 is an example).
-+       */
-+      if (acpi_fadt.revision > FADT2_REVISION_ID)
-+              if (acpi_fadt.force_apic_physical_destination_mode) {
-+                      genapic = &apic_cluster;
-+                      goto print;
-+              }
-+#endif
-+
-+      memset(cluster_cnt, 0, sizeof(cluster_cnt));
-+      for (i = 0; i < NR_CPUS; i++) {
-+              id = bios_cpu_apicid[i];
-+              if (id == BAD_APICID)
-+                      continue;
-+              if (id > max_apic)
-+                      max_apic = id;
-+              cluster_cnt[APIC_CLUSTERID(id)]++;
-+      }
-+
-+      /* Don't use clustered mode on AMD platforms. */
-+      if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
-+              genapic = &apic_physflat;
-+#ifndef CONFIG_HOTPLUG_CPU
-+              /* In the CPU hotplug case we cannot use broadcast mode
-+                 because that opens a race when a CPU is removed.
-+                 Stay at physflat mode in this case.
-+                 It is bad to do this unconditionally though. Once
-+                 we have ACPI platform support for CPU hotplug
-+                 we should detect hotplug capablity from ACPI tables and
-+                 only do this when really needed. -AK */
-+              if (max_apic <= 8)
-+                      genapic = &apic_flat;
-+#endif
-+              goto print;
-+      }
-+
-+      clusters = 0;
-+      max_cluster = 0;
-+
-+      for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
-+              if (cluster_cnt[i] > 0) {
-+                      ++clusters;
-+                      if (cluster_cnt[i] > max_cluster)
-+                              max_cluster = cluster_cnt[i];
-+              }
-+      }
-+
-+      /*
-+       * If we have clusters <= 1 and CPUs <= 8 in cluster 0, then flat mode,
-+       * else if max_cluster <= 4 and cluster_cnt[15] == 0, clustered logical
-+       * else physical mode.
-+       * (We don't use lowest priority delivery + HW APIC IRQ steering, so
-+       * can ignore the clustered logical case and go straight to physical.)
-+       */
-+      if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) {
-+#ifdef CONFIG_HOTPLUG_CPU
-+              /* Don't use APIC shortcuts in CPU hotplug to avoid races */
-+              genapic = &apic_physflat;
-+#else
-+              genapic = &apic_flat;
-+#endif
-+      } else
-+              genapic = &apic_cluster;
-+
-+print:
-+#else
-+      /* hardcode to xen apic functions */
-+      genapic = &apic_xen;
-+#endif
-+      printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
-+}
-+
-+/* Same for both flat and clustered. */
-+
-+#ifdef CONFIG_XEN
-+extern void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest);
-+#endif
-+
-+void send_IPI_self(int vector)
-+{
-+#ifndef CONFIG_XEN
-+      __send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
-+#else
-+      xen_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
-+#endif
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/genapic_xen.c linux-2.6.16.33/arch/x86_64/kernel/genapic_xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/genapic_xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/genapic_xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,162 @@
-+/*
-+ * Copyright 2004 James Cleverdon, IBM.
-+ * Subject to the GNU Public License, v.2
-+ *
-+ * Xen APIC subarch code.  Maximum 8 CPUs, logical delivery.
-+ *
-+ * Hacked for x86-64 by James Cleverdon from i386 architecture code by
-+ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
-+ * James Cleverdon.
-+ *
-+ * Hacked to pieces for Xen by Chris Wright.
-+ */
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <linux/cpumask.h>
-+#include <linux/string.h>
-+#include <linux/kernel.h>
-+#include <linux/ctype.h>
-+#include <linux/init.h>
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-+#include <asm/smp.h>
-+#include <asm/ipi.h>
-+#else
-+#include <asm/apic.h>
-+#include <asm/apicdef.h>
-+#include <asm/genapic.h>
-+#endif
-+#include <xen/evtchn.h>
-+
-+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
-+
-+static inline void __send_IPI_one(unsigned int cpu, int vector)
-+{
-+      int irq = per_cpu(ipi_to_irq, cpu)[vector];
-+      BUG_ON(irq < 0);
-+      notify_remote_via_irq(irq);
-+}
-+
-+void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest)
-+{
-+      int cpu;
-+
-+      switch (shortcut) {
-+      case APIC_DEST_SELF:
-+              __send_IPI_one(smp_processor_id(), vector);
-+              break;
-+      case APIC_DEST_ALLBUT:
-+              for (cpu = 0; cpu < NR_CPUS; ++cpu) {
-+                      if (cpu == smp_processor_id())
-+                              continue;
-+                      if (cpu_isset(cpu, cpu_online_map)) {
-+                              __send_IPI_one(cpu, vector);
-+                      }
-+              }
-+              break;
-+      case APIC_DEST_ALLINC:
-+              for (cpu = 0; cpu < NR_CPUS; ++cpu) {
-+                      if (cpu_isset(cpu, cpu_online_map)) {
-+                              __send_IPI_one(cpu, vector);
-+                      }
-+              }
-+              break;
-+      default:
-+              printk("XXXXXX __send_IPI_shortcut %08x vector %d\n", shortcut,
-+                     vector);
-+              break;
-+      }
-+}
-+
-+static cpumask_t xen_target_cpus(void)
-+{
-+      return cpu_online_map;
-+}
-+
-+/*
-+ * Set up the logical destination ID.
-+ * Do nothing, not called now.
-+ */
-+static void xen_init_apic_ldr(void)
-+{
-+      Dprintk("%s\n", __FUNCTION__);
-+      return;
-+}
-+
-+static void xen_send_IPI_allbutself(int vector)
-+{
-+      /*
-+       * if there are no other CPUs in the system then
-+       * we get an APIC send error if we try to broadcast.
-+       * thus we have to avoid sending IPIs in this case.
-+       */
-+      Dprintk("%s\n", __FUNCTION__);
-+      if (num_online_cpus() > 1)
-+              xen_send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL);
-+}
-+
-+static void xen_send_IPI_all(int vector)
-+{
-+      Dprintk("%s\n", __FUNCTION__);
-+      xen_send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL);
-+}
-+
-+static void xen_send_IPI_mask(cpumask_t cpumask, int vector)
-+{
-+      unsigned long mask = cpus_addr(cpumask)[0];
-+      unsigned int cpu;
-+      unsigned long flags;
-+
-+      Dprintk("%s\n", __FUNCTION__);
-+      local_irq_save(flags);
-+      WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]);
-+
-+      for (cpu = 0; cpu < NR_CPUS; ++cpu) {
-+              if (cpu_isset(cpu, cpumask)) {
-+                      __send_IPI_one(cpu, vector);
-+              }
-+      }
-+      local_irq_restore(flags);
-+}
-+
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-+static int xen_apic_id_registered(void)
-+{
-+      /* better be set */
-+      Dprintk("%s\n", __FUNCTION__);
-+      return physid_isset(smp_processor_id(), phys_cpu_present_map);
-+}
-+#endif
-+
-+static unsigned int xen_cpu_mask_to_apicid(cpumask_t cpumask)
-+{
-+      Dprintk("%s\n", __FUNCTION__);
-+      return cpus_addr(cpumask)[0] & APIC_ALL_CPUS;
-+}
-+
-+static unsigned int phys_pkg_id(int index_msb)
-+{
-+      u32 ebx;
-+
-+      Dprintk("%s\n", __FUNCTION__);
-+      ebx = cpuid_ebx(1);
-+      return ((ebx >> 24) & 0xFF) >> index_msb;
-+}
-+
-+struct genapic apic_xen =  {
-+      .name = "xen",
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-+      .int_delivery_mode = dest_LowestPrio,
-+#endif
-+      .int_dest_mode = (APIC_DEST_LOGICAL != 0),
-+      .int_delivery_dest = APIC_DEST_LOGICAL | APIC_DM_LOWEST,
-+      .target_cpus = xen_target_cpus,
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-+      .apic_id_registered = xen_apic_id_registered,
-+#endif
-+      .init_apic_ldr = xen_init_apic_ldr,
-+      .send_IPI_all = xen_send_IPI_all,
-+      .send_IPI_allbutself = xen_send_IPI_allbutself,
-+      .send_IPI_mask = xen_send_IPI_mask,
-+      .cpu_mask_to_apicid = xen_cpu_mask_to_apicid,
-+      .phys_pkg_id = phys_pkg_id,
-+};
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/head-xen.S linux-2.6.16.33/arch/x86_64/kernel/head-xen.S
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/head-xen.S        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/head-xen.S      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,183 @@
-+/*
-+ *  linux/arch/x86_64/kernel/head.S -- start in 32bit and switch to 64bit
-+ *
-+ *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
-+ *  Copyright (C) 2000 Pavel Machek <pavel@suse.cz>
-+ *  Copyright (C) 2000 Karsten Keil <kkeil@suse.de>
-+ *  Copyright (C) 2001,2002 Andi Kleen <ak@suse.de>
-+ *
-+ *  $Id: head.S,v 1.49 2002/03/19 17:39:25 ak Exp $
-+ *
-+ *  Jun Nakajima <jun.nakajima@intel.com>
-+ *    Modified for Xen                                
-+ */
-+
-+
-+#include <linux/linkage.h>
-+#include <linux/threads.h>
-+#include <linux/init.h>
-+#include <linux/elfnote.h>
-+#include <asm/desc.h>
-+#include <asm/segment.h>
-+#include <asm/page.h>
-+#include <asm/msr.h>
-+#include <asm/cache.h>
-+
-+#include <xen/interface/elfnote.h>
-+
-+      .text
-+      .code64
-+#define VIRT_ENTRY_OFFSET 0x0
-+.org VIRT_ENTRY_OFFSET
-+      .globl startup_64
-+startup_64:
-+ENTRY(_start)
-+      movq $(init_thread_union+THREAD_SIZE-8),%rsp
-+      /* zero EFLAGS after setting rsp */
-+      pushq $0
-+      popfq
-+
-+      /* rsi is pointer to startup info structure.
-+         pass it to C */
-+      movq %rsi,%rdi
-+      jmp x86_64_start_kernel
-+
-+ENTRY(stext)
-+ENTRY(_stext)
-+
-+      $page = 0
-+#define NEXT_PAGE(name) \
-+      $page = $page + 1; \
-+      .org $page * 0x1000; \
-+      phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \
-+ENTRY(name)
-+
-+NEXT_PAGE(init_level4_pgt)
-+      /* This gets initialized in x86_64_start_kernel */
-+      .fill   512,8,0
-+
-+        /*
-+         * We update two pgd entries to make kernel and user pgd consistent
-+         * at pgd_populate(). It can be used for kernel modules. So we place 
-+         * this page here for those cases to avoid memory corruption.
-+         * We also use this page to establish the initiali mapping for
-+         * vsyscall area.
-+         */
-+NEXT_PAGE(init_level4_user_pgt)
-+      .fill   512,8,0
-+
-+NEXT_PAGE(level3_kernel_pgt)
-+      .fill   512,8,0
-+
-+        /*
-+         * This is used for vsyscall area mapping as we have a different
-+         * level4 page table for user.
-+         */
-+NEXT_PAGE(level3_user_pgt)
-+        .fill 512,8,0
-+
-+NEXT_PAGE(level2_kernel_pgt)
-+      .fill   512,8,0
-+
-+NEXT_PAGE(empty_zero_page)
-+      .skip PAGE_SIZE
-+
-+NEXT_PAGE(hypercall_page)
-+      .fill   512,8,0
-+
-+#undef NEXT_PAGE
-+
-+      .data
-+
-+      .align 16
-+      .globl cpu_gdt_descr
-+cpu_gdt_descr:
-+      .word   gdt_end-cpu_gdt_table
-+gdt:
-+      .quad   cpu_gdt_table
-+#ifdef CONFIG_SMP
-+      .rept   NR_CPUS-1
-+      .word   0
-+      .quad   0
-+      .endr
-+#endif
-+
-+/* We need valid kernel segments for data and code in long mode too
-+ * IRET will check the segment types  kkeil 2000/10/28
-+ * Also sysret mandates a special GDT layout 
-+ */
-+                              
-+      .section .data.page_aligned, "aw"
-+      .align PAGE_SIZE
-+
-+/* The TLS descriptors are currently at a different place compared to i386.
-+   Hopefully nobody expects them at a fixed place (Wine?) */
-+
-+ENTRY(cpu_gdt_table)
-+      .quad   0x0000000000000000      /* NULL descriptor */
-+      .quad   0x0                     /* unused */
-+      .quad   0x00af9a000000ffff      /* __KERNEL_CS */
-+      .quad   0x00cf92000000ffff      /* __KERNEL_DS */
-+      .quad   0x00cffa000000ffff      /* __USER32_CS */
-+      .quad   0x00cff2000000ffff      /* __USER_DS, __USER32_DS  */
-+      .quad   0x00affa000000ffff      /* __USER_CS */
-+      .quad   0x00cf9a000000ffff      /* __KERNEL32_CS */
-+      .quad   0,0                     /* TSS */
-+      .quad   0,0                     /* LDT */
-+      .quad   0,0,0                   /* three TLS descriptors */
-+      .quad   0                       /* unused */
-+gdt_end:
-+      /* asm/segment.h:GDT_ENTRIES must match this */
-+      /* This should be a multiple of the cache line size */
-+      /* GDTs of other CPUs are now dynamically allocated */
-+
-+      /* zero the remaining page */
-+      .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+/*
-+ * __xen_guest information
-+ */
-+.macro utoh value
-+ .if (\value) < 0 || (\value) >= 0x10
-+      utoh (((\value)>>4)&0x0fffffffffffffff)
-+ .endif
-+ .if ((\value) & 0xf) < 10
-+  .byte '0' + ((\value) & 0xf)
-+ .else
-+  .byte 'A' + ((\value) & 0xf) - 10
-+ .endif
-+.endm
-+
-+.section __xen_guest
-+      .ascii  "GUEST_OS=linux,GUEST_VER=2.6"
-+      .ascii  ",XEN_VER=xen-3.0"
-+      .ascii  ",VIRT_BASE=0x"
-+              utoh __START_KERNEL_map
-+      .ascii  ",ELF_PADDR_OFFSET=0x"
-+              utoh __START_KERNEL_map
-+      .ascii  ",VIRT_ENTRY=0x"
-+              utoh (__START_KERNEL_map + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
-+      .ascii  ",HYPERCALL_PAGE=0x"
-+              utoh (phys_hypercall_page >> PAGE_SHIFT)
-+      .ascii  ",FEATURES=writable_page_tables"
-+      .ascii           "|writable_descriptor_tables"
-+      .ascii           "|auto_translated_physmap"
-+      .ascii           "|supervisor_mode_kernel"
-+      .ascii  ",LOADER=generic"
-+      .byte   0
-+#endif /* CONFIG_XEN_COMPAT_030002 */
-+      
-+      ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz, "linux")
-+      ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz, "2.6")
-+      ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz, "xen-3.0")
-+      ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .quad,  __START_KERNEL_map)
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  __START_KERNEL_map)
-+#else
-+      ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   .quad,  0)
-+#endif /* !CONFIG_XEN_COMPAT_030002 */
-+      ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .quad,  startup_64)
-+      ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad,  hypercall_page)
-+      ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
-+      ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz, "generic")
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/head64-xen.c linux-2.6.16.33/arch/x86_64/kernel/head64-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/head64-xen.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/head64-xen.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,159 @@
-+/*
-+ *  linux/arch/x86_64/kernel/head64.c -- prepare to run common code
-+ *
-+ *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
-+ *
-+ *  $Id: head64.c,v 1.22 2001/07/06 14:28:20 ak Exp $
-+ *
-+ *  Jun Nakajima <jun.nakajima@intel.com>
-+ *    Modified for Xen.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/linkage.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/percpu.h>
-+#include <linux/module.h>
-+
-+#include <asm/processor.h>
-+#include <asm/proto.h>
-+#include <asm/smp.h>
-+#include <asm/bootsetup.h>
-+#include <asm/setup.h>
-+#include <asm/desc.h>
-+#include <asm/pgtable.h>
-+#include <asm/sections.h>
-+
-+unsigned long start_pfn;
-+
-+/* Don't add a printk in there. printk relies on the PDA which is not initialized 
-+   yet. */
-+#if 0
-+static void __init clear_bss(void)
-+{
-+      memset(__bss_start, 0,
-+             (unsigned long) __bss_stop - (unsigned long) __bss_start);
-+}
-+#endif
-+
-+#define NEW_CL_POINTER                0x228   /* Relative to real mode data */
-+#define OLD_CL_MAGIC_ADDR     0x90020
-+#define OLD_CL_MAGIC            0xA33F
-+#define OLD_CL_BASE_ADDR        0x90000
-+#define OLD_CL_OFFSET           0x90022
-+
-+extern char saved_command_line[];
-+
-+static void __init copy_bootdata(char *real_mode_data)
-+{
-+#ifndef CONFIG_XEN
-+      int new_data;
-+      char * command_line;
-+
-+      memcpy(x86_boot_params, real_mode_data, BOOT_PARAM_SIZE);
-+      new_data = *(int *) (x86_boot_params + NEW_CL_POINTER);
-+      if (!new_data) {
-+              if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) {
-+                      printk("so old bootloader that it does not support commandline?!\n");
-+                      return;
-+              }
-+              new_data = OLD_CL_BASE_ADDR + * (u16 *) OLD_CL_OFFSET;
-+              printk("old bootloader convention, maybe loadlin?\n");
-+      }
-+      command_line = (char *) ((u64)(new_data));
-+      memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
-+#else
-+      int max_cmdline;
-+      
-+      if ((max_cmdline = MAX_GUEST_CMDLINE) > COMMAND_LINE_SIZE)
-+              max_cmdline = COMMAND_LINE_SIZE;
-+      memcpy(saved_command_line, xen_start_info->cmd_line, max_cmdline);
-+      saved_command_line[max_cmdline-1] = '\0';
-+#endif
-+      printk("Bootdata ok (command line is %s)\n", saved_command_line);
-+}
-+
-+static void __init setup_boot_cpu_data(void)
-+{
-+      unsigned int dummy, eax;
-+
-+      /* get vendor info */
-+      cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level,
-+            (unsigned int *)&boot_cpu_data.x86_vendor_id[0],
-+            (unsigned int *)&boot_cpu_data.x86_vendor_id[8],
-+            (unsigned int *)&boot_cpu_data.x86_vendor_id[4]);
-+
-+      /* get cpu type */
-+      cpuid(1, &eax, &dummy, &dummy,
-+              (unsigned int *) &boot_cpu_data.x86_capability);
-+      boot_cpu_data.x86 = (eax >> 8) & 0xf;
-+      boot_cpu_data.x86_model = (eax >> 4) & 0xf;
-+      boot_cpu_data.x86_mask = eax & 0xf;
-+}
-+
-+#include <xen/interface/memory.h>
-+unsigned long *machine_to_phys_mapping;
-+EXPORT_SYMBOL(machine_to_phys_mapping);
-+unsigned int machine_to_phys_order;
-+EXPORT_SYMBOL(machine_to_phys_order);
-+
-+void __init x86_64_start_kernel(char * real_mode_data)
-+{
-+      struct xen_machphys_mapping mapping;
-+      unsigned long machine_to_phys_nr_ents;
-+      char *s;
-+      int i;
-+
-+      xen_start_info = (struct start_info *)real_mode_data;
-+      if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+              phys_to_machine_mapping =
-+                      (unsigned long *)xen_start_info->mfn_list;
-+              start_pfn = (__pa(xen_start_info->pt_base) >> PAGE_SHIFT) +
-+                      xen_start_info->nr_pt_frames;
-+      }
-+
-+
-+      machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
-+      machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
-+      if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
-+              machine_to_phys_mapping = (unsigned long *)mapping.v_start;
-+              machine_to_phys_nr_ents = mapping.max_mfn + 1;
-+      }
-+      while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
-+              machine_to_phys_order++;
-+
-+#if 0
-+      for (i = 0; i < 256; i++)
-+              set_intr_gate(i, early_idt_handler);
-+      asm volatile("lidt %0" :: "m" (idt_descr));
-+#endif
-+
-+      for (i = 0; i < NR_CPUS; i++)
-+              cpu_pda(i) = &boot_cpu_pda[i];
-+
-+      pda_init(0);
-+      copy_bootdata(real_mode_data);
-+#ifdef CONFIG_SMP
-+      cpu_set(0, cpu_online_map);
-+#endif
-+      s = strstr(saved_command_line, "earlyprintk=");
-+      if (s != NULL)
-+              setup_early_printk(strchr(s, '=') + 1);
-+#ifdef CONFIG_NUMA
-+      s = strstr(saved_command_line, "numa=");
-+      if (s != NULL)
-+              numa_setup(s+5);
-+#endif
-+#ifdef CONFIG_X86_IO_APIC
-+      if (strstr(saved_command_line, "disableapic"))
-+              disable_apic = 1;
-+#endif
-+      /* You need early console to see that */
-+      if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE)
-+              panic("Kernel too big for kernel mapping\n");
-+
-+      setup_boot_cpu_data();
-+      start_kernel();
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/init_task.c linux-2.6.16.33/arch/x86_64/kernel/init_task.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/init_task.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/init_task.c     2007-01-08 15:00:45.000000000 +0000
-@@ -37,6 +37,8 @@
- struct task_struct init_task = INIT_TASK(init_task);
- EXPORT_SYMBOL(init_task);
-+
-+#ifndef CONFIG_X86_NO_TSS
- /*
-  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
-  * no more per-task TSS's. The TSS size is kept cacheline-aligned
-@@ -45,5 +47,6 @@
-  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
-  */ 
- DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
-+#endif
- #define ALIGN_TO_4K __attribute__((section(".data.init_task")))
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/io_apic-xen.c linux-2.6.16.33/arch/x86_64/kernel/io_apic-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/io_apic-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/io_apic-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2226 @@
-+/*
-+ *    Intel IO-APIC support for multi-Pentium hosts.
-+ *
-+ *    Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo
-+ *
-+ *    Many thanks to Stig Venaas for trying out countless experimental
-+ *    patches and reporting/debugging problems patiently!
-+ *
-+ *    (c) 1999, Multiple IO-APIC support, developed by
-+ *    Ken-ichi Yaku <yaku@css1.kbnes.nec.co.jp> and
-+ *      Hidemi Kishimoto <kisimoto@css1.kbnes.nec.co.jp>,
-+ *    further tested and cleaned up by Zach Brown <zab@redhat.com>
-+ *    and Ingo Molnar <mingo@redhat.com>
-+ *
-+ *    Fixes
-+ *    Maciej W. Rozycki       :       Bits for genuine 82489DX APICs;
-+ *                                    thanks to Eric Gilmore
-+ *                                    and Rolf G. Tews
-+ *                                    for testing these extensively
-+ *    Paul Diefenbaugh        :       Added full ACPI support
-+ */
-+
-+#include <linux/mm.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/config.h>
-+#include <linux/smp_lock.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/acpi.h>
-+#include <linux/sysdev.h>
-+#ifdef CONFIG_ACPI
-+#include <acpi/acpi_bus.h>
-+#endif
-+
-+#include <asm/io.h>
-+#include <asm/smp.h>
-+#include <asm/desc.h>
-+#include <asm/proto.h>
-+#include <asm/mach_apic.h>
-+#include <asm/acpi.h>
-+#include <asm/dma.h>
-+
-+#define __apicdebuginit  __init
-+
-+int sis_apic_bug; /* not actually supported, dummy for compile */
-+
-+static int no_timer_check;
-+
-+int disable_timer_pin_1 __initdata;
-+
-+#ifndef CONFIG_XEN
-+int timer_over_8254 __initdata = 1;
-+
-+/* Where if anywhere is the i8259 connect in external int mode */
-+static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
-+#endif
-+
-+static DEFINE_SPINLOCK(ioapic_lock);
-+
-+/*
-+ * # of IRQ routing registers
-+ */
-+int nr_ioapic_registers[MAX_IO_APICS];
-+
-+/*
-+ * Rough estimation of how many shared IRQs there are, can
-+ * be changed anytime.
-+ */
-+#define MAX_PLUS_SHARED_IRQS NR_IRQ_VECTORS
-+#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
-+
-+/*
-+ * This is performance-critical, we want to do it O(1)
-+ *
-+ * the indexing order of this array favors 1:1 mappings
-+ * between pins and IRQs.
-+ */
-+
-+static struct irq_pin_list {
-+      short apic, pin, next;
-+} irq_2_pin[PIN_MAP_SIZE];
-+
-+int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
-+#ifdef CONFIG_PCI_MSI
-+#define vector_to_irq(vector)         \
-+      (platform_legacy_irq(vector) ? vector : vector_irq[vector])
-+#else
-+#define vector_to_irq(vector) (vector)
-+#endif
-+
-+#ifdef CONFIG_XEN
-+
-+#include <xen/interface/xen.h>
-+#include <xen/interface/physdev.h>
-+
-+/* Fake i8259 */
-+#define make_8259A_irq(_irq)     (io_apic_irqs &= ~(1UL<<(_irq)))
-+#define disable_8259A_irq(_irq)  ((void)0)
-+#define i8259A_irq_pending(_irq) (0)
-+
-+unsigned long io_apic_irqs;
-+
-+static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
-+{
-+      struct physdev_apic apic_op;
-+      int ret;
-+
-+      apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
-+      apic_op.reg = reg;
-+      ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
-+      if (ret)
-+              return ret;
-+      return apic_op.value;
-+}
-+
-+static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-+{
-+      struct physdev_apic apic_op;
-+
-+      apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
-+      apic_op.reg = reg;
-+      apic_op.value = value;
-+      HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
-+}
-+
-+#define io_apic_read(a,r)    xen_io_apic_read(a,r)
-+#define io_apic_write(a,r,v) xen_io_apic_write(a,r,v)
-+
-+#define clear_IO_APIC() ((void)0)
-+
-+#else
-+
-+#ifdef CONFIG_SMP
-+static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
-+{
-+      unsigned long flags;
-+      unsigned int dest;
-+      cpumask_t tmp;
-+
-+      cpus_and(tmp, mask, cpu_online_map);
-+      if (cpus_empty(tmp))
-+              tmp = TARGET_CPUS;
-+
-+      cpus_and(mask, tmp, CPU_MASK_ALL);
-+
-+      dest = cpu_mask_to_apicid(mask);
-+
-+      /*
-+       * Only the high 8 bits are valid.
-+       */
-+      dest = SET_APIC_LOGICAL_ID(dest);
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      __DO_ACTION(1, = dest, )
-+      set_irq_info(irq, mask);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+#endif
-+
-+#endif /* !CONFIG_XEN */
-+
-+/*
-+ * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
-+ * shared ISA-space IRQs, so we have to support them. We are super
-+ * fast in the common case, and fast for shared ISA-space IRQs.
-+ */
-+static void add_pin_to_irq(unsigned int irq, int apic, int pin)
-+{
-+      static int first_free_entry = NR_IRQS;
-+      struct irq_pin_list *entry = irq_2_pin + irq;
-+
-+      BUG_ON(irq >= NR_IRQS);
-+      while (entry->next)
-+              entry = irq_2_pin + entry->next;
-+
-+      if (entry->pin != -1) {
-+              entry->next = first_free_entry;
-+              entry = irq_2_pin + entry->next;
-+              if (++first_free_entry >= PIN_MAP_SIZE)
-+                      panic("io_apic.c: ran out of irq_2_pin entries!");
-+      }
-+      entry->apic = apic;
-+      entry->pin = pin;
-+}
-+
-+#ifndef CONFIG_XEN
-+#define __DO_ACTION(R, ACTION, FINAL)                                 \
-+                                                                      \
-+{                                                                     \
-+      int pin;                                                        \
-+      struct irq_pin_list *entry = irq_2_pin + irq;                   \
-+                                                                      \
-+      BUG_ON(irq >= NR_IRQS);                                         \
-+      for (;;) {                                                      \
-+              unsigned int reg;                                       \
-+              pin = entry->pin;                                       \
-+              if (pin == -1)                                          \
-+                      break;                                          \
-+              reg = io_apic_read(entry->apic, 0x10 + R + pin*2);      \
-+              reg ACTION;                                             \
-+              io_apic_modify(entry->apic, reg);                       \
-+              if (!entry->next)                                       \
-+                      break;                                          \
-+              entry = irq_2_pin + entry->next;                        \
-+      }                                                               \
-+      FINAL;                                                          \
-+}
-+
-+#define DO_ACTION(name,R,ACTION, FINAL)                                       \
-+                                                                      \
-+      static void name##_IO_APIC_irq (unsigned int irq)               \
-+      __DO_ACTION(R, ACTION, FINAL)
-+
-+DO_ACTION( __mask,             0, |= 0x00010000, io_apic_sync(entry->apic) )
-+                                              /* mask = 1 */
-+DO_ACTION( __unmask,           0, &= 0xfffeffff, )
-+                                              /* mask = 0 */
-+
-+static void mask_IO_APIC_irq (unsigned int irq)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      __mask_IO_APIC_irq(irq);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+static void unmask_IO_APIC_irq (unsigned int irq)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      __unmask_IO_APIC_irq(irq);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
-+{
-+      struct IO_APIC_route_entry entry;
-+      unsigned long flags;
-+
-+      /* Check delivery_mode to be sure we're not clearing an SMI pin */
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
-+      *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+      if (entry.delivery_mode == dest_SMI)
-+              return;
-+      /*
-+       * Disable it in the IO-APIC irq-routing table:
-+       */
-+      memset(&entry, 0, sizeof(entry));
-+      entry.mask = 1;
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0));
-+      io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+static void clear_IO_APIC (void)
-+{
-+      int apic, pin;
-+
-+      for (apic = 0; apic < nr_ioapics; apic++)
-+              for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
-+                      clear_IO_APIC_pin(apic, pin);
-+}
-+
-+#endif /* !CONFIG_XEN */
-+
-+static u8 gsi_2_irq[NR_IRQ_VECTORS] = { [0 ... NR_IRQ_VECTORS-1] = 0xFF };
-+
-+/*
-+ * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
-+ * specific CPU-side IRQs.
-+ */
-+
-+#define MAX_PIRQS 8
-+static int pirq_entries [MAX_PIRQS];
-+static int pirqs_enabled;
-+int skip_ioapic_setup;
-+int ioapic_force;
-+
-+/* dummy parsing: see setup.c */
-+
-+static int __init disable_ioapic_setup(char *str)
-+{
-+      skip_ioapic_setup = 1;
-+      return 1;
-+}
-+
-+static int __init enable_ioapic_setup(char *str)
-+{
-+      ioapic_force = 1;
-+      skip_ioapic_setup = 0;
-+      return 1;
-+}
-+
-+__setup("noapic", disable_ioapic_setup);
-+__setup("apic", enable_ioapic_setup);
-+
-+#ifndef CONFIG_XEN
-+static int __init setup_disable_8254_timer(char *s)
-+{
-+      timer_over_8254 = -1;
-+      return 1;
-+}
-+static int __init setup_enable_8254_timer(char *s)
-+{
-+      timer_over_8254 = 2;
-+      return 1;
-+}
-+
-+__setup("disable_8254_timer", setup_disable_8254_timer);
-+__setup("enable_8254_timer", setup_enable_8254_timer);
-+#endif /* !CONFIG_XEN */
-+
-+#include <asm/pci-direct.h>
-+#include <linux/pci_ids.h>
-+#include <linux/pci.h>
-+
-+/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC
-+   off. Check for an Nvidia or VIA PCI bridge and turn it off.
-+   Use pci direct infrastructure because this runs before the PCI subsystem. 
-+
-+   Can be overwritten with "apic"
-+
-+   And another hack to disable the IOMMU on VIA chipsets.
-+
-+   ... and others. Really should move this somewhere else.
-+
-+   Kludge-O-Rama. */
-+void __init check_ioapic(void) 
-+{ 
-+      int num,slot,func; 
-+      /* Poor man's PCI discovery */
-+      for (num = 0; num < 32; num++) { 
-+              for (slot = 0; slot < 32; slot++) { 
-+                      for (func = 0; func < 8; func++) { 
-+                              u32 class;
-+                              u32 vendor;
-+                              u8 type;
-+                              class = read_pci_config(num,slot,func,
-+                                                      PCI_CLASS_REVISION);
-+                              if (class == 0xffffffff)
-+                                      break; 
-+
-+                              if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
-+                                      continue; 
-+
-+                              vendor = read_pci_config(num, slot, func, 
-+                                                       PCI_VENDOR_ID);
-+                              vendor &= 0xffff;
-+                              switch (vendor) { 
-+                              case PCI_VENDOR_ID_VIA:
-+#ifdef CONFIG_GART_IOMMU
-+                                      if ((end_pfn > MAX_DMA32_PFN ||
-+                                           force_iommu) &&
-+                                          !iommu_aperture_allowed) {
-+                                              printk(KERN_INFO
-+    "Looks like a VIA chipset. Disabling IOMMU. Overwrite with \"iommu=allowed\"\n");
-+                                              iommu_aperture_disabled = 1;
-+                                      }
-+#endif
-+                                      return;
-+                              case PCI_VENDOR_ID_NVIDIA:
-+#ifdef CONFIG_ACPI
-+                                      /* All timer overrides on Nvidia
-+                                         seem to be wrong. Skip them. */
-+                                      acpi_skip_timer_override = 1;
-+                                      printk(KERN_INFO 
-+           "Nvidia board detected. Ignoring ACPI timer override.\n");
-+#endif
-+                                      /* RED-PEN skip them on mptables too? */
-+                                      return;
-+                              case PCI_VENDOR_ID_ATI:
-+
-+                              /* This should be actually default, but
-+                                 for 2.6.16 let's do it for ATI only where
-+                                 it's really needed. */
-+#ifndef CONFIG_XEN
-+                                      if (timer_over_8254 == 1) {     
-+                                              timer_over_8254 = 0;    
-+                                      printk(KERN_INFO
-+              "ATI board detected. Disabling timer routing over 8254.\n");
-+                                      }       
-+#endif
-+                                      return;
-+                              } 
-+
-+
-+                              /* No multi-function device? */
-+                              type = read_pci_config_byte(num,slot,func,
-+                                                          PCI_HEADER_TYPE);
-+                              if (!(type & 0x80))
-+                                      break;
-+                      } 
-+              }
-+      }
-+} 
-+
-+static int __init ioapic_pirq_setup(char *str)
-+{
-+      int i, max;
-+      int ints[MAX_PIRQS+1];
-+
-+      get_options(str, ARRAY_SIZE(ints), ints);
-+
-+      for (i = 0; i < MAX_PIRQS; i++)
-+              pirq_entries[i] = -1;
-+
-+      pirqs_enabled = 1;
-+      apic_printk(APIC_VERBOSE, "PIRQ redirection, working around broken MP-BIOS.\n");
-+      max = MAX_PIRQS;
-+      if (ints[0] < MAX_PIRQS)
-+              max = ints[0];
-+
-+      for (i = 0; i < max; i++) {
-+              apic_printk(APIC_VERBOSE, "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
-+              /*
-+               * PIRQs are mapped upside down, usually.
-+               */
-+              pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
-+      }
-+      return 1;
-+}
-+
-+__setup("pirq=", ioapic_pirq_setup);
-+
-+/*
-+ * Find the IRQ entry number of a certain pin.
-+ */
-+static int find_irq_entry(int apic, int pin, int type)
-+{
-+      int i;
-+
-+      for (i = 0; i < mp_irq_entries; i++)
-+              if (mp_irqs[i].mpc_irqtype == type &&
-+                  (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid ||
-+                   mp_irqs[i].mpc_dstapic == MP_APIC_ALL) &&
-+                  mp_irqs[i].mpc_dstirq == pin)
-+                      return i;
-+
-+      return -1;
-+}
-+
-+#ifndef CONFIG_XEN
-+/*
-+ * Find the pin to which IRQ[irq] (ISA) is connected
-+ */
-+static int __init find_isa_irq_pin(int irq, int type)
-+{
-+      int i;
-+
-+      for (i = 0; i < mp_irq_entries; i++) {
-+              int lbus = mp_irqs[i].mpc_srcbus;
-+
-+              if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_MCA) &&
-+                  (mp_irqs[i].mpc_irqtype == type) &&
-+                  (mp_irqs[i].mpc_srcbusirq == irq))
-+
-+                      return mp_irqs[i].mpc_dstirq;
-+      }
-+      return -1;
-+}
-+
-+static int __init find_isa_irq_apic(int irq, int type)
-+{
-+      int i;
-+
-+      for (i = 0; i < mp_irq_entries; i++) {
-+              int lbus = mp_irqs[i].mpc_srcbus;
-+
-+              if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
-+                   mp_bus_id_to_type[lbus] == MP_BUS_MCA) &&
-+                  (mp_irqs[i].mpc_irqtype == type) &&
-+                  (mp_irqs[i].mpc_srcbusirq == irq))
-+                      break;
-+      }
-+      if (i < mp_irq_entries) {
-+              int apic;
-+              for(apic = 0; apic < nr_ioapics; apic++) {
-+                      if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
-+                              return apic;
-+              }
-+      }
-+
-+      return -1;
-+}
-+#endif
-+
-+/*
-+ * Find a specific PCI IRQ entry.
-+ * Not an __init, possibly needed by modules
-+ */
-+static int pin_2_irq(int idx, int apic, int pin);
-+
-+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
-+{
-+      int apic, i, best_guess = -1;
-+
-+      apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
-+              bus, slot, pin);
-+      if (mp_bus_id_to_pci_bus[bus] == -1) {
-+              apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
-+              return -1;
-+      }
-+      for (i = 0; i < mp_irq_entries; i++) {
-+              int lbus = mp_irqs[i].mpc_srcbus;
-+
-+              for (apic = 0; apic < nr_ioapics; apic++)
-+                      if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic ||
-+                          mp_irqs[i].mpc_dstapic == MP_APIC_ALL)
-+                              break;
-+
-+              if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
-+                  !mp_irqs[i].mpc_irqtype &&
-+                  (bus == lbus) &&
-+                  (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
-+                      int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
-+
-+                      if (!(apic || IO_APIC_IRQ(irq)))
-+                              continue;
-+
-+                      if (pin == (mp_irqs[i].mpc_srcbusirq & 3))
-+                              return irq;
-+                      /*
-+                       * Use the first all-but-pin matching entry as a
-+                       * best-guess fuzzy result for broken mptables.
-+                       */
-+                      if (best_guess < 0)
-+                              best_guess = irq;
-+              }
-+      }
-+      BUG_ON(best_guess >= NR_IRQS);
-+      return best_guess;
-+}
-+
-+/*
-+ * EISA Edge/Level control register, ELCR
-+ */
-+static int EISA_ELCR(unsigned int irq)
-+{
-+      if (irq < 16) {
-+              unsigned int port = 0x4d0 + (irq >> 3);
-+              return (inb(port) >> (irq & 7)) & 1;
-+      }
-+      apic_printk(APIC_VERBOSE, "Broken MPtable reports ISA irq %d\n", irq);
-+      return 0;
-+}
-+
-+/* EISA interrupts are always polarity zero and can be edge or level
-+ * trigger depending on the ELCR value.  If an interrupt is listed as
-+ * EISA conforming in the MP table, that means its trigger type must
-+ * be read in from the ELCR */
-+
-+#define default_EISA_trigger(idx)     (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq))
-+#define default_EISA_polarity(idx)    (0)
-+
-+/* ISA interrupts are always polarity zero edge triggered,
-+ * when listed as conforming in the MP table. */
-+
-+#define default_ISA_trigger(idx)      (0)
-+#define default_ISA_polarity(idx)     (0)
-+
-+/* PCI interrupts are always polarity one level triggered,
-+ * when listed as conforming in the MP table. */
-+
-+#define default_PCI_trigger(idx)      (1)
-+#define default_PCI_polarity(idx)     (1)
-+
-+/* MCA interrupts are always polarity zero level triggered,
-+ * when listed as conforming in the MP table. */
-+
-+#define default_MCA_trigger(idx)      (1)
-+#define default_MCA_polarity(idx)     (0)
-+
-+static int __init MPBIOS_polarity(int idx)
-+{
-+      int bus = mp_irqs[idx].mpc_srcbus;
-+      int polarity;
-+
-+      /*
-+       * Determine IRQ line polarity (high active or low active):
-+       */
-+      switch (mp_irqs[idx].mpc_irqflag & 3)
-+      {
-+              case 0: /* conforms, ie. bus-type dependent polarity */
-+              {
-+                      switch (mp_bus_id_to_type[bus])
-+                      {
-+                              case MP_BUS_ISA: /* ISA pin */
-+                              {
-+                                      polarity = default_ISA_polarity(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_EISA: /* EISA pin */
-+                              {
-+                                      polarity = default_EISA_polarity(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_PCI: /* PCI pin */
-+                              {
-+                                      polarity = default_PCI_polarity(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_MCA: /* MCA pin */
-+                              {
-+                                      polarity = default_MCA_polarity(idx);
-+                                      break;
-+                              }
-+                              default:
-+                              {
-+                                      printk(KERN_WARNING "broken BIOS!!\n");
-+                                      polarity = 1;
-+                                      break;
-+                              }
-+                      }
-+                      break;
-+              }
-+              case 1: /* high active */
-+              {
-+                      polarity = 0;
-+                      break;
-+              }
-+              case 2: /* reserved */
-+              {
-+                      printk(KERN_WARNING "broken BIOS!!\n");
-+                      polarity = 1;
-+                      break;
-+              }
-+              case 3: /* low active */
-+              {
-+                      polarity = 1;
-+                      break;
-+              }
-+              default: /* invalid */
-+              {
-+                      printk(KERN_WARNING "broken BIOS!!\n");
-+                      polarity = 1;
-+                      break;
-+              }
-+      }
-+      return polarity;
-+}
-+
-+static int MPBIOS_trigger(int idx)
-+{
-+      int bus = mp_irqs[idx].mpc_srcbus;
-+      int trigger;
-+
-+      /*
-+       * Determine IRQ trigger mode (edge or level sensitive):
-+       */
-+      switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
-+      {
-+              case 0: /* conforms, ie. bus-type dependent */
-+              {
-+                      switch (mp_bus_id_to_type[bus])
-+                      {
-+                              case MP_BUS_ISA: /* ISA pin */
-+                              {
-+                                      trigger = default_ISA_trigger(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_EISA: /* EISA pin */
-+                              {
-+                                      trigger = default_EISA_trigger(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_PCI: /* PCI pin */
-+                              {
-+                                      trigger = default_PCI_trigger(idx);
-+                                      break;
-+                              }
-+                              case MP_BUS_MCA: /* MCA pin */
-+                              {
-+                                      trigger = default_MCA_trigger(idx);
-+                                      break;
-+                              }
-+                              default:
-+                              {
-+                                      printk(KERN_WARNING "broken BIOS!!\n");
-+                                      trigger = 1;
-+                                      break;
-+                              }
-+                      }
-+                      break;
-+              }
-+              case 1: /* edge */
-+              {
-+                      trigger = 0;
-+                      break;
-+              }
-+              case 2: /* reserved */
-+              {
-+                      printk(KERN_WARNING "broken BIOS!!\n");
-+                      trigger = 1;
-+                      break;
-+              }
-+              case 3: /* level */
-+              {
-+                      trigger = 1;
-+                      break;
-+              }
-+              default: /* invalid */
-+              {
-+                      printk(KERN_WARNING "broken BIOS!!\n");
-+                      trigger = 0;
-+                      break;
-+              }
-+      }
-+      return trigger;
-+}
-+
-+static inline int irq_polarity(int idx)
-+{
-+      return MPBIOS_polarity(idx);
-+}
-+
-+static inline int irq_trigger(int idx)
-+{
-+      return MPBIOS_trigger(idx);
-+}
-+
-+static int next_irq = 16;
-+
-+/*
-+ * gsi_irq_sharing -- Name overload!  "irq" can be either a legacy IRQ
-+ * in the range 0-15, a linux IRQ in the range 0-223, or a GSI number
-+ * from ACPI, which can reach 800 in large boxen.
-+ *
-+ * Compact the sparse GSI space into a sequential IRQ series and reuse
-+ * vectors if possible.
-+ */
-+int gsi_irq_sharing(int gsi)
-+{
-+      int i, tries, vector;
-+
-+      BUG_ON(gsi >= NR_IRQ_VECTORS);
-+
-+      if (platform_legacy_irq(gsi))
-+              return gsi;
-+
-+      if (gsi_2_irq[gsi] != 0xFF)
-+              return (int)gsi_2_irq[gsi];
-+
-+      tries = NR_IRQS;
-+  try_again:
-+      vector = assign_irq_vector(gsi);
-+
-+      /*
-+       * Sharing vectors means sharing IRQs, so scan irq_vectors for previous
-+       * use of vector and if found, return that IRQ.  However, we never want
-+       * to share legacy IRQs, which usually have a different trigger mode
-+       * than PCI.
-+       */
-+      for (i = 0; i < NR_IRQS; i++)
-+              if (IO_APIC_VECTOR(i) == vector)
-+                      break;
-+      if (platform_legacy_irq(i)) {
-+              if (--tries >= 0) {
-+                      IO_APIC_VECTOR(i) = 0;
-+                      goto try_again;
-+              }
-+              panic("gsi_irq_sharing: didn't find an IRQ using vector 0x%02X for GSI %d", vector, gsi);
-+      }
-+      if (i < NR_IRQS) {
-+              gsi_2_irq[gsi] = i;
-+              printk(KERN_INFO "GSI %d sharing vector 0x%02X and IRQ %d\n",
-+                              gsi, vector, i);
-+              return i;
-+      }
-+
-+      i = next_irq++;
-+      BUG_ON(i >= NR_IRQS);
-+      gsi_2_irq[gsi] = i;
-+      IO_APIC_VECTOR(i) = vector;
-+      printk(KERN_INFO "GSI %d assigned vector 0x%02X and IRQ %d\n",
-+                      gsi, vector, i);
-+      return i;
-+}
-+
-+static int pin_2_irq(int idx, int apic, int pin)
-+{
-+      int irq, i;
-+      int bus = mp_irqs[idx].mpc_srcbus;
-+
-+      /*
-+       * Debugging check, we are in big trouble if this message pops up!
-+       */
-+      if (mp_irqs[idx].mpc_dstirq != pin)
-+              printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
-+
-+      switch (mp_bus_id_to_type[bus])
-+      {
-+              case MP_BUS_ISA: /* ISA pin */
-+              case MP_BUS_EISA:
-+              case MP_BUS_MCA:
-+              {
-+                      irq = mp_irqs[idx].mpc_srcbusirq;
-+                      break;
-+              }
-+              case MP_BUS_PCI: /* PCI pin */
-+              {
-+                      /*
-+                       * PCI IRQs are mapped in order
-+                       */
-+                      i = irq = 0;
-+                      while (i < apic)
-+                              irq += nr_ioapic_registers[i++];
-+                      irq += pin;
-+                      irq = gsi_irq_sharing(irq);
-+                      break;
-+              }
-+              default:
-+              {
-+                      printk(KERN_ERR "unknown bus type %d.\n",bus); 
-+                      irq = 0;
-+                      break;
-+              }
-+      }
-+      BUG_ON(irq >= NR_IRQS);
-+
-+      /*
-+       * PCI IRQ command line redirection. Yes, limits are hardcoded.
-+       */
-+      if ((pin >= 16) && (pin <= 23)) {
-+              if (pirq_entries[pin-16] != -1) {
-+                      if (!pirq_entries[pin-16]) {
-+                              apic_printk(APIC_VERBOSE, "disabling PIRQ%d\n", pin-16);
-+                      } else {
-+                              irq = pirq_entries[pin-16];
-+                              apic_printk(APIC_VERBOSE, "using PIRQ%d -> IRQ %d\n",
-+                                              pin-16, irq);
-+                      }
-+              }
-+      }
-+      BUG_ON(irq >= NR_IRQS);
-+      return irq;
-+}
-+
-+static inline int IO_APIC_irq_trigger(int irq)
-+{
-+      int apic, idx, pin;
-+
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+              for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-+                      idx = find_irq_entry(apic,pin,mp_INT);
-+                      if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin)))
-+                              return irq_trigger(idx);
-+              }
-+      }
-+      /*
-+       * nonexistent IRQs are edge default
-+       */
-+      return 0;
-+}
-+
-+/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-+u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
-+
-+int assign_irq_vector(int irq)
-+{
-+      struct physdev_irq irq_op;
-+  
-+      BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
-+      if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
-+              return IO_APIC_VECTOR(irq);
-+
-+      irq_op.irq = irq;
-+      if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
-+              return -ENOSPC;
-+
-+      vector_irq[irq_op.vector] = irq;
-+      if (irq != AUTO_ASSIGN)
-+              IO_APIC_VECTOR(irq) = irq_op.vector;
-+
-+      return irq_op.vector;
-+}
-+
-+extern void (*interrupt[NR_IRQS])(void);
-+#ifndef CONFIG_XEN
-+static struct hw_interrupt_type ioapic_level_type;
-+static struct hw_interrupt_type ioapic_edge_type;
-+
-+#define IOAPIC_AUTO   -1
-+#define IOAPIC_EDGE   0
-+#define IOAPIC_LEVEL  1
-+
-+static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger)
-+{
-+      if (use_pci_vector() && !platform_legacy_irq(irq)) {
-+              if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
-+                              trigger == IOAPIC_LEVEL)
-+                      irq_desc[vector].handler = &ioapic_level_type;
-+              else
-+                      irq_desc[vector].handler = &ioapic_edge_type;
-+              set_intr_gate(vector, interrupt[vector]);
-+      } else  {
-+              if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
-+                              trigger == IOAPIC_LEVEL)
-+                      irq_desc[irq].handler = &ioapic_level_type;
-+              else
-+                      irq_desc[irq].handler = &ioapic_edge_type;
-+              set_intr_gate(vector, interrupt[irq]);
-+      }
-+}
-+#else
-+#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0)
-+#endif /* !CONFIG_XEN */
-+
-+static void __init setup_IO_APIC_irqs(void)
-+{
-+      struct IO_APIC_route_entry entry;
-+      int apic, pin, idx, irq, first_notcon = 1, vector;
-+      unsigned long flags;
-+
-+      apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
-+
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+      for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-+
-+              /*
-+               * add it to the IO-APIC irq-routing table:
-+               */
-+              memset(&entry,0,sizeof(entry));
-+
-+              entry.delivery_mode = INT_DELIVERY_MODE;
-+              entry.dest_mode = INT_DEST_MODE;
-+              entry.mask = 0;                         /* enable IRQ */
-+              entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-+
-+              idx = find_irq_entry(apic,pin,mp_INT);
-+              if (idx == -1) {
-+                      if (first_notcon) {
-+                              apic_printk(APIC_VERBOSE, KERN_DEBUG " IO-APIC (apicid-pin) %d-%d", mp_ioapics[apic].mpc_apicid, pin);
-+                              first_notcon = 0;
-+                      } else
-+                              apic_printk(APIC_VERBOSE, ", %d-%d", mp_ioapics[apic].mpc_apicid, pin);
-+                      continue;
-+              }
-+
-+              entry.trigger = irq_trigger(idx);
-+              entry.polarity = irq_polarity(idx);
-+
-+              if (irq_trigger(idx)) {
-+                      entry.trigger = 1;
-+                      entry.mask = 1;
-+                      entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-+              }
-+
-+              irq = pin_2_irq(idx, apic, pin);
-+              add_pin_to_irq(irq, apic, pin);
-+
-+              if (/* !apic && */ !IO_APIC_IRQ(irq))
-+                      continue;
-+
-+              if (IO_APIC_IRQ(irq)) {
-+                      vector = assign_irq_vector(irq);
-+                      entry.vector = vector;
-+
-+                      ioapic_register_intr(irq, vector, IOAPIC_AUTO);
-+                      if (!apic && (irq < 16))
-+                              disable_8259A_irq(irq);
-+              }
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
-+              io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
-+              set_native_irq_info(irq, TARGET_CPUS);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+      }
-+      }
-+
-+      if (!first_notcon)
-+              apic_printk(APIC_VERBOSE," not connected.\n");
-+}
-+
-+#ifndef CONFIG_XEN
-+/*
-+ * Set up the 8259A-master output pin as broadcast to all
-+ * CPUs.
-+ */
-+static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
-+{
-+      struct IO_APIC_route_entry entry;
-+      unsigned long flags;
-+
-+      memset(&entry,0,sizeof(entry));
-+
-+      disable_8259A_irq(0);
-+
-+      /* mask LVT0 */
-+      apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
-+
-+      /*
-+       * We use logical delivery to get the timer IRQ
-+       * to the first CPU.
-+       */
-+      entry.dest_mode = INT_DEST_MODE;
-+      entry.mask = 0;                                 /* unmask IRQ now */
-+      entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-+      entry.delivery_mode = INT_DELIVERY_MODE;
-+      entry.polarity = 0;
-+      entry.trigger = 0;
-+      entry.vector = vector;
-+
-+      /*
-+       * The timer IRQ doesn't have to know that behind the
-+       * scene we have a 8259A-master in AEOI mode ...
-+       */
-+      irq_desc[0].handler = &ioapic_edge_type;
-+
-+      /*
-+       * Add it to the IO-APIC irq-routing table:
-+       */
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
-+      io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      enable_8259A_irq(0);
-+}
-+
-+void __init UNEXPECTED_IO_APIC(void)
-+{
-+}
-+
-+void __apicdebuginit print_IO_APIC(void)
-+{
-+      int apic, i;
-+      union IO_APIC_reg_00 reg_00;
-+      union IO_APIC_reg_01 reg_01;
-+      union IO_APIC_reg_02 reg_02;
-+      unsigned long flags;
-+
-+      if (apic_verbosity == APIC_QUIET)
-+              return;
-+
-+      printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
-+      for (i = 0; i < nr_ioapics; i++)
-+              printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
-+                     mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]);
-+
-+      /*
-+       * We are a bit conservative about what we expect.  We have to
-+       * know about every hardware change ASAP.
-+       */
-+      printk(KERN_INFO "testing the IO APIC.......................\n");
-+
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_00.raw = io_apic_read(apic, 0);
-+      reg_01.raw = io_apic_read(apic, 1);
-+      if (reg_01.bits.version >= 0x10)
-+              reg_02.raw = io_apic_read(apic, 2);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      printk("\n");
-+      printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
-+      printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
-+      printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
-+      if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2)
-+              UNEXPECTED_IO_APIC();
-+
-+      printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)&reg_01);
-+      printk(KERN_DEBUG ".......     : max redirection entries: %04X\n", reg_01.bits.entries);
-+      if (    (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */
-+              (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */
-+              (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */
-+              (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */
-+              (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */
-+              (reg_01.bits.entries != 0x2E) &&
-+              (reg_01.bits.entries != 0x3F) &&
-+              (reg_01.bits.entries != 0x03) 
-+      )
-+              UNEXPECTED_IO_APIC();
-+
-+      printk(KERN_DEBUG ".......     : PRQ implemented: %X\n", reg_01.bits.PRQ);
-+      printk(KERN_DEBUG ".......     : IO APIC version: %04X\n", reg_01.bits.version);
-+      if (    (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */
-+              (reg_01.bits.version != 0x02) && /* 82801BA IO-APICs (ICH2) */
-+              (reg_01.bits.version != 0x10) && /* oldest IO-APICs */
-+              (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */
-+              (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */
-+              (reg_01.bits.version != 0x20)    /* Intel P64H (82806 AA) */
-+      )
-+              UNEXPECTED_IO_APIC();
-+      if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2)
-+              UNEXPECTED_IO_APIC();
-+
-+      if (reg_01.bits.version >= 0x10) {
-+              printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
-+              printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.bits.arbitration);
-+              if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2)
-+                      UNEXPECTED_IO_APIC();
-+      }
-+
-+      printk(KERN_DEBUG ".... IRQ redirection table:\n");
-+
-+      printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
-+                        " Stat Dest Deli Vect:   \n");
-+
-+      for (i = 0; i <= reg_01.bits.entries; i++) {
-+              struct IO_APIC_route_entry entry;
-+
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2);
-+              *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+              printk(KERN_DEBUG " %02x %03X %02X  ",
-+                      i,
-+                      entry.dest.logical.logical_dest,
-+                      entry.dest.physical.physical_dest
-+              );
-+
-+              printk("%1d    %1d    %1d   %1d   %1d    %1d    %1d    %02X\n",
-+                      entry.mask,
-+                      entry.trigger,
-+                      entry.irr,
-+                      entry.polarity,
-+                      entry.delivery_status,
-+                      entry.dest_mode,
-+                      entry.delivery_mode,
-+                      entry.vector
-+              );
-+      }
-+      }
-+      if (use_pci_vector())
-+              printk(KERN_INFO "Using vector-based indexing\n");
-+      printk(KERN_DEBUG "IRQ to pin mappings:\n");
-+      for (i = 0; i < NR_IRQS; i++) {
-+              struct irq_pin_list *entry = irq_2_pin + i;
-+              if (entry->pin < 0)
-+                      continue;
-+              if (use_pci_vector() && !platform_legacy_irq(i))
-+                      printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
-+              else
-+                      printk(KERN_DEBUG "IRQ%d ", i);
-+              for (;;) {
-+                      printk("-> %d:%d", entry->apic, entry->pin);
-+                      if (!entry->next)
-+                              break;
-+                      entry = irq_2_pin + entry->next;
-+              }
-+              printk("\n");
-+      }
-+
-+      printk(KERN_INFO ".................................... done.\n");
-+
-+      return;
-+}
-+
-+#if 0
-+
-+static __apicdebuginit void print_APIC_bitfield (int base)
-+{
-+      unsigned int v;
-+      int i, j;
-+
-+      if (apic_verbosity == APIC_QUIET)
-+              return;
-+
-+      printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
-+      for (i = 0; i < 8; i++) {
-+              v = apic_read(base + i*0x10);
-+              for (j = 0; j < 32; j++) {
-+                      if (v & (1<<j))
-+                              printk("1");
-+                      else
-+                              printk("0");
-+              }
-+              printk("\n");
-+      }
-+}
-+
-+void __apicdebuginit print_local_APIC(void * dummy)
-+{
-+      unsigned int v, ver, maxlvt;
-+
-+      if (apic_verbosity == APIC_QUIET)
-+              return;
-+
-+      printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
-+              smp_processor_id(), hard_smp_processor_id());
-+      v = apic_read(APIC_ID);
-+      printk(KERN_INFO "... APIC ID:      %08x (%01x)\n", v, GET_APIC_ID(v));
-+      v = apic_read(APIC_LVR);
-+      printk(KERN_INFO "... APIC VERSION: %08x\n", v);
-+      ver = GET_APIC_VERSION(v);
-+      maxlvt = get_maxlvt();
-+
-+      v = apic_read(APIC_TASKPRI);
-+      printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
-+
-+      v = apic_read(APIC_ARBPRI);
-+      printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
-+              v & APIC_ARBPRI_MASK);
-+      v = apic_read(APIC_PROCPRI);
-+      printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
-+
-+      v = apic_read(APIC_EOI);
-+      printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
-+      v = apic_read(APIC_RRR);
-+      printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
-+      v = apic_read(APIC_LDR);
-+      printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
-+      v = apic_read(APIC_DFR);
-+      printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
-+      v = apic_read(APIC_SPIV);
-+      printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
-+
-+      printk(KERN_DEBUG "... APIC ISR field:\n");
-+      print_APIC_bitfield(APIC_ISR);
-+      printk(KERN_DEBUG "... APIC TMR field:\n");
-+      print_APIC_bitfield(APIC_TMR);
-+      printk(KERN_DEBUG "... APIC IRR field:\n");
-+      print_APIC_bitfield(APIC_IRR);
-+
-+      v = apic_read(APIC_ESR);
-+      printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
-+
-+      v = apic_read(APIC_ICR);
-+      printk(KERN_DEBUG "... APIC ICR: %08x\n", v);
-+      v = apic_read(APIC_ICR2);
-+      printk(KERN_DEBUG "... APIC ICR2: %08x\n", v);
-+
-+      v = apic_read(APIC_LVTT);
-+      printk(KERN_DEBUG "... APIC LVTT: %08x\n", v);
-+
-+      if (maxlvt > 3) {                       /* PC is LVT#4. */
-+              v = apic_read(APIC_LVTPC);
-+              printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v);
-+      }
-+      v = apic_read(APIC_LVT0);
-+      printk(KERN_DEBUG "... APIC LVT0: %08x\n", v);
-+      v = apic_read(APIC_LVT1);
-+      printk(KERN_DEBUG "... APIC LVT1: %08x\n", v);
-+
-+      if (maxlvt > 2) {                       /* ERR is LVT#3. */
-+              v = apic_read(APIC_LVTERR);
-+              printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v);
-+      }
-+
-+      v = apic_read(APIC_TMICT);
-+      printk(KERN_DEBUG "... APIC TMICT: %08x\n", v);
-+      v = apic_read(APIC_TMCCT);
-+      printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
-+      v = apic_read(APIC_TDCR);
-+      printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
-+      printk("\n");
-+}
-+
-+void print_all_local_APICs (void)
-+{
-+      on_each_cpu(print_local_APIC, NULL, 1, 1);
-+}
-+
-+void __apicdebuginit print_PIC(void)
-+{
-+      unsigned int v;
-+      unsigned long flags;
-+
-+      if (apic_verbosity == APIC_QUIET)
-+              return;
-+
-+      printk(KERN_DEBUG "\nprinting PIC contents\n");
-+
-+      spin_lock_irqsave(&i8259A_lock, flags);
-+
-+      v = inb(0xa1) << 8 | inb(0x21);
-+      printk(KERN_DEBUG "... PIC  IMR: %04x\n", v);
-+
-+      v = inb(0xa0) << 8 | inb(0x20);
-+      printk(KERN_DEBUG "... PIC  IRR: %04x\n", v);
-+
-+      outb(0x0b,0xa0);
-+      outb(0x0b,0x20);
-+      v = inb(0xa0) << 8 | inb(0x20);
-+      outb(0x0a,0xa0);
-+      outb(0x0a,0x20);
-+
-+      spin_unlock_irqrestore(&i8259A_lock, flags);
-+
-+      printk(KERN_DEBUG "... PIC  ISR: %04x\n", v);
-+
-+      v = inb(0x4d1) << 8 | inb(0x4d0);
-+      printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
-+}
-+
-+#endif  /*  0  */
-+
-+#else
-+void __init print_IO_APIC(void) { }
-+#endif /* !CONFIG_XEN */
-+
-+static void __init enable_IO_APIC(void)
-+{
-+      union IO_APIC_reg_01 reg_01;
-+#ifndef CONFIG_XEN
-+      int i8259_apic, i8259_pin;
-+#endif
-+      int i, apic;
-+      unsigned long flags;
-+
-+      for (i = 0; i < PIN_MAP_SIZE; i++) {
-+              irq_2_pin[i].pin = -1;
-+              irq_2_pin[i].next = 0;
-+      }
-+      if (!pirqs_enabled)
-+              for (i = 0; i < MAX_PIRQS; i++)
-+                      pirq_entries[i] = -1;
-+
-+      /*
-+       * The number of IO-APIC IRQ registers (== #pins):
-+       */
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              reg_01.raw = io_apic_read(apic, 1);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+              nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-+      }
-+#ifndef CONFIG_XEN
-+      for(apic = 0; apic < nr_ioapics; apic++) {
-+              int pin;
-+              /* See if any of the pins is in ExtINT mode */
-+              for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-+                      struct IO_APIC_route_entry entry;
-+                      spin_lock_irqsave(&ioapic_lock, flags);
-+                      *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
-+                      *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
-+                      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+
-+                      /* If the interrupt line is enabled and in ExtInt mode
-+                       * I have found the pin where the i8259 is connected.
-+                       */
-+                      if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
-+                              ioapic_i8259.apic = apic;
-+                              ioapic_i8259.pin  = pin;
-+                              goto found_i8259;
-+                      }
-+              }
-+      }
-+ found_i8259:
-+      /* Look to see what if the MP table has reported the ExtINT */
-+      i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
-+      i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
-+      /* Trust the MP table if nothing is setup in the hardware */
-+      if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
-+              printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
-+              ioapic_i8259.pin  = i8259_pin;
-+              ioapic_i8259.apic = i8259_apic;
-+      }
-+      /* Complain if the MP table and the hardware disagree */
-+      if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
-+              (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
-+      {
-+              printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
-+      }
-+#endif
-+
-+      /*
-+       * Do not trust the IO-APIC being empty at bootup
-+       */
-+      clear_IO_APIC();
-+}
-+
-+/*
-+ * Not an __init, needed by the reboot code
-+ */
-+void disable_IO_APIC(void)
-+{
-+      /*
-+       * Clear the IO-APIC before rebooting:
-+       */
-+      clear_IO_APIC();
-+
-+#ifndef CONFIG_XEN
-+      /*
-+       * If the i8259 is routed through an IOAPIC
-+       * Put that IOAPIC in virtual wire mode
-+       * so legacy interrupts can be delivered.
-+       */
-+      if (ioapic_i8259.pin != -1) {
-+              struct IO_APIC_route_entry entry;
-+              unsigned long flags;
-+
-+              memset(&entry, 0, sizeof(entry));
-+              entry.mask            = 0; /* Enabled */
-+              entry.trigger         = 0; /* Edge */
-+              entry.irr             = 0;
-+              entry.polarity        = 0; /* High */
-+              entry.delivery_status = 0;
-+              entry.dest_mode       = 0; /* Physical */
-+              entry.delivery_mode   = dest_ExtINT; /* ExtInt */
-+              entry.vector          = 0;
-+              entry.dest.physical.physical_dest =
-+                                      GET_APIC_ID(apic_read(APIC_ID));
-+
-+              /*
-+               * Add it to the IO-APIC irq-routing table:
-+               */
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
-+                      *(((int *)&entry)+1));
-+              io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
-+                      *(((int *)&entry)+0));
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+      }
-+
-+      disconnect_bsp_APIC(ioapic_i8259.pin != -1);
-+#endif
-+}
-+
-+/*
-+ * function to set the IO-APIC physical IDs based on the
-+ * values stored in the MPC table.
-+ *
-+ * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
-+ */
-+
-+#ifndef CONFIG_XEN
-+static void __init setup_ioapic_ids_from_mpc (void)
-+{
-+      union IO_APIC_reg_00 reg_00;
-+      int apic;
-+      int i;
-+      unsigned char old_id;
-+      unsigned long flags;
-+
-+      /*
-+       * Set the IOAPIC ID to the value stored in the MPC table.
-+       */
-+      for (apic = 0; apic < nr_ioapics; apic++) {
-+
-+              /* Read the register 0 value */
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              reg_00.raw = io_apic_read(apic, 0);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+              
-+              old_id = mp_ioapics[apic].mpc_apicid;
-+
-+
-+              printk(KERN_INFO "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid);
-+
-+
-+              /*
-+               * We need to adjust the IRQ routing table
-+               * if the ID changed.
-+               */
-+              if (old_id != mp_ioapics[apic].mpc_apicid)
-+                      for (i = 0; i < mp_irq_entries; i++)
-+                              if (mp_irqs[i].mpc_dstapic == old_id)
-+                                      mp_irqs[i].mpc_dstapic
-+                                              = mp_ioapics[apic].mpc_apicid;
-+
-+              /*
-+               * Read the right value from the MPC table and
-+               * write it into the ID register.
-+               */
-+              apic_printk(APIC_VERBOSE,KERN_INFO "...changing IO-APIC physical APIC ID to %d ...",
-+                              mp_ioapics[apic].mpc_apicid);
-+
-+              reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              io_apic_write(apic, 0, reg_00.raw);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+              /*
-+               * Sanity check
-+               */
-+              spin_lock_irqsave(&ioapic_lock, flags);
-+              reg_00.raw = io_apic_read(apic, 0);
-+              spin_unlock_irqrestore(&ioapic_lock, flags);
-+              if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid)
-+                      printk("could not set ID!\n");
-+              else
-+                      apic_printk(APIC_VERBOSE," ok.\n");
-+      }
-+}
-+#else
-+static void __init setup_ioapic_ids_from_mpc(void) { }
-+#endif
-+
-+/*
-+ * There is a nasty bug in some older SMP boards, their mptable lies
-+ * about the timer IRQ. We do the following to work around the situation:
-+ *
-+ *    - timer IRQ defaults to IO-APIC IRQ
-+ *    - if this function detects that timer IRQs are defunct, then we fall
-+ *      back to ISA timer IRQs
-+ */
-+#ifndef CONFIG_XEN
-+static int __init timer_irq_works(void)
-+{
-+      unsigned long t1 = jiffies;
-+
-+      local_irq_enable();
-+      /* Let ten ticks pass... */
-+      mdelay((10 * 1000) / HZ);
-+
-+      /*
-+       * Expect a few ticks at least, to be sure some possible
-+       * glue logic does not lock up after one or two first
-+       * ticks in a non-ExtINT mode.  Also the local APIC
-+       * might have cached one ExtINT interrupt.  Finally, at
-+       * least one tick may be lost due to delays.
-+       */
-+
-+      /* jiffies wrap? */
-+      if (jiffies - t1 > 4)
-+              return 1;
-+      return 0;
-+}
-+
-+/*
-+ * In the SMP+IOAPIC case it might happen that there are an unspecified
-+ * number of pending IRQ events unhandled. These cases are very rare,
-+ * so we 'resend' these IRQs via IPIs, to the same CPU. It's much
-+ * better to do it this way as thus we do not have to be aware of
-+ * 'pending' interrupts in the IRQ path, except at this point.
-+ */
-+/*
-+ * Edge triggered needs to resend any interrupt
-+ * that was delayed but this is now handled in the device
-+ * independent code.
-+ */
-+
-+/*
-+ * Starting up a edge-triggered IO-APIC interrupt is
-+ * nasty - we need to make sure that we get the edge.
-+ * If it is already asserted for some reason, we need
-+ * return 1 to indicate that is was pending.
-+ *
-+ * This is not complete - we should be able to fake
-+ * an edge even if it isn't on the 8259A...
-+ */
-+
-+static unsigned int startup_edge_ioapic_irq(unsigned int irq)
-+{
-+      int was_pending = 0;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      if (irq < 16) {
-+              disable_8259A_irq(irq);
-+              if (i8259A_irq_pending(irq))
-+                      was_pending = 1;
-+      }
-+      __unmask_IO_APIC_irq(irq);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return was_pending;
-+}
-+
-+/*
-+ * Once we have recorded IRQ_PENDING already, we can mask the
-+ * interrupt for real. This prevents IRQ storms from unhandled
-+ * devices.
-+ */
-+static void ack_edge_ioapic_irq(unsigned int irq)
-+{
-+      move_irq(irq);
-+      if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
-+                                      == (IRQ_PENDING | IRQ_DISABLED))
-+              mask_IO_APIC_irq(irq);
-+      ack_APIC_irq();
-+}
-+
-+/*
-+ * Level triggered interrupts can just be masked,
-+ * and shutting down and starting up the interrupt
-+ * is the same as enabling and disabling them -- except
-+ * with a startup need to return a "was pending" value.
-+ *
-+ * Level triggered interrupts are special because we
-+ * do not touch any IO-APIC register while handling
-+ * them. We ack the APIC in the end-IRQ handler, not
-+ * in the start-IRQ-handler. Protection against reentrance
-+ * from the same interrupt is still provided, both by the
-+ * generic IRQ layer and by the fact that an unacked local
-+ * APIC does not accept IRQs.
-+ */
-+static unsigned int startup_level_ioapic_irq (unsigned int irq)
-+{
-+      unmask_IO_APIC_irq(irq);
-+
-+      return 0; /* don't check for pending */
-+}
-+
-+static void end_level_ioapic_irq (unsigned int irq)
-+{
-+      move_irq(irq);
-+      ack_APIC_irq();
-+}
-+
-+#ifdef CONFIG_PCI_MSI
-+static unsigned int startup_edge_ioapic_vector(unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      return startup_edge_ioapic_irq(irq);
-+}
-+
-+static void ack_edge_ioapic_vector(unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      move_native_irq(vector);
-+      ack_edge_ioapic_irq(irq);
-+}
-+
-+static unsigned int startup_level_ioapic_vector (unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      return startup_level_ioapic_irq (irq);
-+}
-+
-+static void end_level_ioapic_vector (unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      move_native_irq(vector);
-+      end_level_ioapic_irq(irq);
-+}
-+
-+static void mask_IO_APIC_vector (unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      mask_IO_APIC_irq(irq);
-+}
-+
-+static void unmask_IO_APIC_vector (unsigned int vector)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      unmask_IO_APIC_irq(irq);
-+}
-+
-+#ifdef CONFIG_SMP
-+static void set_ioapic_affinity_vector (unsigned int vector,
-+                                      cpumask_t cpu_mask)
-+{
-+      int irq = vector_to_irq(vector);
-+
-+      set_native_irq_info(vector, cpu_mask);
-+      set_ioapic_affinity_irq(irq, cpu_mask);
-+}
-+#endif // CONFIG_SMP
-+#endif // CONFIG_PCI_MSI
-+
-+/*
-+ * Level and edge triggered IO-APIC interrupts need different handling,
-+ * so we use two separate IRQ descriptors. Edge triggered IRQs can be
-+ * handled with the level-triggered descriptor, but that one has slightly
-+ * more overhead. Level-triggered interrupts cannot be handled with the
-+ * edge-triggered handler, without risking IRQ storms and other ugly
-+ * races.
-+ */
-+
-+static struct hw_interrupt_type ioapic_edge_type __read_mostly = {
-+      .typename = "IO-APIC-edge",
-+      .startup        = startup_edge_ioapic,
-+      .shutdown       = shutdown_edge_ioapic,
-+      .enable         = enable_edge_ioapic,
-+      .disable        = disable_edge_ioapic,
-+      .ack            = ack_edge_ioapic,
-+      .end            = end_edge_ioapic,
-+#ifdef CONFIG_SMP
-+      .set_affinity = set_ioapic_affinity,
-+#endif
-+};
-+
-+static struct hw_interrupt_type ioapic_level_type __read_mostly = {
-+      .typename = "IO-APIC-level",
-+      .startup        = startup_level_ioapic,
-+      .shutdown       = shutdown_level_ioapic,
-+      .enable         = enable_level_ioapic,
-+      .disable        = disable_level_ioapic,
-+      .ack            = mask_and_ack_level_ioapic,
-+      .end            = end_level_ioapic,
-+#ifdef CONFIG_SMP
-+      .set_affinity = set_ioapic_affinity,
-+#endif
-+};
-+#endif /* !CONFIG_XEN */
-+
-+static inline void init_IO_APIC_traps(void)
-+{
-+      int irq;
-+
-+      /*
-+       * NOTE! The local APIC isn't very good at handling
-+       * multiple interrupts at the same interrupt level.
-+       * As the interrupt level is determined by taking the
-+       * vector number and shifting that right by 4, we
-+       * want to spread these out a bit so that they don't
-+       * all fall in the same interrupt level.
-+       *
-+       * Also, we've got to be careful not to trash gate
-+       * 0x80, because int 0x80 is hm, kind of importantish. ;)
-+       */
-+      for (irq = 0; irq < NR_IRQS ; irq++) {
-+              int tmp = irq;
-+              if (use_pci_vector()) {
-+                      if (!platform_legacy_irq(tmp))
-+                              if ((tmp = vector_to_irq(tmp)) == -1)
-+                                      continue;
-+              }
-+              if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
-+                      /*
-+                       * Hmm.. We don't have an entry for this,
-+                       * so default to an old-fashioned 8259
-+                       * interrupt if we can..
-+                       */
-+                      if (irq < 16)
-+                              make_8259A_irq(irq);
-+#ifndef CONFIG_XEN
-+                      else
-+                              /* Strange. Oh, well.. */
-+                              irq_desc[irq].handler = &no_irq_type;
-+#endif
-+              }
-+      }
-+}
-+
-+#ifndef CONFIG_XEN
-+static void enable_lapic_irq (unsigned int irq)
-+{
-+      unsigned long v;
-+
-+      v = apic_read(APIC_LVT0);
-+      apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
-+}
-+
-+static void disable_lapic_irq (unsigned int irq)
-+{
-+      unsigned long v;
-+
-+      v = apic_read(APIC_LVT0);
-+      apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
-+}
-+
-+static void ack_lapic_irq (unsigned int irq)
-+{
-+      ack_APIC_irq();
-+}
-+
-+static void end_lapic_irq (unsigned int i) { /* nothing */ }
-+
-+static struct hw_interrupt_type lapic_irq_type __read_mostly = {
-+      .typename = "local-APIC-edge",
-+      .startup = NULL, /* startup_irq() not used for IRQ0 */
-+      .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */
-+      .enable = enable_lapic_irq,
-+      .disable = disable_lapic_irq,
-+      .ack = ack_lapic_irq,
-+      .end = end_lapic_irq,
-+};
-+
-+static void setup_nmi (void)
-+{
-+      /*
-+       * Dirty trick to enable the NMI watchdog ...
-+       * We put the 8259A master into AEOI mode and
-+       * unmask on all local APICs LVT0 as NMI.
-+       *
-+       * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
-+       * is from Maciej W. Rozycki - so we do not have to EOI from
-+       * the NMI handler or the timer interrupt.
-+       */ 
-+      printk(KERN_INFO "activating NMI Watchdog ...");
-+
-+      enable_NMI_through_LVT0(NULL);
-+
-+      printk(" done.\n");
-+}
-+
-+/*
-+ * This looks a bit hackish but it's about the only one way of sending
-+ * a few INTA cycles to 8259As and any associated glue logic.  ICR does
-+ * not support the ExtINT mode, unfortunately.  We need to send these
-+ * cycles as some i82489DX-based boards have glue logic that keeps the
-+ * 8259A interrupt line asserted until INTA.  --macro
-+ */
-+static inline void unlock_ExtINT_logic(void)
-+{
-+      int apic, pin, i;
-+      struct IO_APIC_route_entry entry0, entry1;
-+      unsigned char save_control, save_freq_select;
-+      unsigned long flags;
-+
-+      pin  = find_isa_irq_pin(8, mp_INT);
-+      apic = find_isa_irq_apic(8, mp_INT);
-+      if (pin == -1)
-+              return;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
-+      *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+      clear_IO_APIC_pin(apic, pin);
-+
-+      memset(&entry1, 0, sizeof(entry1));
-+
-+      entry1.dest_mode = 0;                   /* physical delivery */
-+      entry1.mask = 0;                        /* unmask IRQ now */
-+      entry1.dest.physical.physical_dest = hard_smp_processor_id();
-+      entry1.delivery_mode = dest_ExtINT;
-+      entry1.polarity = entry0.polarity;
-+      entry1.trigger = 0;
-+      entry1.vector = 0;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
-+      io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      save_control = CMOS_READ(RTC_CONTROL);
-+      save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
-+      CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6,
-+                 RTC_FREQ_SELECT);
-+      CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL);
-+
-+      i = 100;
-+      while (i-- > 0) {
-+              mdelay(10);
-+              if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF)
-+                      i -= 10;
-+      }
-+
-+      CMOS_WRITE(save_control, RTC_CONTROL);
-+      CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-+      clear_IO_APIC_pin(apic, pin);
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
-+      io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+}
-+
-+/*
-+ * This code may look a bit paranoid, but it's supposed to cooperate with
-+ * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
-+ * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
-+ * fanatically on his truly buggy board.
-+ *
-+ * FIXME: really need to revamp this for modern platforms only.
-+ */
-+static inline void check_timer(void)
-+{
-+      int apic1, pin1, apic2, pin2;
-+      int vector;
-+
-+      /*
-+       * get/set the timer IRQ vector:
-+       */
-+      disable_8259A_irq(0);
-+      vector = assign_irq_vector(0);
-+      set_intr_gate(vector, interrupt[0]);
-+
-+      /*
-+       * Subtle, code in do_timer_interrupt() expects an AEOI
-+       * mode for the 8259A whenever interrupts are routed
-+       * through I/O APICs.  Also IRQ0 has to be enabled in
-+       * the 8259A which implies the virtual wire has to be
-+       * disabled in the local APIC.
-+       */
-+      apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
-+      init_8259A(1);
-+      if (timer_over_8254 > 0)
-+              enable_8259A_irq(0);
-+
-+      pin1  = find_isa_irq_pin(0, mp_INT);
-+      apic1 = find_isa_irq_apic(0, mp_INT);
-+      pin2  = ioapic_i8259.pin;
-+      apic2 = ioapic_i8259.apic;
-+
-+      apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
-+              vector, apic1, pin1, apic2, pin2);
-+
-+      if (pin1 != -1) {
-+              /*
-+               * Ok, does IRQ0 through the IOAPIC work?
-+               */
-+              unmask_IO_APIC_irq(0);
-+              if (!no_timer_check && timer_irq_works()) {
-+                      nmi_watchdog_default();
-+                      if (nmi_watchdog == NMI_IO_APIC) {
-+                              disable_8259A_irq(0);
-+                              setup_nmi();
-+                              enable_8259A_irq(0);
-+                      }
-+                      if (disable_timer_pin_1 > 0)
-+                              clear_IO_APIC_pin(0, pin1);
-+                      return;
-+              }
-+              clear_IO_APIC_pin(apic1, pin1);
-+              apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: 8254 timer not "
-+                              "connected to IO-APIC\n");
-+      }
-+
-+      apic_printk(APIC_VERBOSE,KERN_INFO "...trying to set up timer (IRQ0) "
-+                              "through the 8259A ... ");
-+      if (pin2 != -1) {
-+              apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...",
-+                      apic2, pin2);
-+              /*
-+               * legacy devices should be connected to IO APIC #0
-+               */
-+              setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
-+              if (timer_irq_works()) {
-+                      printk("works.\n");
-+                      nmi_watchdog_default();
-+                      if (nmi_watchdog == NMI_IO_APIC) {
-+                              setup_nmi();
-+                      }
-+                      return;
-+              }
-+              /*
-+               * Cleanup, just in case ...
-+               */
-+              clear_IO_APIC_pin(apic2, pin2);
-+      }
-+      printk(" failed.\n");
-+
-+      if (nmi_watchdog == NMI_IO_APIC) {
-+              printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
-+              nmi_watchdog = 0;
-+      }
-+
-+      apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
-+
-+      disable_8259A_irq(0);
-+      irq_desc[0].handler = &lapic_irq_type;
-+      apic_write(APIC_LVT0, APIC_DM_FIXED | vector);  /* Fixed mode */
-+      enable_8259A_irq(0);
-+
-+      if (timer_irq_works()) {
-+              apic_printk(APIC_QUIET, " works.\n");
-+              return;
-+      }
-+      apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
-+      apic_printk(APIC_VERBOSE," failed.\n");
-+
-+      apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as ExtINT IRQ...");
-+
-+      init_8259A(0);
-+      make_8259A_irq(0);
-+      apic_write(APIC_LVT0, APIC_DM_EXTINT);
-+
-+      unlock_ExtINT_logic();
-+
-+      if (timer_irq_works()) {
-+              apic_printk(APIC_VERBOSE," works.\n");
-+              return;
-+      }
-+      apic_printk(APIC_VERBOSE," failed :(.\n");
-+      panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n");
-+}
-+#else
-+#define check_timer() ((void)0)
-+#endif /* !CONFIG_XEN */
-+
-+static int __init notimercheck(char *s)
-+{
-+      no_timer_check = 1;
-+      return 1;
-+}
-+__setup("no_timer_check", notimercheck);
-+
-+/*
-+ *
-+ * IRQ's that are handled by the PIC in the MPS IOAPIC case.
-+ * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
-+ *   Linux doesn't really care, as it's not actually used
-+ *   for any interrupt handling anyway.
-+ */
-+#define PIC_IRQS      (1<<2)
-+
-+void __init setup_IO_APIC(void)
-+{
-+      enable_IO_APIC();
-+
-+      if (acpi_ioapic)
-+              io_apic_irqs = ~0;      /* all IRQs go through IOAPIC */
-+      else
-+              io_apic_irqs = ~PIC_IRQS;
-+
-+      apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
-+
-+      /*
-+       * Set up the IO-APIC IRQ routing table.
-+       */
-+      if (!acpi_ioapic)
-+              setup_ioapic_ids_from_mpc();
-+#ifndef CONFIG_XEN
-+      sync_Arb_IDs();
-+#endif /* !CONFIG_XEN */
-+      setup_IO_APIC_irqs();
-+      init_IO_APIC_traps();
-+      check_timer();
-+      if (!acpi_ioapic)
-+              print_IO_APIC();
-+}
-+
-+struct sysfs_ioapic_data {
-+      struct sys_device dev;
-+      struct IO_APIC_route_entry entry[0];
-+};
-+static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
-+
-+static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
-+{
-+      struct IO_APIC_route_entry *entry;
-+      struct sysfs_ioapic_data *data;
-+      unsigned long flags;
-+      int i;
-+
-+      data = container_of(dev, struct sysfs_ioapic_data, dev);
-+      entry = data->entry;
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
-+              *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i);
-+              *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i);
-+      }
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int ioapic_resume(struct sys_device *dev)
-+{
-+      struct IO_APIC_route_entry *entry;
-+      struct sysfs_ioapic_data *data;
-+      unsigned long flags;
-+      union IO_APIC_reg_00 reg_00;
-+      int i;
-+
-+      data = container_of(dev, struct sysfs_ioapic_data, dev);
-+      entry = data->entry;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_00.raw = io_apic_read(dev->id, 0);
-+      if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) {
-+              reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
-+              io_apic_write(dev->id, 0, reg_00.raw);
-+      }
-+      for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
-+              io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1));
-+              io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0));
-+      }
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return 0;
-+}
-+
-+static struct sysdev_class ioapic_sysdev_class = {
-+      set_kset_name("ioapic"),
-+      .suspend = ioapic_suspend,
-+      .resume = ioapic_resume,
-+};
-+
-+static int __init ioapic_init_sysfs(void)
-+{
-+      struct sys_device * dev;
-+      int i, size, error = 0;
-+
-+      error = sysdev_class_register(&ioapic_sysdev_class);
-+      if (error)
-+              return error;
-+
-+      for (i = 0; i < nr_ioapics; i++ ) {
-+              size = sizeof(struct sys_device) + nr_ioapic_registers[i]
-+                      * sizeof(struct IO_APIC_route_entry);
-+              mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL);
-+              if (!mp_ioapic_data[i]) {
-+                      printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
-+                      continue;
-+              }
-+              memset(mp_ioapic_data[i], 0, size);
-+              dev = &mp_ioapic_data[i]->dev;
-+              dev->id = i;
-+              dev->cls = &ioapic_sysdev_class;
-+              error = sysdev_register(dev);
-+              if (error) {
-+                      kfree(mp_ioapic_data[i]);
-+                      mp_ioapic_data[i] = NULL;
-+                      printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
-+                      continue;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+device_initcall(ioapic_init_sysfs);
-+
-+/* --------------------------------------------------------------------------
-+                          ACPI-based IOAPIC Configuration
-+   -------------------------------------------------------------------------- */
-+
-+#ifdef CONFIG_ACPI
-+
-+#define IO_APIC_MAX_ID                0xFE
-+
-+int __init io_apic_get_version (int ioapic)
-+{
-+      union IO_APIC_reg_01    reg_01;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_01.raw = io_apic_read(ioapic, 1);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return reg_01.bits.version;
-+}
-+
-+
-+int __init io_apic_get_redir_entries (int ioapic)
-+{
-+      union IO_APIC_reg_01    reg_01;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      reg_01.raw = io_apic_read(ioapic, 1);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return reg_01.bits.entries;
-+}
-+
-+
-+int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low)
-+{
-+      struct IO_APIC_route_entry entry;
-+      unsigned long flags;
-+
-+      if (!IO_APIC_IRQ(irq)) {
-+              apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
-+                      ioapic);
-+              return -EINVAL;
-+      }
-+
-+      /*
-+       * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
-+       * Note that we mask (disable) IRQs now -- these get enabled when the
-+       * corresponding device driver registers for this IRQ.
-+       */
-+
-+      memset(&entry,0,sizeof(entry));
-+
-+      entry.delivery_mode = INT_DELIVERY_MODE;
-+      entry.dest_mode = INT_DEST_MODE;
-+      entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
-+      entry.trigger = edge_level;
-+      entry.polarity = active_high_low;
-+      entry.mask = 1;                                  /* Disabled (masked) */
-+
-+      irq = gsi_irq_sharing(irq);
-+      /*
-+       * IRQs < 16 are already in the irq_2_pin[] map
-+       */
-+      if (irq >= 16)
-+              add_pin_to_irq(irq, ioapic, pin);
-+
-+      entry.vector = assign_irq_vector(irq);
-+
-+      apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
-+              "IRQ %d Mode:%i Active:%i)\n", ioapic, 
-+             mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
-+             edge_level, active_high_low);
-+
-+      ioapic_register_intr(irq, entry.vector, edge_level);
-+
-+      if (!ioapic && (irq < 16))
-+              disable_8259A_irq(irq);
-+
-+      spin_lock_irqsave(&ioapic_lock, flags);
-+      io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
-+      io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
-+      set_native_irq_info(use_pci_vector() ?  entry.vector : irq, TARGET_CPUS);
-+      spin_unlock_irqrestore(&ioapic_lock, flags);
-+
-+      return 0;
-+}
-+
-+#endif /* CONFIG_ACPI */
-+
-+
-+#ifndef CONFIG_XEN
-+/*
-+ * This function currently is only a helper for the i386 smp boot process where
-+ * we need to reprogram the ioredtbls to cater for the cpus which have come online
-+ * so mask in all cases should simply be TARGET_CPUS
-+ */
-+#ifdef CONFIG_SMP
-+void __init setup_ioapic_dest(void)
-+{
-+      int pin, ioapic, irq, irq_entry;
-+
-+      if (skip_ioapic_setup == 1)
-+              return;
-+
-+      for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
-+              for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
-+                      irq_entry = find_irq_entry(ioapic, pin, mp_INT);
-+                      if (irq_entry == -1)
-+                              continue;
-+                      irq = pin_2_irq(irq_entry, ioapic, pin);
-+                      set_ioapic_affinity_irq(irq, TARGET_CPUS);
-+              }
-+
-+      }
-+}
-+#endif
-+#endif /* !CONFIG_XEN */
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/ioport-xen.c linux-2.6.16.33/arch/x86_64/kernel/ioport-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/ioport-xen.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/ioport-xen.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,99 @@
-+/*
-+ *    linux/arch/x86_64/kernel/ioport.c
-+ *
-+ * This contains the io-permission bitmap code - written by obz, with changes
-+ * by Linus.
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/capability.h>
-+#include <linux/errno.h>
-+#include <linux/types.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/stddef.h>
-+#include <linux/slab.h>
-+#include <linux/thread_info.h>
-+#include <xen/interface/physdev.h>
-+
-+/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
-+static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
-+{
-+      int i;
-+
-+      if (new_value)
-+              for (i = base; i < base + extent; i++)
-+                      __set_bit(i, bitmap);
-+      else
-+              for (i = base; i < base + extent; i++)
-+                      clear_bit(i, bitmap);
-+}
-+
-+/*
-+ * this changes the io permissions bitmap in the current task.
-+ */
-+asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
-+{
-+      struct thread_struct * t = &current->thread;
-+      unsigned long *bitmap;
-+      struct physdev_set_iobitmap set_iobitmap;
-+
-+      if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
-+              return -EINVAL;
-+      if (turn_on && !capable(CAP_SYS_RAWIO))
-+              return -EPERM;
-+
-+      /*
-+       * If it's the first ioperm() call in this thread's lifetime, set the
-+       * IO bitmap up. ioperm() is much less timing critical than clone(),
-+       * this is why we delay this operation until now:
-+       */
-+      if (!t->io_bitmap_ptr) {
-+              bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
-+              if (!bitmap)
-+                      return -ENOMEM;
-+
-+              memset(bitmap, 0xff, IO_BITMAP_BYTES);
-+              t->io_bitmap_ptr = bitmap;
-+
-+              set_iobitmap.bitmap   = (char *)bitmap;
-+              set_iobitmap.nr_ports = IO_BITMAP_BITS;
-+              HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
-+      }
-+
-+      set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
-+
-+      return 0;
-+}
-+
-+/*
-+ * sys_iopl has to be used when you want to access the IO ports
-+ * beyond the 0x3ff range: to get the full 65536 ports bitmapped
-+ * you'd need 8kB of bitmaps/process, which is a bit excessive.
-+ *
-+ */
-+
-+asmlinkage long sys_iopl(unsigned int new_iopl, struct pt_regs *regs)
-+{
-+      unsigned int old_iopl = current->thread.iopl;
-+      struct physdev_set_iopl set_iopl;
-+
-+      if (new_iopl > 3)
-+              return -EINVAL;
-+
-+      /* Need "raw I/O" privileges for direct port access. */
-+      if ((new_iopl > old_iopl) && !capable(CAP_SYS_RAWIO))
-+              return -EPERM;
-+
-+      /* Change our version of the privilege levels. */
-+      current->thread.iopl = new_iopl;
-+
-+      /* Force the change at ring 0. */
-+      set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
-+      HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
-+
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/irq-xen.c linux-2.6.16.33/arch/x86_64/kernel/irq-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/irq-xen.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/irq-xen.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,168 @@
-+/*
-+ *    linux/arch/x86_64/kernel/irq.c
-+ *
-+ *    Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
-+ *
-+ * This file contains the lowest level x86_64-specific interrupt
-+ * entry and irq statistics code. All the remaining irq logic is
-+ * done by the generic kernel/irq/ code and in the
-+ * x86_64-specific irq controller code. (e.g. i8259.c and
-+ * io_apic.c.)
-+ */
-+
-+#include <linux/kernel_stat.h>
-+#include <linux/interrupt.h>
-+#include <linux/seq_file.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <asm/uaccess.h>
-+#include <asm/io_apic.h>
-+#include <asm/idle.h>
-+
-+atomic_t irq_err_count;
-+#ifdef CONFIG_X86_IO_APIC
-+#ifdef APIC_MISMATCH_DEBUG
-+atomic_t irq_mis_count;
-+#endif
-+#endif
-+
-+/*
-+ * Generic, controller-independent functions:
-+ */
-+
-+int show_interrupts(struct seq_file *p, void *v)
-+{
-+      int i = *(loff_t *) v, j;
-+      struct irqaction * action;
-+      unsigned long flags;
-+
-+      if (i == 0) {
-+              seq_printf(p, "           ");
-+              for (j=0; j<NR_CPUS; j++)
-+                      if (cpu_online(j))
-+                              seq_printf(p, "CPU%d       ",j);
-+              seq_putc(p, '\n');
-+      }
-+
-+      if (i < NR_IRQS) {
-+              spin_lock_irqsave(&irq_desc[i].lock, flags);
-+              action = irq_desc[i].action;
-+              if (!action) 
-+                      goto skip;
-+              seq_printf(p, "%3d: ",i);
-+#ifndef CONFIG_SMP
-+              seq_printf(p, "%10u ", kstat_irqs(i));
-+#else
-+              for (j=0; j<NR_CPUS; j++)
-+                      if (cpu_online(j))
-+                      seq_printf(p, "%10u ",
-+                              kstat_cpu(j).irqs[i]);
-+#endif
-+              seq_printf(p, " %14s", irq_desc[i].handler->typename);
-+
-+              seq_printf(p, "  %s", action->name);
-+              for (action=action->next; action; action = action->next)
-+                      seq_printf(p, ", %s", action->name);
-+              seq_putc(p, '\n');
-+skip:
-+              spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-+      } else if (i == NR_IRQS) {
-+              seq_printf(p, "NMI: ");
-+              for (j = 0; j < NR_CPUS; j++)
-+                      if (cpu_online(j))
-+                              seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
-+              seq_putc(p, '\n');
-+#ifdef CONFIG_X86_LOCAL_APIC
-+              seq_printf(p, "LOC: ");
-+              for (j = 0; j < NR_CPUS; j++)
-+                      if (cpu_online(j))
-+                              seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
-+              seq_putc(p, '\n');
-+#endif
-+              seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-+#ifdef CONFIG_X86_IO_APIC
-+#ifdef APIC_MISMATCH_DEBUG
-+              seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
-+#endif
-+#endif
-+      }
-+      return 0;
-+}
-+
-+/*
-+ * do_IRQ handles all normal device IRQ's (the special
-+ * SMP cross-CPU interrupts have their own specific
-+ * handlers).
-+ */
-+asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
-+{     
-+      /* high bit used in ret_from_ code  */
-+      unsigned irq = ~regs->orig_rax;
-+
-+      exit_idle();
-+      irq_enter();
-+
-+      __do_IRQ(irq, regs);
-+      irq_exit();
-+
-+      return 1;
-+}
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+void fixup_irqs(cpumask_t map)
-+{
-+      unsigned int irq;
-+      static int warned;
-+
-+      for (irq = 0; irq < NR_IRQS; irq++) {
-+              cpumask_t mask;
-+              if (irq == 2)
-+                      continue;
-+
-+              cpus_and(mask, irq_affinity[irq], map);
-+              if (any_online_cpu(mask) == NR_CPUS) {
-+                      printk("Breaking affinity for irq %i\n", irq);
-+                      mask = map;
-+              }
-+              if (irq_desc[irq].handler->set_affinity)
-+                      irq_desc[irq].handler->set_affinity(irq, mask);
-+              else if (irq_desc[irq].action && !(warned++))
-+                      printk("Cannot set affinity for irq %i\n", irq);
-+      }
-+
-+      /* That doesn't seem sufficient.  Give it 1ms. */
-+      local_irq_enable();
-+      mdelay(1);
-+      local_irq_disable();
-+}
-+#endif
-+
-+extern void call_softirq(void);
-+
-+asmlinkage void do_softirq(void)
-+{
-+      __u32 pending;
-+      unsigned long flags;
-+
-+      if (in_interrupt())
-+              return;
-+
-+      local_irq_save(flags);
-+      pending = local_softirq_pending();
-+      /* Switch to interrupt stack */
-+      if (pending)
-+              call_softirq();
-+      local_irq_restore(flags);
-+}
-+EXPORT_SYMBOL(do_softirq);
-+
-+#ifndef CONFIG_X86_LOCAL_APIC
-+/*
-+ * 'what should we do if we get a hw irq event on an illegal vector'.
-+ * each architecture has to answer this themselves.
-+ */
-+void ack_bad_irq(unsigned int irq)
-+{
-+        printk("unexpected IRQ trap at vector %02x\n", irq);
-+}
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/irq.c linux-2.6.16.33/arch/x86_64/kernel/irq.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/irq.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/irq.c   2007-05-23 21:00:01.000000000 +0000
-@@ -96,8 +96,8 @@
-  */
- asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
- {     
--      /* high bits used in ret_from_ code  */
--      unsigned irq = regs->orig_rax & 0xff;
-+      /* high bit used in ret_from_ code  */
-+      unsigned irq = ~regs->orig_rax;
-       exit_idle();
-       irq_enter();
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/ldt-xen.c linux-2.6.16.33/arch/x86_64/kernel/ldt-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/ldt-xen.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/ldt-xen.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,282 @@
-+/*
-+ * linux/arch/x86_64/kernel/ldt.c
-+ *
-+ * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
-+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
-+ * Copyright (C) 2002 Andi Kleen
-+ * 
-+ * This handles calls from both 32bit and 64bit mode.
-+ */
-+
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/vmalloc.h>
-+#include <linux/slab.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <asm/ldt.h>
-+#include <asm/desc.h>
-+#include <asm/proto.h>
-+#include <asm/pgalloc.h>
-+
-+#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
-+static void flush_ldt(void *null)
-+{
-+      if (current->active_mm)
-+               load_LDT(&current->active_mm->context);
-+}
-+#endif
-+
-+static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
-+{
-+      void *oldldt;
-+      void *newldt;
-+      unsigned oldsize;
-+
-+      if (mincount <= (unsigned)pc->size)
-+              return 0;
-+      oldsize = pc->size;
-+      mincount = (mincount+511)&(~511);
-+      if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
-+              newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
-+      else
-+              newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
-+
-+      if (!newldt)
-+              return -ENOMEM;
-+
-+      if (oldsize)
-+              memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
-+      oldldt = pc->ldt;
-+      memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
-+      wmb();
-+      pc->ldt = newldt;
-+      wmb();
-+      pc->size = mincount;
-+      wmb();
-+      if (reload) {
-+#ifdef CONFIG_SMP
-+              cpumask_t mask;
-+
-+              preempt_disable();
-+#endif
-+              make_pages_readonly(
-+                      pc->ldt,
-+                      (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                      XENFEAT_writable_descriptor_tables);
-+              load_LDT(pc);
-+#ifdef CONFIG_SMP
-+              mask = cpumask_of_cpu(smp_processor_id());
-+              if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+                      smp_call_function(flush_ldt, NULL, 1, 1);
-+              preempt_enable();
-+#endif
-+      }
-+      if (oldsize) {
-+              make_pages_writable(
-+                      oldldt,
-+                      (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                      XENFEAT_writable_descriptor_tables);
-+              if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
-+                      vfree(oldldt);
-+              else
-+                      kfree(oldldt);
-+      }
-+      return 0;
-+}
-+
-+static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+{
-+      int err = alloc_ldt(new, old->size, 0);
-+      if (err < 0)
-+              return err;
-+      memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+      make_pages_readonly(
-+              new->ldt,
-+              (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+              XENFEAT_writable_descriptor_tables);
-+      return 0;
-+}
-+
-+/*
-+ * we do not have to muck with descriptors here, that is
-+ * done in switch_mm() as needed.
-+ */
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+      struct mm_struct * old_mm;
-+      int retval = 0;
-+
-+      memset(&mm->context, 0, sizeof(mm->context));
-+      init_MUTEX(&mm->context.sem);
-+      old_mm = current->mm;
-+      if (old_mm && old_mm->context.size > 0) {
-+              down(&old_mm->context.sem);
-+              retval = copy_ldt(&mm->context, &old_mm->context);
-+              up(&old_mm->context.sem);
-+      }
-+      if (retval == 0) {
-+              spin_lock(&mm_unpinned_lock);
-+              list_add(&mm->context.unpinned, &mm_unpinned);
-+              spin_unlock(&mm_unpinned_lock);
-+      }
-+      return retval;
-+}
-+
-+/*
-+ * 
-+ * Don't touch the LDT register - we're already in the next thread.
-+ */
-+void destroy_context(struct mm_struct *mm)
-+{
-+      if (mm->context.size) {
-+              if (mm == current->active_mm)
-+                      clear_LDT();
-+              make_pages_writable(
-+                      mm->context.ldt,
-+                      (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE,
-+                      XENFEAT_writable_descriptor_tables);
-+              if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
-+                      vfree(mm->context.ldt);
-+              else
-+                      kfree(mm->context.ldt);
-+              mm->context.size = 0;
-+      }
-+      if (!mm->context.pinned) {
-+              spin_lock(&mm_unpinned_lock);
-+              list_del(&mm->context.unpinned);
-+              spin_unlock(&mm_unpinned_lock);
-+      }
-+}
-+
-+static int read_ldt(void __user * ptr, unsigned long bytecount)
-+{
-+      int err;
-+      unsigned long size;
-+      struct mm_struct * mm = current->mm;
-+
-+      if (!mm->context.size)
-+              return 0;
-+      if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
-+              bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
-+
-+      down(&mm->context.sem);
-+      size = mm->context.size*LDT_ENTRY_SIZE;
-+      if (size > bytecount)
-+              size = bytecount;
-+
-+      err = 0;
-+      if (copy_to_user(ptr, mm->context.ldt, size))
-+              err = -EFAULT;
-+      up(&mm->context.sem);
-+      if (err < 0)
-+              goto error_return;
-+      if (size != bytecount) {
-+              /* zero-fill the rest */
-+              if (clear_user(ptr+size, bytecount-size) != 0) {
-+                      err = -EFAULT;
-+                      goto error_return;
-+              }
-+      }
-+      return bytecount;
-+error_return:
-+      return err;
-+}
-+
-+static int read_default_ldt(void __user * ptr, unsigned long bytecount)
-+{
-+      /* Arbitrary number */ 
-+      /* x86-64 default LDT is all zeros */
-+      if (bytecount > 128) 
-+              bytecount = 128;        
-+      if (clear_user(ptr, bytecount))
-+              return -EFAULT;
-+      return bytecount; 
-+}
-+
-+static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+{
-+      struct task_struct *me = current;
-+      struct mm_struct * mm = me->mm;
-+      __u32 entry_1, entry_2, *lp;
-+      unsigned long mach_lp;
-+      int error;
-+      struct user_desc ldt_info;
-+
-+      error = -EINVAL;
-+
-+      if (bytecount != sizeof(ldt_info))
-+              goto out;
-+      error = -EFAULT;        
-+      if (copy_from_user(&ldt_info, ptr, bytecount))
-+              goto out;
-+
-+      error = -EINVAL;
-+      if (ldt_info.entry_number >= LDT_ENTRIES)
-+              goto out;
-+      if (ldt_info.contents == 3) {
-+              if (oldmode)
-+                      goto out;
-+              if (ldt_info.seg_not_present == 0)
-+                      goto out;
-+      }
-+
-+      down(&mm->context.sem);
-+      if (ldt_info.entry_number >= (unsigned)mm->context.size) {
-+              error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+              if (error < 0)
-+                      goto out_unlock;
-+      }
-+
-+      lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
-+      mach_lp = arbitrary_virt_to_machine(lp);
-+
-+      /* Allow LDTs to be cleared by the user. */
-+      if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
-+              if (oldmode || LDT_empty(&ldt_info)) {
-+                      entry_1 = 0;
-+                      entry_2 = 0;
-+                      goto install;
-+              }
-+      }
-+
-+      entry_1 = LDT_entry_a(&ldt_info);
-+      entry_2 = LDT_entry_b(&ldt_info);
-+      if (oldmode)
-+              entry_2 &= ~(1 << 20);
-+
-+      /* Install the new entry ...  */
-+install:
-+      error = HYPERVISOR_update_descriptor(mach_lp, (unsigned long)((entry_1 | (unsigned long) entry_2 << 32)));
-+
-+out_unlock:
-+      up(&mm->context.sem);
-+out:
-+      return error;
-+}
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+      int ret = -ENOSYS;
-+
-+      switch (func) {
-+      case 0:
-+              ret = read_ldt(ptr, bytecount);
-+              break;
-+      case 1:
-+              ret = write_ldt(ptr, bytecount, 1);
-+              break;
-+      case 2:
-+              ret = read_default_ldt(ptr, bytecount);
-+              break;
-+      case 0x11:
-+              ret = write_ldt(ptr, bytecount, 0);
-+              break;
-+      }
-+      return ret;
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/machine_kexec.c linux-2.6.16.33/arch/x86_64/kernel/machine_kexec.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/machine_kexec.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/machine_kexec.c 2007-01-08 15:00:45.000000000 +0000
-@@ -15,6 +15,113 @@
- #include <asm/mmu_context.h>
- #include <asm/io.h>
-+#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
-+static u64 kexec_pgd[512] PAGE_ALIGNED;
-+static u64 kexec_pud0[512] PAGE_ALIGNED;
-+static u64 kexec_pmd0[512] PAGE_ALIGNED;
-+static u64 kexec_pte0[512] PAGE_ALIGNED;
-+static u64 kexec_pud1[512] PAGE_ALIGNED;
-+static u64 kexec_pmd1[512] PAGE_ALIGNED;
-+static u64 kexec_pte1[512] PAGE_ALIGNED;
-+
-+#ifdef CONFIG_XEN
-+
-+/* In the case of Xen, override hypervisor functions to be able to create
-+ * a regular identity mapping page table...
-+ */
-+
-+#include <xen/interface/kexec.h>
-+#include <xen/interface/memory.h>
-+
-+#define x__pmd(x) ((pmd_t) { (x) } )
-+#define x__pud(x) ((pud_t) { (x) } )
-+#define x__pgd(x) ((pgd_t) { (x) } )
-+
-+#define x_pmd_val(x)   ((x).pmd)
-+#define x_pud_val(x)   ((x).pud)
-+#define x_pgd_val(x)   ((x).pgd)
-+
-+static inline void x_set_pmd(pmd_t *dst, pmd_t val)
-+{
-+      x_pmd_val(*dst) = x_pmd_val(val);
-+}
-+
-+static inline void x_set_pud(pud_t *dst, pud_t val)
-+{
-+      x_pud_val(*dst) = phys_to_machine(x_pud_val(val));
-+}
-+
-+static inline void x_pud_clear (pud_t *pud)
-+{
-+      x_pud_val(*pud) = 0;
-+}
-+
-+static inline void x_set_pgd(pgd_t *dst, pgd_t val)
-+{
-+      x_pgd_val(*dst) = phys_to_machine(x_pgd_val(val));
-+}
-+
-+static inline void x_pgd_clear (pgd_t * pgd)
-+{
-+      x_pgd_val(*pgd) = 0;
-+}
-+
-+#define X__PAGE_KERNEL_LARGE_EXEC \
-+         _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_PSE
-+#define X_KERNPG_TABLE _PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY
-+
-+#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT)
-+
-+#if PAGES_NR > KEXEC_XEN_NO_PAGES
-+#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break
-+#endif
-+
-+#if PA_CONTROL_PAGE != 0
-+#error PA_CONTROL_PAGE is non zero - Xen support will break
-+#endif
-+
-+void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
-+{
-+      void *control_page;
-+      void *table_page;
-+
-+      memset(xki->page_list, 0, sizeof(xki->page_list));
-+
-+      control_page = page_address(image->control_code_page) + PAGE_SIZE;
-+      memcpy(control_page, relocate_kernel, PAGE_SIZE);
-+
-+      table_page = page_address(image->control_code_page);
-+
-+      xki->page_list[PA_CONTROL_PAGE] = __ma(control_page);
-+      xki->page_list[PA_TABLE_PAGE] = __ma(table_page);
-+
-+      xki->page_list[PA_PGD] = __ma(kexec_pgd);
-+      xki->page_list[PA_PUD_0] = __ma(kexec_pud0);
-+      xki->page_list[PA_PUD_1] = __ma(kexec_pud1);
-+      xki->page_list[PA_PMD_0] = __ma(kexec_pmd0);
-+      xki->page_list[PA_PMD_1] = __ma(kexec_pmd1);
-+      xki->page_list[PA_PTE_0] = __ma(kexec_pte0);
-+      xki->page_list[PA_PTE_1] = __ma(kexec_pte1);
-+}
-+
-+#else /* CONFIG_XEN */
-+
-+#define x__pmd(x) __pmd(x)
-+#define x__pud(x) __pud(x)
-+#define x__pgd(x) __pgd(x)
-+
-+#define x_set_pmd(x, y) set_pmd(x, y)
-+#define x_set_pud(x, y) set_pud(x, y)
-+#define x_set_pgd(x, y) set_pgd(x, y)
-+
-+#define x_pud_clear(x) pud_clear(x)
-+#define x_pgd_clear(x) pgd_clear(x)
-+
-+#define X__PAGE_KERNEL_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
-+#define X_KERNPG_TABLE _KERNPG_TABLE
-+
-+#endif /* CONFIG_XEN */
-+
- static void init_level2_page(pmd_t *level2p, unsigned long addr)
- {
-       unsigned long end_addr;
-@@ -22,7 +129,7 @@
-       addr &= PAGE_MASK;
-       end_addr = addr + PUD_SIZE;
-       while (addr < end_addr) {
--              set_pmd(level2p++, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
-+              x_set_pmd(level2p++, x__pmd(addr | X__PAGE_KERNEL_LARGE_EXEC));
-               addr += PMD_SIZE;
-       }
- }
-@@ -47,12 +154,12 @@
-               }
-               level2p = (pmd_t *)page_address(page);
-               init_level2_page(level2p, addr);
--              set_pud(level3p++, __pud(__pa(level2p) | _KERNPG_TABLE));
-+              x_set_pud(level3p++, x__pud(__pa(level2p) | X_KERNPG_TABLE));
-               addr += PUD_SIZE;
-       }
-       /* clear the unused entries */
-       while (addr < end_addr) {
--              pud_clear(level3p++);
-+              x_pud_clear(level3p++);
-               addr += PUD_SIZE;
-       }
- out:
-@@ -83,12 +190,12 @@
-               if (result) {
-                       goto out;
-               }
--              set_pgd(level4p++, __pgd(__pa(level3p) | _KERNPG_TABLE));
-+              x_set_pgd(level4p++, x__pgd(__pa(level3p) | X_KERNPG_TABLE));
-               addr += PGDIR_SIZE;
-       }
-       /* clear the unused entries */
-       while (addr < end_addr) {
--              pgd_clear(level4p++);
-+              x_pgd_clear(level4p++);
-               addr += PGDIR_SIZE;
-       }
- out:
-@@ -99,77 +206,29 @@
- static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
- {
-       pgd_t *level4p;
--      level4p = (pgd_t *)__va(start_pgtable);
--      return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT);
--}
--
--static void set_idt(void *newidt, u16 limit)
--{
--      struct desc_ptr curidt;
-+      unsigned long x_end_pfn = end_pfn;
--      /* x86-64 supports unaliged loads & stores */
--      curidt.size    = limit;
--      curidt.address = (unsigned long)newidt;
-+#ifdef CONFIG_XEN
-+      x_end_pfn = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
-+#endif
--      __asm__ __volatile__ (
--              "lidtq %0\n"
--              : : "m" (curidt)
--              );
--};
--
--
--static void set_gdt(void *newgdt, u16 limit)
--{
--      struct desc_ptr curgdt;
--
--      /* x86-64 supports unaligned loads & stores */
--      curgdt.size    = limit;
--      curgdt.address = (unsigned long)newgdt;
--
--      __asm__ __volatile__ (
--              "lgdtq %0\n"
--              : : "m" (curgdt)
--              );
--};
--
--static void load_segments(void)
--{
--      __asm__ __volatile__ (
--              "\tmovl %0,%%ds\n"
--              "\tmovl %0,%%es\n"
--              "\tmovl %0,%%ss\n"
--              "\tmovl %0,%%fs\n"
--              "\tmovl %0,%%gs\n"
--              : : "a" (__KERNEL_DS) : "memory"
--              );
-+      level4p = (pgd_t *)__va(start_pgtable);
-+      return init_level4_page(image, level4p, 0, x_end_pfn << PAGE_SHIFT);
- }
--typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page,
--                                      unsigned long control_code_buffer,
--                                      unsigned long start_address,
--                                      unsigned long pgtable) ATTRIB_NORET;
--
--const extern unsigned char relocate_new_kernel[];
--const extern unsigned long relocate_new_kernel_size;
--
- int machine_kexec_prepare(struct kimage *image)
- {
--      unsigned long start_pgtable, control_code_buffer;
-+      unsigned long start_pgtable;
-       int result;
-       /* Calculate the offsets */
-       start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
--      control_code_buffer = start_pgtable + PAGE_SIZE;
-       /* Setup the identity mapped 64bit page table */
-       result = init_pgtable(image, start_pgtable);
-       if (result)
-               return result;
--      /* Place the code in the reboot code buffer */
--      memcpy(__va(control_code_buffer), relocate_new_kernel,
--                                              relocate_new_kernel_size);
--
-       return 0;
- }
-@@ -178,54 +237,43 @@
-       return;
- }
-+#ifndef CONFIG_XEN
- /*
-  * Do not allocate memory (or fail in any way) in machine_kexec().
-  * We are past the point of no return, committed to rebooting now.
-  */
- NORET_TYPE void machine_kexec(struct kimage *image)
- {
--      unsigned long page_list;
--      unsigned long control_code_buffer;
--      unsigned long start_pgtable;
--      relocate_new_kernel_t rnk;
-+      unsigned long page_list[PAGES_NR];
-+      void *control_page;
-       /* Interrupts aren't acceptable while we reboot */
-       local_irq_disable();
--      /* Calculate the offsets */
--      page_list = image->head;
--      start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
--      control_code_buffer = start_pgtable + PAGE_SIZE;
-+      control_page = page_address(image->control_code_page) + PAGE_SIZE;
-+      memcpy(control_page, relocate_kernel, PAGE_SIZE);
-+
-+      page_list[PA_CONTROL_PAGE] = __pa(control_page);
-+      page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
-+      page_list[PA_PGD] = __pa(kexec_pgd);
-+      page_list[VA_PGD] = (unsigned long)kexec_pgd;
-+      page_list[PA_PUD_0] = __pa(kexec_pud0);
-+      page_list[VA_PUD_0] = (unsigned long)kexec_pud0;
-+      page_list[PA_PMD_0] = __pa(kexec_pmd0);
-+      page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
-+      page_list[PA_PTE_0] = __pa(kexec_pte0);
-+      page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
-+      page_list[PA_PUD_1] = __pa(kexec_pud1);
-+      page_list[VA_PUD_1] = (unsigned long)kexec_pud1;
-+      page_list[PA_PMD_1] = __pa(kexec_pmd1);
-+      page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
-+      page_list[PA_PTE_1] = __pa(kexec_pte1);
-+      page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
-+
-+      page_list[PA_TABLE_PAGE] =
-+        (unsigned long)__pa(page_address(image->control_code_page));
--      /* Set the low half of the page table to my identity mapped
--       * page table for kexec.  Leave the high half pointing at the
--       * kernel pages.   Don't bother to flush the global pages
--       * as that will happen when I fully switch to my identity mapped
--       * page table anyway.
--       */
--      memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2);
--      __flush_tlb();
--
--
--      /* The segment registers are funny things, they are
--       * automatically loaded from a table, in memory wherever you
--       * set them to a specific selector, but this table is never
--       * accessed again unless you set the segment to a different selector.
--       *
--       * The more common model are caches where the behide
--       * the scenes work is done, but is also dropped at arbitrary
--       * times.
--       *
--       * I take advantage of this here by force loading the
--       * segments, before I zap the gdt with an invalid value.
--       */
--      load_segments();
--      /* The gdt & idt are now invalid.
--       * If you want to load them you must set up your own idt & gdt.
--       */
--      set_gdt(phys_to_virt(0),0);
--      set_idt(phys_to_virt(0),0);
--      /* now call it */
--      rnk = (relocate_new_kernel_t) control_code_buffer;
--      (*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
-+      relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
-+                      image->start);
- }
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/machine_kexec.c~ linux-2.6.16.33/arch/x86_64/kernel/machine_kexec.c~
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/machine_kexec.c~  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/machine_kexec.c~        2007-05-23 21:00:01.000000000 +0000
-@@ -0,0 +1,228 @@
-+/*
-+ * machine_kexec.c - handle transition of Linux booting another kernel
-+ * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
-+ *
-+ * This source code is licensed under the GNU General Public License,
-+ * Version 2.  See the file COPYING for more details.
-+ */
-+
-+#include <linux/mm.h>
-+#include <linux/kexec.h>
-+#include <linux/string.h>
-+#include <linux/reboot.h>
-+#include <asm/pgtable.h>
-+#include <asm/tlbflush.h>
-+#include <asm/mmu_context.h>
-+#include <asm/io.h>
-+
-+static void init_level2_page(pmd_t *level2p, unsigned long addr)
-+{
-+      unsigned long end_addr;
-+
-+      addr &= PAGE_MASK;
-+      end_addr = addr + PUD_SIZE;
-+      while (addr < end_addr) {
-+              set_pmd(level2p++, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
-+              addr += PMD_SIZE;
-+      }
-+}
-+
-+static int init_level3_page(struct kimage *image, pud_t *level3p,
-+                              unsigned long addr, unsigned long last_addr)
-+{
-+      unsigned long end_addr;
-+      int result;
-+
-+      result = 0;
-+      addr &= PAGE_MASK;
-+      end_addr = addr + PGDIR_SIZE;
-+      while ((addr < last_addr) && (addr < end_addr)) {
-+              struct page *page;
-+              pmd_t *level2p;
-+
-+              page = kimage_alloc_control_pages(image, 0);
-+              if (!page) {
-+                      result = -ENOMEM;
-+                      goto out;
-+              }
-+              level2p = (pmd_t *)page_address(page);
-+              init_level2_page(level2p, addr);
-+              set_pud(level3p++, __pud(__pa(level2p) | _KERNPG_TABLE));
-+              addr += PUD_SIZE;
-+      }
-+      /* clear the unused entries */
-+      while (addr < end_addr) {
-+              pud_clear(level3p++);
-+              addr += PUD_SIZE;
-+      }
-+out:
-+      return result;
-+}
-+
-+
-+static int init_level4_page(struct kimage *image, pgd_t *level4p,
-+                              unsigned long addr, unsigned long last_addr)
-+{
-+      unsigned long end_addr;
-+      int result;
-+
-+      result = 0;
-+      addr &= PAGE_MASK;
-+      end_addr = addr + (PTRS_PER_PGD * PGDIR_SIZE);
-+      while ((addr < last_addr) && (addr < end_addr)) {
-+              struct page *page;
-+              pud_t *level3p;
-+
-+              page = kimage_alloc_control_pages(image, 0);
-+              if (!page) {
-+                      result = -ENOMEM;
-+                      goto out;
-+              }
-+              level3p = (pud_t *)page_address(page);
-+              result = init_level3_page(image, level3p, addr, last_addr);
-+              if (result) {
-+                      goto out;
-+              }
-+              set_pgd(level4p++, __pgd(__pa(level3p) | _KERNPG_TABLE));
-+              addr += PGDIR_SIZE;
-+      }
-+      /* clear the unused entries */
-+      while (addr < end_addr) {
-+              pgd_clear(level4p++);
-+              addr += PGDIR_SIZE;
-+      }
-+out:
-+      return result;
-+}
-+
-+
-+static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
-+{
-+      pgd_t *level4p;
-+      level4p = (pgd_t *)__va(start_pgtable);
-+      return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT);
-+}
-+
-+static void set_idt(void *newidt, u16 limit)
-+{
-+      struct desc_ptr curidt;
-+
-+      /* x86-64 supports unaliged loads & stores */
-+      curidt.size    = limit;
-+      curidt.address = (unsigned long)newidt;
-+
-+      __asm__ __volatile__ (
-+              "lidtq %0\n"
-+              : : "m" (curidt)
-+              );
-+};
-+
-+
-+static void set_gdt(void *newgdt, u16 limit)
-+{
-+      struct desc_ptr curgdt;
-+
-+      /* x86-64 supports unaligned loads & stores */
-+      curgdt.size    = limit;
-+      curgdt.address = (unsigned long)newgdt;
-+
-+      __asm__ __volatile__ (
-+              "lgdtq %0\n"
-+              : : "m" (curgdt)
-+              );
-+};
-+
-+static void load_segments(void)
-+{
-+      __asm__ __volatile__ (
-+              "\tmovl %0,%%ds\n"
-+              "\tmovl %0,%%es\n"
-+              "\tmovl %0,%%ss\n"
-+              "\tmovl %0,%%fs\n"
-+              "\tmovl %0,%%gs\n"
-+              : : "a" (__KERNEL_DS) : "memory"
-+              );
-+}
-+
-+typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page,
-+                                      unsigned long control_code_buffer,
-+                                      unsigned long start_address,
-+                                      unsigned long pgtable) ATTRIB_NORET;
-+
-+extern const unsigned char relocate_new_kernel[];
-+extern const unsigned long relocate_new_kernel_size;
-+
-+int machine_kexec_prepare(struct kimage *image)
-+{
-+      unsigned long start_pgtable, control_code_buffer;
-+      int result;
-+
-+      /* Calculate the offsets */
-+      start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
-+      control_code_buffer = start_pgtable + PAGE_SIZE;
-+
-+      /* Setup the identity mapped 64bit page table */
-+      result = init_pgtable(image, start_pgtable);
-+      if (result)
-+              return result;
-+
-+      /* Place the code in the reboot code buffer */
-+      memcpy(__va(control_code_buffer), relocate_new_kernel,
-+                                              relocate_new_kernel_size);
-+
-+      return 0;
-+}
-+
-+void machine_kexec_cleanup(struct kimage *image)
-+{
-+      return;
-+}
-+
-+/*
-+ * Do not allocate memory (or fail in any way) in machine_kexec().
-+ * We are past the point of no return, committed to rebooting now.
-+ */
-+NORET_TYPE void machine_kexec(struct kimage *image)
-+{
-+      unsigned long page_list;
-+      unsigned long control_code_buffer;
-+      unsigned long start_pgtable;
-+      relocate_new_kernel_t rnk;
-+
-+      /* Interrupts aren't acceptable while we reboot */
-+      local_irq_disable();
-+
-+      /* Calculate the offsets */
-+      page_list = image->head;
-+      start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
-+      control_code_buffer = start_pgtable + PAGE_SIZE;
-+
-+      /* Set the low half of the page table to my identity mapped
-+       * page table for kexec.  Leave the high half pointing at the
-+       * kernel pages.   Don't bother to flush the global pages
-+       * as that will happen when I fully switch to my identity mapped
-+       * page table anyway.
-+       */
-+      memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2);
-+      __flush_tlb();
-+
-+
-+      /* The segment registers are funny things, they have both a
-+       * visible and an invisible part.  Whenever the visible part is
-+       * set to a specific selector, the invisible part is loaded
-+       * with from a table in memory.  At no other time is the
-+       * descriptor table in memory accessed.
-+       *
-+       * I take advantage of this here by force loading the
-+       * segments, before I zap the gdt with an invalid value.
-+       */
-+      load_segments();
-+      /* The gdt & idt are now invalid.
-+       * If you want to load them you must set up your own idt & gdt.
-+       */
-+      set_gdt(phys_to_virt(0),0);
-+      set_idt(phys_to_virt(0),0);
-+      /* now call it */
-+      rnk = (relocate_new_kernel_t) control_code_buffer;
-+      (*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/mpparse-xen.c linux-2.6.16.33/arch/x86_64/kernel/mpparse-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/mpparse-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/mpparse-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1005 @@
-+/*
-+ *    Intel Multiprocessor Specification 1.1 and 1.4
-+ *    compliant MP-table parsing routines.
-+ *
-+ *    (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
-+ *    (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
-+ *
-+ *    Fixes
-+ *            Erich Boleyn    :       MP v1.4 and additional changes.
-+ *            Alan Cox        :       Added EBDA scanning
-+ *            Ingo Molnar     :       various cleanups and rewrites
-+ *            Maciej W. Rozycki:      Bits for default MP configurations
-+ *            Paul Diefenbaugh:       Added full ACPI support
-+ */
-+
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/config.h>
-+#include <linux/bootmem.h>
-+#include <linux/smp_lock.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/acpi.h>
-+#include <linux/module.h>
-+
-+#include <asm/smp.h>
-+#include <asm/mtrr.h>
-+#include <asm/mpspec.h>
-+#include <asm/pgalloc.h>
-+#include <asm/io_apic.h>
-+#include <asm/proto.h>
-+#include <asm/acpi.h>
-+
-+/* Have we found an MP table */
-+int smp_found_config;
-+unsigned int __initdata maxcpus = NR_CPUS;
-+
-+int acpi_found_madt;
-+
-+/*
-+ * Various Linux-internal data structures created from the
-+ * MP-table.
-+ */
-+unsigned char apic_version [MAX_APICS];
-+unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
-+int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
-+
-+static int mp_current_pci_id = 0;
-+/* I/O APIC entries */
-+struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
-+
-+/* # of MP IRQ source entries */
-+struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
-+
-+/* MP IRQ source entries */
-+int mp_irq_entries;
-+
-+int nr_ioapics;
-+int pic_mode;
-+unsigned long mp_lapic_addr = 0;
-+
-+
-+
-+/* Processor that is doing the boot up */
-+unsigned int boot_cpu_id = -1U;
-+/* Internal processor count */
-+unsigned int num_processors __initdata = 0;
-+
-+unsigned disabled_cpus __initdata;
-+
-+/* Bitmask of physically existing CPUs */
-+physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
-+
-+/* ACPI MADT entry parsing functions */
-+#ifdef CONFIG_ACPI
-+extern struct acpi_boot_flags acpi_boot;
-+#ifdef CONFIG_X86_LOCAL_APIC
-+extern int acpi_parse_lapic (acpi_table_entry_header *header);
-+extern int acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header);
-+extern int acpi_parse_lapic_nmi (acpi_table_entry_header *header);
-+#endif /*CONFIG_X86_LOCAL_APIC*/
-+#ifdef CONFIG_X86_IO_APIC
-+extern int acpi_parse_ioapic (acpi_table_entry_header *header);
-+#endif /*CONFIG_X86_IO_APIC*/
-+#endif /*CONFIG_ACPI*/
-+
-+u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-+
-+
-+/*
-+ * Intel MP BIOS table parsing routines:
-+ */
-+
-+/*
-+ * Checksum an MP configuration block.
-+ */
-+
-+static int __init mpf_checksum(unsigned char *mp, int len)
-+{
-+      int sum = 0;
-+
-+      while (len--)
-+              sum += *mp++;
-+
-+      return sum & 0xFF;
-+}
-+
-+#ifndef CONFIG_XEN
-+static void __init MP_processor_info (struct mpc_config_processor *m)
-+{
-+      int cpu;
-+      unsigned char ver;
-+      static int found_bsp=0;
-+
-+      if (!(m->mpc_cpuflag & CPU_ENABLED)) {
-+              disabled_cpus++;
-+              return;
-+      }
-+
-+      printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n",
-+              m->mpc_apicid,
-+             (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8,
-+             (m->mpc_cpufeature & CPU_MODEL_MASK)>>4,
-+              m->mpc_apicver);
-+
-+      if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
-+              Dprintk("    Bootup CPU\n");
-+              boot_cpu_id = m->mpc_apicid;
-+      }
-+      if (num_processors >= NR_CPUS) {
-+              printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
-+                      " Processor ignored.\n", NR_CPUS);
-+              return;
-+      }
-+
-+      cpu = num_processors++;
-+      
-+#if MAX_APICS < 255   
-+      if ((int)m->mpc_apicid > MAX_APICS) {
-+              printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
-+                      m->mpc_apicid, MAX_APICS);
-+              return;
-+      }
-+#endif
-+      ver = m->mpc_apicver;
-+
-+      physid_set(m->mpc_apicid, phys_cpu_present_map);
-+      /*
-+       * Validate version
-+       */
-+      if (ver == 0x0) {
-+              printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
-+              ver = 0x10;
-+      }
-+      apic_version[m->mpc_apicid] = ver;
-+      if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
-+              /*
-+               * bios_cpu_apicid is required to have processors listed
-+               * in same order as logical cpu numbers. Hence the first
-+               * entry is BSP, and so on.
-+               */
-+              cpu = 0;
-+
-+              bios_cpu_apicid[0] = m->mpc_apicid;
-+              x86_cpu_to_apicid[0] = m->mpc_apicid;
-+              found_bsp = 1;
-+      } else
-+              cpu = num_processors - found_bsp;
-+      bios_cpu_apicid[cpu] = m->mpc_apicid;
-+      x86_cpu_to_apicid[cpu] = m->mpc_apicid;
-+
-+      cpu_set(cpu, cpu_possible_map);
-+      cpu_set(cpu, cpu_present_map);
-+}
-+#else
-+void __init MP_processor_info (struct mpc_config_processor *m)
-+{
-+      num_processors++;
-+}
-+#endif /* CONFIG_XEN */
-+
-+static void __init MP_bus_info (struct mpc_config_bus *m)
-+{
-+      char str[7];
-+
-+      memcpy(str, m->mpc_bustype, 6);
-+      str[6] = 0;
-+      Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
-+
-+      if (strncmp(str, "ISA", 3) == 0) {
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
-+      } else if (strncmp(str, "EISA", 4) == 0) {
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
-+      } else if (strncmp(str, "PCI", 3) == 0) {
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
-+              mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
-+              mp_current_pci_id++;
-+      } else if (strncmp(str, "MCA", 3) == 0) {
-+              mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
-+      } else {
-+              printk(KERN_ERR "Unknown bustype %s\n", str);
-+      }
-+}
-+
-+static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
-+{
-+      if (!(m->mpc_flags & MPC_APIC_USABLE))
-+              return;
-+
-+      printk("I/O APIC #%d Version %d at 0x%X.\n",
-+              m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
-+      if (nr_ioapics >= MAX_IO_APICS) {
-+              printk(KERN_ERR "Max # of I/O APICs (%d) exceeded (found %d).\n",
-+                      MAX_IO_APICS, nr_ioapics);
-+              panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
-+      }
-+      if (!m->mpc_apicaddr) {
-+              printk(KERN_ERR "WARNING: bogus zero I/O APIC address"
-+                      " found in MP table, skipping!\n");
-+              return;
-+      }
-+      mp_ioapics[nr_ioapics] = *m;
-+      nr_ioapics++;
-+}
-+
-+static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
-+{
-+      mp_irqs [mp_irq_entries] = *m;
-+      Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
-+              " IRQ %02x, APIC ID %x, APIC INT %02x\n",
-+                      m->mpc_irqtype, m->mpc_irqflag & 3,
-+                      (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
-+                      m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
-+      if (++mp_irq_entries >= MAX_IRQ_SOURCES)
-+              panic("Max # of irq sources exceeded!!\n");
-+}
-+
-+static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
-+{
-+      Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
-+              " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
-+                      m->mpc_irqtype, m->mpc_irqflag & 3,
-+                      (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
-+                      m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
-+      /*
-+       * Well it seems all SMP boards in existence
-+       * use ExtINT/LVT1 == LINT0 and
-+       * NMI/LVT2 == LINT1 - the following check
-+       * will show us if this assumptions is false.
-+       * Until then we do not have to add baggage.
-+       */
-+      if ((m->mpc_irqtype == mp_ExtINT) &&
-+              (m->mpc_destapiclint != 0))
-+                      BUG();
-+      if ((m->mpc_irqtype == mp_NMI) &&
-+              (m->mpc_destapiclint != 1))
-+                      BUG();
-+}
-+
-+/*
-+ * Read/parse the MPC
-+ */
-+
-+static int __init smp_read_mpc(struct mp_config_table *mpc)
-+{
-+      char str[16];
-+      int count=sizeof(*mpc);
-+      unsigned char *mpt=((unsigned char *)mpc)+count;
-+
-+      if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
-+              printk("SMP mptable: bad signature [%c%c%c%c]!\n",
-+                      mpc->mpc_signature[0],
-+                      mpc->mpc_signature[1],
-+                      mpc->mpc_signature[2],
-+                      mpc->mpc_signature[3]);
-+              return 0;
-+      }
-+      if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
-+              printk("SMP mptable: checksum error!\n");
-+              return 0;
-+      }
-+      if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
-+              printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n",
-+                      mpc->mpc_spec);
-+              return 0;
-+      }
-+      if (!mpc->mpc_lapic) {
-+              printk(KERN_ERR "SMP mptable: null local APIC address!\n");
-+              return 0;
-+      }
-+      memcpy(str,mpc->mpc_oem,8);
-+      str[8]=0;
-+      printk(KERN_INFO "OEM ID: %s ",str);
-+
-+      memcpy(str,mpc->mpc_productid,12);
-+      str[12]=0;
-+      printk("Product ID: %s ",str);
-+
-+      printk("APIC at: 0x%X\n",mpc->mpc_lapic);
-+
-+      /* save the local APIC address, it might be non-default */
-+      if (!acpi_lapic)
-+      mp_lapic_addr = mpc->mpc_lapic;
-+
-+      /*
-+       *      Now process the configuration blocks.
-+       */
-+      while (count < mpc->mpc_length) {
-+              switch(*mpt) {
-+                      case MP_PROCESSOR:
-+                      {
-+                              struct mpc_config_processor *m=
-+                                      (struct mpc_config_processor *)mpt;
-+                              if (!acpi_lapic)
-+                              MP_processor_info(m);
-+                              mpt += sizeof(*m);
-+                              count += sizeof(*m);
-+                              break;
-+                      }
-+                      case MP_BUS:
-+                      {
-+                              struct mpc_config_bus *m=
-+                                      (struct mpc_config_bus *)mpt;
-+                              MP_bus_info(m);
-+                              mpt += sizeof(*m);
-+                              count += sizeof(*m);
-+                              break;
-+                      }
-+                      case MP_IOAPIC:
-+                      {
-+                              struct mpc_config_ioapic *m=
-+                                      (struct mpc_config_ioapic *)mpt;
-+                              MP_ioapic_info(m);
-+                              mpt+=sizeof(*m);
-+                              count+=sizeof(*m);
-+                              break;
-+                      }
-+                      case MP_INTSRC:
-+                      {
-+                              struct mpc_config_intsrc *m=
-+                                      (struct mpc_config_intsrc *)mpt;
-+
-+                              MP_intsrc_info(m);
-+                              mpt+=sizeof(*m);
-+                              count+=sizeof(*m);
-+                              break;
-+                      }
-+                      case MP_LINTSRC:
-+                      {
-+                              struct mpc_config_lintsrc *m=
-+                                      (struct mpc_config_lintsrc *)mpt;
-+                              MP_lintsrc_info(m);
-+                              mpt+=sizeof(*m);
-+                              count+=sizeof(*m);
-+                              break;
-+                      }
-+              }
-+      }
-+      clustered_apic_check();
-+      if (!num_processors)
-+              printk(KERN_ERR "SMP mptable: no processors registered!\n");
-+      return num_processors;
-+}
-+
-+static int __init ELCR_trigger(unsigned int irq)
-+{
-+      unsigned int port;
-+
-+      port = 0x4d0 + (irq >> 3);
-+      return (inb(port) >> (irq & 7)) & 1;
-+}
-+
-+static void __init construct_default_ioirq_mptable(int mpc_default_type)
-+{
-+      struct mpc_config_intsrc intsrc;
-+      int i;
-+      int ELCR_fallback = 0;
-+
-+      intsrc.mpc_type = MP_INTSRC;
-+      intsrc.mpc_irqflag = 0;                 /* conforming */
-+      intsrc.mpc_srcbus = 0;
-+      intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
-+
-+      intsrc.mpc_irqtype = mp_INT;
-+
-+      /*
-+       *  If true, we have an ISA/PCI system with no IRQ entries
-+       *  in the MP table. To prevent the PCI interrupts from being set up
-+       *  incorrectly, we try to use the ELCR. The sanity check to see if
-+       *  there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
-+       *  never be level sensitive, so we simply see if the ELCR agrees.
-+       *  If it does, we assume it's valid.
-+       */
-+      if (mpc_default_type == 5) {
-+              printk(KERN_INFO "ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
-+
-+              if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
-+                      printk(KERN_ERR "ELCR contains invalid data... not using ELCR\n");
-+              else {
-+                      printk(KERN_INFO "Using ELCR to identify PCI interrupts\n");
-+                      ELCR_fallback = 1;
-+              }
-+      }
-+
-+      for (i = 0; i < 16; i++) {
-+              switch (mpc_default_type) {
-+              case 2:
-+                      if (i == 0 || i == 13)
-+                              continue;       /* IRQ0 & IRQ13 not connected */
-+                      /* fall through */
-+              default:
-+                      if (i == 2)
-+                              continue;       /* IRQ2 is never connected */
-+              }
-+
-+              if (ELCR_fallback) {
-+                      /*
-+                       *  If the ELCR indicates a level-sensitive interrupt, we
-+                       *  copy that information over to the MP table in the
-+                       *  irqflag field (level sensitive, active high polarity).
-+                       */
-+                      if (ELCR_trigger(i))
-+                              intsrc.mpc_irqflag = 13;
-+                      else
-+                              intsrc.mpc_irqflag = 0;
-+              }
-+
-+              intsrc.mpc_srcbusirq = i;
-+              intsrc.mpc_dstirq = i ? i : 2;          /* IRQ0 to INTIN2 */
-+              MP_intsrc_info(&intsrc);
-+      }
-+
-+      intsrc.mpc_irqtype = mp_ExtINT;
-+      intsrc.mpc_srcbusirq = 0;
-+      intsrc.mpc_dstirq = 0;                          /* 8259A to INTIN0 */
-+      MP_intsrc_info(&intsrc);
-+}
-+
-+static inline void __init construct_default_ISA_mptable(int mpc_default_type)
-+{
-+      struct mpc_config_processor processor;
-+      struct mpc_config_bus bus;
-+      struct mpc_config_ioapic ioapic;
-+      struct mpc_config_lintsrc lintsrc;
-+      int linttypes[2] = { mp_ExtINT, mp_NMI };
-+      int i;
-+
-+      /*
-+       * local APIC has default address
-+       */
-+      mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-+
-+      /*
-+       * 2 CPUs, numbered 0 & 1.
-+       */
-+      processor.mpc_type = MP_PROCESSOR;
-+      /* Either an integrated APIC or a discrete 82489DX. */
-+      processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
-+      processor.mpc_cpuflag = CPU_ENABLED;
-+      processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
-+                                 (boot_cpu_data.x86_model << 4) |
-+                                 boot_cpu_data.x86_mask;
-+      processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
-+      processor.mpc_reserved[0] = 0;
-+      processor.mpc_reserved[1] = 0;
-+      for (i = 0; i < 2; i++) {
-+              processor.mpc_apicid = i;
-+              MP_processor_info(&processor);
-+      }
-+
-+      bus.mpc_type = MP_BUS;
-+      bus.mpc_busid = 0;
-+      switch (mpc_default_type) {
-+              default:
-+                      printk(KERN_ERR "???\nUnknown standard configuration %d\n",
-+                              mpc_default_type);
-+                      /* fall through */
-+              case 1:
-+              case 5:
-+                      memcpy(bus.mpc_bustype, "ISA   ", 6);
-+                      break;
-+              case 2:
-+              case 6:
-+              case 3:
-+                      memcpy(bus.mpc_bustype, "EISA  ", 6);
-+                      break;
-+              case 4:
-+              case 7:
-+                      memcpy(bus.mpc_bustype, "MCA   ", 6);
-+      }
-+      MP_bus_info(&bus);
-+      if (mpc_default_type > 4) {
-+              bus.mpc_busid = 1;
-+              memcpy(bus.mpc_bustype, "PCI   ", 6);
-+              MP_bus_info(&bus);
-+      }
-+
-+      ioapic.mpc_type = MP_IOAPIC;
-+      ioapic.mpc_apicid = 2;
-+      ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
-+      ioapic.mpc_flags = MPC_APIC_USABLE;
-+      ioapic.mpc_apicaddr = 0xFEC00000;
-+      MP_ioapic_info(&ioapic);
-+
-+      /*
-+       * We set up most of the low 16 IO-APIC pins according to MPS rules.
-+       */
-+      construct_default_ioirq_mptable(mpc_default_type);
-+
-+      lintsrc.mpc_type = MP_LINTSRC;
-+      lintsrc.mpc_irqflag = 0;                /* conforming */
-+      lintsrc.mpc_srcbusid = 0;
-+      lintsrc.mpc_srcbusirq = 0;
-+      lintsrc.mpc_destapic = MP_APIC_ALL;
-+      for (i = 0; i < 2; i++) {
-+              lintsrc.mpc_irqtype = linttypes[i];
-+              lintsrc.mpc_destapiclint = i;
-+              MP_lintsrc_info(&lintsrc);
-+      }
-+}
-+
-+static struct intel_mp_floating *mpf_found;
-+
-+/*
-+ * Scan the memory blocks for an SMP configuration block.
-+ */
-+void __init get_smp_config (void)
-+{
-+      struct intel_mp_floating *mpf = mpf_found;
-+
-+      /*
-+       * ACPI supports both logical (e.g. Hyper-Threading) and physical 
-+       * processors, where MPS only supports physical.
-+       */
-+      if (acpi_lapic && acpi_ioapic) {
-+              printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
-+              return;
-+      }
-+      else if (acpi_lapic)
-+              printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
-+
-+      printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
-+      if (mpf->mpf_feature2 & (1<<7)) {
-+              printk(KERN_INFO "    IMCR and PIC compatibility mode.\n");
-+              pic_mode = 1;
-+      } else {
-+              printk(KERN_INFO "    Virtual Wire compatibility mode.\n");
-+              pic_mode = 0;
-+      }
-+
-+      /*
-+       * Now see if we need to read further.
-+       */
-+      if (mpf->mpf_feature1 != 0) {
-+
-+              printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1);
-+              construct_default_ISA_mptable(mpf->mpf_feature1);
-+
-+      } else if (mpf->mpf_physptr) {
-+
-+              /*
-+               * Read the physical hardware table.  Anything here will
-+               * override the defaults.
-+               */
-+              if (!smp_read_mpc(isa_bus_to_virt(mpf->mpf_physptr))) {
-+                      smp_found_config = 0;
-+                      printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
-+                      printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
-+                      return;
-+              }
-+              /*
-+               * If there are no explicit MP IRQ entries, then we are
-+               * broken.  We set up most of the low 16 IO-APIC pins to
-+               * ISA defaults and hope it will work.
-+               */
-+              if (!mp_irq_entries) {
-+                      struct mpc_config_bus bus;
-+
-+                      printk(KERN_ERR "BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
-+
-+                      bus.mpc_type = MP_BUS;
-+                      bus.mpc_busid = 0;
-+                      memcpy(bus.mpc_bustype, "ISA   ", 6);
-+                      MP_bus_info(&bus);
-+
-+                      construct_default_ioirq_mptable(0);
-+              }
-+
-+      } else
-+              BUG();
-+
-+      printk(KERN_INFO "Processors: %d\n", num_processors);
-+      /*
-+       * Only use the first configuration found.
-+       */
-+}
-+
-+static int __init smp_scan_config (unsigned long base, unsigned long length)
-+{
-+      extern void __bad_mpf_size(void); 
-+      unsigned int *bp = isa_bus_to_virt(base);
-+      struct intel_mp_floating *mpf;
-+
-+      Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
-+      if (sizeof(*mpf) != 16)
-+              __bad_mpf_size();
-+
-+      while (length > 0) {
-+              mpf = (struct intel_mp_floating *)bp;
-+              if ((*bp == SMP_MAGIC_IDENT) &&
-+                      (mpf->mpf_length == 1) &&
-+                      !mpf_checksum((unsigned char *)bp, 16) &&
-+                      ((mpf->mpf_specification == 1)
-+                              || (mpf->mpf_specification == 4)) ) {
-+
-+                      smp_found_config = 1;
-+                      mpf_found = mpf;
-+                      return 1;
-+              }
-+              bp += 4;
-+              length -= 16;
-+      }
-+      return 0;
-+}
-+
-+void __init find_intel_smp (void)
-+{
-+      unsigned int address;
-+
-+      /*
-+       * FIXME: Linux assumes you have 640K of base ram..
-+       * this continues the error...
-+       *
-+       * 1) Scan the bottom 1K for a signature
-+       * 2) Scan the top 1K of base RAM
-+       * 3) Scan the 64K of bios
-+       */
-+      if (smp_scan_config(0x0,0x400) ||
-+              smp_scan_config(639*0x400,0x400) ||
-+                      smp_scan_config(0xF0000,0x10000))
-+              return;
-+      /*
-+       * If it is an SMP machine we should know now, unless the
-+       * configuration is in an EISA/MCA bus machine with an
-+       * extended bios data area.
-+       *
-+       * there is a real-mode segmented pointer pointing to the
-+       * 4K EBDA area at 0x40E, calculate and scan it here.
-+       *
-+       * NOTE! There are Linux loaders that will corrupt the EBDA
-+       * area, and as such this kind of SMP config may be less
-+       * trustworthy, simply because the SMP table may have been
-+       * stomped on during early boot. These loaders are buggy and
-+       * should be fixed.
-+       */
-+
-+      address = *(unsigned short *)phys_to_virt(0x40E);
-+      address <<= 4;
-+      if (smp_scan_config(address, 0x1000))
-+              return;
-+
-+      /* If we have come this far, we did not find an MP table  */
-+       printk(KERN_INFO "No mptable found.\n");
-+}
-+
-+/*
-+ * - Intel MP Configuration Table
-+ */
-+void __init find_smp_config (void)
-+{
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      find_intel_smp();
-+#endif
-+}
-+
-+
-+/* --------------------------------------------------------------------------
-+                            ACPI-based MP Configuration
-+   -------------------------------------------------------------------------- */
-+
-+#ifdef CONFIG_ACPI
-+
-+void __init mp_register_lapic_address (
-+      u64                     address)
-+{
-+#ifndef CONFIG_XEN
-+      mp_lapic_addr = (unsigned long) address;
-+
-+      set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
-+
-+      if (boot_cpu_id == -1U)
-+              boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
-+
-+      Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid);
-+#endif
-+}
-+
-+
-+void __init mp_register_lapic (
-+      u8                      id, 
-+      u8                      enabled)
-+{
-+      struct mpc_config_processor processor;
-+      int                     boot_cpu = 0;
-+      
-+      if (id >= MAX_APICS) {
-+              printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
-+                      id, MAX_APICS);
-+              return;
-+      }
-+
-+      if (id == boot_cpu_physical_apicid)
-+              boot_cpu = 1;
-+
-+#ifndef CONFIG_XEN
-+      processor.mpc_type = MP_PROCESSOR;
-+      processor.mpc_apicid = id;
-+      processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR));
-+      processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
-+      processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
-+      processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 
-+              (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
-+      processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
-+      processor.mpc_reserved[0] = 0;
-+      processor.mpc_reserved[1] = 0;
-+#endif
-+
-+      MP_processor_info(&processor);
-+}
-+
-+#ifdef CONFIG_X86_IO_APIC
-+
-+#define MP_ISA_BUS            0
-+#define MP_MAX_IOAPIC_PIN     127
-+
-+static struct mp_ioapic_routing {
-+      int                     apic_id;
-+      int                     gsi_start;
-+      int                     gsi_end;
-+      u32                     pin_programmed[4];
-+} mp_ioapic_routing[MAX_IO_APICS];
-+
-+
-+static int mp_find_ioapic (
-+      int                     gsi)
-+{
-+      int                     i = 0;
-+
-+      /* Find the IOAPIC that manages this GSI. */
-+      for (i = 0; i < nr_ioapics; i++) {
-+              if ((gsi >= mp_ioapic_routing[i].gsi_start)
-+                      && (gsi <= mp_ioapic_routing[i].gsi_end))
-+                      return i;
-+      }
-+
-+      printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
-+
-+      return -1;
-+}
-+      
-+
-+void __init mp_register_ioapic (
-+      u8                      id, 
-+      u32                     address,
-+      u32                     gsi_base)
-+{
-+      int                     idx = 0;
-+
-+      if (nr_ioapics >= MAX_IO_APICS) {
-+              printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
-+                      "(found %d)\n", MAX_IO_APICS, nr_ioapics);
-+              panic("Recompile kernel with bigger MAX_IO_APICS!\n");
-+      }
-+      if (!address) {
-+              printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
-+                      " found in MADT table, skipping!\n");
-+              return;
-+      }
-+
-+      idx = nr_ioapics++;
-+
-+      mp_ioapics[idx].mpc_type = MP_IOAPIC;
-+      mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE;
-+      mp_ioapics[idx].mpc_apicaddr = address;
-+
-+#ifndef CONFIG_XEN
-+      set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-+#endif
-+      mp_ioapics[idx].mpc_apicid = id;
-+      mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
-+      
-+      /* 
-+       * Build basic IRQ lookup table to facilitate gsi->io_apic lookups
-+       * and to prevent reprogramming of IOAPIC pins (PCI IRQs).
-+       */
-+      mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
-+      mp_ioapic_routing[idx].gsi_start = gsi_base;
-+      mp_ioapic_routing[idx].gsi_end = gsi_base + 
-+              io_apic_get_redir_entries(idx);
-+
-+      printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
-+              "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 
-+              mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
-+              mp_ioapic_routing[idx].gsi_start,
-+              mp_ioapic_routing[idx].gsi_end);
-+
-+      return;
-+}
-+
-+
-+void __init mp_override_legacy_irq (
-+      u8                      bus_irq,
-+      u8                      polarity, 
-+      u8                      trigger, 
-+      u32                     gsi)
-+{
-+      struct mpc_config_intsrc intsrc;
-+      int                     ioapic = -1;
-+      int                     pin = -1;
-+
-+      /* 
-+       * Convert 'gsi' to 'ioapic.pin'.
-+       */
-+      ioapic = mp_find_ioapic(gsi);
-+      if (ioapic < 0)
-+              return;
-+      pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
-+
-+      /*
-+       * TBD: This check is for faulty timer entries, where the override
-+       *      erroneously sets the trigger to level, resulting in a HUGE 
-+       *      increase of timer interrupts!
-+       */
-+      if ((bus_irq == 0) && (trigger == 3))
-+              trigger = 1;
-+
-+      intsrc.mpc_type = MP_INTSRC;
-+      intsrc.mpc_irqtype = mp_INT;
-+      intsrc.mpc_irqflag = (trigger << 2) | polarity;
-+      intsrc.mpc_srcbus = MP_ISA_BUS;
-+      intsrc.mpc_srcbusirq = bus_irq;                                /* IRQ */
-+      intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;        /* APIC ID */
-+      intsrc.mpc_dstirq = pin;                                    /* INTIN# */
-+
-+      Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", 
-+              intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 
-+              (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
-+              intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
-+
-+      mp_irqs[mp_irq_entries] = intsrc;
-+      if (++mp_irq_entries == MAX_IRQ_SOURCES)
-+              panic("Max # of irq sources exceeded!\n");
-+
-+      return;
-+}
-+
-+
-+void __init mp_config_acpi_legacy_irqs (void)
-+{
-+      struct mpc_config_intsrc intsrc;
-+      int                     i = 0;
-+      int                     ioapic = -1;
-+
-+      /* 
-+       * Fabricate the legacy ISA bus (bus #31).
-+       */
-+      mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA;
-+      Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
-+
-+      /* 
-+       * Locate the IOAPIC that manages the ISA IRQs (0-15). 
-+       */
-+      ioapic = mp_find_ioapic(0);
-+      if (ioapic < 0)
-+              return;
-+
-+      intsrc.mpc_type = MP_INTSRC;
-+      intsrc.mpc_irqflag = 0;                                 /* Conforming */
-+      intsrc.mpc_srcbus = MP_ISA_BUS;
-+      intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;
-+
-+      /* 
-+       * Use the default configuration for the IRQs 0-15.  Unless
-+       * overridden by (MADT) interrupt source override entries.
-+       */
-+      for (i = 0; i < 16; i++) {
-+              int idx;
-+
-+              for (idx = 0; idx < mp_irq_entries; idx++) {
-+                      struct mpc_config_intsrc *irq = mp_irqs + idx;
-+
-+                      /* Do we already have a mapping for this ISA IRQ? */
-+                      if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i)
-+                              break;
-+
-+                      /* Do we already have a mapping for this IOAPIC pin */
-+                      if ((irq->mpc_dstapic == intsrc.mpc_dstapic) &&
-+                              (irq->mpc_dstirq == i))
-+                              break;
-+              }
-+
-+              if (idx != mp_irq_entries) {
-+                      printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i);
-+                      continue;                       /* IRQ already used */
-+              }
-+
-+              intsrc.mpc_irqtype = mp_INT;
-+              intsrc.mpc_srcbusirq = i;                  /* Identity mapped */
-+              intsrc.mpc_dstirq = i;
-+
-+              Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, "
-+                      "%d-%d\n", intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 
-+                      (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
-+                      intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, 
-+                      intsrc.mpc_dstirq);
-+
-+              mp_irqs[mp_irq_entries] = intsrc;
-+              if (++mp_irq_entries == MAX_IRQ_SOURCES)
-+                      panic("Max # of irq sources exceeded!\n");
-+      }
-+
-+      return;
-+}
-+
-+#define MAX_GSI_NUM   4096
-+
-+int mp_register_gsi(u32 gsi, int triggering, int polarity)
-+{
-+      int                     ioapic = -1;
-+      int                     ioapic_pin = 0;
-+      int                     idx, bit = 0;
-+      static int              pci_irq = 16;
-+      /*
-+       * Mapping between Global System Interrupts, which
-+       * represent all possible interrupts, to the IRQs
-+       * assigned to actual devices.
-+       */
-+      static int              gsi_to_irq[MAX_GSI_NUM];
-+
-+      if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
-+              return gsi;
-+
-+      /* Don't set up the ACPI SCI because it's already set up */
-+      if (acpi_fadt.sci_int == gsi)
-+              return gsi;
-+
-+      ioapic = mp_find_ioapic(gsi);
-+      if (ioapic < 0) {
-+              printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
-+              return gsi;
-+      }
-+
-+      ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
-+
-+      /* 
-+       * Avoid pin reprogramming.  PRTs typically include entries  
-+       * with redundant pin->gsi mappings (but unique PCI devices);
-+       * we only program the IOAPIC on the first.
-+       */
-+      bit = ioapic_pin % 32;
-+      idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
-+      if (idx > 3) {
-+              printk(KERN_ERR "Invalid reference to IOAPIC pin "
-+                      "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
-+                      ioapic_pin);
-+              return gsi;
-+      }
-+      if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
-+              Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
-+                      mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-+              return gsi_to_irq[gsi];
-+      }
-+
-+      mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
-+
-+      if (triggering == ACPI_LEVEL_SENSITIVE) {
-+              /*
-+               * For PCI devices assign IRQs in order, avoiding gaps
-+               * due to unused I/O APIC pins.
-+               */
-+              int irq = gsi;
-+              if (gsi < MAX_GSI_NUM) {
-+                      if (gsi > 15)
-+                              gsi = pci_irq++;
-+                      /*
-+                       * Don't assign IRQ used by ACPI SCI
-+                       */
-+                      if (gsi == acpi_fadt.sci_int)
-+                              gsi = pci_irq++;
-+                      gsi_to_irq[irq] = gsi;
-+              } else {
-+                      printk(KERN_ERR "GSI %u is too high\n", gsi);
-+                      return gsi;
-+              }
-+      }
-+
-+      io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
-+              triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
-+              polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-+      return gsi;
-+}
-+
-+#endif /*CONFIG_X86_IO_APIC*/
-+#endif /*CONFIG_ACPI*/
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/pci-swiotlb-xen.c linux-2.6.16.33/arch/x86_64/kernel/pci-swiotlb-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/pci-swiotlb-xen.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/pci-swiotlb-xen.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,54 @@
-+/* Glue code to lib/swiotlb.c */
-+
-+#include <linux/pci.h>
-+#include <linux/cache.h>
-+#include <linux/module.h>
-+#include <asm/dma-mapping.h>
-+#include <asm/proto.h>
-+#include <asm/swiotlb.h>
-+#include <asm/dma.h>
-+
-+#if 0
-+int swiotlb __read_mostly;
-+EXPORT_SYMBOL(swiotlb);
-+#endif
-+
-+struct dma_mapping_ops swiotlb_dma_ops = {
-+#if 0
-+      .mapping_error = swiotlb_dma_mapping_error,
-+      .alloc_coherent = swiotlb_alloc_coherent,
-+      .free_coherent = swiotlb_free_coherent,
-+      .map_single = swiotlb_map_single,
-+      .unmap_single = swiotlb_unmap_single,
-+      .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
-+      .sync_single_for_device = swiotlb_sync_single_for_device,
-+      .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
-+      .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
-+      .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
-+      .sync_sg_for_device = swiotlb_sync_sg_for_device,
-+      .map_sg = swiotlb_map_sg,
-+      .unmap_sg = swiotlb_unmap_sg,
-+      .dma_supported = NULL,
-+#endif
-+};
-+
-+void pci_swiotlb_init(void)
-+{
-+#if 0
-+      /* don't initialize swiotlb if iommu=off (no_iommu=1) */
-+      if (!iommu_aperture && !no_iommu &&
-+          (end_pfn > MAX_DMA32_PFN || force_iommu))
-+             swiotlb = 1;
-+      if (swiotlb) {
-+              printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
-+              swiotlb_init();
-+              dma_ops = &swiotlb_dma_ops;
-+      }
-+#else
-+      swiotlb_init();
-+      if (swiotlb) {
-+              printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
-+              dma_ops = &swiotlb_dma_ops;
-+      }
-+#endif
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/process-xen.c linux-2.6.16.33/arch/x86_64/kernel/process-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/process-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/process-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,802 @@
-+/*
-+ *  linux/arch/x86-64/kernel/process.c
-+ *
-+ *  Copyright (C) 1995  Linus Torvalds
-+ *
-+ *  Pentium III FXSR, SSE support
-+ *    Gareth Hughes <gareth@valinux.com>, May 2000
-+ * 
-+ *  X86-64 port
-+ *    Andi Kleen.
-+ *
-+ *    CPU hotplug support - ashok.raj@intel.com
-+ *  $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $
-+ * 
-+ *  Jun Nakajima <jun.nakajima@intel.com> 
-+ *     Modified for Xen
-+ */
-+
-+/*
-+ * This file handles the architecture-dependent parts of process handling..
-+ */
-+
-+#include <stdarg.h>
-+
-+#include <linux/cpu.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/elfcore.h>
-+#include <linux/smp.h>
-+#include <linux/slab.h>
-+#include <linux/user.h>
-+#include <linux/module.h>
-+#include <linux/a.out.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <linux/ptrace.h>
-+#include <linux/utsname.h>
-+#include <linux/random.h>
-+#include <linux/kprobes.h>
-+#include <linux/notifier.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/pgtable.h>
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/processor.h>
-+#include <asm/i387.h>
-+#include <asm/mmu_context.h>
-+#include <asm/pda.h>
-+#include <asm/prctl.h>
-+#include <asm/kdebug.h>
-+#include <xen/interface/dom0_ops.h>
-+#include <xen/interface/physdev.h>
-+#include <xen/interface/vcpu.h>
-+#include <asm/desc.h>
-+#include <asm/proto.h>
-+#include <asm/hardirq.h>
-+#include <asm/ia32.h>
-+#include <asm/idle.h>
-+
-+#include <xen/cpu_hotplug.h>
-+
-+asmlinkage extern void ret_from_fork(void);
-+
-+unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
-+
-+unsigned long boot_option_idle_override = 0;
-+EXPORT_SYMBOL(boot_option_idle_override);
-+
-+/*
-+ * Powermanagement idle function, if any..
-+ */
-+void (*pm_idle)(void);
-+static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
-+
-+static struct notifier_block *idle_notifier;
-+static DEFINE_SPINLOCK(idle_notifier_lock);
-+
-+void idle_notifier_register(struct notifier_block *n)
-+{
-+      unsigned long flags;
-+      spin_lock_irqsave(&idle_notifier_lock, flags);
-+      notifier_chain_register(&idle_notifier, n);
-+      spin_unlock_irqrestore(&idle_notifier_lock, flags);
-+}
-+EXPORT_SYMBOL_GPL(idle_notifier_register);
-+
-+void idle_notifier_unregister(struct notifier_block *n)
-+{
-+      unsigned long flags;
-+      spin_lock_irqsave(&idle_notifier_lock, flags);
-+      notifier_chain_unregister(&idle_notifier, n);
-+      spin_unlock_irqrestore(&idle_notifier_lock, flags);
-+}
-+EXPORT_SYMBOL(idle_notifier_unregister);
-+
-+enum idle_state { CPU_IDLE, CPU_NOT_IDLE };
-+static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE;
-+
-+void enter_idle(void)
-+{
-+      __get_cpu_var(idle_state) = CPU_IDLE;
-+      notifier_call_chain(&idle_notifier, IDLE_START, NULL);
-+}
-+
-+static void __exit_idle(void)
-+{
-+      __get_cpu_var(idle_state) = CPU_NOT_IDLE;
-+      notifier_call_chain(&idle_notifier, IDLE_END, NULL);
-+}
-+
-+/* Called from interrupts to signify idle end */
-+void exit_idle(void)
-+{
-+      if (current->pid | read_pda(irqcount))
-+              return;
-+      __exit_idle();
-+}
-+
-+/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-+void xen_idle(void)
-+{
-+      local_irq_disable();
-+
-+      if (need_resched())
-+              local_irq_enable();
-+      else {
-+              clear_thread_flag(TIF_POLLING_NRFLAG);
-+              smp_mb__after_clear_bit();
-+              safe_halt();
-+              set_thread_flag(TIF_POLLING_NRFLAG);
-+      }
-+}
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+static inline void play_dead(void)
-+{
-+      idle_task_exit();
-+      local_irq_disable();
-+      cpu_clear(smp_processor_id(), cpu_initialized);
-+      preempt_enable_no_resched();
-+      HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
-+      cpu_bringup();
-+}
-+#else
-+static inline void play_dead(void)
-+{
-+      BUG();
-+}
-+#endif /* CONFIG_HOTPLUG_CPU */
-+
-+/*
-+ * The idle thread. There's no useful work to be
-+ * done, so just try to conserve power and have a
-+ * low exit latency (ie sit in a loop waiting for
-+ * somebody to say that they'd like to reschedule)
-+ */
-+void cpu_idle (void)
-+{
-+      set_thread_flag(TIF_POLLING_NRFLAG);
-+
-+      /* endless idle loop with no priority at all */
-+      while (1) {
-+              while (!need_resched()) {
-+                      if (__get_cpu_var(cpu_idle_state))
-+                              __get_cpu_var(cpu_idle_state) = 0;
-+                      rmb();
-+                      
-+                      if (cpu_is_offline(smp_processor_id()))
-+                              play_dead();
-+                      enter_idle();
-+                      xen_idle();
-+                      __exit_idle();
-+              }
-+
-+              preempt_enable_no_resched();
-+              schedule();
-+              preempt_disable();
-+      }
-+}
-+
-+void cpu_idle_wait(void)
-+{
-+      unsigned int cpu, this_cpu = get_cpu();
-+      cpumask_t map;
-+
-+      set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
-+      put_cpu();
-+
-+      cpus_clear(map);
-+      for_each_online_cpu(cpu) {
-+              per_cpu(cpu_idle_state, cpu) = 1;
-+              cpu_set(cpu, map);
-+      }
-+
-+      __get_cpu_var(cpu_idle_state) = 0;
-+
-+      wmb();
-+      do {
-+              ssleep(1);
-+              for_each_online_cpu(cpu) {
-+                      if (cpu_isset(cpu, map) &&
-+                                      !per_cpu(cpu_idle_state, cpu))
-+                              cpu_clear(cpu, map);
-+              }
-+              cpus_and(map, map, cpu_online_map);
-+      } while (!cpus_empty(map));
-+}
-+EXPORT_SYMBOL_GPL(cpu_idle_wait);
-+
-+/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
-+/* Always use xen_idle() instead. */
-+void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) {}
-+
-+/* Prints also some state that isn't saved in the pt_regs */ 
-+void __show_regs(struct pt_regs * regs)
-+{
-+      unsigned long fs, gs, shadowgs;
-+      unsigned int fsindex,gsindex;
-+      unsigned int ds,cs,es; 
-+
-+      printk("\n");
-+      print_modules();
-+      printk("Pid: %d, comm: %.20s %s %s %.*s\n",
-+              current->pid, current->comm, print_tainted(),
-+              system_utsname.release,
-+              (int)strcspn(system_utsname.version, " "),
-+              system_utsname.version);
-+      printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
-+      printk_address(regs->rip); 
-+      printk("\nRSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
-+              regs->eflags);
-+      printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
-+             regs->rax, regs->rbx, regs->rcx);
-+      printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
-+             regs->rdx, regs->rsi, regs->rdi); 
-+      printk("RBP: %016lx R08: %016lx R09: %016lx\n",
-+             regs->rbp, regs->r8, regs->r9); 
-+      printk("R10: %016lx R11: %016lx R12: %016lx\n",
-+             regs->r10, regs->r11, regs->r12); 
-+      printk("R13: %016lx R14: %016lx R15: %016lx\n",
-+             regs->r13, regs->r14, regs->r15); 
-+
-+      asm("mov %%ds,%0" : "=r" (ds)); 
-+      asm("mov %%cs,%0" : "=r" (cs)); 
-+      asm("mov %%es,%0" : "=r" (es)); 
-+      asm("mov %%fs,%0" : "=r" (fsindex));
-+      asm("mov %%gs,%0" : "=r" (gsindex));
-+
-+      rdmsrl(MSR_FS_BASE, fs);
-+      rdmsrl(MSR_GS_BASE, gs); 
-+      rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); 
-+
-+      printk("FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", 
-+             fs,fsindex,gs,gsindex,shadowgs); 
-+      printk("CS:  %04x DS: %04x ES: %04x\n", cs, ds, es); 
-+
-+}
-+
-+void show_regs(struct pt_regs *regs)
-+{
-+      printk("CPU %d:", smp_processor_id());
-+      __show_regs(regs);
-+      show_trace(&regs->rsp);
-+}
-+
-+/*
-+ * Free current thread data structures etc..
-+ */
-+void exit_thread(void)
-+{
-+      struct task_struct *me = current;
-+      struct thread_struct *t = &me->thread;
-+
-+      /*
-+       * Remove function-return probe instances associated with this task
-+       * and put them back on the free list. Do not insert an exit probe for
-+       * this function, it will be disabled by kprobe_flush_task if you do.
-+       */
-+      kprobe_flush_task(me);
-+
-+      if (me->thread.io_bitmap_ptr) { 
-+#ifndef CONFIG_X86_NO_TSS
-+              struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
-+#endif
-+#ifdef CONFIG_XEN
-+              struct physdev_set_iobitmap iobmp_op = { 0 };
-+#endif
-+
-+              kfree(t->io_bitmap_ptr);
-+              t->io_bitmap_ptr = NULL;
-+              /*
-+               * Careful, clear this in the TSS too:
-+               */
-+#ifndef CONFIG_X86_NO_TSS
-+              memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
-+              put_cpu();
-+#endif
-+#ifdef CONFIG_XEN
-+              HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &iobmp_op);
-+#endif
-+              t->io_bitmap_max = 0;
-+      }
-+}
-+
-+void load_gs_index(unsigned gs)
-+{
-+      HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, gs);
-+}
-+
-+void flush_thread(void)
-+{
-+      struct task_struct *tsk = current;
-+      struct thread_info *t = current_thread_info();
-+
-+      if (t->flags & _TIF_ABI_PENDING)
-+              t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);
-+
-+      tsk->thread.debugreg0 = 0;
-+      tsk->thread.debugreg1 = 0;
-+      tsk->thread.debugreg2 = 0;
-+      tsk->thread.debugreg3 = 0;
-+      tsk->thread.debugreg6 = 0;
-+      tsk->thread.debugreg7 = 0;
-+      memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
-+      /*
-+       * Forget coprocessor state..
-+       */
-+      clear_fpu(tsk);
-+      clear_used_math();
-+}
-+
-+void release_thread(struct task_struct *dead_task)
-+{
-+      if (dead_task->mm) {
-+              if (dead_task->mm->context.size) {
-+                      printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
-+                                      dead_task->comm,
-+                                      dead_task->mm->context.ldt,
-+                                      dead_task->mm->context.size);
-+                      BUG();
-+              }
-+      }
-+}
-+
-+static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr)
-+{
-+      struct user_desc ud = { 
-+              .base_addr = addr,
-+              .limit = 0xfffff,
-+              .seg_32bit = 1,
-+              .limit_in_pages = 1,
-+              .useable = 1,
-+      };
-+      struct n_desc_struct *desc = (void *)t->thread.tls_array;
-+      desc += tls;
-+      desc->a = LDT_entry_a(&ud); 
-+      desc->b = LDT_entry_b(&ud); 
-+}
-+
-+static inline u32 read_32bit_tls(struct task_struct *t, int tls)
-+{
-+      struct desc_struct *desc = (void *)t->thread.tls_array;
-+      desc += tls;
-+      return desc->base0 | 
-+              (((u32)desc->base1) << 16) | 
-+              (((u32)desc->base2) << 24);
-+}
-+
-+/*
-+ * This gets called before we allocate a new thread and copy
-+ * the current task into it.
-+ */
-+void prepare_to_copy(struct task_struct *tsk)
-+{
-+      unlazy_fpu(tsk);
-+}
-+
-+int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, 
-+              unsigned long unused,
-+      struct task_struct * p, struct pt_regs * regs)
-+{
-+      int err;
-+      struct pt_regs * childregs;
-+      struct task_struct *me = current;
-+
-+      childregs = ((struct pt_regs *)
-+                      (THREAD_SIZE + task_stack_page(p))) - 1;
-+      *childregs = *regs;
-+
-+      childregs->rax = 0;
-+      childregs->rsp = rsp;
-+      if (rsp == ~0UL)
-+              childregs->rsp = (unsigned long)childregs;
-+
-+      p->thread.rsp = (unsigned long) childregs;
-+      p->thread.rsp0 = (unsigned long) (childregs+1);
-+      p->thread.userrsp = me->thread.userrsp; 
-+
-+      set_tsk_thread_flag(p, TIF_FORK);
-+
-+      p->thread.fs = me->thread.fs;
-+      p->thread.gs = me->thread.gs;
-+
-+      asm("mov %%gs,%0" : "=m" (p->thread.gsindex));
-+      asm("mov %%fs,%0" : "=m" (p->thread.fsindex));
-+      asm("mov %%es,%0" : "=m" (p->thread.es));
-+      asm("mov %%ds,%0" : "=m" (p->thread.ds));
-+
-+      if (unlikely(me->thread.io_bitmap_ptr != NULL)) { 
-+              p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
-+              if (!p->thread.io_bitmap_ptr) {
-+                      p->thread.io_bitmap_max = 0;
-+                      return -ENOMEM;
-+              }
-+              memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
-+                              IO_BITMAP_BYTES);
-+      } 
-+
-+      /*
-+       * Set a new TLS for the child thread?
-+       */
-+      if (clone_flags & CLONE_SETTLS) {
-+#ifdef CONFIG_IA32_EMULATION
-+              if (test_thread_flag(TIF_IA32))
-+                      err = ia32_child_tls(p, childregs); 
-+              else                    
-+#endif         
-+                      err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8); 
-+              if (err) 
-+                      goto out;
-+      }
-+        p->thread.iopl = current->thread.iopl;
-+
-+      err = 0;
-+out:
-+      if (err && p->thread.io_bitmap_ptr) {
-+              kfree(p->thread.io_bitmap_ptr);
-+              p->thread.io_bitmap_max = 0;
-+      }
-+      return err;
-+}
-+
-+static inline void __save_init_fpu( struct task_struct *tsk )
-+{
-+      asm volatile( "rex64 ; fxsave %0 ; fnclex"
-+                    : "=m" (tsk->thread.i387.fxsave));
-+      tsk->thread_info->status &= ~TS_USEDFPU;
-+}
-+
-+/*
-+ *    switch_to(x,y) should switch tasks from x to y.
-+ *
-+ * This could still be optimized: 
-+ * - fold all the options into a flag word and test it with a single test.
-+ * - could test fs/gs bitsliced
-+ *
-+ * Kprobes not supported here. Set the probe on schedule instead.
-+ */
-+__kprobes struct task_struct *
-+__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
-+{
-+      struct thread_struct *prev = &prev_p->thread,
-+                               *next = &next_p->thread;
-+      int cpu = smp_processor_id();  
-+#ifndef CONFIG_X86_NO_TSS
-+      struct tss_struct *tss = &per_cpu(init_tss, cpu);
-+#endif
-+      struct physdev_set_iopl iopl_op;
-+      struct physdev_set_iobitmap iobmp_op;
-+      multicall_entry_t _mcl[8], *mcl = _mcl;
-+
-+      /*
-+       * This is basically '__unlazy_fpu', except that we queue a
-+       * multicall to indicate FPU task switch, rather than
-+       * synchronously trapping to Xen.
-+       * This must be here to ensure both math_state_restore() and
-+       * kernel_fpu_begin() work consistently.
-+       * The AMD workaround requires it to be after DS reload, or
-+       * after DS has been cleared, which we do in __prepare_arch_switch.
-+       */
-+      if (prev_p->thread_info->status & TS_USEDFPU) {
-+              __save_init_fpu(prev_p); /* _not_ save_init_fpu() */
-+              mcl->op      = __HYPERVISOR_fpu_taskswitch;
-+              mcl->args[0] = 1;
-+              mcl++;
-+      }
-+
-+      /*
-+       * Reload esp0, LDT and the page table pointer:
-+       */
-+      mcl->op      = __HYPERVISOR_stack_switch;
-+      mcl->args[0] = __KERNEL_DS;
-+      mcl->args[1] = next->rsp0;
-+      mcl++;
-+
-+      /*
-+       * Load the per-thread Thread-Local Storage descriptor.
-+       * This is load_TLS(next, cpu) with multicalls.
-+       */
-+#define C(i) do {                                                     \
-+      if (unlikely(next->tls_array[i] != prev->tls_array[i])) {       \
-+              mcl->op      = __HYPERVISOR_update_descriptor;          \
-+              mcl->args[0] = virt_to_machine(                         \
-+                      &cpu_gdt(cpu)[GDT_ENTRY_TLS_MIN + i]);          \
-+              mcl->args[1] = next->tls_array[i];                      \
-+              mcl++;                                                  \
-+      }                                                               \
-+} while (0)
-+      C(0); C(1); C(2);
-+#undef C
-+
-+      if (unlikely(prev->iopl != next->iopl)) {
-+              iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
-+              mcl->op      = __HYPERVISOR_physdev_op;
-+              mcl->args[0] = PHYSDEVOP_set_iopl;
-+              mcl->args[1] = (unsigned long)&iopl_op;
-+              mcl++;
-+      }
-+
-+      if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
-+              iobmp_op.bitmap   = (char *)next->io_bitmap_ptr;
-+              iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
-+              mcl->op      = __HYPERVISOR_physdev_op;
-+              mcl->args[0] = PHYSDEVOP_set_iobitmap;
-+              mcl->args[1] = (unsigned long)&iobmp_op;
-+              mcl++;
-+      }
-+
-+      (void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
-+      /* 
-+       * Switch DS and ES.
-+       * This won't pick up thread selector changes, but I guess that is ok.
-+       */
-+      if (unlikely(next->es))
-+              loadsegment(es, next->es); 
-+      
-+      if (unlikely(next->ds))
-+              loadsegment(ds, next->ds);
-+
-+      /* 
-+       * Switch FS and GS.
-+       */
-+      if (unlikely(next->fsindex))
-+              loadsegment(fs, next->fsindex);
-+
-+      if (next->fs)
-+              HYPERVISOR_set_segment_base(SEGBASE_FS, next->fs); 
-+      
-+      if (unlikely(next->gsindex))
-+              load_gs_index(next->gsindex);
-+
-+      if (next->gs)
-+              HYPERVISOR_set_segment_base(SEGBASE_GS_USER, next->gs); 
-+
-+      /* 
-+       * Switch the PDA context.
-+       */
-+      prev->userrsp = read_pda(oldrsp); 
-+      write_pda(oldrsp, next->userrsp); 
-+      write_pda(pcurrent, next_p); 
-+      write_pda(kernelstack,
-+                task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
-+
-+      /*
-+       * Now maybe reload the debug registers
-+       */
-+      if (unlikely(next->debugreg7)) {
-+              set_debugreg(next->debugreg0, 0);
-+              set_debugreg(next->debugreg1, 1);
-+              set_debugreg(next->debugreg2, 2);
-+              set_debugreg(next->debugreg3, 3);
-+              /* no 4 and 5 */
-+              set_debugreg(next->debugreg6, 6);
-+              set_debugreg(next->debugreg7, 7);
-+      }
-+
-+      return prev_p;
-+}
-+
-+/*
-+ * sys_execve() executes a new program.
-+ */
-+asmlinkage 
-+long sys_execve(char __user *name, char __user * __user *argv,
-+              char __user * __user *envp, struct pt_regs regs)
-+{
-+      long error;
-+      char * filename;
-+
-+      filename = getname(name);
-+      error = PTR_ERR(filename);
-+      if (IS_ERR(filename)) 
-+              return error;
-+      error = do_execve(filename, argv, envp, &regs); 
-+      if (error == 0) {
-+              task_lock(current);
-+              current->ptrace &= ~PT_DTRACE;
-+              task_unlock(current);
-+      }
-+      putname(filename);
-+      return error;
-+}
-+
-+void set_personality_64bit(void)
-+{
-+      /* inherit personality from parent */
-+
-+      /* Make sure to be in 64bit mode */
-+      clear_thread_flag(TIF_IA32); 
-+
-+      /* TBD: overwrites user setup. Should have two bits.
-+         But 64bit processes have always behaved this way,
-+         so it's not too bad. The main problem is just that
-+         32bit childs are affected again. */
-+      current->personality &= ~READ_IMPLIES_EXEC;
-+}
-+
-+asmlinkage long sys_fork(struct pt_regs *regs)
-+{
-+      return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL);
-+}
-+
-+asmlinkage long
-+sys_clone(unsigned long clone_flags, unsigned long newsp,
-+        void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
-+{
-+      if (!newsp)
-+              newsp = regs->rsp;
-+      return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
-+}
-+
-+/*
-+ * This is trivial, and on the face of it looks like it
-+ * could equally well be done in user mode.
-+ *
-+ * Not so, for quite unobvious reasons - register pressure.
-+ * In user mode vfork() cannot have a stack frame, and if
-+ * done by calling the "clone()" system call directly, you
-+ * do not have enough call-clobbered registers to hold all
-+ * the information you need.
-+ */
-+asmlinkage long sys_vfork(struct pt_regs *regs)
-+{
-+      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->rsp, regs, 0,
-+                  NULL, NULL);
-+}
-+
-+unsigned long get_wchan(struct task_struct *p)
-+{
-+      unsigned long stack;
-+      u64 fp,rip;
-+      int count = 0;
-+
-+      if (!p || p == current || p->state==TASK_RUNNING)
-+              return 0; 
-+      stack = (unsigned long)task_stack_page(p);
-+      if (p->thread.rsp < stack || p->thread.rsp > stack+THREAD_SIZE)
-+              return 0;
-+      fp = *(u64 *)(p->thread.rsp);
-+      do { 
-+              if (fp < (unsigned long)stack ||
-+                  fp > (unsigned long)stack+THREAD_SIZE)
-+                      return 0; 
-+              rip = *(u64 *)(fp+8); 
-+              if (!in_sched_functions(rip))
-+                      return rip; 
-+              fp = *(u64 *)fp; 
-+      } while (count++ < 16); 
-+      return 0;
-+}
-+
-+long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
-+{ 
-+      int ret = 0; 
-+      int doit = task == current;
-+      int cpu;
-+
-+      switch (code) { 
-+      case ARCH_SET_GS:
-+              if (addr >= TASK_SIZE_OF(task))
-+                      return -EPERM; 
-+              cpu = get_cpu();
-+              /* handle small bases via the GDT because that's faster to 
-+                 switch. */
-+              if (addr <= 0xffffffff) {  
-+                      set_32bit_tls(task, GS_TLS, addr); 
-+                      if (doit) { 
-+                              load_TLS(&task->thread, cpu);
-+                              load_gs_index(GS_TLS_SEL); 
-+                      }
-+                      task->thread.gsindex = GS_TLS_SEL; 
-+                      task->thread.gs = 0;
-+              } else { 
-+                      task->thread.gsindex = 0;
-+                      task->thread.gs = addr;
-+                      if (doit) {
-+                              load_gs_index(0);
-+                              ret = HYPERVISOR_set_segment_base(
-+                                      SEGBASE_GS_USER, addr);
-+                      } 
-+              }
-+              put_cpu();
-+              break;
-+      case ARCH_SET_FS:
-+              /* Not strictly needed for fs, but do it for symmetry
-+                 with gs */
-+              if (addr >= TASK_SIZE_OF(task))
-+                      return -EPERM; 
-+              cpu = get_cpu();
-+              /* handle small bases via the GDT because that's faster to 
-+                 switch. */
-+              if (addr <= 0xffffffff) { 
-+                      set_32bit_tls(task, FS_TLS, addr);
-+                      if (doit) { 
-+                              load_TLS(&task->thread, cpu); 
-+                              asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL));
-+                      }
-+                      task->thread.fsindex = FS_TLS_SEL;
-+                      task->thread.fs = 0;
-+              } else { 
-+                      task->thread.fsindex = 0;
-+                      task->thread.fs = addr;
-+                      if (doit) {
-+                              /* set the selector to 0 to not confuse
-+                                 __switch_to */
-+                              asm volatile("movl %0,%%fs" :: "r" (0));
-+                                ret = HYPERVISOR_set_segment_base(SEGBASE_FS,
-+                                                                addr);
-+                      }
-+              }
-+              put_cpu();
-+              break;
-+      case ARCH_GET_FS: { 
-+              unsigned long base; 
-+              if (task->thread.fsindex == FS_TLS_SEL)
-+                      base = read_32bit_tls(task, FS_TLS);
-+              else if (doit)
-+                      rdmsrl(MSR_FS_BASE, base);
-+              else
-+                      base = task->thread.fs;
-+              ret = put_user(base, (unsigned long __user *)addr); 
-+              break; 
-+      }
-+      case ARCH_GET_GS: { 
-+              unsigned long base;
-+              if (task->thread.gsindex == GS_TLS_SEL)
-+                      base = read_32bit_tls(task, GS_TLS);
-+              else if (doit)
-+                      rdmsrl(MSR_KERNEL_GS_BASE, base);
-+              else
-+                      base = task->thread.gs;
-+              ret = put_user(base, (unsigned long __user *)addr); 
-+              break;
-+      }
-+
-+      default:
-+              ret = -EINVAL;
-+              break;
-+      } 
-+
-+      return ret;     
-+} 
-+
-+long sys_arch_prctl(int code, unsigned long addr)
-+{
-+      return do_arch_prctl(current, code, addr);
-+} 
-+
-+/* 
-+ * Capture the user space registers if the task is not running (in user space)
-+ */
-+int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
-+{
-+      struct pt_regs *pp, ptregs;
-+
-+      pp = task_pt_regs(tsk);
-+
-+      ptregs = *pp; 
-+      ptregs.cs &= 0xffff;
-+      ptregs.ss &= 0xffff;
-+
-+      elf_core_copy_regs(regs, &ptregs);
-+ 
-+        boot_option_idle_override = 1;
-+      return 1;
-+}
-+
-+unsigned long arch_align_stack(unsigned long sp)
-+{
-+      if (randomize_va_space)
-+              sp -= get_random_int() % 8192;
-+      return sp & ~0xf;
-+}
-+
-+#ifndef CONFIG_SMP
-+void _restore_vcpu(void)
-+{
-+}
-+#endif
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/relocate_kernel.S linux-2.6.16.33/arch/x86_64/kernel/relocate_kernel.S
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/relocate_kernel.S 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/relocate_kernel.S       2007-05-23 21:00:01.000000000 +0000
-@@ -7,31 +7,195 @@
-  */
- #include <linux/linkage.h>
-+#include <asm/page.h>
-+#include <asm/kexec.h>
--      /*
--       * Must be relocatable PIC code callable as a C function, that once
--       * it starts can not use the previous processes stack.
--       */
--      .globl relocate_new_kernel
-+/*
-+ * Must be relocatable PIC code callable as a C function
-+ */
-+
-+#define PTR(x) (x << 3)
-+#define PAGE_ALIGNED (1 << PAGE_SHIFT)
-+#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
-+
-+      .text
-+      .align PAGE_ALIGNED
-       .code64
-+      .globl relocate_kernel
-+relocate_kernel:
-+      /* %rdi indirection_page
-+       * %rsi page_list
-+       * %rdx start address
-+       */
-+
-+      /* map the control page at its virtual address */
-+
-+      movq    $0x0000ff8000000000, %r10        /* mask */
-+      mov     $(39 - 3), %cl                   /* bits to shift */
-+      movq    PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PGD)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PUD_0)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PUD_0)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PMD_0)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PMD_0)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PTE_0)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PTE_0)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_CONTROL_PAGE)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      /* identity map the control page at its physical address */
-+
-+      movq    $0x0000ff8000000000, %r10        /* mask */
-+      mov     $(39 - 3), %cl                   /* bits to shift */
-+      movq    PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PGD)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PUD_1)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PUD_1)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PMD_1)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PMD_1)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_PTE_1)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
-+      shrq    $9, %r10
-+      sub     $9, %cl
-+
-+      movq    %r11, %r9
-+      andq    %r10, %r9
-+      shrq    %cl, %r9
-+
-+      movq    PTR(VA_PTE_1)(%rsi), %r8
-+      addq    %r8, %r9
-+      movq    PTR(PA_CONTROL_PAGE)(%rsi), %r8
-+      orq     $PAGE_ATTR, %r8
-+      movq    %r8, (%r9)
-+
- relocate_new_kernel:
--      /* %rdi page_list
--       * %rsi reboot_code_buffer
-+      /* %rdi indirection_page
-+       * %rsi page_list
-        * %rdx start address
--       * %rcx page_table
--       * %r8  arg5
--       * %r9  arg6
-        */
-       /* zero out flags, and disable interrupts */
-       pushq $0
-       popfq
--      /* set a new stack at the bottom of our page... */
--      lea   4096(%rsi), %rsp
--
--      /* store the parameters back on the stack */
--      pushq   %rdx /* store the start address */
-+      /* get physical address of control page now */
-+      /* this is impossible after page table switch */
-+      movq    PTR(PA_CONTROL_PAGE)(%rsi), %r8
-+
-+      /* get physical address of page table now too */
-+      movq    PTR(PA_TABLE_PAGE)(%rsi), %rcx
-+
-+      /* switch to new set of page tables */
-+      movq    PTR(PA_PGD)(%rsi), %r9
-+      movq    %r9, %cr3
-+
-+      /* setup idt */
-+      movq    %r8, %rax
-+      addq    $(idt_80 - relocate_kernel), %rax
-+      lidtq   (%rax)
-+
-+      /* setup gdt */
-+      movq    %r8, %rax
-+      addq    $(gdt - relocate_kernel), %rax
-+      movq    %r8, %r9
-+      addq    $((gdt_80 - relocate_kernel) + 2), %r9
-+      movq    %rax, (%r9)
-+
-+      movq    %r8, %rax
-+      addq    $(gdt_80 - relocate_kernel), %rax
-+      lgdtq   (%rax)
-+
-+      /* setup data segment registers */
-+      xorl    %eax, %eax
-+      movl    %eax, %ds
-+      movl    %eax, %es
-+      movl    %eax, %fs
-+      movl    %eax, %gs
-+      movl    %eax, %ss
-+      
-+      /* setup a new stack at the end of the physical control page */
-+      lea     4096(%r8), %rsp
-+
-+      /* load new code segment and jump to identity mapped page */
-+      movq    %r8, %rax
-+      addq    $(identity_mapped - relocate_kernel), %rax
-+      pushq   $(gdt_cs - gdt)
-+      pushq   %rax
-+      lretq
-+
-+identity_mapped:
-+      /* store the start address on the stack */
-+      pushq   %rdx
-       /* Set cr0 to a known state:
-        * 31 1 == Paging enabled
-@@ -134,10 +298,19 @@
-       xorq    %r13, %r13
-       xorq    %r14, %r14
-       xorq    %r15, %r15
--
-       ret
--relocate_new_kernel_end:
--      .globl relocate_new_kernel_size
--relocate_new_kernel_size:
--      .quad relocate_new_kernel_end - relocate_new_kernel
-+      .align  16
-+gdt:
-+      .quad   0x0000000000000000      /* NULL descriptor */
-+gdt_cs:
-+      .quad   0x00af9a000000ffff
-+gdt_end:
-+
-+gdt_80:
-+      .word   gdt_end - gdt - 1       /* limit */
-+      .quad   0                       /* base - filled in by code above */
-+
-+idt_80:
-+      .word   0                       /* limit */
-+      .quad   0                       /* base */
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/setup-xen.c linux-2.6.16.33/arch/x86_64/kernel/setup-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/setup-xen.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/setup-xen.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1672 @@
-+/*
-+ *  linux/arch/x86-64/kernel/setup.c
-+ *
-+ *  Copyright (C) 1995  Linus Torvalds
-+ *
-+ *  Nov 2001 Dave Jones <davej@suse.de>
-+ *  Forked from i386 setup code.
-+ *
-+ *  $Id$
-+ */
-+
-+/*
-+ * This file handles the architecture-dependent parts of initialization
-+ */
-+
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/stddef.h>
-+#include <linux/unistd.h>
-+#include <linux/ptrace.h>
-+#include <linux/slab.h>
-+#include <linux/user.h>
-+#include <linux/a.out.h>
-+#include <linux/tty.h>
-+#include <linux/ioport.h>
-+#include <linux/delay.h>
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/initrd.h>
-+#include <linux/highmem.h>
-+#include <linux/bootmem.h>
-+#include <linux/module.h>
-+#include <asm/processor.h>
-+#include <linux/console.h>
-+#include <linux/seq_file.h>
-+#include <linux/crash_dump.h>
-+#include <linux/root_dev.h>
-+#include <linux/pci.h>
-+#include <linux/acpi.h>
-+#include <linux/kallsyms.h>
-+#include <linux/edd.h>
-+#include <linux/mmzone.h>
-+#include <linux/kexec.h>
-+#include <linux/cpufreq.h>
-+#include <linux/dmi.h>
-+#include <linux/dma-mapping.h>
-+
-+#include <asm/mtrr.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/smp.h>
-+#include <asm/msr.h>
-+#include <asm/desc.h>
-+#include <video/edid.h>
-+#include <asm/e820.h>
-+#include <asm/dma.h>
-+#include <asm/mpspec.h>
-+#include <asm/mmu_context.h>
-+#include <asm/bootsetup.h>
-+#include <asm/proto.h>
-+#include <asm/setup.h>
-+#include <asm/mach_apic.h>
-+#include <asm/numa.h>
-+#include <asm/swiotlb.h>
-+#include <asm/sections.h>
-+#include <asm/gart-mapping.h>
-+#ifdef CONFIG_XEN
-+#include <linux/percpu.h>
-+#include <xen/interface/physdev.h>
-+#include "setup_arch_pre.h"
-+#include <asm/hypervisor.h>
-+#include <xen/interface/nmi.h>
-+#include <xen/features.h>
-+#include <xen/xencons.h>
-+#define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-+#define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
-+#include <asm/mach-xen/setup_arch_post.h>
-+#include <xen/interface/memory.h>
-+
-+#ifdef CONFIG_XEN
-+#include <xen/interface/kexec.h>
-+#endif
-+
-+extern unsigned long start_pfn;
-+extern struct edid_info edid_info;
-+
-+shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
-+EXPORT_SYMBOL(HYPERVISOR_shared_info);
-+
-+extern char hypercall_page[PAGE_SIZE];
-+EXPORT_SYMBOL(hypercall_page);
-+
-+/* Allows setting of maximum possible memory size  */
-+unsigned long xen_override_max_pfn;
-+
-+static int xen_panic_event(struct notifier_block *, unsigned long, void *);
-+static struct notifier_block xen_panic_block = {
-+      xen_panic_event, NULL, 0 /* try to go last */
-+};
-+
-+unsigned long *phys_to_machine_mapping;
-+unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[512];
-+
-+EXPORT_SYMBOL(phys_to_machine_mapping);
-+
-+DEFINE_PER_CPU(multicall_entry_t, multicall_list[8]);
-+DEFINE_PER_CPU(int, nr_multicall_ents);
-+
-+/* Raw start-of-day parameters from the hypervisor. */
-+start_info_t *xen_start_info;
-+EXPORT_SYMBOL(xen_start_info);
-+#endif
-+
-+/*
-+ * Machine setup..
-+ */
-+
-+struct cpuinfo_x86 boot_cpu_data __read_mostly;
-+
-+unsigned long mmu_cr4_features;
-+
-+int acpi_disabled;
-+EXPORT_SYMBOL(acpi_disabled);
-+#ifdef        CONFIG_ACPI
-+extern int __initdata acpi_ht;
-+extern acpi_interrupt_flags   acpi_sci_flags;
-+int __initdata acpi_force = 0;
-+#endif
-+
-+int acpi_numa __initdata;
-+
-+/* Boot loader ID as an integer, for the benefit of proc_dointvec */
-+int bootloader_type;
-+
-+unsigned long saved_video_mode;
-+
-+/*
-+ * Setup options
-+ */
-+struct screen_info screen_info;
-+struct sys_desc_table_struct {
-+      unsigned short length;
-+      unsigned char table[0];
-+};
-+
-+struct edid_info edid_info;
-+struct e820map e820;
-+#ifdef CONFIG_XEN
-+struct e820map machine_e820;
-+#endif
-+
-+extern int root_mountflags;
-+
-+char command_line[COMMAND_LINE_SIZE];
-+
-+struct resource standard_io_resources[] = {
-+      { .name = "dma1", .start = 0x00, .end = 0x1f,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-+      { .name = "pic1", .start = 0x20, .end = 0x21,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-+      { .name = "timer0", .start = 0x40, .end = 0x43,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-+      { .name = "timer1", .start = 0x50, .end = 0x53,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-+      { .name = "keyboard", .start = 0x60, .end = 0x6f,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-+      { .name = "dma page reg", .start = 0x80, .end = 0x8f,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-+      { .name = "pic2", .start = 0xa0, .end = 0xa1,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-+      { .name = "dma2", .start = 0xc0, .end = 0xdf,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO },
-+      { .name = "fpu", .start = 0xf0, .end = 0xff,
-+              .flags = IORESOURCE_BUSY | IORESOURCE_IO }
-+};
-+
-+#define STANDARD_IO_RESOURCES \
-+      (sizeof standard_io_resources / sizeof standard_io_resources[0])
-+
-+#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
-+
-+struct resource data_resource = {
-+      .name = "Kernel data",
-+      .start = 0,
-+      .end = 0,
-+      .flags = IORESOURCE_RAM,
-+};
-+struct resource code_resource = {
-+      .name = "Kernel code",
-+      .start = 0,
-+      .end = 0,
-+      .flags = IORESOURCE_RAM,
-+};
-+
-+#define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM)
-+
-+static struct resource system_rom_resource = {
-+      .name = "System ROM",
-+      .start = 0xf0000,
-+      .end = 0xfffff,
-+      .flags = IORESOURCE_ROM,
-+};
-+
-+static struct resource extension_rom_resource = {
-+      .name = "Extension ROM",
-+      .start = 0xe0000,
-+      .end = 0xeffff,
-+      .flags = IORESOURCE_ROM,
-+};
-+
-+static struct resource adapter_rom_resources[] = {
-+      { .name = "Adapter ROM", .start = 0xc8000, .end = 0,
-+              .flags = IORESOURCE_ROM },
-+      { .name = "Adapter ROM", .start = 0, .end = 0,
-+              .flags = IORESOURCE_ROM },
-+      { .name = "Adapter ROM", .start = 0, .end = 0,
-+              .flags = IORESOURCE_ROM },
-+      { .name = "Adapter ROM", .start = 0, .end = 0,
-+              .flags = IORESOURCE_ROM },
-+      { .name = "Adapter ROM", .start = 0, .end = 0,
-+              .flags = IORESOURCE_ROM },
-+      { .name = "Adapter ROM", .start = 0, .end = 0,
-+              .flags = IORESOURCE_ROM }
-+};
-+
-+#define ADAPTER_ROM_RESOURCES \
-+      (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
-+
-+static struct resource video_rom_resource = {
-+      .name = "Video ROM",
-+      .start = 0xc0000,
-+      .end = 0xc7fff,
-+      .flags = IORESOURCE_ROM,
-+};
-+
-+static struct resource video_ram_resource = {
-+      .name = "Video RAM area",
-+      .start = 0xa0000,
-+      .end = 0xbffff,
-+      .flags = IORESOURCE_RAM,
-+};
-+
-+#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
-+
-+static int __init romchecksum(unsigned char *rom, unsigned long length)
-+{
-+      unsigned char *p, sum = 0;
-+
-+      for (p = rom; p < rom + length; p++)
-+              sum += *p;
-+      return sum == 0;
-+}
-+
-+static void __init probe_roms(void)
-+{
-+      unsigned long start, length, upper;
-+      unsigned char *rom;
-+      int           i;
-+
-+#ifdef CONFIG_XEN
-+      /* Nothing to do if not running in dom0. */
-+      if (!is_initial_xendomain())
-+              return;
-+#endif
-+
-+      /* video rom */
-+      upper = adapter_rom_resources[0].start;
-+      for (start = video_rom_resource.start; start < upper; start += 2048) {
-+              rom = isa_bus_to_virt(start);
-+              if (!romsignature(rom))
-+                      continue;
-+
-+              video_rom_resource.start = start;
-+
-+              /* 0 < length <= 0x7f * 512, historically */
-+              length = rom[2] * 512;
-+
-+              /* if checksum okay, trust length byte */
-+              if (length && romchecksum(rom, length))
-+                      video_rom_resource.end = start + length - 1;
-+
-+              request_resource(&iomem_resource, &video_rom_resource);
-+              break;
-+                      }
-+
-+      start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
-+      if (start < upper)
-+              start = upper;
-+
-+      /* system rom */
-+      request_resource(&iomem_resource, &system_rom_resource);
-+      upper = system_rom_resource.start;
-+
-+      /* check for extension rom (ignore length byte!) */
-+      rom = isa_bus_to_virt(extension_rom_resource.start);
-+      if (romsignature(rom)) {
-+              length = extension_rom_resource.end - extension_rom_resource.start + 1;
-+              if (romchecksum(rom, length)) {
-+                      request_resource(&iomem_resource, &extension_rom_resource);
-+                      upper = extension_rom_resource.start;
-+              }
-+      }
-+
-+      /* check for adapter roms on 2k boundaries */
-+      for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
-+              rom = isa_bus_to_virt(start);
-+              if (!romsignature(rom))
-+                      continue;
-+
-+              /* 0 < length <= 0x7f * 512, historically */
-+              length = rom[2] * 512;
-+
-+              /* but accept any length that fits if checksum okay */
-+              if (!length || start + length > upper || !romchecksum(rom, length))
-+                      continue;
-+
-+              adapter_rom_resources[i].start = start;
-+              adapter_rom_resources[i].end = start + length - 1;
-+              request_resource(&iomem_resource, &adapter_rom_resources[i]);
-+
-+              start = adapter_rom_resources[i++].end & ~2047UL;
-+      }
-+}
-+
-+static __init void parse_cmdline_early (char ** cmdline_p)
-+{
-+      char c = ' ', *to = command_line, *from = COMMAND_LINE;
-+      int len = 0;
-+      int userdef = 0;
-+
-+      for (;;) {
-+              if (c != ' ') 
-+                      goto next_char; 
-+
-+#ifdef  CONFIG_SMP
-+              /*
-+               * If the BIOS enumerates physical processors before logical,
-+               * maxcpus=N at enumeration-time can be used to disable HT.
-+               */
-+              else if (!memcmp(from, "maxcpus=", 8)) {
-+                      extern unsigned int maxcpus;
-+
-+                      maxcpus = simple_strtoul(from + 8, NULL, 0);
-+              }
-+#endif
-+#ifdef CONFIG_ACPI
-+              /* "acpi=off" disables both ACPI table parsing and interpreter init */
-+              if (!memcmp(from, "acpi=off", 8))
-+                      disable_acpi();
-+
-+              if (!memcmp(from, "acpi=force", 10)) { 
-+                      /* add later when we do DMI horrors: */
-+                      acpi_force = 1;
-+                      acpi_disabled = 0;
-+              }
-+
-+              /* acpi=ht just means: do ACPI MADT parsing 
-+                 at bootup, but don't enable the full ACPI interpreter */
-+              if (!memcmp(from, "acpi=ht", 7)) { 
-+                      if (!acpi_force)
-+                              disable_acpi();
-+                      acpi_ht = 1; 
-+              }
-+                else if (!memcmp(from, "pci=noacpi", 10)) 
-+                      acpi_disable_pci();
-+              else if (!memcmp(from, "acpi=noirq", 10))
-+                      acpi_noirq_set();
-+
-+              else if (!memcmp(from, "acpi_sci=edge", 13))
-+                      acpi_sci_flags.trigger =  1;
-+              else if (!memcmp(from, "acpi_sci=level", 14))
-+                      acpi_sci_flags.trigger = 3;
-+              else if (!memcmp(from, "acpi_sci=high", 13))
-+                      acpi_sci_flags.polarity = 1;
-+              else if (!memcmp(from, "acpi_sci=low", 12))
-+                      acpi_sci_flags.polarity = 3;
-+
-+              /* acpi=strict disables out-of-spec workarounds */
-+              else if (!memcmp(from, "acpi=strict", 11)) {
-+                      acpi_strict = 1;
-+              }
-+#ifdef CONFIG_X86_IO_APIC
-+              else if (!memcmp(from, "acpi_skip_timer_override", 24))
-+                      acpi_skip_timer_override = 1;
-+#endif
-+#endif
-+
-+#ifndef CONFIG_XEN
-+              if (!memcmp(from, "nolapic", 7) ||
-+                  !memcmp(from, "disableapic", 11))
-+                      disable_apic = 1;
-+
-+              /* Don't confuse with noapictimer */
-+              if (!memcmp(from, "noapic", 6) &&
-+                      (from[6] == ' ' || from[6] == 0))
-+                      skip_ioapic_setup = 1;
-+
-+              /* Make sure to not confuse with apic= */
-+              if (!memcmp(from, "apic", 4) &&
-+                      (from[4] == ' ' || from[4] == 0)) {
-+                      skip_ioapic_setup = 0;
-+                      ioapic_force = 1;
-+              }
-+#endif
-+                      
-+              if (!memcmp(from, "mem=", 4))
-+                      parse_memopt(from+4, &from); 
-+
-+              if (!memcmp(from, "memmap=", 7)) {
-+                      /* exactmap option is for used defined memory */
-+                      if (!memcmp(from+7, "exactmap", 8)) {
-+#ifdef CONFIG_CRASH_DUMP
-+                              /* If we are doing a crash dump, we
-+                               * still need to know the real mem
-+                               * size before original memory map is
-+                               * reset.
-+                               */
-+                              saved_max_pfn = e820_end_of_ram();
-+#endif
-+                              from += 8+7;
-+                              end_pfn_map = 0;
-+                              e820.nr_map = 0;
-+                              userdef = 1;
-+                      }
-+                      else {
-+                              parse_memmapopt(from+7, &from);
-+                              userdef = 1;
-+                      }
-+              }
-+
-+#ifdef CONFIG_NUMA
-+              if (!memcmp(from, "numa=", 5))
-+                      numa_setup(from+5); 
-+#endif
-+
-+              if (!memcmp(from,"iommu=",6)) { 
-+                      iommu_setup(from+6); 
-+              }
-+
-+              if (!memcmp(from,"oops=panic", 10))
-+                      panic_on_oops = 1;
-+
-+              if (!memcmp(from, "noexec=", 7))
-+                      nonx_setup(from + 7);
-+
-+#ifdef CONFIG_KEXEC
-+              /* crashkernel=size@addr specifies the location to reserve for
-+               * a crash kernel.  By reserving this memory we guarantee
-+               * that linux never set's it up as a DMA target.
-+               * Useful for holding code to do something appropriate
-+               * after a kernel panic.
-+               */
-+              else if (!memcmp(from, "crashkernel=", 12)) {
-+#ifndef CONFIG_XEN
-+                      unsigned long size, base;
-+                      size = memparse(from+12, &from);
-+                      if (*from == '@') {
-+                              base = memparse(from+1, &from);
-+                              /* FIXME: Do I want a sanity check
-+                               * to validate the memory range?
-+                               */
-+                              crashk_res.start = base;
-+                              crashk_res.end   = base + size - 1;
-+                      }
-+#else
-+                      printk("Ignoring crashkernel command line, "
-+                             "parameter will be supplied by xen\n");
-+#endif
-+              }
-+#endif
-+
-+#ifdef CONFIG_PROC_VMCORE
-+              /* elfcorehdr= specifies the location of elf core header
-+               * stored by the crashed kernel. This option will be passed
-+               * by kexec loader to the capture kernel.
-+               */
-+              else if(!memcmp(from, "elfcorehdr=", 11))
-+                      elfcorehdr_addr = memparse(from+11, &from);
-+#endif
-+
-+#if defined(CONFIG_HOTPLUG_CPU) && !defined(CONFIG_XEN)
-+              else if (!memcmp(from, "additional_cpus=", 16))
-+                      setup_additional_cpus(from+16);
-+#endif
-+
-+      next_char:
-+              c = *(from++);
-+              if (!c)
-+                      break;
-+              if (COMMAND_LINE_SIZE <= ++len)
-+                      break;
-+              *(to++) = c;
-+      }
-+      if (userdef) {
-+              printk(KERN_INFO "user-defined physical RAM map:\n");
-+              e820_print_map("user");
-+      }
-+      *to = '\0';
-+      *cmdline_p = command_line;
-+}
-+
-+#ifndef CONFIG_NUMA
-+static void __init
-+contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
-+{
-+      unsigned long bootmap_size, bootmap;
-+
-+      bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
-+      bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
-+      if (bootmap == -1L)
-+              panic("Cannot find bootmem map of size %ld\n",bootmap_size);
-+      bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
-+#ifdef CONFIG_XEN
-+      e820_bootmem_free(NODE_DATA(0), 0, xen_start_info->nr_pages<<PAGE_SHIFT);
-+#else
-+      e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
-+#endif
-+      reserve_bootmem(bootmap, bootmap_size);
-+} 
-+#endif
-+
-+/* Use inline assembly to define this because the nops are defined 
-+   as inline assembly strings in the include files and we cannot 
-+   get them easily into strings. */
-+asm("\t.data\nk8nops: " 
-+    K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
-+    K8_NOP7 K8_NOP8); 
-+    
-+extern unsigned char k8nops[];
-+static unsigned char *k8_nops[ASM_NOP_MAX+1] = { 
-+     NULL,
-+     k8nops,
-+     k8nops + 1,
-+     k8nops + 1 + 2,
-+     k8nops + 1 + 2 + 3,
-+     k8nops + 1 + 2 + 3 + 4,
-+     k8nops + 1 + 2 + 3 + 4 + 5,
-+     k8nops + 1 + 2 + 3 + 4 + 5 + 6,
-+     k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
-+}; 
-+
-+extern char __vsyscall_0;
-+
-+/* Replace instructions with better alternatives for this CPU type.
-+
-+   This runs before SMP is initialized to avoid SMP problems with
-+   self modifying code. This implies that assymetric systems where
-+   APs have less capabilities than the boot processor are not handled. 
-+   In this case boot with "noreplacement". */ 
-+void apply_alternatives(void *start, void *end) 
-+{ 
-+      struct alt_instr *a; 
-+      int diff, i, k;
-+      for (a = start; (void *)a < end; a++) { 
-+              u8 *instr;
-+
-+              if (!boot_cpu_has(a->cpuid))
-+                      continue;
-+
-+              BUG_ON(a->replacementlen > a->instrlen); 
-+              instr = a->instr;
-+              /* vsyscall code is not mapped yet. resolve it manually. */
-+              if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END)
-+                      instr -= VSYSCALL_START - (unsigned long)&__vsyscall_0;
-+              __inline_memcpy(instr, a->replacement, a->replacementlen);
-+              diff = a->instrlen - a->replacementlen; 
-+
-+              /* Pad the rest with nops */
-+              for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
-+                      k = diff;
-+                      if (k > ASM_NOP_MAX)
-+                              k = ASM_NOP_MAX;
-+                      __inline_memcpy(instr + i, k8_nops[k], k);
-+              } 
-+      }
-+} 
-+
-+static int no_replacement __initdata = 0; 
-+ 
-+void __init alternative_instructions(void)
-+{
-+      extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
-+      if (no_replacement) 
-+              return;
-+      apply_alternatives(__alt_instructions, __alt_instructions_end);
-+}
-+
-+static int __init noreplacement_setup(char *s)
-+{ 
-+     no_replacement = 1; 
-+     return 0; 
-+} 
-+
-+__setup("noreplacement", noreplacement_setup); 
-+
-+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-+struct edd edd;
-+#ifdef CONFIG_EDD_MODULE
-+EXPORT_SYMBOL(edd);
-+#endif
-+/**
-+ * copy_edd() - Copy the BIOS EDD information
-+ *              from boot_params into a safe place.
-+ *
-+ */
-+static inline void copy_edd(void)
-+{
-+     memcpy(edd.mbr_signature, EDD_MBR_SIGNATURE, sizeof(edd.mbr_signature));
-+     memcpy(edd.edd_info, EDD_BUF, sizeof(edd.edd_info));
-+     edd.mbr_signature_nr = EDD_MBR_SIG_NR;
-+     edd.edd_info_nr = EDD_NR;
-+}
-+#else
-+static inline void copy_edd(void)
-+{
-+}
-+#endif
-+
-+#ifndef CONFIG_XEN
-+#define EBDA_ADDR_POINTER 0x40E
-+static void __init reserve_ebda_region(void)
-+{
-+      unsigned int addr;
-+      /** 
-+       * there is a real-mode segmented pointer pointing to the 
-+       * 4K EBDA area at 0x40E
-+       */
-+      addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER);
-+      addr <<= 4;
-+      if (addr)
-+              reserve_bootmem_generic(addr, PAGE_SIZE);
-+}
-+#endif
-+
-+void __init setup_arch(char **cmdline_p)
-+{
-+      unsigned long kernel_end;
-+      struct xen_memory_map memmap;
-+
-+#ifdef CONFIG_XEN
-+      /* Register a call for panic conditions. */
-+      notifier_chain_register(&panic_notifier_list, &xen_panic_block);
-+
-+      ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); 
-+      kernel_end = 0;         /* dummy */
-+      screen_info = SCREEN_INFO;
-+
-+      if (is_initial_xendomain()) {
-+              /* This is drawn from a dump from vgacon:startup in
-+               * standard Linux. */
-+              screen_info.orig_video_mode = 3;
-+              screen_info.orig_video_isVGA = 1;
-+              screen_info.orig_video_lines = 25;
-+              screen_info.orig_video_cols = 80;
-+              screen_info.orig_video_ega_bx = 3;
-+              screen_info.orig_video_points = 16;
-+              screen_info.orig_y = screen_info.orig_video_lines - 1;
-+              if (xen_start_info->console.dom0.info_size >=
-+                  sizeof(struct dom0_vga_console_info)) {
-+                      const struct dom0_vga_console_info *info =
-+                              (struct dom0_vga_console_info *)(
-+                                      (char *)xen_start_info +
-+                                      xen_start_info->console.dom0.info_off);
-+                      dom0_init_screen_info(info);
-+              }
-+              xen_start_info->console.domU.mfn = 0;
-+              xen_start_info->console.domU.evtchn = 0;
-+      } else
-+              screen_info.orig_video_isVGA = 0;
-+
-+      edid_info = EDID_INFO;
-+      saved_video_mode = SAVED_VIDEO_MODE;
-+      bootloader_type = LOADER_TYPE;
-+
-+#ifdef CONFIG_BLK_DEV_RAM
-+      rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-+      rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
-+      rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-+
-+
-+#endif
-+
-+      setup_xen_features();
-+
-+      HYPERVISOR_vm_assist(VMASST_CMD_enable,
-+                           VMASST_TYPE_writable_pagetables);
-+
-+      ARCH_SETUP
-+#else
-+      ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-+      screen_info = SCREEN_INFO;
-+      edid_info = EDID_INFO;
-+      saved_video_mode = SAVED_VIDEO_MODE;
-+      bootloader_type = LOADER_TYPE;
-+
-+#ifdef CONFIG_BLK_DEV_RAM
-+      rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-+      rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
-+      rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-+#endif
-+#endif        /* !CONFIG_XEN */
-+      setup_memory_region();
-+      copy_edd();
-+
-+      if (!MOUNT_ROOT_RDONLY)
-+              root_mountflags &= ~MS_RDONLY;
-+      init_mm.start_code = (unsigned long) &_text;
-+      init_mm.end_code = (unsigned long) &_etext;
-+      init_mm.end_data = (unsigned long) &_edata;
-+      init_mm.brk = (unsigned long) &_end;
-+
-+      code_resource.start = virt_to_phys(&_text);
-+      code_resource.end = virt_to_phys(&_etext)-1;
-+      data_resource.start = virt_to_phys(&_etext);
-+      data_resource.end = virt_to_phys(&_edata)-1;
-+
-+      parse_cmdline_early(cmdline_p);
-+
-+      early_identify_cpu(&boot_cpu_data);
-+
-+      /*
-+       * partially used pages are not usable - thus
-+       * we are rounding upwards:
-+       */
-+      end_pfn = e820_end_of_ram();
-+
-+      check_efer();
-+
-+      init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
-+
-+#ifdef CONFIG_ACPI_NUMA
-+      /*
-+       * Parse SRAT to discover nodes.
-+       */
-+      acpi_numa_init();
-+#endif
-+
-+#ifdef CONFIG_NUMA
-+      numa_initmem_init(0, end_pfn); 
-+#else
-+      contig_initmem_init(0, end_pfn);
-+#endif
-+
-+      /* Reserve direct mapping */
-+      reserve_bootmem_generic(table_start << PAGE_SHIFT, 
-+                              (table_end - table_start) << PAGE_SHIFT);
-+
-+      /* reserve kernel */
-+      kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE);
-+      reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY);
-+
-+#ifdef CONFIG_XEN
-+      /* reserve physmap, start info and initial page tables */
-+      reserve_bootmem(kernel_end, (table_start<<PAGE_SHIFT)-kernel_end);
-+#else
-+      /*
-+       * reserve physical page 0 - it's a special BIOS page on many boxes,
-+       * enabling clean reboots, SMP operation, laptop functions.
-+       */
-+      reserve_bootmem_generic(0, PAGE_SIZE);
-+
-+      /* reserve ebda region */
-+      reserve_ebda_region();
-+#endif
-+
-+#ifdef CONFIG_SMP
-+      /*
-+       * But first pinch a few for the stack/trampoline stuff
-+       * FIXME: Don't need the extra page at 4K, but need to fix
-+       * trampoline before removing it. (see the GDT stuff)
-+       */
-+      reserve_bootmem_generic(PAGE_SIZE, PAGE_SIZE);
-+
-+      /* Reserve SMP trampoline */
-+      reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, PAGE_SIZE);
-+#endif
-+
-+#ifdef CONFIG_ACPI_SLEEP
-+       /*
-+        * Reserve low memory region for sleep support.
-+        */
-+       acpi_reserve_bootmem();
-+#endif
-+#ifdef CONFIG_XEN
-+#ifdef CONFIG_BLK_DEV_INITRD
-+      if (xen_start_info->mod_start) {
-+              if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) {
-+                      /*reserve_bootmem_generic(INITRD_START, INITRD_SIZE);*/
-+                      initrd_start = INITRD_START + PAGE_OFFSET;
-+                      initrd_end = initrd_start+INITRD_SIZE;
-+                      initrd_below_start_ok = 1;
-+              } else {
-+                      printk(KERN_ERR "initrd extends beyond end of memory "
-+                              "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-+                              (unsigned long)(INITRD_START + INITRD_SIZE),
-+                              (unsigned long)(end_pfn << PAGE_SHIFT));
-+                      initrd_start = 0;
-+              }
-+      }
-+#endif
-+#else /* CONFIG_XEN */
-+#ifdef CONFIG_BLK_DEV_INITRD
-+      if (LOADER_TYPE && INITRD_START) {
-+              if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) {
-+                      reserve_bootmem_generic(INITRD_START, INITRD_SIZE);
-+                      initrd_start =
-+                              INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
-+                      initrd_end = initrd_start+INITRD_SIZE;
-+              }
-+              else {
-+                      printk(KERN_ERR "initrd extends beyond end of memory "
-+                          "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-+                          (unsigned long)(INITRD_START + INITRD_SIZE),
-+                          (unsigned long)(end_pfn << PAGE_SHIFT));
-+                      initrd_start = 0;
-+              }
-+      }
-+#endif
-+#endif        /* !CONFIG_XEN */
-+#ifdef CONFIG_KEXEC
-+#ifdef CONFIG_XEN
-+      xen_machine_kexec_setup_resources();
-+#else
-+      if (crashk_res.start != crashk_res.end) {
-+              reserve_bootmem(crashk_res.start,
-+                      crashk_res.end - crashk_res.start + 1);
-+      }
-+#endif
-+#endif
-+
-+      paging_init();
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      /*
-+       * Find and reserve possible boot-time SMP configuration:
-+       */
-+      find_smp_config();
-+#endif
-+#ifdef CONFIG_XEN
-+      {
-+              int i, j, k, fpp;
-+
-+              if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      /* Make sure we have a large enough P->M table. */
-+                      phys_to_machine_mapping = alloc_bootmem_pages(
-+                              end_pfn * sizeof(unsigned long));
-+                      memset(phys_to_machine_mapping, ~0,
-+                             end_pfn * sizeof(unsigned long));
-+                      memcpy(phys_to_machine_mapping,
-+                             (unsigned long *)xen_start_info->mfn_list,
-+                             xen_start_info->nr_pages * sizeof(unsigned long));
-+                      free_bootmem(
-+                              __pa(xen_start_info->mfn_list),
-+                              PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
-+                                              sizeof(unsigned long))));
-+
-+                      /*
-+                       * Initialise the list of the frames that specify the
-+                       * list of frames that make up the p2m table. Used by
-+                         * save/restore.
-+                       */
-+                      pfn_to_mfn_frame_list_list = alloc_bootmem_pages(PAGE_SIZE);
-+                      HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
-+                              virt_to_mfn(pfn_to_mfn_frame_list_list);
-+
-+                      fpp = PAGE_SIZE/sizeof(unsigned long);
-+                      for (i=0, j=0, k=-1; i< end_pfn; i+=fpp, j++) {
-+                              if ((j % fpp) == 0) {
-+                                      k++;
-+                                      BUG_ON(k>=fpp);
-+                                      pfn_to_mfn_frame_list[k] =
-+                                              alloc_bootmem_pages(PAGE_SIZE);
-+                                      pfn_to_mfn_frame_list_list[k] =
-+                                              virt_to_mfn(pfn_to_mfn_frame_list[k]);
-+                                      j=0;
-+                              }
-+                              pfn_to_mfn_frame_list[k][j] =
-+                                      virt_to_mfn(&phys_to_machine_mapping[i]);
-+                      }
-+                      HYPERVISOR_shared_info->arch.max_pfn = end_pfn;
-+              }
-+
-+      }
-+
-+      if (!is_initial_xendomain()) {
-+              acpi_disabled = 1;
-+#ifdef  CONFIG_ACPI
-+              acpi_ht = 0;
-+#endif
-+      }
-+#endif
-+
-+#ifndef CONFIG_XEN
-+      check_ioapic();
-+#endif
-+
-+      zap_low_mappings(0);
-+
-+#ifdef CONFIG_ACPI
-+      /*
-+       * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
-+       * Call this early for SRAT node setup.
-+       */
-+      acpi_boot_table_init();
-+
-+      /*
-+       * Read APIC and some other early information from ACPI tables.
-+       */
-+      acpi_boot_init();
-+#endif
-+
-+      init_cpu_to_node();
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      /*
-+       * get boot-time SMP configuration:
-+       */
-+      if (smp_found_config)
-+              get_smp_config();
-+#ifndef CONFIG_XEN
-+      init_apic_mappings();
-+#endif
-+#endif
-+#if defined(CONFIG_XEN) && defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
-+      prefill_possible_map();
-+#endif
-+
-+      /*
-+       * Request address space for all standard RAM and ROM resources
-+       * and also for regions reported as reserved by the e820.
-+       */
-+      probe_roms();
-+#ifdef CONFIG_XEN
-+      if (is_initial_xendomain()) {
-+              memmap.nr_entries = E820MAX;
-+              set_xen_guest_handle(memmap.buffer, machine_e820.map);
-+
-+              if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap))
-+                      BUG();
-+              machine_e820.nr_map = memmap.nr_entries;
-+
-+              e820_reserve_resources(machine_e820.map, machine_e820.nr_map);
-+      }
-+#else
-+      e820_reserve_resources(e820.map, e820.nr_map);
-+#endif
-+
-+      request_resource(&iomem_resource, &video_ram_resource);
-+
-+      {
-+      unsigned i;
-+      /* request I/O space for devices used on all i[345]86 PCs */
-+      for (i = 0; i < STANDARD_IO_RESOURCES; i++)
-+              request_resource(&ioport_resource, &standard_io_resources[i]);
-+      }
-+
-+#ifdef CONFIG_XEN
-+      if (is_initial_xendomain())
-+              e820_setup_gap(machine_e820.map, machine_e820.nr_map);
-+#else
-+      e820_setup_gap(e820.map, e820.nr_map);
-+#endif
-+
-+#ifdef CONFIG_GART_IOMMU
-+      iommu_hole_init();
-+#endif
-+
-+#ifdef CONFIG_XEN
-+      {
-+              struct physdev_set_iopl set_iopl;
-+
-+              set_iopl.iopl = 1;
-+              HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
-+
-+              if (is_initial_xendomain()) {
-+#ifdef CONFIG_VT
-+#if defined(CONFIG_VGA_CONSOLE)
-+                      conswitchp = &vga_con;
-+#elif defined(CONFIG_DUMMY_CONSOLE)
-+                      conswitchp = &dummy_con;
-+#endif
-+#endif
-+              } else {
-+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
-+                      conswitchp = &dummy_con;
-+#endif
-+                }
-+      }
-+      xencons_early_setup();
-+#else /* CONFIG_XEN */
-+
-+#ifdef CONFIG_VT
-+#if defined(CONFIG_VGA_CONSOLE)
-+      conswitchp = &vga_con;
-+#elif defined(CONFIG_DUMMY_CONSOLE)
-+      conswitchp = &dummy_con;
-+#endif
-+#endif
-+
-+#endif /* !CONFIG_XEN */
-+}
-+
-+#ifdef CONFIG_XEN
-+static int
-+xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
-+{
-+      HYPERVISOR_shutdown(SHUTDOWN_crash);
-+      /* we're never actually going to get here... */
-+      return NOTIFY_DONE;
-+}
-+#endif /* !CONFIG_XEN */
-+
-+
-+static int __cpuinit get_model_name(struct cpuinfo_x86 *c)
-+{
-+      unsigned int *v;
-+
-+      if (c->extended_cpuid_level < 0x80000004)
-+              return 0;
-+
-+      v = (unsigned int *) c->x86_model_id;
-+      cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
-+      cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
-+      cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
-+      c->x86_model_id[48] = 0;
-+      return 1;
-+}
-+
-+
-+static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
-+{
-+      unsigned int n, dummy, eax, ebx, ecx, edx;
-+
-+      n = c->extended_cpuid_level;
-+
-+      if (n >= 0x80000005) {
-+              cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
-+              printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
-+                      edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
-+              c->x86_cache_size=(ecx>>24)+(edx>>24);
-+              /* On K8 L1 TLB is inclusive, so don't count it */
-+              c->x86_tlbsize = 0;
-+      }
-+
-+      if (n >= 0x80000006) {
-+              cpuid(0x80000006, &dummy, &ebx, &ecx, &edx);
-+              ecx = cpuid_ecx(0x80000006);
-+              c->x86_cache_size = ecx >> 16;
-+              c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff);
-+
-+              printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
-+              c->x86_cache_size, ecx & 0xFF);
-+      }
-+
-+      if (n >= 0x80000007)
-+              cpuid(0x80000007, &dummy, &dummy, &dummy, &c->x86_power); 
-+      if (n >= 0x80000008) {
-+              cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); 
-+              c->x86_virt_bits = (eax >> 8) & 0xff;
-+              c->x86_phys_bits = eax & 0xff;
-+      }
-+}
-+
-+#ifdef CONFIG_NUMA
-+static int nearby_node(int apicid)
-+{
-+      int i;
-+      for (i = apicid - 1; i >= 0; i--) {
-+              int node = apicid_to_node[i];
-+              if (node != NUMA_NO_NODE && node_online(node))
-+                      return node;
-+      }
-+      for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
-+              int node = apicid_to_node[i];
-+              if (node != NUMA_NO_NODE && node_online(node))
-+                      return node;
-+      }
-+      return first_node(node_online_map); /* Shouldn't happen */
-+}
-+#endif
-+
-+/*
-+ * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
-+ * Assumes number of cores is a power of two.
-+ */
-+static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
-+{
-+#ifdef CONFIG_SMP
-+      int cpu = smp_processor_id();
-+      unsigned bits;
-+#ifdef CONFIG_NUMA
-+      int node = 0;
-+      unsigned apicid = phys_proc_id[cpu];
-+#endif
-+
-+      bits = 0;
-+      while ((1 << bits) < c->x86_max_cores)
-+              bits++;
-+
-+      /* Low order bits define the core id (index of core in socket) */
-+      cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1);
-+      /* Convert the APIC ID into the socket ID */
-+      phys_proc_id[cpu] >>= bits;
-+
-+#ifdef CONFIG_NUMA
-+      node = phys_proc_id[cpu];
-+      if (apicid_to_node[apicid] != NUMA_NO_NODE)
-+              node = apicid_to_node[apicid];
-+      if (!node_online(node)) {
-+              /* Two possibilities here:
-+                 - The CPU is missing memory and no node was created.
-+                 In that case try picking one from a nearby CPU
-+                 - The APIC IDs differ from the HyperTransport node IDs
-+                 which the K8 northbridge parsing fills in.
-+                 Assume they are all increased by a constant offset,
-+                 but in the same order as the HT nodeids.
-+                 If that doesn't result in a usable node fall back to the
-+                 path for the previous case.  */
-+              int ht_nodeid = apicid - (phys_proc_id[0] << bits);
-+              if (ht_nodeid >= 0 &&
-+                  apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
-+                      node = apicid_to_node[ht_nodeid];
-+              /* Pick a nearby node */
-+              if (!node_online(node))
-+                      node = nearby_node(apicid);
-+      }
-+      numa_set_node(cpu, node);
-+
-+      printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
-+                      cpu, c->x86_max_cores, node, cpu_core_id[cpu]);
-+#endif
-+#endif
-+}
-+
-+static int __init init_amd(struct cpuinfo_x86 *c)
-+{
-+      int r;
-+      unsigned level;
-+
-+#ifdef CONFIG_SMP
-+      unsigned long value;
-+
-+      /*
-+       * Disable TLB flush filter by setting HWCR.FFDIS on K8
-+       * bit 6 of msr C001_0015
-+       *
-+       * Errata 63 for SH-B3 steppings
-+       * Errata 122 for all steppings (F+ have it disabled by default)
-+       */
-+      if (c->x86 == 15) {
-+              rdmsrl(MSR_K8_HWCR, value);
-+              value |= 1 << 6;
-+              wrmsrl(MSR_K8_HWCR, value);
-+      }
-+#endif
-+
-+      /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
-+         3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
-+      clear_bit(0*32+31, &c->x86_capability);
-+      
-+      /* On C+ stepping K8 rep microcode works well for copy/memset */
-+      level = cpuid_eax(1);
-+      if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
-+              set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
-+
-+      /* Enable workaround for FXSAVE leak */
-+      if (c->x86 >= 6)
-+              set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
-+
-+      r = get_model_name(c);
-+      if (!r) { 
-+              switch (c->x86) { 
-+              case 15:
-+                      /* Should distinguish Models here, but this is only
-+                         a fallback anyways. */
-+                      strcpy(c->x86_model_id, "Hammer");
-+                      break; 
-+              } 
-+      } 
-+      display_cacheinfo(c);
-+
-+      /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
-+      if (c->x86_power & (1<<8))
-+              set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
-+
-+      if (c->extended_cpuid_level >= 0x80000008) {
-+              c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
-+              if (c->x86_max_cores & (c->x86_max_cores - 1))
-+                      c->x86_max_cores = 1;
-+
-+              amd_detect_cmp(c);
-+      }
-+
-+      return r;
-+}
-+
-+static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
-+{
-+#ifdef CONFIG_SMP
-+      u32     eax, ebx, ecx, edx;
-+      int     index_msb, core_bits;
-+      int     cpu = smp_processor_id();
-+
-+      cpuid(1, &eax, &ebx, &ecx, &edx);
-+
-+      c->apicid = phys_pkg_id(0);
-+
-+      if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
-+              return;
-+
-+      smp_num_siblings = (ebx & 0xff0000) >> 16;
-+
-+      if (smp_num_siblings == 1) {
-+              printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
-+      } else if (smp_num_siblings > 1 ) {
-+
-+              if (smp_num_siblings > NR_CPUS) {
-+                      printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
-+                      smp_num_siblings = 1;
-+                      return;
-+              }
-+
-+              index_msb = get_count_order(smp_num_siblings);
-+              phys_proc_id[cpu] = phys_pkg_id(index_msb);
-+
-+              printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
-+                     phys_proc_id[cpu]);
-+
-+              smp_num_siblings = smp_num_siblings / c->x86_max_cores;
-+
-+              index_msb = get_count_order(smp_num_siblings) ;
-+
-+              core_bits = get_count_order(c->x86_max_cores);
-+
-+              cpu_core_id[cpu] = phys_pkg_id(index_msb) &
-+                                             ((1 << core_bits) - 1);
-+
-+              if (c->x86_max_cores > 1)
-+                      printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
-+                             cpu_core_id[cpu]);
-+      }
-+#endif
-+}
-+
-+/*
-+ * find out the number of processor cores on the die
-+ */
-+static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
-+{
-+      unsigned int eax;
-+
-+      if (c->cpuid_level < 4)
-+              return 1;
-+
-+      __asm__("cpuid"
-+              : "=a" (eax)
-+              : "0" (4), "c" (0)
-+              : "bx", "dx");
-+
-+      if (eax & 0x1f)
-+              return ((eax >> 26) + 1);
-+      else
-+              return 1;
-+}
-+
-+static void srat_detect_node(void)
-+{
-+#ifdef CONFIG_NUMA
-+      unsigned node;
-+      int cpu = smp_processor_id();
-+
-+      /* Don't do the funky fallback heuristics the AMD version employs
-+         for now. */
-+      node = apicid_to_node[hard_smp_processor_id()];
-+      if (node == NUMA_NO_NODE)
-+              node = 0;
-+      numa_set_node(cpu, node);
-+
-+      if (acpi_numa > 0)
-+              printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node);
-+#endif
-+}
-+
-+static void __cpuinit init_intel(struct cpuinfo_x86 *c)
-+{
-+      /* Cache sizes */
-+      unsigned n;
-+
-+      init_intel_cacheinfo(c);
-+      n = c->extended_cpuid_level;
-+      if (n >= 0x80000008) {
-+              unsigned eax = cpuid_eax(0x80000008);
-+              c->x86_virt_bits = (eax >> 8) & 0xff;
-+              c->x86_phys_bits = eax & 0xff;
-+              /* CPUID workaround for Intel 0F34 CPU */
-+              if (c->x86_vendor == X86_VENDOR_INTEL &&
-+                  c->x86 == 0xF && c->x86_model == 0x3 &&
-+                  c->x86_mask == 0x4)
-+                      c->x86_phys_bits = 36;
-+      }
-+
-+      if (c->x86 == 15)
-+              c->x86_cache_alignment = c->x86_clflush_size * 2;
-+      if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
-+          (c->x86 == 0x6 && c->x86_model >= 0x0e))
-+              set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
-+      set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
-+      c->x86_max_cores = intel_num_cpu_cores(c);
-+
-+      srat_detect_node();
-+}
-+
-+static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
-+{
-+      char *v = c->x86_vendor_id;
-+
-+      if (!strcmp(v, "AuthenticAMD"))
-+              c->x86_vendor = X86_VENDOR_AMD;
-+      else if (!strcmp(v, "GenuineIntel"))
-+              c->x86_vendor = X86_VENDOR_INTEL;
-+      else
-+              c->x86_vendor = X86_VENDOR_UNKNOWN;
-+}
-+
-+struct cpu_model_info {
-+      int vendor;
-+      int family;
-+      char *model_names[16];
-+};
-+
-+/* Do some early cpuid on the boot CPU to get some parameter that are
-+   needed before check_bugs. Everything advanced is in identify_cpu
-+   below. */
-+void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
-+{
-+      u32 tfms;
-+
-+      c->loops_per_jiffy = loops_per_jiffy;
-+      c->x86_cache_size = -1;
-+      c->x86_vendor = X86_VENDOR_UNKNOWN;
-+      c->x86_model = c->x86_mask = 0; /* So far unknown... */
-+      c->x86_vendor_id[0] = '\0'; /* Unset */
-+      c->x86_model_id[0] = '\0';  /* Unset */
-+      c->x86_clflush_size = 64;
-+      c->x86_cache_alignment = c->x86_clflush_size;
-+      c->x86_max_cores = 1;
-+      c->extended_cpuid_level = 0;
-+      memset(&c->x86_capability, 0, sizeof c->x86_capability);
-+
-+      /* Get vendor name */
-+      cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
-+            (unsigned int *)&c->x86_vendor_id[0],
-+            (unsigned int *)&c->x86_vendor_id[8],
-+            (unsigned int *)&c->x86_vendor_id[4]);
-+              
-+      get_cpu_vendor(c);
-+
-+      /* Initialize the standard set of capabilities */
-+      /* Note that the vendor-specific code below might override */
-+
-+      /* Intel-defined flags: level 0x00000001 */
-+      if (c->cpuid_level >= 0x00000001) {
-+              __u32 misc;
-+              cpuid(0x00000001, &tfms, &misc, &c->x86_capability[4],
-+                    &c->x86_capability[0]);
-+              c->x86 = (tfms >> 8) & 0xf;
-+              c->x86_model = (tfms >> 4) & 0xf;
-+              c->x86_mask = tfms & 0xf;
-+              if (c->x86 == 0xf)
-+                      c->x86 += (tfms >> 20) & 0xff;
-+              if (c->x86 >= 0x6)
-+                      c->x86_model += ((tfms >> 16) & 0xF) << 4;
-+              if (c->x86_capability[0] & (1<<19)) 
-+                      c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
-+      } else {
-+              /* Have CPUID level 0 only - unheard of */
-+              c->x86 = 4;
-+      }
-+
-+#ifdef CONFIG_SMP
-+      phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
-+#endif
-+}
-+
-+/*
-+ * This does the hard work of actually picking apart the CPU stuff...
-+ */
-+void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
-+{
-+      int i;
-+      u32 xlvl;
-+
-+      early_identify_cpu(c);
-+
-+      /* AMD-defined flags: level 0x80000001 */
-+      xlvl = cpuid_eax(0x80000000);
-+      c->extended_cpuid_level = xlvl;
-+      if ((xlvl & 0xffff0000) == 0x80000000) {
-+              if (xlvl >= 0x80000001) {
-+                      c->x86_capability[1] = cpuid_edx(0x80000001);
-+                      c->x86_capability[6] = cpuid_ecx(0x80000001);
-+              }
-+              if (xlvl >= 0x80000004)
-+                      get_model_name(c); /* Default name */
-+      }
-+
-+      /* Transmeta-defined flags: level 0x80860001 */
-+      xlvl = cpuid_eax(0x80860000);
-+      if ((xlvl & 0xffff0000) == 0x80860000) {
-+              /* Don't set x86_cpuid_level here for now to not confuse. */
-+              if (xlvl >= 0x80860001)
-+                      c->x86_capability[2] = cpuid_edx(0x80860001);
-+      }
-+
-+      /*
-+       * Vendor-specific initialization.  In this section we
-+       * canonicalize the feature flags, meaning if there are
-+       * features a certain CPU supports which CPUID doesn't
-+       * tell us, CPUID claiming incorrect flags, or other bugs,
-+       * we handle them here.
-+       *
-+       * At the end of this section, c->x86_capability better
-+       * indicate the features this CPU genuinely supports!
-+       */
-+      switch (c->x86_vendor) {
-+      case X86_VENDOR_AMD:
-+              init_amd(c);
-+              break;
-+
-+      case X86_VENDOR_INTEL:
-+              init_intel(c);
-+              break;
-+
-+      case X86_VENDOR_UNKNOWN:
-+      default:
-+              display_cacheinfo(c);
-+              break;
-+      }
-+
-+      select_idle_routine(c);
-+      detect_ht(c); 
-+
-+      /*
-+       * On SMP, boot_cpu_data holds the common feature set between
-+       * all CPUs; so make sure that we indicate which features are
-+       * common between the CPUs.  The first time this routine gets
-+       * executed, c == &boot_cpu_data.
-+       */
-+      if (c != &boot_cpu_data) {
-+              /* AND the already accumulated flags with these */
-+              for (i = 0 ; i < NCAPINTS ; i++)
-+                      boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
-+      }
-+
-+#ifdef CONFIG_X86_MCE
-+      mcheck_init(c);
-+#endif
-+      if (c == &boot_cpu_data)
-+              mtrr_bp_init();
-+      else
-+              mtrr_ap_init();
-+#ifdef CONFIG_NUMA
-+      numa_add_cpu(smp_processor_id());
-+#endif
-+}
-+ 
-+
-+void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
-+{
-+      if (c->x86_model_id[0])
-+              printk("%s", c->x86_model_id);
-+
-+      if (c->x86_mask || c->cpuid_level >= 0) 
-+              printk(" stepping %02x\n", c->x86_mask);
-+      else
-+              printk("\n");
-+}
-+
-+/*
-+ *    Get CPU information for use by the procfs.
-+ */
-+
-+static int show_cpuinfo(struct seq_file *m, void *v)
-+{
-+      struct cpuinfo_x86 *c = v;
-+
-+      /* 
-+       * These flag bits must match the definitions in <asm/cpufeature.h>.
-+       * NULL means this bit is undefined or reserved; either way it doesn't
-+       * have meaning as far as Linux is concerned.  Note that it's important
-+       * to realize there is a difference between this table and CPUID -- if
-+       * applications want to get the raw CPUID data, they should access
-+       * /dev/cpu/<cpu_nr>/cpuid instead.
-+       */
-+      static char *x86_cap_flags[] = {
-+              /* Intel-defined */
-+              "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-+              "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-+              "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-+              "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
-+
-+              /* AMD-defined */
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
-+              NULL, "fxsr_opt", "rdtscp", NULL, NULL, "lm", "3dnowext", "3dnow",
-+
-+              /* Transmeta-defined */
-+              "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+
-+              /* Other (Linux-defined) */
-+              "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
-+              "constant_tsc", NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+
-+              /* Intel-defined (#2) */
-+              "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
-+              "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+
-+              /* VIA/Cyrix/Centaur-defined */
-+              NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+
-+              /* AMD-defined (#2) */
-+              "lahf_lm", "cmp_legacy", "svm", NULL, "cr8_legacy", NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+      };
-+      static char *x86_power_flags[] = { 
-+              "ts",   /* temperature sensor */
-+              "fid",  /* frequency id control */
-+              "vid",  /* voltage id control */
-+              "ttp",  /* thermal trip */
-+              "tm",
-+              "stc",
-+              NULL,
-+              /* nothing */   /* constant_tsc - moved to flags */
-+      };
-+
-+
-+#ifdef CONFIG_SMP
-+      if (!cpu_online(c-cpu_data))
-+              return 0;
-+#endif
-+
-+      seq_printf(m,"processor\t: %u\n"
-+                   "vendor_id\t: %s\n"
-+                   "cpu family\t: %d\n"
-+                   "model\t\t: %d\n"
-+                   "model name\t: %s\n",
-+                   (unsigned)(c-cpu_data),
-+                   c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
-+                   c->x86,
-+                   (int)c->x86_model,
-+                   c->x86_model_id[0] ? c->x86_model_id : "unknown");
-+      
-+      if (c->x86_mask || c->cpuid_level >= 0)
-+              seq_printf(m, "stepping\t: %d\n", c->x86_mask);
-+      else
-+              seq_printf(m, "stepping\t: unknown\n");
-+      
-+      if (cpu_has(c,X86_FEATURE_TSC)) {
-+              unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
-+              if (!freq)
-+                      freq = cpu_khz;
-+              seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-+                           freq / 1000, (freq % 1000));
-+      }
-+
-+      /* Cache size */
-+      if (c->x86_cache_size >= 0) 
-+              seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
-+      
-+#ifdef CONFIG_SMP
-+      if (smp_num_siblings * c->x86_max_cores > 1) {
-+              int cpu = c - cpu_data;
-+              seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]);
-+              seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu]));
-+              seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]);
-+              seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
-+      }
-+#endif        
-+
-+      seq_printf(m,
-+              "fpu\t\t: yes\n"
-+              "fpu_exception\t: yes\n"
-+              "cpuid level\t: %d\n"
-+              "wp\t\t: yes\n"
-+              "flags\t\t:",
-+                 c->cpuid_level);
-+
-+      { 
-+              int i; 
-+              for ( i = 0 ; i < 32*NCAPINTS ; i++ )
-+                      if ( test_bit(i, &c->x86_capability) &&
-+                           x86_cap_flags[i] != NULL )
-+                              seq_printf(m, " %s", x86_cap_flags[i]);
-+      }
-+              
-+      seq_printf(m, "\nbogomips\t: %lu.%02lu\n",
-+                 c->loops_per_jiffy/(500000/HZ),
-+                 (c->loops_per_jiffy/(5000/HZ)) % 100);
-+
-+      if (c->x86_tlbsize > 0) 
-+              seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize);
-+      seq_printf(m, "clflush size\t: %d\n", c->x86_clflush_size);
-+      seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment);
-+
-+      seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n", 
-+                 c->x86_phys_bits, c->x86_virt_bits);
-+
-+      seq_printf(m, "power management:");
-+      {
-+              unsigned i;
-+              for (i = 0; i < 32; i++) 
-+                      if (c->x86_power & (1 << i)) {
-+                              if (i < ARRAY_SIZE(x86_power_flags) &&
-+                                      x86_power_flags[i])
-+                                      seq_printf(m, "%s%s",
-+                                              x86_power_flags[i][0]?" ":"",
-+                                              x86_power_flags[i]);
-+                              else
-+                                      seq_printf(m, " [%d]", i);
-+                      }
-+      }
-+
-+      seq_printf(m, "\n\n");
-+
-+      return 0;
-+}
-+
-+static void *c_start(struct seq_file *m, loff_t *pos)
-+{
-+      return *pos < NR_CPUS ? cpu_data + *pos : NULL;
-+}
-+
-+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-+{
-+      ++*pos;
-+      return c_start(m, pos);
-+}
-+
-+static void c_stop(struct seq_file *m, void *v)
-+{
-+}
-+
-+struct seq_operations cpuinfo_op = {
-+      .start =c_start,
-+      .next = c_next,
-+      .stop = c_stop,
-+      .show = show_cpuinfo,
-+};
-+
-+static int __init run_dmi_scan(void)
-+{
-+      dmi_scan_machine();
-+      return 0;
-+}
-+core_initcall(run_dmi_scan);
-+
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/setup64-xen.c linux-2.6.16.33/arch/x86_64/kernel/setup64-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/setup64-xen.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/setup64-xen.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,360 @@
-+/* 
-+ * X86-64 specific CPU setup.
-+ * Copyright (C) 1995  Linus Torvalds
-+ * Copyright 2001, 2002, 2003 SuSE Labs / Andi Kleen.
-+ * See setup.c for older changelog.
-+ * $Id: setup64.c,v 1.12 2002/03/21 10:09:17 ak Exp $
-+ *
-+ * Jun Nakajima <jun.nakajima@intel.com> 
-+ *   Modified for Xen
-+ *
-+ */ 
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/string.h>
-+#include <linux/bootmem.h>
-+#include <linux/bitops.h>
-+#include <linux/module.h>
-+#include <asm/bootsetup.h>
-+#include <asm/pda.h>
-+#include <asm/pgtable.h>
-+#include <asm/processor.h>
-+#include <asm/desc.h>
-+#include <asm/atomic.h>
-+#include <asm/mmu_context.h>
-+#include <asm/smp.h>
-+#include <asm/i387.h>
-+#include <asm/percpu.h>
-+#include <asm/proto.h>
-+#include <asm/sections.h>
-+#ifdef CONFIG_XEN
-+#include <asm/hypervisor.h>
-+#endif
-+
-+char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
-+
-+cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
-+
-+struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly;
-+struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
-+
-+#ifndef CONFIG_X86_NO_IDT
-+struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; 
-+#endif
-+
-+char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
-+
-+unsigned long __supported_pte_mask __read_mostly = ~0UL;
-+static int do_not_nx __cpuinitdata = 0;
-+
-+/* noexec=on|off
-+Control non executable mappings for 64bit processes.
-+
-+on    Enable(default)
-+off   Disable
-+*/ 
-+int __init nonx_setup(char *str)
-+{
-+      if (!strncmp(str, "on", 2)) {
-+                __supported_pte_mask |= _PAGE_NX; 
-+              do_not_nx = 0; 
-+      } else if (!strncmp(str, "off", 3)) {
-+              do_not_nx = 1;
-+              __supported_pte_mask &= ~_PAGE_NX;
-+        }
-+      return 0;
-+} 
-+__setup("noexec=", nonx_setup);       /* parsed early actually */
-+
-+int force_personality32 = READ_IMPLIES_EXEC;
-+
-+/* noexec32=on|off
-+Control non executable heap for 32bit processes.
-+To control the stack too use noexec=off
-+
-+on    PROT_READ does not imply PROT_EXEC for 32bit processes
-+off   PROT_READ implies PROT_EXEC (default)
-+*/
-+static int __init nonx32_setup(char *str)
-+{
-+      if (!strcmp(str, "on"))
-+              force_personality32 &= ~READ_IMPLIES_EXEC;
-+      else if (!strcmp(str, "off"))
-+              force_personality32 |= READ_IMPLIES_EXEC;
-+      return 0;
-+}
-+__setup("noexec32=", nonx32_setup);
-+
-+/*
-+ * Great future plan:
-+ * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
-+ * Always point %gs to its beginning
-+ */
-+void __init setup_per_cpu_areas(void)
-+{ 
-+      int i;
-+      unsigned long size;
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+      prefill_possible_map();
-+#endif
-+
-+      /* Copy section for each CPU (we discard the original) */
-+      size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
-+#ifdef CONFIG_MODULES
-+      if (size < PERCPU_ENOUGH_ROOM)
-+              size = PERCPU_ENOUGH_ROOM;
-+#endif
-+
-+      for_each_cpu_mask (i, cpu_possible_map) {
-+              char *ptr;
-+
-+              if (!NODE_DATA(cpu_to_node(i))) {
-+                      printk("cpu with no node %d, num_online_nodes %d\n",
-+                             i, num_online_nodes());
-+                      ptr = alloc_bootmem(size);
-+              } else { 
-+                      ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
-+              }
-+              if (!ptr)
-+                      panic("Cannot allocate cpu data for CPU %d\n", i);
-+              cpu_pda(i)->data_offset = ptr - __per_cpu_start;
-+              memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
-+      }
-+} 
-+
-+#ifdef CONFIG_XEN
-+static void switch_pt(void)
-+{
-+      xen_pt_switch(__pa(init_level4_pgt));
-+        xen_new_user_pt(__pa(init_level4_user_pgt));
-+}
-+
-+void __cpuinit cpu_gdt_init(struct desc_ptr *gdt_descr)
-+{
-+      unsigned long frames[16];
-+      unsigned long va;
-+      int f;
-+
-+      for (va = gdt_descr->address, f = 0;
-+           va < gdt_descr->address + gdt_descr->size;
-+           va += PAGE_SIZE, f++) {
-+              frames[f] = virt_to_mfn(va);
-+              make_page_readonly(
-+                      (void *)va, XENFEAT_writable_descriptor_tables);
-+      }
-+      if (HYPERVISOR_set_gdt(frames, gdt_descr->size /
-+                               sizeof (struct desc_struct)))
-+              BUG();
-+}
-+#else
-+static void switch_pt(void)
-+{
-+      asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
-+}
-+
-+void __init cpu_gdt_init(struct desc_ptr *gdt_descr)
-+{
-+      asm volatile("lgdt %0" :: "m" (*gdt_descr));
-+      asm volatile("lidt %0" :: "m" (idt_descr));
-+}
-+#endif
-+
-+void pda_init(int cpu)
-+{ 
-+      struct x8664_pda *pda = cpu_pda(cpu);
-+
-+      /* Setup up data that may be needed in __get_free_pages early */
-+      asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); 
-+#ifndef CONFIG_XEN
-+      wrmsrl(MSR_GS_BASE, pda);
-+#else
-+      HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL, (unsigned long)pda);
-+#endif
-+      pda->cpunumber = cpu; 
-+      pda->irqcount = -1;
-+      pda->kernelstack = 
-+              (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; 
-+      pda->active_mm = &init_mm;
-+      pda->mmu_state = 0;
-+
-+      if (cpu == 0) {
-+#ifdef CONFIG_XEN
-+              xen_init_pt();
-+#endif
-+              /* others are initialized in smpboot.c */
-+              pda->pcurrent = &init_task;
-+              pda->irqstackptr = boot_cpu_stack; 
-+      } else {
-+              pda->irqstackptr = (char *)
-+                      __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
-+              if (!pda->irqstackptr)
-+                      panic("cannot allocate irqstack for cpu %d", cpu); 
-+      }
-+
-+      switch_pt();
-+
-+      pda->irqstackptr += IRQSTACKSIZE-64;
-+} 
-+
-+#ifndef CONFIG_X86_NO_TSS
-+char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]
-+__attribute__((section(".bss.page_aligned")));
-+#endif
-+
-+/* May not be marked __init: used by software suspend */
-+void syscall_init(void)
-+{
-+#ifndef CONFIG_XEN
-+      /* 
-+       * LSTAR and STAR live in a bit strange symbiosis.
-+       * They both write to the same internal register. STAR allows to set CS/DS
-+       * but only a 32bit target. LSTAR sets the 64bit rip.    
-+       */ 
-+      wrmsrl(MSR_STAR,  ((u64)__USER32_CS)<<48  | ((u64)__KERNEL_CS)<<32); 
-+      wrmsrl(MSR_LSTAR, system_call); 
-+
-+      /* Flags to clear on syscall */
-+      wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); 
-+#endif
-+#ifdef CONFIG_IA32_EMULATION                  
-+      syscall32_cpu_init ();
-+#endif
-+}
-+
-+void __cpuinit check_efer(void)
-+{
-+      unsigned long efer;
-+
-+      rdmsrl(MSR_EFER, efer); 
-+        if (!(efer & EFER_NX) || do_not_nx) { 
-+                __supported_pte_mask &= ~_PAGE_NX; 
-+        }       
-+}
-+
-+/*
-+ * cpu_init() initializes state that is per-CPU. Some data is already
-+ * initialized (naturally) in the bootstrap process, such as the GDT
-+ * and IDT. We reload them nevertheless, this function acts as a
-+ * 'CPU state barrier', nothing should get across.
-+ * A lot of state is already set up in PDA init.
-+ */
-+void __cpuinit cpu_init (void)
-+{
-+      int cpu = stack_smp_processor_id();
-+#ifndef CONFIG_X86_NO_TSS
-+      struct tss_struct *t = &per_cpu(init_tss, cpu);
-+      unsigned long v; 
-+      char *estacks = NULL; 
-+      unsigned i;
-+#endif
-+      struct task_struct *me;
-+
-+      /* CPU 0 is initialised in head64.c */
-+      if (cpu != 0) {
-+              pda_init(cpu);
-+              zap_low_mappings(cpu);
-+      }
-+#ifndef CONFIG_X86_NO_TSS
-+      else
-+              estacks = boot_exception_stacks; 
-+#endif
-+
-+      me = current;
-+
-+      if (cpu_test_and_set(cpu, cpu_initialized))
-+              panic("CPU#%d already initialized!\n", cpu);
-+
-+      printk("Initializing CPU#%d\n", cpu);
-+
-+      clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
-+
-+      /*
-+       * Initialize the per-CPU GDT with the boot GDT,
-+       * and set up the GDT descriptor:
-+       */
-+#ifndef CONFIG_XEN 
-+      if (cpu)
-+              memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
-+#endif
-+
-+      cpu_gdt_descr[cpu].size = GDT_SIZE;
-+      cpu_gdt_init(&cpu_gdt_descr[cpu]);
-+
-+      memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
-+      syscall_init();
-+
-+      wrmsrl(MSR_FS_BASE, 0);
-+      wrmsrl(MSR_KERNEL_GS_BASE, 0);
-+      barrier(); 
-+
-+      check_efer();
-+
-+#ifndef CONFIG_X86_NO_TSS
-+      /*
-+       * set up and load the per-CPU TSS
-+       */
-+      for (v = 0; v < N_EXCEPTION_STACKS; v++) {
-+              if (cpu) {
-+                      static const unsigned int order[N_EXCEPTION_STACKS] = {
-+                              [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
-+                              [DEBUG_STACK - 1] = DEBUG_STACK_ORDER
-+                      };
-+
-+                      estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]);
-+                      if (!estacks)
-+                              panic("Cannot allocate exception stack %ld %d\n",
-+                                    v, cpu); 
-+              }
-+              switch (v + 1) {
-+#if DEBUG_STKSZ > EXCEPTION_STKSZ
-+              case DEBUG_STACK:
-+                      cpu_pda[cpu].debugstack = (unsigned long)estacks;
-+                      estacks += DEBUG_STKSZ;
-+                      break;
-+#endif
-+              default:
-+                      estacks += EXCEPTION_STKSZ;
-+                      break;
-+              }
-+              t->ist[v] = (unsigned long)estacks;
-+      }
-+
-+      t->io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
-+      /*
-+       * <= is required because the CPU will access up to
-+       * 8 bits beyond the end of the IO permission bitmap.
-+       */
-+      for (i = 0; i <= IO_BITMAP_LONGS; i++)
-+              t->io_bitmap[i] = ~0UL;
-+#endif
-+
-+      atomic_inc(&init_mm.mm_count);
-+      me->active_mm = &init_mm;
-+      if (me->mm)
-+              BUG();
-+      enter_lazy_tlb(&init_mm, me);
-+
-+#ifndef CONFIG_X86_NO_TSS
-+      set_tss_desc(cpu, t);
-+#endif
-+#ifndef CONFIG_XEN
-+      load_TR_desc();
-+#endif
-+      load_LDT(&init_mm.context);
-+
-+      /*
-+       * Clear all 6 debug registers:
-+       */
-+
-+      set_debug(0UL, 0);
-+      set_debug(0UL, 1);
-+      set_debug(0UL, 2);
-+      set_debug(0UL, 3);
-+      set_debug(0UL, 6);
-+      set_debug(0UL, 7);
-+
-+      fpu_init(); 
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/smp-xen.c linux-2.6.16.33/arch/x86_64/kernel/smp-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/smp-xen.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/smp-xen.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,596 @@
-+/*
-+ *    Intel SMP support routines.
-+ *
-+ *    (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
-+ *    (c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com>
-+ *      (c) 2002,2003 Andi Kleen, SuSE Labs.
-+ *
-+ *    This code is released under the GNU General Public License version 2 or
-+ *    later.
-+ */
-+
-+#include <linux/init.h>
-+
-+#include <linux/mm.h>
-+#include <linux/delay.h>
-+#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
-+#include <linux/smp.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/mtrr.h>
-+#include <asm/pgalloc.h>
-+#include <asm/tlbflush.h>
-+#include <asm/mach_apic.h>
-+#include <asm/mmu_context.h>
-+#include <asm/proto.h>
-+#include <asm/apicdef.h>
-+#include <asm/idle.h>
-+#ifdef CONFIG_XEN
-+#include <xen/evtchn.h>
-+#endif
-+
-+#ifndef CONFIG_XEN
-+/*
-+ *    Smarter SMP flushing macros. 
-+ *            c/o Linus Torvalds.
-+ *
-+ *    These mean you can really definitely utterly forget about
-+ *    writing to user space from interrupts. (Its not allowed anyway).
-+ *
-+ *    Optimizations Manfred Spraul <manfred@colorfullife.com>
-+ *
-+ *    More scalable flush, from Andi Kleen
-+ *
-+ *    To avoid global state use 8 different call vectors.
-+ *    Each CPU uses a specific vector to trigger flushes on other
-+ *    CPUs. Depending on the received vector the target CPUs look into
-+ *    the right per cpu variable for the flush data.
-+ *
-+ *    With more than 8 CPUs they are hashed to the 8 available
-+ *    vectors. The limited global vector space forces us to this right now.
-+ *    In future when interrupts are split into per CPU domains this could be
-+ *    fixed, at the cost of triggering multiple IPIs in some cases.
-+ */
-+
-+union smp_flush_state {
-+      struct {
-+              cpumask_t flush_cpumask;
-+              struct mm_struct *flush_mm;
-+              unsigned long flush_va;
-+#define FLUSH_ALL     -1ULL
-+              spinlock_t tlbstate_lock;
-+      };
-+      char pad[SMP_CACHE_BYTES];
-+} ____cacheline_aligned;
-+
-+/* State is put into the per CPU data section, but padded
-+   to a full cache line because other CPUs can access it and we don't
-+   want false sharing in the per cpu data segment. */
-+static DEFINE_PER_CPU(union smp_flush_state, flush_state);
-+#endif
-+
-+/*
-+ * We cannot call mmdrop() because we are in interrupt context, 
-+ * instead update mm->cpu_vm_mask.
-+ */
-+static inline void leave_mm(unsigned long cpu)
-+{
-+      if (read_pda(mmu_state) == TLBSTATE_OK)
-+              BUG();
-+      clear_bit(cpu, &read_pda(active_mm)->cpu_vm_mask);
-+      load_cr3(swapper_pg_dir);
-+}
-+
-+#ifndef CONFIG_XEN
-+/*
-+ *
-+ * The flush IPI assumes that a thread switch happens in this order:
-+ * [cpu0: the cpu that switches]
-+ * 1) switch_mm() either 1a) or 1b)
-+ * 1a) thread switch to a different mm
-+ * 1a1) clear_bit(cpu, &old_mm->cpu_vm_mask);
-+ *    Stop ipi delivery for the old mm. This is not synchronized with
-+ *    the other cpus, but smp_invalidate_interrupt ignore flush ipis
-+ *    for the wrong mm, and in the worst case we perform a superfluous
-+ *    tlb flush.
-+ * 1a2) set cpu mmu_state to TLBSTATE_OK
-+ *    Now the smp_invalidate_interrupt won't call leave_mm if cpu0
-+ *    was in lazy tlb mode.
-+ * 1a3) update cpu active_mm
-+ *    Now cpu0 accepts tlb flushes for the new mm.
-+ * 1a4) set_bit(cpu, &new_mm->cpu_vm_mask);
-+ *    Now the other cpus will send tlb flush ipis.
-+ * 1a4) change cr3.
-+ * 1b) thread switch without mm change
-+ *    cpu active_mm is correct, cpu0 already handles
-+ *    flush ipis.
-+ * 1b1) set cpu mmu_state to TLBSTATE_OK
-+ * 1b2) test_and_set the cpu bit in cpu_vm_mask.
-+ *    Atomically set the bit [other cpus will start sending flush ipis],
-+ *    and test the bit.
-+ * 1b3) if the bit was 0: leave_mm was called, flush the tlb.
-+ * 2) switch %%esp, ie current
-+ *
-+ * The interrupt must handle 2 special cases:
-+ * - cr3 is changed before %%esp, ie. it cannot use current->{active_,}mm.
-+ * - the cpu performs speculative tlb reads, i.e. even if the cpu only
-+ *   runs in kernel space, the cpu could load tlb entries for user space
-+ *   pages.
-+ *
-+ * The good news is that cpu mmu_state is local to each cpu, no
-+ * write/read ordering problems.
-+ */
-+
-+/*
-+ * TLB flush IPI:
-+ *
-+ * 1) Flush the tlb entries if the cpu uses the mm that's being flushed.
-+ * 2) Leave the mm if we are in the lazy tlb mode.
-+ *
-+ * Interrupts are disabled.
-+ */
-+
-+asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
-+{
-+      int cpu;
-+      int sender;
-+      union smp_flush_state *f;
-+
-+      cpu = smp_processor_id();
-+      /*
-+       * orig_rax contains the interrupt vector - 256.
-+       * Use that to determine where the sender put the data.
-+       */
-+      sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
-+      f = &per_cpu(flush_state, sender);
-+
-+      if (!cpu_isset(cpu, f->flush_cpumask))
-+              goto out;
-+              /* 
-+               * This was a BUG() but until someone can quote me the
-+               * line from the intel manual that guarantees an IPI to
-+               * multiple CPUs is retried _only_ on the erroring CPUs
-+               * its staying as a return
-+               *
-+               * BUG();
-+               */
-+               
-+      if (f->flush_mm == read_pda(active_mm)) {
-+              if (read_pda(mmu_state) == TLBSTATE_OK) {
-+                      if (f->flush_va == FLUSH_ALL)
-+                              local_flush_tlb();
-+                      else
-+                              __flush_tlb_one(f->flush_va);
-+              } else
-+                      leave_mm(cpu);
-+      }
-+out:
-+      ack_APIC_irq();
-+      cpu_clear(cpu, f->flush_cpumask);
-+}
-+
-+static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
-+                                              unsigned long va)
-+{
-+      int sender;
-+      union smp_flush_state *f;
-+
-+      /* Caller has disabled preemption */
-+      sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
-+      f = &per_cpu(flush_state, sender);
-+
-+      /* Could avoid this lock when
-+         num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is
-+         probably not worth checking this for a cache-hot lock. */
-+      spin_lock(&f->tlbstate_lock);
-+
-+      f->flush_mm = mm;
-+      f->flush_va = va;
-+      cpus_or(f->flush_cpumask, cpumask, f->flush_cpumask);
-+
-+      /*
-+       * We have to send the IPI only to
-+       * CPUs affected.
-+       */
-+      send_IPI_mask(cpumask, INVALIDATE_TLB_VECTOR_START + sender);
-+
-+      while (!cpus_empty(f->flush_cpumask))
-+              cpu_relax();
-+
-+      f->flush_mm = NULL;
-+      f->flush_va = 0;
-+      spin_unlock(&f->tlbstate_lock);
-+}
-+
-+int __cpuinit init_smp_flush(void)
-+{
-+      int i;
-+      for_each_cpu_mask(i, cpu_possible_map) {
-+              spin_lock_init(&per_cpu(flush_state.tlbstate_lock, i));
-+      }
-+      return 0;
-+}
-+
-+core_initcall(init_smp_flush);
-+      
-+void flush_tlb_current_task(void)
-+{
-+      struct mm_struct *mm = current->mm;
-+      cpumask_t cpu_mask;
-+
-+      preempt_disable();
-+      cpu_mask = mm->cpu_vm_mask;
-+      cpu_clear(smp_processor_id(), cpu_mask);
-+
-+      local_flush_tlb();
-+      if (!cpus_empty(cpu_mask))
-+              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-+      preempt_enable();
-+}
-+
-+void flush_tlb_mm (struct mm_struct * mm)
-+{
-+      cpumask_t cpu_mask;
-+
-+      preempt_disable();
-+      cpu_mask = mm->cpu_vm_mask;
-+      cpu_clear(smp_processor_id(), cpu_mask);
-+
-+      if (current->active_mm == mm) {
-+              if (current->mm)
-+                      local_flush_tlb();
-+              else
-+                      leave_mm(smp_processor_id());
-+      }
-+      if (!cpus_empty(cpu_mask))
-+              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-+
-+      preempt_enable();
-+}
-+
-+void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
-+{
-+      struct mm_struct *mm = vma->vm_mm;
-+      cpumask_t cpu_mask;
-+
-+      preempt_disable();
-+      cpu_mask = mm->cpu_vm_mask;
-+      cpu_clear(smp_processor_id(), cpu_mask);
-+
-+      if (current->active_mm == mm) {
-+              if(current->mm)
-+                      __flush_tlb_one(va);
-+               else
-+                      leave_mm(smp_processor_id());
-+      }
-+
-+      if (!cpus_empty(cpu_mask))
-+              flush_tlb_others(cpu_mask, mm, va);
-+
-+      preempt_enable();
-+}
-+
-+static void do_flush_tlb_all(void* info)
-+{
-+      unsigned long cpu = smp_processor_id();
-+
-+      __flush_tlb_all();
-+      if (read_pda(mmu_state) == TLBSTATE_LAZY)
-+              leave_mm(cpu);
-+}
-+
-+void flush_tlb_all(void)
-+{
-+      on_each_cpu(do_flush_tlb_all, NULL, 1, 1);
-+}
-+#else
-+asmlinkage void smp_invalidate_interrupt (void)
-+{ return; }
-+void flush_tlb_current_task(void)
-+{ xen_tlb_flush_mask(&current->mm->cpu_vm_mask); }
-+void flush_tlb_mm (struct mm_struct * mm)
-+{ xen_tlb_flush_mask(&mm->cpu_vm_mask); }
-+void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
-+{ xen_invlpg_mask(&vma->vm_mm->cpu_vm_mask, va); }
-+void flush_tlb_all(void)
-+{ xen_tlb_flush_all(); }
-+#endif /* Xen */
-+
-+/*
-+ * this function sends a 'reschedule' IPI to another CPU.
-+ * it goes straight through and wastes no time serializing
-+ * anything. Worst case is that we lose a reschedule ...
-+ */
-+
-+void smp_send_reschedule(int cpu)
-+{
-+      send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
-+}
-+
-+/*
-+ * Structure and data for smp_call_function(). This is designed to minimise
-+ * static memory requirements. It also looks cleaner.
-+ */
-+static DEFINE_SPINLOCK(call_lock);
-+
-+struct call_data_struct {
-+      void (*func) (void *info);
-+      void *info;
-+      atomic_t started;
-+      atomic_t finished;
-+      int wait;
-+};
-+
-+static struct call_data_struct * call_data;
-+
-+void lock_ipi_call_lock(void)
-+{
-+      spin_lock_irq(&call_lock);
-+}
-+
-+void unlock_ipi_call_lock(void)
-+{
-+      spin_unlock_irq(&call_lock);
-+}
-+
-+/*
-+ * this function sends a 'generic call function' IPI to one other CPU
-+ * in the system.
-+ *
-+ * cpu is a standard Linux logical CPU number.
-+ */
-+static void
-+__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
-+                              int nonatomic, int wait)
-+{
-+      struct call_data_struct data;
-+      int cpus = 1;
-+
-+      data.func = func;
-+      data.info = info;
-+      atomic_set(&data.started, 0);
-+      data.wait = wait;
-+      if (wait)
-+              atomic_set(&data.finished, 0);
-+
-+      call_data = &data;
-+      wmb();
-+      /* Send a message to all other CPUs and wait for them to respond */
-+      send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
-+
-+      /* Wait for response */
-+      while (atomic_read(&data.started) != cpus)
-+              cpu_relax();
-+
-+      if (!wait)
-+              return;
-+
-+      while (atomic_read(&data.finished) != cpus)
-+              cpu_relax();
-+}
-+
-+/*
-+ * smp_call_function_single - Run a function on another CPU
-+ * @func: The function to run. This must be fast and non-blocking.
-+ * @info: An arbitrary pointer to pass to the function.
-+ * @nonatomic: Currently unused.
-+ * @wait: If true, wait until function has completed on other CPUs.
-+ *
-+ * Retrurns 0 on success, else a negative status code.
-+ *
-+ * Does not return until the remote CPU is nearly ready to execute <func>
-+ * or is or has executed.
-+ */
-+
-+int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
-+      int nonatomic, int wait)
-+{
-+      /* prevent preemption and reschedule on another processor */
-+      int me = get_cpu();
-+      if (cpu == me) {
-+              WARN_ON(1);
-+              put_cpu();
-+              return -EBUSY;
-+      }
-+      spin_lock_bh(&call_lock);
-+      __smp_call_function_single(cpu, func, info, nonatomic, wait);
-+      spin_unlock_bh(&call_lock);
-+      put_cpu();
-+      return 0;
-+}
-+
-+/*
-+ * this function sends a 'generic call function' IPI to all other CPUs
-+ * in the system.
-+ */
-+static void __smp_call_function (void (*func) (void *info), void *info,
-+                              int nonatomic, int wait)
-+{
-+      struct call_data_struct data;
-+      int cpus = num_online_cpus()-1;
-+
-+      if (!cpus)
-+              return;
-+
-+      data.func = func;
-+      data.info = info;
-+      atomic_set(&data.started, 0);
-+      data.wait = wait;
-+      if (wait)
-+              atomic_set(&data.finished, 0);
-+
-+      call_data = &data;
-+      wmb();
-+      /* Send a message to all other CPUs and wait for them to respond */
-+      send_IPI_allbutself(CALL_FUNCTION_VECTOR);
-+
-+      /* Wait for response */
-+      while (atomic_read(&data.started) != cpus)
-+#ifndef CONFIG_XEN
-+              cpu_relax();
-+#else
-+              barrier();
-+#endif
-+
-+      if (!wait)
-+              return;
-+
-+      while (atomic_read(&data.finished) != cpus)
-+#ifndef CONFIG_XEN
-+              cpu_relax();
-+#else
-+              barrier();
-+#endif
-+}
-+
-+/*
-+ * smp_call_function - run a function on all other CPUs.
-+ * @func: The function to run. This must be fast and non-blocking.
-+ * @info: An arbitrary pointer to pass to the function.
-+ * @nonatomic: currently unused.
-+ * @wait: If true, wait (atomically) until function has completed on other
-+ *        CPUs.
-+ *
-+ * Returns 0 on success, else a negative status code. Does not return until
-+ * remote CPUs are nearly ready to execute func or are or have executed.
-+ *
-+ * You must not call this function with disabled interrupts or from a
-+ * hardware interrupt handler or from a bottom half handler.
-+ * Actually there are a few legal cases, like panic.
-+ */
-+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
-+                      int wait)
-+{
-+      spin_lock(&call_lock);
-+      __smp_call_function(func,info,nonatomic,wait);
-+      spin_unlock(&call_lock);
-+      return 0;
-+}
-+
-+void smp_stop_cpu(void)
-+{
-+      unsigned long flags;
-+      /*
-+       * Remove this CPU:
-+       */
-+      cpu_clear(smp_processor_id(), cpu_online_map);
-+      local_irq_save(flags);
-+#ifndef CONFIG_XEN
-+      disable_local_APIC();
-+#endif
-+      local_irq_restore(flags); 
-+}
-+
-+static void smp_really_stop_cpu(void *dummy)
-+{
-+      smp_stop_cpu(); 
-+      for (;;) 
-+              halt();
-+} 
-+
-+void smp_send_stop(void)
-+{
-+      int nolock = 0;
-+#ifndef CONFIG_XEN
-+      if (reboot_force)
-+              return;
-+#endif
-+      /* Don't deadlock on the call lock in panic */
-+      if (!spin_trylock(&call_lock)) {
-+              /* ignore locking because we have paniced anyways */
-+              nolock = 1;
-+      }
-+      __smp_call_function(smp_really_stop_cpu, NULL, 0, 0);
-+      if (!nolock)
-+              spin_unlock(&call_lock);
-+
-+      local_irq_disable();
-+#ifndef CONFIG_XEN
-+      disable_local_APIC();
-+#endif
-+      local_irq_enable();
-+}
-+
-+/*
-+ * Reschedule call back. Nothing to do,
-+ * all the work is done automatically when
-+ * we return from the interrupt.
-+ */
-+#ifndef CONFIG_XEN
-+asmlinkage void smp_reschedule_interrupt(void)
-+#else
-+asmlinkage irqreturn_t smp_reschedule_interrupt(void)
-+#endif
-+{
-+#ifndef CONFIG_XEN
-+      ack_APIC_irq();
-+#else
-+      return IRQ_HANDLED;
-+#endif
-+}
-+
-+#ifndef CONFIG_XEN
-+asmlinkage void smp_call_function_interrupt(void)
-+#else
-+asmlinkage irqreturn_t smp_call_function_interrupt(void)
-+#endif
-+{
-+      void (*func) (void *info) = call_data->func;
-+      void *info = call_data->info;
-+      int wait = call_data->wait;
-+
-+#ifndef CONFIG_XEN
-+      ack_APIC_irq();
-+#endif
-+      /*
-+       * Notify initiating CPU that I've grabbed the data and am
-+       * about to execute the function
-+       */
-+      mb();
-+      atomic_inc(&call_data->started);
-+      /*
-+       * At this point the info structure may be out of scope unless wait==1
-+       */
-+      exit_idle();
-+      irq_enter();
-+      (*func)(info);
-+      irq_exit();
-+      if (wait) {
-+              mb();
-+              atomic_inc(&call_data->finished);
-+      }
-+#ifdef CONFIG_XEN
-+      return IRQ_HANDLED;
-+#endif
-+}
-+
-+int safe_smp_processor_id(void)
-+{
-+#ifdef CONFIG_XEN
-+      return smp_processor_id();
-+#else
-+      int apicid, i;
-+
-+      if (disable_apic)
-+              return 0;
-+
-+      apicid = hard_smp_processor_id();
-+      if (x86_cpu_to_apicid[apicid] == apicid)
-+              return apicid;
-+
-+      for (i = 0; i < NR_CPUS; ++i) {
-+              if (x86_cpu_to_apicid[i] == apicid)
-+                      return i;
-+      }
-+
-+      /* No entries in x86_cpu_to_apicid?  Either no MPS|ACPI,
-+       * or called too early.  Either way, we must be CPU 0. */
-+              if (x86_cpu_to_apicid[0] == BAD_APICID)
-+              return 0;
-+
-+      return 0; /* Should not happen */
-+#endif
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/smp.c linux-2.6.16.33/arch/x86_64/kernel/smp.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/smp.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/smp.c   2007-05-23 21:00:01.000000000 +0000
-@@ -135,10 +135,10 @@
-       cpu = smp_processor_id();
-       /*
--       * orig_rax contains the interrupt vector - 256.
-+       * orig_rax contains the negated interrupt vector.
-        * Use that to determine where the sender put the data.
-        */
--      sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
-+      sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
-       f = &per_cpu(flush_state, sender);
-       if (!cpu_isset(cpu, f->flush_cpumask))
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/traps-xen.c linux-2.6.16.33/arch/x86_64/kernel/traps-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/traps-xen.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/traps-xen.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1028 @@
-+/*
-+ *  linux/arch/x86-64/traps.c
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
-+ *
-+ *  Pentium III FXSR, SSE support
-+ *    Gareth Hughes <gareth@valinux.com>, May 2000
-+ *
-+ *  $Id: traps.c,v 1.36 2002/03/24 11:09:10 ak Exp $
-+ */
-+
-+/*
-+ * 'Traps.c' handles hardware traps and faults after we have saved some
-+ * state in 'entry.S'.
-+ */
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/timer.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/spinlock.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/nmi.h>
-+#include <linux/kprobes.h>
-+#include <linux/kexec.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <asm/atomic.h>
-+#include <asm/debugreg.h>
-+#include <asm/desc.h>
-+#include <asm/i387.h>
-+#include <asm/kdebug.h>
-+#include <asm/processor.h>
-+
-+#include <asm/smp.h>
-+#include <asm/pgalloc.h>
-+#include <asm/pda.h>
-+#include <asm/proto.h>
-+#include <asm/nmi.h>
-+
-+#ifndef CONFIG_X86_NO_IDT
-+extern struct gate_struct idt_table[256]; 
-+#endif
-+
-+asmlinkage void divide_error(void);
-+asmlinkage void debug(void);
-+asmlinkage void nmi(void);
-+asmlinkage void int3(void);
-+asmlinkage void overflow(void);
-+asmlinkage void bounds(void);
-+asmlinkage void invalid_op(void);
-+asmlinkage void device_not_available(void);
-+asmlinkage void double_fault(void);
-+asmlinkage void coprocessor_segment_overrun(void);
-+asmlinkage void invalid_TSS(void);
-+asmlinkage void segment_not_present(void);
-+asmlinkage void stack_segment(void);
-+asmlinkage void general_protection(void);
-+asmlinkage void page_fault(void);
-+asmlinkage void coprocessor_error(void);
-+asmlinkage void simd_coprocessor_error(void);
-+asmlinkage void reserved(void);
-+asmlinkage void alignment_check(void);
-+asmlinkage void machine_check(void);
-+asmlinkage void spurious_interrupt_bug(void);
-+
-+struct notifier_block *die_chain;
-+static DEFINE_SPINLOCK(die_notifier_lock);
-+
-+int register_die_notifier(struct notifier_block *nb)
-+{
-+      int err = 0;
-+      unsigned long flags;
-+      spin_lock_irqsave(&die_notifier_lock, flags);
-+      err = notifier_chain_register(&die_chain, nb);
-+      spin_unlock_irqrestore(&die_notifier_lock, flags);
-+      return err;
-+}
-+
-+static inline void conditional_sti(struct pt_regs *regs)
-+{
-+      if (regs->eflags & X86_EFLAGS_IF)
-+              local_irq_enable();
-+}
-+
-+static inline void preempt_conditional_sti(struct pt_regs *regs)
-+{
-+      preempt_disable();
-+      if (regs->eflags & X86_EFLAGS_IF)
-+              local_irq_enable();
-+}
-+
-+static inline void preempt_conditional_cli(struct pt_regs *regs)
-+{
-+      if (regs->eflags & X86_EFLAGS_IF)
-+              local_irq_disable();
-+      preempt_enable_no_resched();
-+}
-+
-+static int kstack_depth_to_print = 10;
-+
-+#ifdef CONFIG_KALLSYMS
-+#include <linux/kallsyms.h> 
-+int printk_address(unsigned long address)
-+{ 
-+      unsigned long offset = 0, symsize;
-+      const char *symname;
-+      char *modname;
-+      char *delim = ":"; 
-+      char namebuf[128];
-+
-+      symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); 
-+      if (!symname) 
-+              return printk("[<%016lx>]", address);
-+      if (!modname) 
-+              modname = delim = "";           
-+        return printk("<%016lx>{%s%s%s%s%+ld}",
-+                    address,delim,modname,delim,symname,offset); 
-+} 
-+#else
-+int printk_address(unsigned long address)
-+{ 
-+      return printk("[<%016lx>]", address);
-+} 
-+#endif
-+
-+static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
-+                                      unsigned *usedp, const char **idp)
-+{
-+#ifndef CONFIG_X86_NO_TSS
-+      static char ids[][8] = {
-+              [DEBUG_STACK - 1] = "#DB",
-+              [NMI_STACK - 1] = "NMI",
-+              [DOUBLEFAULT_STACK - 1] = "#DF",
-+              [STACKFAULT_STACK - 1] = "#SS",
-+              [MCE_STACK - 1] = "#MC",
-+#if DEBUG_STKSZ > EXCEPTION_STKSZ
-+              [N_EXCEPTION_STACKS ... N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
-+#endif
-+      };
-+      unsigned k;
-+
-+      for (k = 0; k < N_EXCEPTION_STACKS; k++) {
-+              unsigned long end;
-+
-+              switch (k + 1) {
-+#if DEBUG_STKSZ > EXCEPTION_STKSZ
-+              case DEBUG_STACK:
-+                      end = cpu_pda(cpu)->debugstack + DEBUG_STKSZ;
-+                      break;
-+#endif
-+              default:
-+                      end = per_cpu(init_tss, cpu).ist[k];
-+                      break;
-+              }
-+              if (stack >= end)
-+                      continue;
-+              if (stack >= end - EXCEPTION_STKSZ) {
-+                      if (*usedp & (1U << k))
-+                              break;
-+                      *usedp |= 1U << k;
-+                      *idp = ids[k];
-+                      return (unsigned long *)end;
-+              }
-+#if DEBUG_STKSZ > EXCEPTION_STKSZ
-+              if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) {
-+                      unsigned j = N_EXCEPTION_STACKS - 1;
-+
-+                      do {
-+                              ++j;
-+                              end -= EXCEPTION_STKSZ;
-+                              ids[j][4] = '1' + (j - N_EXCEPTION_STACKS);
-+                      } while (stack < end - EXCEPTION_STKSZ);
-+                      if (*usedp & (1U << j))
-+                              break;
-+                      *usedp |= 1U << j;
-+                      *idp = ids[j];
-+                      return (unsigned long *)end;
-+              }
-+#endif
-+      }
-+#endif
-+      return NULL;
-+}
-+
-+/*
-+ * x86-64 can have upto three kernel stacks: 
-+ * process stack
-+ * interrupt stack
-+ * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
-+ */
-+
-+void show_trace(unsigned long *stack)
-+{
-+      const unsigned cpu = safe_smp_processor_id();
-+      unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
-+      int i;
-+      unsigned used = 0;
-+
-+      printk("\nCall Trace:");
-+
-+#define HANDLE_STACK(cond) \
-+      do while (cond) { \
-+              unsigned long addr = *stack++; \
-+              if (kernel_text_address(addr)) { \
-+                      if (i > 50) { \
-+                              printk("\n       "); \
-+                              i = 0; \
-+                      } \
-+                      else \
-+                              i += printk(" "); \
-+                      /* \
-+                       * If the address is either in the text segment of the \
-+                       * kernel, or in the region which contains vmalloc'ed \
-+                       * memory, it *may* be the address of a calling \
-+                       * routine; if so, print it so that someone tracing \
-+                       * down the cause of the crash will be able to figure \
-+                       * out the call path that was taken. \
-+                       */ \
-+                      i += printk_address(addr); \
-+              } \
-+      } while (0)
-+
-+      for(i = 11; ; ) {
-+              const char *id;
-+              unsigned long *estack_end;
-+              estack_end = in_exception_stack(cpu, (unsigned long)stack,
-+                                              &used, &id);
-+
-+              if (estack_end) {
-+                      i += printk(" <%s>", id);
-+                      HANDLE_STACK (stack < estack_end);
-+                      i += printk(" <EOE>");
-+                      stack = (unsigned long *) estack_end[-2];
-+                      continue;
-+              }
-+              if (irqstack_end) {
-+                      unsigned long *irqstack;
-+                      irqstack = irqstack_end -
-+                              (IRQSTACKSIZE - 64) / sizeof(*irqstack);
-+
-+                      if (stack >= irqstack && stack < irqstack_end) {
-+                              i += printk(" <IRQ>");
-+                              HANDLE_STACK (stack < irqstack_end);
-+                              stack = (unsigned long *) (irqstack_end[-1]);
-+                              irqstack_end = NULL;
-+                              i += printk(" <EOI>");
-+                              continue;
-+                      }
-+              }
-+              break;
-+      }
-+
-+      HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0);
-+#undef HANDLE_STACK
-+      printk("\n");
-+}
-+
-+void show_stack(struct task_struct *tsk, unsigned long * rsp)
-+{
-+      unsigned long *stack;
-+      int i;
-+      const int cpu = safe_smp_processor_id();
-+      unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr);
-+      unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
-+
-+      // debugging aid: "show_stack(NULL, NULL);" prints the
-+      // back trace for this cpu.
-+
-+      if (rsp == NULL) {
-+              if (tsk)
-+                      rsp = (unsigned long *)tsk->thread.rsp;
-+              else
-+                      rsp = (unsigned long *)&rsp;
-+      }
-+
-+      stack = rsp;
-+      for(i=0; i < kstack_depth_to_print; i++) {
-+              if (stack >= irqstack && stack <= irqstack_end) {
-+                      if (stack == irqstack_end) {
-+                              stack = (unsigned long *) (irqstack_end[-1]);
-+                              printk(" <EOI> ");
-+                      }
-+              } else {
-+              if (((long) stack & (THREAD_SIZE-1)) == 0)
-+                      break;
-+              }
-+              if (i && ((i % 4) == 0))
-+                      printk("\n       ");
-+              printk("%016lx ", *stack++);
-+              touch_nmi_watchdog();
-+      }
-+      show_trace((unsigned long *)rsp);
-+}
-+
-+/*
-+ * The architecture-independent dump_stack generator
-+ */
-+void dump_stack(void)
-+{
-+      unsigned long dummy;
-+      show_trace(&dummy);
-+}
-+
-+EXPORT_SYMBOL(dump_stack);
-+
-+void show_registers(struct pt_regs *regs)
-+{
-+      int i;
-+      int in_kernel = !user_mode(regs);
-+      unsigned long rsp;
-+      const int cpu = safe_smp_processor_id(); 
-+      struct task_struct *cur = cpu_pda(cpu)->pcurrent;
-+
-+              rsp = regs->rsp;
-+
-+      printk("CPU %d ", cpu);
-+      __show_regs(regs);
-+      printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
-+              cur->comm, cur->pid, task_thread_info(cur), cur);
-+
-+      /*
-+       * When in-kernel, we also print out the stack and code at the
-+       * time of the fault..
-+       */
-+      if (in_kernel) {
-+
-+              printk("Stack: ");
-+              show_stack(NULL, (unsigned long*)rsp);
-+
-+              printk("\nCode: ");
-+              if(regs->rip < PAGE_OFFSET)
-+                      goto bad;
-+
-+              for(i=0;i<20;i++)
-+              {
-+                      unsigned char c;
-+                      if(__get_user(c, &((unsigned char*)regs->rip)[i])) {
-+bad:
-+                              printk(" Bad RIP value.");
-+                              break;
-+                      }
-+                      printk("%02x ", c);
-+              }
-+      }
-+      printk("\n");
-+}     
-+
-+void handle_BUG(struct pt_regs *regs)
-+{ 
-+      struct bug_frame f;
-+      long len;
-+      const char *prefix = "";
-+
-+      if (user_mode(regs))
-+              return; 
-+      if (__copy_from_user(&f, (const void __user *) regs->rip,
-+                           sizeof(struct bug_frame)))
-+              return; 
-+      if (f.filename >= 0 ||
-+          f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) 
-+              return;
-+      len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1;
-+      if (len < 0 || len >= PATH_MAX)
-+              f.filename = (int)(long)"unmapped filename";
-+      else if (len > 50) {
-+              f.filename += len - 50;
-+              prefix = "...";
-+      }
-+      printk("----------- [cut here ] --------- [please bite here ] ---------\n");
-+      printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line);
-+} 
-+
-+#ifdef CONFIG_BUG
-+void out_of_line_bug(void)
-+{ 
-+      BUG(); 
-+} 
-+#endif
-+
-+static DEFINE_SPINLOCK(die_lock);
-+static int die_owner = -1;
-+
-+unsigned __kprobes long oops_begin(void)
-+{
-+      int cpu = safe_smp_processor_id();
-+      unsigned long flags;
-+
-+      /* racy, but better than risking deadlock. */
-+      local_irq_save(flags);
-+      if (!spin_trylock(&die_lock)) { 
-+              if (cpu == die_owner) 
-+                      /* nested oops. should stop eventually */;
-+              else
-+                      spin_lock(&die_lock);
-+      }
-+      die_owner = cpu;
-+      console_verbose();
-+      bust_spinlocks(1);
-+      return flags;
-+}
-+
-+void __kprobes oops_end(unsigned long flags)
-+{ 
-+      die_owner = -1;
-+      bust_spinlocks(0);
-+      spin_unlock_irqrestore(&die_lock, flags);
-+      if (panic_on_oops)
-+              panic("Oops");
-+}
-+
-+void __kprobes __die(const char * str, struct pt_regs * regs, long err)
-+{
-+      static int die_counter;
-+      printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter);
-+#ifdef CONFIG_PREEMPT
-+      printk("PREEMPT ");
-+#endif
-+#ifdef CONFIG_SMP
-+      printk("SMP ");
-+#endif
-+#ifdef CONFIG_DEBUG_PAGEALLOC
-+      printk("DEBUG_PAGEALLOC");
-+#endif
-+      printk("\n");
-+      notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
-+      show_registers(regs);
-+      /* Executive summary in case the oops scrolled away */
-+      printk(KERN_ALERT "RIP ");
-+      printk_address(regs->rip); 
-+      printk(" RSP <%016lx>\n", regs->rsp); 
-+      if (kexec_should_crash(current))
-+              crash_kexec(regs);
-+}
-+
-+void die(const char * str, struct pt_regs * regs, long err)
-+{
-+      unsigned long flags = oops_begin();
-+
-+      handle_BUG(regs);
-+      __die(str, regs, err);
-+      oops_end(flags);
-+      do_exit(SIGSEGV); 
-+}
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+void __kprobes die_nmi(char *str, struct pt_regs *regs)
-+{
-+      unsigned long flags = oops_begin();
-+
-+      /*
-+       * We are in trouble anyway, lets at least try
-+       * to get a message out.
-+       */
-+      printk(str, safe_smp_processor_id());
-+      show_registers(regs);
-+      if (kexec_should_crash(current))
-+              crash_kexec(regs);
-+      if (panic_on_timeout || panic_on_oops)
-+              panic("nmi watchdog");
-+      printk("console shuts up ...\n");
-+      oops_end(flags);
-+      do_exit(SIGSEGV);
-+}
-+#endif
-+
-+static void __kprobes do_trap(int trapnr, int signr, char *str,
-+                            struct pt_regs * regs, long error_code,
-+                            siginfo_t *info)
-+{
-+      struct task_struct *tsk = current;
-+
-+      conditional_sti(regs);
-+
-+      tsk->thread.error_code = error_code;
-+      tsk->thread.trap_no = trapnr;
-+
-+      if (user_mode(regs)) {
-+              if (exception_trace && unhandled_signal(tsk, signr))
-+                      printk(KERN_INFO
-+                             "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
-+                             tsk->comm, tsk->pid, str,
-+                             regs->rip,regs->rsp,error_code); 
-+
-+              if (info)
-+                      force_sig_info(signr, info, tsk);
-+              else
-+                      force_sig(signr, tsk);
-+              return;
-+      }
-+
-+
-+      /* kernel trap */ 
-+      {            
-+              const struct exception_table_entry *fixup;
-+              fixup = search_exception_tables(regs->rip);
-+              if (fixup) {
-+                      regs->rip = fixup->fixup;
-+              } else  
-+                      die(str, regs, error_code);
-+              return;
-+      }
-+}
-+
-+#define DO_ERROR(trapnr, signr, str, name) \
-+asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
-+{ \
-+      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-+                                                      == NOTIFY_STOP) \
-+              return; \
-+      do_trap(trapnr, signr, str, regs, error_code, NULL); \
-+}
-+
-+#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
-+asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
-+{ \
-+      siginfo_t info; \
-+      info.si_signo = signr; \
-+      info.si_errno = 0; \
-+      info.si_code = sicode; \
-+      info.si_addr = (void __user *)siaddr; \
-+      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
-+                                                      == NOTIFY_STOP) \
-+              return; \
-+      do_trap(trapnr, signr, str, regs, error_code, &info); \
-+}
-+
-+DO_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->rip)
-+DO_ERROR( 4, SIGSEGV, "overflow", overflow)
-+DO_ERROR( 5, SIGSEGV, "bounds", bounds)
-+DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->rip)
-+DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
-+DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
-+DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
-+DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
-+DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
-+DO_ERROR(18, SIGSEGV, "reserved", reserved)
-+DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
-+
-+asmlinkage void do_double_fault(struct pt_regs * regs, long error_code)
-+{
-+      static const char str[] = "double fault";
-+      struct task_struct *tsk = current;
-+
-+      /* Return not checked because double check cannot be ignored */
-+      notify_die(DIE_TRAP, str, regs, error_code, 8, SIGSEGV);
-+
-+      tsk->thread.error_code = error_code;
-+      tsk->thread.trap_no = 8;
-+
-+      /* This is always a kernel trap and never fixable (and thus must
-+         never return). */
-+      for (;;)
-+              die(str, regs, error_code);
-+}
-+
-+asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
-+                                              long error_code)
-+{
-+      struct task_struct *tsk = current;
-+
-+      conditional_sti(regs);
-+
-+      tsk->thread.error_code = error_code;
-+      tsk->thread.trap_no = 13;
-+
-+      if (user_mode(regs)) {
-+              if (exception_trace && unhandled_signal(tsk, SIGSEGV))
-+                      printk(KERN_INFO
-+                     "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
-+                             tsk->comm, tsk->pid,
-+                             regs->rip,regs->rsp,error_code); 
-+
-+              force_sig(SIGSEGV, tsk);
-+              return;
-+      } 
-+
-+      /* kernel gp */
-+      {
-+              const struct exception_table_entry *fixup;
-+              fixup = search_exception_tables(regs->rip);
-+              if (fixup) {
-+                      regs->rip = fixup->fixup;
-+                      return;
-+              }
-+              if (notify_die(DIE_GPF, "general protection fault", regs,
-+                                      error_code, 13, SIGSEGV) == NOTIFY_STOP)
-+                      return;
-+              die("general protection fault", regs, error_code);
-+      }
-+}
-+
-+static __kprobes void
-+mem_parity_error(unsigned char reason, struct pt_regs * regs)
-+{
-+      printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
-+      printk("You probably have a hardware problem with your RAM chips\n");
-+
-+#if 0 /* XEN */
-+      /* Clear and disable the memory parity error line. */
-+      reason = (reason & 0xf) | 4;
-+      outb(reason, 0x61);
-+#endif /* XEN */
-+}
-+
-+static __kprobes void
-+io_check_error(unsigned char reason, struct pt_regs * regs)
-+{
-+      printk("NMI: IOCK error (debug interrupt?)\n");
-+      show_registers(regs);
-+
-+#if 0 /* XEN */
-+      /* Re-enable the IOCK line, wait for a few seconds */
-+      reason = (reason & 0xf) | 8;
-+      outb(reason, 0x61);
-+      mdelay(2000);
-+      reason &= ~8;
-+      outb(reason, 0x61);
-+#endif /* XEN */
-+}
-+
-+static __kprobes void
-+unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
-+{     printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
-+      printk("Dazed and confused, but trying to continue\n");
-+      printk("Do you have a strange power saving mode enabled?\n");
-+}
-+
-+/* Runs on IST stack. This code must keep interrupts off all the time.
-+   Nested NMIs are prevented by the CPU. */
-+asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs)
-+{
-+      unsigned char reason = 0;
-+      int cpu;
-+
-+      cpu = smp_processor_id();
-+
-+      /* Only the BSP gets external NMIs from the system.  */
-+      if (!cpu)
-+              reason = get_nmi_reason();
-+
-+      if (!(reason & 0xc0)) {
-+              if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
-+                                                              == NOTIFY_STOP)
-+                      return;
-+#ifdef CONFIG_X86_LOCAL_APIC
-+              /*
-+               * Ok, so this is none of the documented NMI sources,
-+               * so it must be the NMI watchdog.
-+               */
-+              if (nmi_watchdog > 0) {
-+                      nmi_watchdog_tick(regs,reason);
-+                      return;
-+              }
-+#endif
-+              unknown_nmi_error(reason, regs);
-+              return;
-+      }
-+      if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
-+              return; 
-+
-+      /* AK: following checks seem to be broken on modern chipsets. FIXME */
-+
-+      if (reason & 0x80)
-+              mem_parity_error(reason, regs);
-+      if (reason & 0x40)
-+              io_check_error(reason, regs);
-+}
-+
-+/* runs on IST stack. */
-+asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code)
-+{
-+      if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
-+              return;
-+      }
-+      do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
-+      return;
-+}
-+
-+/* Help handler running on IST stack to switch back to user stack
-+   for scheduling or signal handling. The actual stack switch is done in
-+   entry.S */
-+asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
-+{
-+      struct pt_regs *regs = eregs;
-+      /* Did already sync */
-+      if (eregs == (struct pt_regs *)eregs->rsp)
-+              ;
-+      /* Exception from user space */
-+      else if (user_mode(eregs))
-+              regs = task_pt_regs(current);
-+      /* Exception from kernel and interrupts are enabled. Move to
-+         kernel process stack. */
-+      else if (eregs->eflags & X86_EFLAGS_IF)
-+              regs = (struct pt_regs *)(eregs->rsp -= sizeof(struct pt_regs));
-+      if (eregs != regs)
-+              *regs = *eregs;
-+      return regs;
-+}
-+
-+/* runs on IST stack. */
-+asmlinkage void __kprobes do_debug(struct pt_regs * regs,
-+                                 unsigned long error_code)
-+{
-+      unsigned long condition;
-+      struct task_struct *tsk = current;
-+      siginfo_t info;
-+
-+      get_debugreg(condition, 6);
-+
-+      if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
-+                                              SIGTRAP) == NOTIFY_STOP)
-+              return;
-+
-+      preempt_conditional_sti(regs);
-+
-+      /* Mask out spurious debug traps due to lazy DR7 setting */
-+      if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
-+              if (!tsk->thread.debugreg7) { 
-+                      goto clear_dr7;
-+              }
-+      }
-+
-+      tsk->thread.debugreg6 = condition;
-+
-+      /* Mask out spurious TF errors due to lazy TF clearing */
-+      if (condition & DR_STEP) {
-+              /*
-+               * The TF error should be masked out only if the current
-+               * process is not traced and if the TRAP flag has been set
-+               * previously by a tracing process (condition detected by
-+               * the PT_DTRACE flag); remember that the i386 TRAP flag
-+               * can be modified by the process itself in user mode,
-+               * allowing programs to debug themselves without the ptrace()
-+               * interface.
-+               */
-+                if (!user_mode(regs))
-+                       goto clear_TF_reenable;
-+              /*
-+               * Was the TF flag set by a debugger? If so, clear it now,
-+               * so that register information is correct.
-+               */
-+              if (tsk->ptrace & PT_DTRACE) {
-+                      regs->eflags &= ~TF_MASK;
-+                      tsk->ptrace &= ~PT_DTRACE;
-+              }
-+      }
-+
-+      /* Ok, finally something we can handle */
-+      tsk->thread.trap_no = 1;
-+      tsk->thread.error_code = error_code;
-+      info.si_signo = SIGTRAP;
-+      info.si_errno = 0;
-+      info.si_code = TRAP_BRKPT;
-+      info.si_addr = user_mode(regs) ? (void __user *)regs->rip : NULL;
-+      force_sig_info(SIGTRAP, &info, tsk);
-+
-+clear_dr7:
-+      set_debugreg(0UL, 7);
-+      preempt_conditional_cli(regs);
-+      return;
-+
-+clear_TF_reenable:
-+      set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
-+      regs->eflags &= ~TF_MASK;
-+      preempt_conditional_cli(regs);
-+}
-+
-+static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
-+{
-+      const struct exception_table_entry *fixup;
-+      fixup = search_exception_tables(regs->rip);
-+      if (fixup) {
-+              regs->rip = fixup->fixup;
-+              return 1;
-+      }
-+      notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
-+      /* Illegal floating point operation in the kernel */
-+      current->thread.trap_no = trapnr;
-+      die(str, regs, 0);
-+      return 0;
-+}
-+
-+/*
-+ * Note that we play around with the 'TS' bit in an attempt to get
-+ * the correct behaviour even in the presence of the asynchronous
-+ * IRQ13 behaviour
-+ */
-+asmlinkage void do_coprocessor_error(struct pt_regs *regs)
-+{
-+      void __user *rip = (void __user *)(regs->rip);
-+      struct task_struct * task;
-+      siginfo_t info;
-+      unsigned short cwd, swd;
-+
-+      conditional_sti(regs);
-+      if (!user_mode(regs) &&
-+          kernel_math_error(regs, "kernel x87 math error", 16))
-+              return;
-+
-+      /*
-+       * Save the info for the exception handler and clear the error.
-+       */
-+      task = current;
-+      save_init_fpu(task);
-+      task->thread.trap_no = 16;
-+      task->thread.error_code = 0;
-+      info.si_signo = SIGFPE;
-+      info.si_errno = 0;
-+      info.si_code = __SI_FAULT;
-+      info.si_addr = rip;
-+      /*
-+       * (~cwd & swd) will mask out exceptions that are not set to unmasked
-+       * status.  0x3f is the exception bits in these regs, 0x200 is the
-+       * C1 reg you need in case of a stack fault, 0x040 is the stack
-+       * fault bit.  We should only be taking one exception at a time,
-+       * so if this combination doesn't produce any single exception,
-+       * then we have a bad program that isn't synchronizing its FPU usage
-+       * and it will suffer the consequences since we won't be able to
-+       * fully reproduce the context of the exception
-+       */
-+      cwd = get_fpu_cwd(task);
-+      swd = get_fpu_swd(task);
-+      switch (swd & ~cwd & 0x3f) {
-+              case 0x000:
-+              default:
-+                      break;
-+              case 0x001: /* Invalid Op */
-+                      /*
-+                       * swd & 0x240 == 0x040: Stack Underflow
-+                       * swd & 0x240 == 0x240: Stack Overflow
-+                       * User must clear the SF bit (0x40) if set
-+                       */
-+                      info.si_code = FPE_FLTINV;
-+                      break;
-+              case 0x002: /* Denormalize */
-+              case 0x010: /* Underflow */
-+                      info.si_code = FPE_FLTUND;
-+                      break;
-+              case 0x004: /* Zero Divide */
-+                      info.si_code = FPE_FLTDIV;
-+                      break;
-+              case 0x008: /* Overflow */
-+                      info.si_code = FPE_FLTOVF;
-+                      break;
-+              case 0x020: /* Precision */
-+                      info.si_code = FPE_FLTRES;
-+                      break;
-+      }
-+      force_sig_info(SIGFPE, &info, task);
-+}
-+
-+asmlinkage void bad_intr(void)
-+{
-+      printk("bad interrupt"); 
-+}
-+
-+asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
-+{
-+      void __user *rip = (void __user *)(regs->rip);
-+      struct task_struct * task;
-+      siginfo_t info;
-+      unsigned short mxcsr;
-+
-+      conditional_sti(regs);
-+      if (!user_mode(regs) &&
-+              kernel_math_error(regs, "kernel simd math error", 19))
-+              return;
-+
-+      /*
-+       * Save the info for the exception handler and clear the error.
-+       */
-+      task = current;
-+      save_init_fpu(task);
-+      task->thread.trap_no = 19;
-+      task->thread.error_code = 0;
-+      info.si_signo = SIGFPE;
-+      info.si_errno = 0;
-+      info.si_code = __SI_FAULT;
-+      info.si_addr = rip;
-+      /*
-+       * The SIMD FPU exceptions are handled a little differently, as there
-+       * is only a single status/control register.  Thus, to determine which
-+       * unmasked exception was caught we must mask the exception mask bits
-+       * at 0x1f80, and then use these to mask the exception bits at 0x3f.
-+       */
-+      mxcsr = get_fpu_mxcsr(task);
-+      switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
-+              case 0x000:
-+              default:
-+                      break;
-+              case 0x001: /* Invalid Op */
-+                      info.si_code = FPE_FLTINV;
-+                      break;
-+              case 0x002: /* Denormalize */
-+              case 0x010: /* Underflow */
-+                      info.si_code = FPE_FLTUND;
-+                      break;
-+              case 0x004: /* Zero Divide */
-+                      info.si_code = FPE_FLTDIV;
-+                      break;
-+              case 0x008: /* Overflow */
-+                      info.si_code = FPE_FLTOVF;
-+                      break;
-+              case 0x020: /* Precision */
-+                      info.si_code = FPE_FLTRES;
-+                      break;
-+      }
-+      force_sig_info(SIGFPE, &info, task);
-+}
-+
-+asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
-+{
-+}
-+
-+#if 0
-+asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
-+{
-+}
-+#endif
-+
-+asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void)
-+{
-+}
-+
-+/*
-+ *  'math_state_restore()' saves the current math information in the
-+ * old math state array, and gets the new ones from the current task
-+ *
-+ * Careful.. There are problems with IBM-designed IRQ13 behaviour.
-+ * Don't touch unless you *really* know how it works.
-+ */
-+asmlinkage void math_state_restore(void)
-+{
-+      struct task_struct *me = current;
-+        /* clts(); */ /* 'clts' is done for us by Xen during virtual trap. */
-+
-+      if (!used_math())
-+              init_fpu(me);
-+      restore_fpu_checking(&me->thread.i387.fxsave);
-+      task_thread_info(me)->status |= TS_USEDFPU;
-+}
-+
-+
-+/*
-+ * NB. All these are "interrupt gates" (i.e. events_mask is set) because we
-+ * specify <dpl>|4 in the second field.
-+ */
-+static trap_info_t trap_table[] = {
-+        {  0, 0|4, __KERNEL_CS, (unsigned long)divide_error               },
-+        {  1, 0|4, __KERNEL_CS, (unsigned long)debug                      },
-+        {  3, 3|4, __KERNEL_CS, (unsigned long)int3                       },
-+        {  4, 3|4, __KERNEL_CS, (unsigned long)overflow                   },
-+        {  5, 0|4, __KERNEL_CS, (unsigned long)bounds                     },
-+        {  6, 0|4, __KERNEL_CS, (unsigned long)invalid_op                 },
-+        {  7, 0|4, __KERNEL_CS, (unsigned long)device_not_available       },
-+        {  9, 0|4, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun},
-+        { 10, 0|4, __KERNEL_CS, (unsigned long)invalid_TSS                },
-+        { 11, 0|4, __KERNEL_CS, (unsigned long)segment_not_present        },
-+        { 12, 0|4, __KERNEL_CS, (unsigned long)stack_segment              },
-+        { 13, 0|4, __KERNEL_CS, (unsigned long)general_protection         },
-+        { 14, 0|4, __KERNEL_CS, (unsigned long)page_fault                 },
-+        { 15, 0|4, __KERNEL_CS, (unsigned long)spurious_interrupt_bug     },
-+        { 16, 0|4, __KERNEL_CS, (unsigned long)coprocessor_error          },
-+        { 17, 0|4, __KERNEL_CS, (unsigned long)alignment_check            },
-+#ifdef CONFIG_X86_MCE
-+        { 18, 0|4, __KERNEL_CS, (unsigned long)machine_check              },
-+#endif
-+        { 19, 0|4, __KERNEL_CS, (unsigned long)simd_coprocessor_error     },
-+#ifdef CONFIG_IA32_EMULATION
-+      { IA32_SYSCALL_VECTOR, 3|4, __KERNEL_CS, (unsigned long)ia32_syscall},
-+#endif
-+        {  0, 0,           0, 0                                              }
-+};
-+
-+void __init trap_init(void)
-+{
-+        int ret;
-+
-+        ret = HYPERVISOR_set_trap_table(trap_table);
-+        
-+        if (ret) 
-+                printk("HYPERVISOR_set_trap_table faild: error %d\n",
-+                       ret);
-+
-+      /*
-+       * Should be a barrier for any external CPU state.
-+       */
-+      cpu_init();
-+}
-+
-+void smp_trap_init(trap_info_t *trap_ctxt)
-+{
-+      trap_info_t *t = trap_table;
-+
-+      for (t = trap_table; t->address; t++) {
-+              trap_ctxt[t->vector].flags = t->flags;
-+              trap_ctxt[t->vector].cs = t->cs;
-+              trap_ctxt[t->vector].address = t->address;
-+      }
-+}
-+
-+
-+/* Actual parsing is done early in setup.c. */
-+static int __init oops_dummy(char *s)
-+{ 
-+      panic_on_oops = 1;
-+      return -1; 
-+} 
-+__setup("oops=", oops_dummy); 
-+
-+static int __init kstack_setup(char *s)
-+{
-+      kstack_depth_to_print = simple_strtoul(s,NULL,0);
-+      return 0;
-+}
-+__setup("kstack=", kstack_setup);
-+
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/vmlinux.lds.S linux-2.6.16.33/arch/x86_64/kernel/vmlinux.lds.S
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/vmlinux.lds.S     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/vmlinux.lds.S   2007-05-23 21:00:01.000000000 +0000
-@@ -14,6 +14,13 @@
- OUTPUT_ARCH(i386:x86-64)
- ENTRY(phys_startup_64)
- jiffies_64 = jiffies;
-+PHDRS {
-+      text PT_LOAD FLAGS(5);  /* R_E */
-+      data PT_LOAD FLAGS(7);  /* RWE */
-+      user PT_LOAD FLAGS(7);  /* RWE */
-+      data.init PT_LOAD FLAGS(7);     /* RWE */
-+      note PT_NOTE FLAGS(4);  /* R__ */
-+}
- SECTIONS
- {
-   . = __START_KERNEL;
-@@ -26,7 +33,7 @@
-       KPROBES_TEXT
-       *(.fixup)
-       *(.gnu.warning)
--      } = 0x9090
-+      } :text = 0x9090
-                               /* out-of-line lock text */
-   .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
-@@ -43,17 +50,10 @@
-   .data : AT(ADDR(.data) - LOAD_OFFSET) {
-       *(.data)
-       CONSTRUCTORS
--      }
-+      } :data
-   _edata = .;                 /* End of data section */
--  __bss_start = .;            /* BSS */
--  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
--      *(.bss.page_aligned)    
--      *(.bss)
--      }
--  __bss_stop = .;
--
-   . = ALIGN(PAGE_SIZE);
-   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
-@@ -75,7 +75,7 @@
- #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
-   . = VSYSCALL_ADDR;
--  .vsyscall_0 :        AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) }
-+  .vsyscall_0 :        AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user
-   __vsyscall_0 = VSYSCALL_VIRT_ADDR;
-   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-@@ -118,7 +118,7 @@
-   . = ALIGN(8192);            /* init_task */
-   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-       *(.data.init_task)
--  }
-+  }:data.init
-   . = ALIGN(4096);
-   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
-@@ -188,6 +188,14 @@
-   . = ALIGN(4096);
-   __nosave_end = .;
-+  __bss_start = .;            /* BSS */
-+  . = ALIGN(4096);
-+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-+      *(.bss.page_aligned)
-+      *(.bss)
-+      }
-+  __bss_stop = .;
-+
-   _end = . ;
-   /* Sections to be discarded */
-@@ -201,4 +209,6 @@
-   STABS_DEBUG
-   DWARF_DEBUG
-+
-+  NOTES
- }
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/vmlinux.lds.S~ linux-2.6.16.33/arch/x86_64/kernel/vmlinux.lds.S~
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/vmlinux.lds.S~    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/vmlinux.lds.S~  2007-05-23 21:00:01.000000000 +0000
-@@ -0,0 +1,213 @@
-+/* ld script to make x86-64 Linux kernel
-+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
-+ */
-+
-+#define LOAD_OFFSET __START_KERNEL_map
-+
-+#include <asm-generic/vmlinux.lds.h>
-+#include <asm/page.h>
-+#include <linux/config.h>
-+
-+#undef i386   /* in case the preprocessor is a 32bit one */
-+
-+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-+OUTPUT_ARCH(i386:x86-64)
-+ENTRY(phys_startup_64)
-+jiffies_64 = jiffies;
-+PHDRS {
-+      text PT_LOAD FLAGS(5);  /* R_E */
-+      data PT_LOAD FLAGS(7);  /* RWE */
-+      user PT_LOAD FLAGS(7);  /* RWE */
-+      note PT_NOTE FLAGS(4);  /* R__ */
-+}
-+SECTIONS
-+{
-+  . = __START_KERNEL;
-+  phys_startup_64 = startup_64 - LOAD_OFFSET;
-+  _text = .;                  /* Text and read-only data */
-+  .text :  AT(ADDR(.text) - LOAD_OFFSET) {
-+      *(.text)
-+      SCHED_TEXT
-+      LOCK_TEXT
-+      KPROBES_TEXT
-+      *(.fixup)
-+      *(.gnu.warning)
-+      } :text = 0x9090
-+                              /* out-of-line lock text */
-+  .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
-+
-+  _etext = .;                 /* End of text section */
-+
-+  . = ALIGN(16);              /* Exception table */
-+  __start___ex_table = .;
-+  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
-+  __stop___ex_table = .;
-+
-+  RODATA
-+
-+                              /* Data */
-+  .data : AT(ADDR(.data) - LOAD_OFFSET) {
-+      *(.data)
-+      CONSTRUCTORS
-+      } :data
-+
-+  _edata = .;                 /* End of data section */
-+
-+  . = ALIGN(PAGE_SIZE);
-+  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-+  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
-+      *(.data.cacheline_aligned)
-+  }
-+  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-+  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
-+      *(.data.read_mostly)
-+  }
-+
-+#define VSYSCALL_ADDR (-10*1024*1024)
-+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
-+#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
-+
-+#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
-+#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
-+
-+#define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR)
-+#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
-+
-+  . = VSYSCALL_ADDR;
-+  .vsyscall_0 :        AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user
-+  __vsyscall_0 = VSYSCALL_VIRT_ADDR;
-+
-+  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-+  .xtime_lock : AT(VLOAD(.xtime_lock)) { *(.xtime_lock) }
-+  xtime_lock = VVIRT(.xtime_lock);
-+
-+  .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) }
-+  vxtime = VVIRT(.vxtime);
-+
-+  .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) }
-+  wall_jiffies = VVIRT(.wall_jiffies);
-+
-+  .sys_tz : AT(VLOAD(.sys_tz)) { *(.sys_tz) }
-+  sys_tz = VVIRT(.sys_tz);
-+
-+  .sysctl_vsyscall : AT(VLOAD(.sysctl_vsyscall)) { *(.sysctl_vsyscall) }
-+  sysctl_vsyscall = VVIRT(.sysctl_vsyscall);
-+
-+  .xtime : AT(VLOAD(.xtime)) { *(.xtime) }
-+  xtime = VVIRT(.xtime);
-+
-+  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-+  .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) }
-+  jiffies = VVIRT(.jiffies);
-+
-+  .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) { *(.vsyscall_1) }
-+  .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) { *(.vsyscall_2) }
-+  .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { *(.vsyscall_3) }
-+
-+  . = VSYSCALL_VIRT_ADDR + 4096;
-+
-+#undef VSYSCALL_ADDR
-+#undef VSYSCALL_PHYS_ADDR
-+#undef VSYSCALL_VIRT_ADDR
-+#undef VLOAD_OFFSET
-+#undef VLOAD
-+#undef VVIRT_OFFSET
-+#undef VVIRT
-+
-+  . = ALIGN(8192);            /* init_task */
-+  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-+      *(.data.init_task)
-+  } :data
-+
-+  . = ALIGN(4096);
-+  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
-+      *(.data.page_aligned)
-+  }
-+
-+  . = ALIGN(4096);            /* Init code and data */
-+  __init_begin = .;
-+  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
-+      _sinittext = .;
-+      *(.init.text)
-+      _einittext = .;
-+  }
-+  __initdata_begin = .;
-+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
-+  __initdata_end = .;
-+  . = ALIGN(16);
-+  __setup_start = .;
-+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
-+  __setup_end = .;
-+  __initcall_start = .;
-+  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
-+      *(.initcall1.init) 
-+      *(.initcall2.init) 
-+      *(.initcall3.init) 
-+      *(.initcall4.init) 
-+      *(.initcall5.init) 
-+      *(.initcall6.init) 
-+      *(.initcall7.init)
-+  }
-+  __initcall_end = .;
-+  __con_initcall_start = .;
-+  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
-+      *(.con_initcall.init)
-+  }
-+  __con_initcall_end = .;
-+  SECURITY_INIT
-+  . = ALIGN(8);
-+  __alt_instructions = .;
-+  .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
-+      *(.altinstructions)
-+  }
-+  __alt_instructions_end = .; 
-+  .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
-+      *(.altinstr_replacement)
-+  }
-+  /* .exit.text is discard at runtime, not link time, to deal with references
-+     from .altinstructions and .eh_frame */
-+  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
-+  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
-+  . = ALIGN(4096);
-+  __initramfs_start = .;
-+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
-+  __initramfs_end = .;
-+  /* temporary here to work around NR_CPUS. If you see this comment in 2.6.17+
-+   complain */
-+  . = ALIGN(4096);    
-+  __init_end = .;     
-+  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-+  __per_cpu_start = .;
-+  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
-+  __per_cpu_end = .;
-+
-+  . = ALIGN(4096);
-+  __nosave_begin = .;
-+  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
-+  . = ALIGN(4096);
-+  __nosave_end = .;
-+
-+  __bss_start = .;            /* BSS */
-+  . = ALIGN(4096);
-+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-+      *(.bss.page_aligned)
-+      *(.bss)
-+      }
-+  __bss_stop = .;
-+
-+  _end = . ;
-+
-+  /* Sections to be discarded */
-+  /DISCARD/ : {
-+      *(.exitcall.exit)
-+#ifndef CONFIG_UNWIND_INFO
-+      *(.eh_frame)
-+#endif
-+      }
-+
-+  STABS_DEBUG
-+
-+  DWARF_DEBUG
-+
-+  NOTES
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/vsyscall-xen.c linux-2.6.16.33/arch/x86_64/kernel/vsyscall-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/vsyscall-xen.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/vsyscall-xen.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,239 @@
-+/*
-+ *  linux/arch/x86_64/kernel/vsyscall.c
-+ *
-+ *  Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
-+ *  Copyright 2003 Andi Kleen, SuSE Labs.
-+ *
-+ *  Thanks to hpa@transmeta.com for some useful hint.
-+ *  Special thanks to Ingo Molnar for his early experience with
-+ *  a different vsyscall implementation for Linux/IA32 and for the name.
-+ *
-+ *  vsyscall 1 is located at -10Mbyte, vsyscall 2 is located
-+ *  at virtual address -10Mbyte+1024bytes etc... There are at max 4
-+ *  vsyscalls. One vsyscall can reserve more than 1 slot to avoid
-+ *  jumping out of line if necessary. We cannot add more with this
-+ *  mechanism because older kernels won't return -ENOSYS.
-+ *  If we want more than four we need a vDSO.
-+ *
-+ *  Note: the concept clashes with user mode linux. If you use UML and
-+ *  want per guest time just set the kernel.vsyscall64 sysctl to 0.
-+ */
-+
-+#include <linux/time.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/timer.h>
-+#include <linux/seqlock.h>
-+#include <linux/jiffies.h>
-+#include <linux/sysctl.h>
-+
-+#include <asm/vsyscall.h>
-+#include <asm/pgtable.h>
-+#include <asm/page.h>
-+#include <asm/fixmap.h>
-+#include <asm/errno.h>
-+#include <asm/io.h>
-+
-+#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
-+
-+int __sysctl_vsyscall __section_sysctl_vsyscall = 1;
-+seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED;
-+
-+#include <asm/unistd.h>
-+
-+static __always_inline void timeval_normalize(struct timeval * tv)
-+{
-+      time_t __sec;
-+
-+      __sec = tv->tv_usec / 1000000;
-+      if (__sec) {
-+              tv->tv_usec %= 1000000;
-+              tv->tv_sec += __sec;
-+      }
-+}
-+
-+static __always_inline void do_vgettimeofday(struct timeval * tv)
-+{
-+      long sequence, t;
-+      unsigned long sec, usec;
-+
-+      do {
-+              sequence = read_seqbegin(&__xtime_lock);
-+              
-+              sec = __xtime.tv_sec;
-+              usec = (__xtime.tv_nsec / 1000) +
-+                      (__jiffies - __wall_jiffies) * (1000000 / HZ);
-+
-+              if (__vxtime.mode != VXTIME_HPET) {
-+                      t = get_cycles_sync();
-+                      if (t < __vxtime.last_tsc)
-+                              t = __vxtime.last_tsc;
-+                      usec += ((t - __vxtime.last_tsc) *
-+                               __vxtime.tsc_quot) >> 32;
-+                      /* See comment in x86_64 do_gettimeofday. */
-+              } else {
-+                      usec += ((readl((void *)fix_to_virt(VSYSCALL_HPET) + 0xf0) -
-+                                __vxtime.last) * __vxtime.quot) >> 32;
-+              }
-+      } while (read_seqretry(&__xtime_lock, sequence));
-+
-+      tv->tv_sec = sec + usec / 1000000;
-+      tv->tv_usec = usec % 1000000;
-+}
-+
-+/* RED-PEN may want to readd seq locking, but then the variable should be write-once. */
-+static __always_inline void do_get_tz(struct timezone * tz)
-+{
-+      *tz = __sys_tz;
-+}
-+
-+static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
-+{
-+      int ret;
-+      asm volatile("vsysc2: syscall"
-+              : "=a" (ret)
-+              : "0" (__NR_gettimeofday),"D" (tv),"S" (tz) : __syscall_clobber );
-+      return ret;
-+}
-+
-+static __always_inline long time_syscall(long *t)
-+{
-+      long secs;
-+      asm volatile("vsysc1: syscall"
-+              : "=a" (secs)
-+              : "0" (__NR_time),"D" (t) : __syscall_clobber);
-+      return secs;
-+}
-+
-+int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
-+{
-+      if (unlikely(!__sysctl_vsyscall))
-+              return gettimeofday(tv,tz);
-+      if (tv)
-+              do_vgettimeofday(tv);
-+      if (tz)
-+              do_get_tz(tz);
-+      return 0;
-+}
-+
-+/* This will break when the xtime seconds get inaccurate, but that is
-+ * unlikely */
-+time_t __vsyscall(1) vtime(time_t *t)
-+{
-+      if (unlikely(!__sysctl_vsyscall))
-+              return time_syscall(t);
-+      else if (t)
-+              *t = __xtime.tv_sec;            
-+      return __xtime.tv_sec;
-+}
-+
-+long __vsyscall(2) venosys_0(void)
-+{
-+      return -ENOSYS;
-+}
-+
-+long __vsyscall(3) venosys_1(void)
-+{
-+      return -ENOSYS;
-+}
-+
-+#ifdef CONFIG_SYSCTL
-+
-+#define SYSCALL 0x050f
-+#define NOP2    0x9090
-+
-+/*
-+ * NOP out syscall in vsyscall page when not needed.
-+ */
-+static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
-+                        void __user *buffer, size_t *lenp, loff_t *ppos)
-+{
-+      extern u16 vsysc1, vsysc2;
-+      u16 *map1, *map2;
-+      int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
-+      if (!write)
-+              return ret;
-+      /* gcc has some trouble with __va(__pa()), so just do it this
-+         way. */
-+      map1 = ioremap(__pa_symbol(&vsysc1), 2);
-+      if (!map1)
-+              return -ENOMEM;
-+      map2 = ioremap(__pa_symbol(&vsysc2), 2);
-+      if (!map2) {
-+              ret = -ENOMEM;
-+              goto out;
-+      }
-+      if (!sysctl_vsyscall) {
-+              *map1 = SYSCALL;
-+              *map2 = SYSCALL;
-+      } else {
-+              *map1 = NOP2;
-+              *map2 = NOP2;
-+      }
-+      iounmap(map2);
-+out:
-+      iounmap(map1);
-+      return ret;
-+}
-+
-+static int vsyscall_sysctl_nostrat(ctl_table *t, int __user *name, int nlen,
-+                              void __user *oldval, size_t __user *oldlenp,
-+                              void __user *newval, size_t newlen,
-+                              void **context)
-+{
-+      return -ENOSYS;
-+}
-+
-+static ctl_table kernel_table2[] = {
-+      { .ctl_name = 99, .procname = "vsyscall64",
-+        .data = &sysctl_vsyscall, .maxlen = sizeof(int), .mode = 0644,
-+        .strategy = vsyscall_sysctl_nostrat,
-+        .proc_handler = vsyscall_sysctl_change },
-+      { 0, }
-+};
-+
-+static ctl_table kernel_root_table2[] = {
-+      { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
-+        .child = kernel_table2 },
-+      { 0 },
-+};
-+
-+#endif
-+
-+static void __init map_vsyscall(void)
-+{
-+      extern char __vsyscall_0;
-+      unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0);
-+
-+      __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL);
-+}
-+
-+#ifdef CONFIG_XEN
-+static void __init map_vsyscall_user(void)
-+{
-+      extern void __set_fixmap_user(enum fixed_addresses, unsigned long, pgprot_t);
-+      extern char __vsyscall_0;
-+      unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0);
-+
-+      __set_fixmap_user(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL);
-+}
-+#endif
-+
-+static int __init vsyscall_init(void)
-+{
-+      BUG_ON(((unsigned long) &vgettimeofday !=
-+                      VSYSCALL_ADDR(__NR_vgettimeofday)));
-+      BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime));
-+      BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE)));
-+      map_vsyscall();
-+#ifdef CONFIG_XEN
-+      map_vsyscall_user();
-+      sysctl_vsyscall = 0; /* disable vgettimeofay() */
-+#endif
-+#ifdef CONFIG_SYSCTL
-+      register_sysctl_table(kernel_root_table2, 0);
-+#endif
-+      return 0;
-+}
-+
-+__initcall(vsyscall_init);
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/x8664_ksyms-xen.c linux-2.6.16.33/arch/x86_64/kernel/x8664_ksyms-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/x8664_ksyms-xen.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/x8664_ksyms-xen.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,163 @@
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/smp.h>
-+#include <linux/user.h>
-+#include <linux/sched.h>
-+#include <linux/in6.h>
-+#include <linux/interrupt.h>
-+#include <linux/smp_lock.h>
-+#include <linux/pm.h>
-+#include <linux/pci.h>
-+#include <linux/apm_bios.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/syscalls.h>
-+#include <linux/tty.h>
-+
-+#include <asm/semaphore.h>
-+#include <asm/processor.h>
-+#include <asm/i387.h>
-+#include <asm/uaccess.h>
-+#include <asm/checksum.h>
-+#include <asm/io.h>
-+#include <asm/delay.h>
-+#include <asm/irq.h>
-+#include <asm/mmx.h>
-+#include <asm/desc.h>
-+#include <asm/pgtable.h>
-+#include <asm/pgalloc.h>
-+#include <asm/nmi.h>
-+#include <asm/kdebug.h>
-+#include <asm/unistd.h>
-+#include <asm/tlbflush.h>
-+#include <asm/kdebug.h>
-+
-+#ifdef CONFIG_SMP
-+extern void __write_lock_failed(rwlock_t *rw);
-+extern void __read_lock_failed(rwlock_t *rw);
-+#endif
-+
-+/* platform dependent support */
-+EXPORT_SYMBOL(boot_cpu_data);
-+//EXPORT_SYMBOL(dump_fpu);
-+EXPORT_SYMBOL(kernel_thread);
-+EXPORT_SYMBOL(pm_idle);
-+EXPORT_SYMBOL(pm_power_off);
-+
-+EXPORT_SYMBOL(__down_failed);
-+EXPORT_SYMBOL(__down_failed_interruptible);
-+EXPORT_SYMBOL(__down_failed_trylock);
-+EXPORT_SYMBOL(__up_wakeup);
-+/* Networking helper routines. */
-+EXPORT_SYMBOL(csum_partial_copy_nocheck);
-+EXPORT_SYMBOL(ip_compute_csum);
-+/* Delay loops */
-+EXPORT_SYMBOL(__udelay);
-+EXPORT_SYMBOL(__ndelay);
-+EXPORT_SYMBOL(__delay);
-+EXPORT_SYMBOL(__const_udelay);
-+
-+EXPORT_SYMBOL(__get_user_1);
-+EXPORT_SYMBOL(__get_user_2);
-+EXPORT_SYMBOL(__get_user_4);
-+EXPORT_SYMBOL(__get_user_8);
-+EXPORT_SYMBOL(__put_user_1);
-+EXPORT_SYMBOL(__put_user_2);
-+EXPORT_SYMBOL(__put_user_4);
-+EXPORT_SYMBOL(__put_user_8);
-+
-+EXPORT_SYMBOL(strncpy_from_user);
-+EXPORT_SYMBOL(__strncpy_from_user);
-+EXPORT_SYMBOL(clear_user);
-+EXPORT_SYMBOL(__clear_user);
-+EXPORT_SYMBOL(copy_user_generic);
-+EXPORT_SYMBOL(copy_from_user);
-+EXPORT_SYMBOL(copy_to_user);
-+EXPORT_SYMBOL(copy_in_user);
-+EXPORT_SYMBOL(strnlen_user);
-+
-+#ifdef CONFIG_PCI
-+EXPORT_SYMBOL(pci_mem_start);
-+#endif
-+
-+EXPORT_SYMBOL(copy_page);
-+EXPORT_SYMBOL(clear_page);
-+
-+EXPORT_SYMBOL(_cpu_pda);
-+#ifdef CONFIG_SMP
-+EXPORT_SYMBOL(__write_lock_failed);
-+EXPORT_SYMBOL(__read_lock_failed);
-+
-+EXPORT_SYMBOL(smp_call_function);
-+#endif
-+
-+#ifdef CONFIG_VT
-+EXPORT_SYMBOL(screen_info);
-+#endif
-+
-+EXPORT_SYMBOL(get_wchan);
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+EXPORT_SYMBOL_GPL(set_nmi_callback);
-+EXPORT_SYMBOL_GPL(unset_nmi_callback);
-+#endif
-+
-+/* Export string functions. We normally rely on gcc builtin for most of these,
-+   but gcc sometimes decides not to inline them. */    
-+#undef memcpy
-+#undef memset
-+#undef memmove
-+#undef strlen
-+
-+extern void * memset(void *,int,__kernel_size_t);
-+extern size_t strlen(const char *);
-+extern void * memmove(void * dest,const void *src,size_t count);
-+extern void * memcpy(void *,const void *,__kernel_size_t);
-+extern void * __memcpy(void *,const void *,__kernel_size_t);
-+
-+EXPORT_SYMBOL(memset);
-+EXPORT_SYMBOL(strlen);
-+EXPORT_SYMBOL(memmove);
-+EXPORT_SYMBOL(memcpy);
-+EXPORT_SYMBOL(__memcpy);
-+
-+#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
-+/* prototypes are wrong, these are assembly with custom calling functions */
-+extern void rwsem_down_read_failed_thunk(void);
-+extern void rwsem_wake_thunk(void);
-+extern void rwsem_downgrade_thunk(void);
-+extern void rwsem_down_write_failed_thunk(void);
-+EXPORT_SYMBOL(rwsem_down_read_failed_thunk);
-+EXPORT_SYMBOL(rwsem_wake_thunk);
-+EXPORT_SYMBOL(rwsem_downgrade_thunk);
-+EXPORT_SYMBOL(rwsem_down_write_failed_thunk);
-+#endif
-+
-+EXPORT_SYMBOL(empty_zero_page);
-+
-+EXPORT_SYMBOL(die_chain);
-+EXPORT_SYMBOL(register_die_notifier);
-+
-+#ifdef CONFIG_SMP
-+EXPORT_SYMBOL(cpu_sibling_map);
-+EXPORT_SYMBOL(smp_num_siblings);
-+#endif
-+
-+extern void do_softirq_thunk(void);
-+EXPORT_SYMBOL(do_softirq_thunk);
-+
-+#ifdef CONFIG_BUG
-+EXPORT_SYMBOL(out_of_line_bug);
-+#endif
-+
-+EXPORT_SYMBOL(init_level4_pgt);
-+
-+extern unsigned long __supported_pte_mask;
-+EXPORT_SYMBOL(__supported_pte_mask);
-+
-+#ifdef CONFIG_SMP
-+EXPORT_SYMBOL(flush_tlb_page);
-+#endif
-+
-+EXPORT_SYMBOL(load_gs_index);
-+
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/kernel/xen_entry.S linux-2.6.16.33/arch/x86_64/kernel/xen_entry.S
---- linux-2.6.16.33-noxen/arch/x86_64/kernel/xen_entry.S       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/kernel/xen_entry.S     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,40 @@
-+/*
-+ * Copied from arch/xen/i386/kernel/entry.S
-+ */                        
-+/* Offsets into shared_info_t. */                
-+#define evtchn_upcall_pending         /* 0 */
-+#define evtchn_upcall_mask            1
-+
-+#define sizeof_vcpu_shift             6
-+
-+#ifdef CONFIG_SMP
-+//#define preempt_disable(reg)        incl threadinfo_preempt_count(reg)
-+//#define preempt_enable(reg) decl threadinfo_preempt_count(reg)
-+#define preempt_disable(reg)
-+#define preempt_enable(reg)
-+#define XEN_GET_VCPU_INFO(reg)        preempt_disable(%rbp)                   ; \
-+                              movq %gs:pda_cpunumber,reg              ; \
-+                              shl  $32, reg                           ; \
-+                              shr  $32-sizeof_vcpu_shift,reg          ; \
-+                              addq HYPERVISOR_shared_info,reg
-+#define XEN_PUT_VCPU_INFO(reg)        preempt_enable(%rbp)                    ; \
-+#define XEN_PUT_VCPU_INFO_fixup .byte 0xff,0xff,0xff
-+#else
-+#define XEN_GET_VCPU_INFO(reg)        movq HYPERVISOR_shared_info,reg
-+#define XEN_PUT_VCPU_INFO(reg)
-+#define XEN_PUT_VCPU_INFO_fixup
-+#endif
-+
-+#define XEN_LOCKED_BLOCK_EVENTS(reg)  movb $1,evtchn_upcall_mask(reg)
-+#define XEN_LOCKED_UNBLOCK_EVENTS(reg)        movb $0,evtchn_upcall_mask(reg)
-+#define XEN_BLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg)                  ; \
-+                              XEN_LOCKED_BLOCK_EVENTS(reg)            ; \
-+                              XEN_PUT_VCPU_INFO(reg)
-+#define XEN_UNBLOCK_EVENTS(reg)       XEN_GET_VCPU_INFO(reg)                  ; \
-+                              XEN_LOCKED_UNBLOCK_EVENTS(reg)          ; \
-+                              XEN_PUT_VCPU_INFO(reg)
-+#define XEN_TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg)
-+
-+VGCF_IN_SYSCALL = (1<<8)
-+        
-+      
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/mm/Makefile linux-2.6.16.33/arch/x86_64/mm/Makefile
---- linux-2.6.16.33-noxen/arch/x86_64/mm/Makefile      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/mm/Makefile    2007-01-08 15:00:45.000000000 +0000
-@@ -9,3 +9,13 @@
- obj-$(CONFIG_ACPI_NUMA) += srat.o
- hugetlbpage-y = ../../i386/mm/hugetlbpage.o
-+
-+ifdef CONFIG_XEN
-+include $(srctree)/scripts/Makefile.xen
-+
-+ioremap-y     += ../../i386/mm/ioremap-xen.o
-+hypervisor-y  += ../../i386/mm/hypervisor.o
-+obj-y         += hypervisor.o
-+
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/mm/fault-xen.c linux-2.6.16.33/arch/x86_64/mm/fault-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/mm/fault-xen.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/mm/fault-xen.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,641 @@
-+/*
-+ *  linux/arch/x86-64/mm/fault.c
-+ *
-+ *  Copyright (C) 1995  Linus Torvalds
-+ *  Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/ptrace.h>
-+#include <linux/mman.h>
-+#include <linux/mm.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/interrupt.h>
-+#include <linux/init.h>
-+#include <linux/tty.h>
-+#include <linux/vt_kern.h>            /* For unblank_screen() */
-+#include <linux/compiler.h>
-+#include <linux/module.h>
-+#include <linux/kprobes.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/pgalloc.h>
-+#include <asm/smp.h>
-+#include <asm/tlbflush.h>
-+#include <asm/proto.h>
-+#include <asm/kdebug.h>
-+#include <asm-generic/sections.h>
-+
-+/* Page fault error code bits */
-+#define PF_PROT       (1<<0)          /* or no page found */
-+#define PF_WRITE      (1<<1)
-+#define PF_USER       (1<<2)
-+#define PF_RSVD       (1<<3)
-+#define PF_INSTR      (1<<4)
-+
-+void bust_spinlocks(int yes)
-+{
-+      int loglevel_save = console_loglevel;
-+      if (yes) {
-+              oops_in_progress = 1;
-+      } else {
-+#ifdef CONFIG_VT
-+              unblank_screen();
-+#endif
-+              oops_in_progress = 0;
-+              /*
-+               * OK, the message is on the console.  Now we call printk()
-+               * without oops_in_progress set so that printk will give klogd
-+               * a poke.  Hold onto your hats...
-+               */
-+              console_loglevel = 15;          /* NMI oopser may have shut the console up */
-+              printk(" ");
-+              console_loglevel = loglevel_save;
-+      }
-+}
-+
-+/* Sometimes the CPU reports invalid exceptions on prefetch.
-+   Check that here and ignore.
-+   Opcode checker based on code by Richard Brunner */
-+static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
-+                              unsigned long error_code)
-+{ 
-+      unsigned char *instr;
-+      int scan_more = 1;
-+      int prefetch = 0; 
-+      unsigned char *max_instr;
-+
-+      /* If it was a exec fault ignore */
-+      if (error_code & PF_INSTR)
-+              return 0;
-+      
-+      instr = (unsigned char *)convert_rip_to_linear(current, regs);
-+      max_instr = instr + 15;
-+
-+      if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
-+              return 0;
-+
-+      while (scan_more && instr < max_instr) { 
-+              unsigned char opcode;
-+              unsigned char instr_hi;
-+              unsigned char instr_lo;
-+
-+              if (__get_user(opcode, instr))
-+                      break; 
-+
-+              instr_hi = opcode & 0xf0; 
-+              instr_lo = opcode & 0x0f; 
-+              instr++;
-+
-+              switch (instr_hi) { 
-+              case 0x20:
-+              case 0x30:
-+                      /* Values 0x26,0x2E,0x36,0x3E are valid x86
-+                         prefixes.  In long mode, the CPU will signal
-+                         invalid opcode if some of these prefixes are
-+                         present so we will never get here anyway */
-+                      scan_more = ((instr_lo & 7) == 0x6);
-+                      break;
-+                      
-+              case 0x40:
-+                      /* In AMD64 long mode, 0x40 to 0x4F are valid REX prefixes
-+                         Need to figure out under what instruction mode the
-+                         instruction was issued ... */
-+                      /* Could check the LDT for lm, but for now it's good
-+                         enough to assume that long mode only uses well known
-+                         segments or kernel. */
-+                      scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
-+                      break;
-+                      
-+              case 0x60:
-+                      /* 0x64 thru 0x67 are valid prefixes in all modes. */
-+                      scan_more = (instr_lo & 0xC) == 0x4;
-+                      break;          
-+              case 0xF0:
-+                      /* 0xF0, 0xF2, and 0xF3 are valid prefixes in all modes. */
-+                      scan_more = !instr_lo || (instr_lo>>1) == 1;
-+                      break;                  
-+              case 0x00:
-+                      /* Prefetch instruction is 0x0F0D or 0x0F18 */
-+                      scan_more = 0;
-+                      if (__get_user(opcode, instr)) 
-+                              break;
-+                      prefetch = (instr_lo == 0xF) &&
-+                              (opcode == 0x0D || opcode == 0x18);
-+                      break;                  
-+              default:
-+                      scan_more = 0;
-+                      break;
-+              } 
-+      }
-+      return prefetch;
-+}
-+
-+static int bad_address(void *p) 
-+{ 
-+      unsigned long dummy;
-+      return __get_user(dummy, (unsigned long *)p);
-+} 
-+
-+void dump_pagetable(unsigned long address)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+
-+      pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK);
-+      pgd += pgd_index(address);
-+      if (bad_address(pgd)) goto bad;
-+      printk("PGD %lx ", pgd_val(*pgd));
-+      if (!pgd_present(*pgd)) goto ret; 
-+
-+      pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address);
-+      if (bad_address(pud)) goto bad;
-+      printk("PUD %lx ", pud_val(*pud));
-+      if (!pud_present(*pud)) goto ret;
-+
-+      pmd = pmd_offset(pud, address);
-+      if (bad_address(pmd)) goto bad;
-+      printk("PMD %lx ", pmd_val(*pmd));
-+      if (!pmd_present(*pmd)) goto ret;        
-+
-+      pte = pte_offset_kernel(pmd, address);
-+      if (bad_address(pte)) goto bad;
-+      printk("PTE %lx", pte_val(*pte)); 
-+ret:
-+      printk("\n");
-+      return;
-+bad:
-+      printk("BAD\n");
-+}
-+
-+static const char errata93_warning[] = 
-+KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
-+KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
-+KERN_ERR "******* Please consider a BIOS update.\n"
-+KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
-+
-+/* Workaround for K8 erratum #93 & buggy BIOS.
-+   BIOS SMM functions are required to use a specific workaround
-+   to avoid corruption of the 64bit RIP register on C stepping K8. 
-+   A lot of BIOS that didn't get tested properly miss this. 
-+   The OS sees this as a page fault with the upper 32bits of RIP cleared.
-+   Try to work around it here.
-+   Note we only handle faults in kernel here. */
-+
-+static int is_errata93(struct pt_regs *regs, unsigned long address) 
-+{
-+      static int warned;
-+      if (address != regs->rip)
-+              return 0;
-+      if ((address >> 32) != 0) 
-+              return 0;
-+      address |= 0xffffffffUL << 32;
-+      if ((address >= (u64)_stext && address <= (u64)_etext) || 
-+          (address >= MODULES_VADDR && address <= MODULES_END)) { 
-+              if (!warned) {
-+                      printk(errata93_warning);               
-+                      warned = 1;
-+              }
-+              regs->rip = address;
-+              return 1;
-+      }
-+      return 0;
-+} 
-+
-+int unhandled_signal(struct task_struct *tsk, int sig)
-+{
-+      if (tsk->pid == 1)
-+              return 1;
-+      if (tsk->ptrace & PT_PTRACED)
-+              return 0;
-+      return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) ||
-+              (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
-+}
-+
-+static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
-+                               unsigned long error_code)
-+{
-+      unsigned long flags = oops_begin();
-+      struct task_struct *tsk;
-+
-+      printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
-+             current->comm, address);
-+      dump_pagetable(address);
-+      tsk = current;
-+      tsk->thread.cr2 = address;
-+      tsk->thread.trap_no = 14;
-+      tsk->thread.error_code = error_code;
-+      __die("Bad pagetable", regs, error_code);
-+      oops_end(flags);
-+      do_exit(SIGKILL);
-+}
-+
-+/*
-+ * Handle a fault on the vmalloc area
-+ *
-+ * This assumes no large pages in there.
-+ */
-+static int vmalloc_fault(unsigned long address)
-+{
-+      pgd_t *pgd, *pgd_ref;
-+      pud_t *pud, *pud_ref;
-+      pmd_t *pmd, *pmd_ref;
-+      pte_t *pte, *pte_ref;
-+
-+      /* Copy kernel mappings over when needed. This can also
-+         happen within a race in page table update. In the later
-+         case just flush. */
-+
-+      /* On Xen the line below does not always work. Needs investigating! */
-+      /*pgd = pgd_offset(current->mm ?: &init_mm, address);*/
-+      pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK);
-+      pgd += pgd_index(address);
-+      pgd_ref = pgd_offset_k(address);
-+      if (pgd_none(*pgd_ref))
-+              return -1;
-+      if (pgd_none(*pgd))
-+              set_pgd(pgd, *pgd_ref);
-+
-+      /* Below here mismatches are bugs because these lower tables
-+         are shared */
-+
-+      pud = pud_offset(pgd, address);
-+      pud_ref = pud_offset(pgd_ref, address);
-+      if (pud_none(*pud_ref))
-+              return -1;
-+      if (pud_none(*pud) || pud_page(*pud) != pud_page(*pud_ref))
-+              BUG();
-+      pmd = pmd_offset(pud, address);
-+      pmd_ref = pmd_offset(pud_ref, address);
-+      if (pmd_none(*pmd_ref))
-+              return -1;
-+      if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
-+              BUG();
-+      pte_ref = pte_offset_kernel(pmd_ref, address);
-+      if (!pte_present(*pte_ref))
-+              return -1;
-+      pte = pte_offset_kernel(pmd, address);
-+      /* Don't use pte_page here, because the mappings can point
-+         outside mem_map, and the NUMA hash lookup cannot handle
-+         that. */
-+      if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
-+              BUG();
-+      return 0;
-+}
-+
-+int page_fault_trace = 0;
-+int exception_trace = 1;
-+
-+
-+#define MEM_VERBOSE 1
-+
-+#ifdef MEM_VERBOSE
-+#define MEM_LOG(_f, _a...)                    \
-+      printk("fault.c:[%d]-> " _f "\n",       \
-+      __LINE__ , ## _a )
-+#else
-+#define MEM_LOG(_f, _a...) ((void)0)
-+#endif
-+
-+static int spurious_fault(struct pt_regs *regs,
-+                        unsigned long address,
-+                        unsigned long error_code)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+
-+#ifdef CONFIG_XEN
-+      /* Faults in hypervisor area are never spurious. */
-+      if ((address >= HYPERVISOR_VIRT_START) &&
-+          (address < HYPERVISOR_VIRT_END))
-+              return 0;
-+#endif
-+
-+      /* Reserved-bit violation or user access to kernel space? */
-+      if (error_code & (PF_RSVD|PF_USER))
-+              return 0;
-+
-+      pgd = init_mm.pgd + pgd_index(address);
-+      if (!pgd_present(*pgd))
-+              return 0;
-+
-+      pud = pud_offset(pgd, address);
-+      if (!pud_present(*pud))
-+              return 0;
-+
-+      pmd = pmd_offset(pud, address);
-+      if (!pmd_present(*pmd))
-+              return 0;
-+
-+      pte = pte_offset_kernel(pmd, address);
-+      if (!pte_present(*pte))
-+              return 0;
-+      if ((error_code & PF_WRITE) && !pte_write(*pte))
-+              return 0;
-+      if ((error_code & PF_INSTR) && (pte_val(*pte) & _PAGE_NX))
-+              return 0;
-+
-+      return 1;
-+}
-+
-+/*
-+ * This routine handles page faults.  It determines the address,
-+ * and the problem, and then passes it off to one of the appropriate
-+ * routines.
-+ */
-+asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
-+                                      unsigned long error_code)
-+{
-+      struct task_struct *tsk;
-+      struct mm_struct *mm;
-+      struct vm_area_struct * vma;
-+      unsigned long address;
-+      const struct exception_table_entry *fixup;
-+      int write;
-+      unsigned long flags;
-+      siginfo_t info;
-+
-+      if (!user_mode(regs))
-+              error_code &= ~PF_USER; /* means kernel */
-+
-+      /* get the address */
-+      address = HYPERVISOR_shared_info->vcpu_info[
-+              smp_processor_id()].arch.cr2;
-+      if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
-+                                      SIGSEGV) == NOTIFY_STOP)
-+              return;
-+
-+      if (likely(regs->eflags & X86_EFLAGS_IF))
-+              local_irq_enable();
-+
-+      if (unlikely(page_fault_trace))
-+              printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n",
-+                     regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code); 
-+
-+      tsk = current;
-+      mm = tsk->mm;
-+      info.si_code = SEGV_MAPERR;
-+
-+
-+      /*
-+       * We fault-in kernel-space virtual memory on-demand. The
-+       * 'reference' page table is init_mm.pgd.
-+       *
-+       * NOTE! We MUST NOT take any locks for this case. We may
-+       * be in an interrupt or a critical region, and should
-+       * only copy the information from the master page table,
-+       * nothing more.
-+       *
-+       * This verifies that the fault happens in kernel space
-+       * (error_code & 4) == 0, and that the fault was not a
-+       * protection error (error_code & 9) == 0.
-+       */
-+      if (unlikely(address >= TASK_SIZE64)) {
-+              /*
-+               * Don't check for the module range here: its PML4
-+               * is always initialized because it's shared with the main
-+               * kernel text. Only vmalloc may need PML4 syncups.
-+               */
-+              if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
-+                    ((address >= VMALLOC_START && address < VMALLOC_END))) {
-+                      if (vmalloc_fault(address) < 0)
-+                              goto bad_area_nosemaphore;
-+                      return;
-+              }
-+              /* Can take a spurious fault if mapping changes R/O -> R/W. */
-+              if (spurious_fault(regs, address, error_code))
-+                      return;
-+              /*
-+               * Don't take the mm semaphore here. If we fixup a prefetch
-+               * fault we could otherwise deadlock.
-+               */
-+              goto bad_area_nosemaphore;
-+      }
-+
-+      if (unlikely(error_code & PF_RSVD))
-+              pgtable_bad(address, regs, error_code);
-+
-+      /*
-+       * If we're in an interrupt or have no user
-+       * context, we must not take the fault..
-+       */
-+      if (unlikely(in_atomic() || !mm))
-+              goto bad_area_nosemaphore;
-+
-+ again:
-+      /* When running in the kernel we expect faults to occur only to
-+       * addresses in user space.  All other faults represent errors in the
-+       * kernel and should generate an OOPS.  Unfortunatly, in the case of an
-+       * erroneous fault occuring in a code path which already holds mmap_sem
-+       * we will deadlock attempting to validate the fault against the
-+       * address space.  Luckily the kernel only validly references user
-+       * space from well defined areas of code, which are listed in the
-+       * exceptions table.
-+       *
-+       * As the vast majority of faults will be valid we will only perform
-+       * the source reference check when there is a possibilty of a deadlock.
-+       * Attempt to lock the address space, if we cannot we then validate the
-+       * source.  If this is invalid we can skip the address space check,
-+       * thus avoiding the deadlock.
-+       */
-+      if (!down_read_trylock(&mm->mmap_sem)) {
-+              if ((error_code & PF_USER) == 0 &&
-+                  !search_exception_tables(regs->rip))
-+                      goto bad_area_nosemaphore;
-+              down_read(&mm->mmap_sem);
-+      }
-+
-+      vma = find_vma(mm, address);
-+      if (!vma)
-+              goto bad_area;
-+      if (likely(vma->vm_start <= address))
-+              goto good_area;
-+      if (!(vma->vm_flags & VM_GROWSDOWN))
-+              goto bad_area;
-+      if (error_code & 4) {
-+              // XXX: align red zone size with ABI 
-+              if (address + 128 < regs->rsp)
-+                      goto bad_area;
-+      }
-+      if (expand_stack(vma, address))
-+              goto bad_area;
-+/*
-+ * Ok, we have a good vm_area for this memory access, so
-+ * we can handle it..
-+ */
-+good_area:
-+      info.si_code = SEGV_ACCERR;
-+      write = 0;
-+      switch (error_code & (PF_PROT|PF_WRITE)) {
-+              default:        /* 3: write, present */
-+                      /* fall through */
-+              case PF_WRITE:          /* write, not present */
-+                      if (!(vma->vm_flags & VM_WRITE))
-+                              goto bad_area;
-+                      write++;
-+                      break;
-+              case PF_PROT:           /* read, present */
-+                      goto bad_area;
-+              case 0:                 /* read, not present */
-+                      if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
-+                              goto bad_area;
-+      }
-+
-+      /*
-+       * If for any reason at all we couldn't handle the fault,
-+       * make sure we exit gracefully rather than endlessly redo
-+       * the fault.
-+       */
-+      switch (handle_mm_fault(mm, vma, address, write)) {
-+      case VM_FAULT_MINOR:
-+              tsk->min_flt++;
-+              break;
-+      case VM_FAULT_MAJOR:
-+              tsk->maj_flt++;
-+              break;
-+      case VM_FAULT_SIGBUS:
-+              goto do_sigbus;
-+      default:
-+              goto out_of_memory;
-+      }
-+
-+      up_read(&mm->mmap_sem);
-+      return;
-+
-+/*
-+ * Something tried to access memory that isn't in our memory map..
-+ * Fix it, but check if it's kernel or user first..
-+ */
-+bad_area:
-+      up_read(&mm->mmap_sem);
-+
-+bad_area_nosemaphore:
-+      /* User mode accesses just cause a SIGSEGV */
-+      if (error_code & PF_USER) {
-+              if (is_prefetch(regs, address, error_code))
-+                      return;
-+
-+              /* Work around K8 erratum #100 K8 in compat mode
-+                 occasionally jumps to illegal addresses >4GB.  We
-+                 catch this here in the page fault handler because
-+                 these addresses are not reachable. Just detect this
-+                 case and return.  Any code segment in LDT is
-+                 compatibility mode. */
-+              if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
-+                  (address >> 32))
-+                      return;
-+
-+              if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
-+                      printk(
-+                     "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
-+                                      tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
-+                                      tsk->comm, tsk->pid, address, regs->rip,
-+                                      regs->rsp, error_code);
-+              }
-+       
-+              tsk->thread.cr2 = address;
-+              /* Kernel addresses are always protection faults */
-+              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
-+              tsk->thread.trap_no = 14;
-+              info.si_signo = SIGSEGV;
-+              info.si_errno = 0;
-+              /* info.si_code has been set above */
-+              info.si_addr = (void __user *)address;
-+              force_sig_info(SIGSEGV, &info, tsk);
-+              return;
-+      }
-+
-+no_context:
-+      
-+      /* Are we prepared to handle this kernel fault?  */
-+      fixup = search_exception_tables(regs->rip);
-+      if (fixup) {
-+              regs->rip = fixup->fixup;
-+              return;
-+      }
-+
-+      /* 
-+       * Hall of shame of CPU/BIOS bugs.
-+       */
-+
-+      if (is_prefetch(regs, address, error_code))
-+              return;
-+
-+      if (is_errata93(regs, address))
-+              return; 
-+
-+/*
-+ * Oops. The kernel tried to access some bad page. We'll have to
-+ * terminate things with extreme prejudice.
-+ */
-+
-+      flags = oops_begin();
-+
-+      if (address < PAGE_SIZE)
-+              printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-+      else
-+              printk(KERN_ALERT "Unable to handle kernel paging request");
-+      printk(" at %016lx RIP: \n" KERN_ALERT,address);
-+      printk_address(regs->rip);
-+      printk("\n");
-+      dump_pagetable(address);
-+      tsk->thread.cr2 = address;
-+      tsk->thread.trap_no = 14;
-+      tsk->thread.error_code = error_code;
-+      __die("Oops", regs, error_code);
-+      /* Executive summary in case the body of the oops scrolled away */
-+      printk(KERN_EMERG "CR2: %016lx\n", address);
-+      oops_end(flags);
-+      do_exit(SIGKILL);
-+
-+/*
-+ * We ran out of memory, or some other thing happened to us that made
-+ * us unable to handle the page fault gracefully.
-+ */
-+out_of_memory:
-+      up_read(&mm->mmap_sem);
-+      if (current->pid == 1) { 
-+              yield();
-+              goto again;
-+      }
-+      printk("VM: killing process %s\n", tsk->comm);
-+      if (error_code & 4)
-+              do_exit(SIGKILL);
-+      goto no_context;
-+
-+do_sigbus:
-+      up_read(&mm->mmap_sem);
-+
-+      /* Kernel mode? Handle exceptions or die */
-+      if (!(error_code & PF_USER))
-+              goto no_context;
-+
-+      tsk->thread.cr2 = address;
-+      tsk->thread.error_code = error_code;
-+      tsk->thread.trap_no = 14;
-+      info.si_signo = SIGBUS;
-+      info.si_errno = 0;
-+      info.si_code = BUS_ADRERR;
-+      info.si_addr = (void __user *)address;
-+      force_sig_info(SIGBUS, &info, tsk);
-+      return;
-+}
-+
-+static int __init enable_pagefaulttrace(char *str)
-+{
-+      page_fault_trace = 1;
-+      return 0;
-+}
-+__setup("pagefaulttrace", enable_pagefaulttrace);
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/mm/init-xen.c linux-2.6.16.33/arch/x86_64/mm/init-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/mm/init-xen.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/mm/init-xen.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1162 @@
-+/*
-+ *  linux/arch/x86_64/mm/init.c
-+ *
-+ *  Copyright (C) 1995  Linus Torvalds
-+ *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
-+ *  Copyright (C) 2002,2003 Andi Kleen <ak@suse.de>
-+ *
-+ *  Jun Nakajima <jun.nakajima@intel.com>
-+ *    Modified for Xen.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/ptrace.h>
-+#include <linux/mman.h>
-+#include <linux/mm.h>
-+#include <linux/swap.h>
-+#include <linux/smp.h>
-+#include <linux/init.h>
-+#include <linux/pagemap.h>
-+#include <linux/bootmem.h>
-+#include <linux/proc_fs.h>
-+#include <linux/pci.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/module.h>
-+#include <linux/memory_hotplug.h>
-+
-+#include <asm/processor.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/pgtable.h>
-+#include <asm/pgalloc.h>
-+#include <asm/dma.h>
-+#include <asm/fixmap.h>
-+#include <asm/e820.h>
-+#include <asm/apic.h>
-+#include <asm/tlb.h>
-+#include <asm/mmu_context.h>
-+#include <asm/proto.h>
-+#include <asm/smp.h>
-+#include <asm/sections.h>
-+#include <asm/dma-mapping.h>
-+#include <asm/swiotlb.h>
-+
-+#include <xen/features.h>
-+
-+#ifndef Dprintk
-+#define Dprintk(x...)
-+#endif
-+
-+struct dma_mapping_ops* dma_ops;
-+EXPORT_SYMBOL(dma_ops);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+unsigned int __kernel_page_user;
-+EXPORT_SYMBOL(__kernel_page_user);
-+#endif
-+
-+extern unsigned long *contiguous_bitmap;
-+
-+static unsigned long dma_reserve __initdata;
-+
-+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-+extern unsigned long start_pfn;
-+
-+/*
-+ * Use this until direct mapping is established, i.e. before __va() is 
-+ * available in init_memory_mapping().
-+ */
-+
-+#define addr_to_page(addr, page)                              \
-+      (addr) &= PHYSICAL_PAGE_MASK;                           \
-+      (page) = ((unsigned long *) ((unsigned long)            \
-+      (((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) +   \
-+      __START_KERNEL_map)))
-+
-+static void early_make_page_readonly(void *va, unsigned int feature)
-+{
-+      unsigned long addr, _va = (unsigned long)va;
-+      pte_t pte, *ptep;
-+      unsigned long *page = (unsigned long *) init_level4_pgt;
-+
-+      if (xen_feature(feature))
-+              return;
-+
-+      addr = (unsigned long) page[pgd_index(_va)];
-+      addr_to_page(addr, page);
-+
-+      addr = page[pud_index(_va)];
-+      addr_to_page(addr, page);
-+
-+      addr = page[pmd_index(_va)];
-+      addr_to_page(addr, page);
-+
-+      ptep = (pte_t *) &page[pte_index(_va)];
-+
-+      pte.pte = ptep->pte & ~_PAGE_RW;
-+      if (HYPERVISOR_update_va_mapping(_va, pte, 0))
-+              BUG();
-+}
-+
-+void make_page_readonly(void *va, unsigned int feature)
-+{
-+      pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
-+      unsigned long addr = (unsigned long) va;
-+
-+      if (xen_feature(feature))
-+              return;
-+
-+      pgd = pgd_offset_k(addr);
-+      pud = pud_offset(pgd, addr);
-+      pmd = pmd_offset(pud, addr);
-+      ptep = pte_offset_kernel(pmd, addr);
-+
-+      pte.pte = ptep->pte & ~_PAGE_RW;
-+      if (HYPERVISOR_update_va_mapping(addr, pte, 0))
-+              xen_l1_entry_update(ptep, pte); /* fallback */
-+
-+      if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
-+              make_page_readonly(__va(pte_pfn(pte) << PAGE_SHIFT), feature);
-+}
-+
-+void make_page_writable(void *va, unsigned int feature)
-+{
-+      pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t pte, *ptep;
-+      unsigned long addr = (unsigned long) va;
-+
-+      if (xen_feature(feature))
-+              return;
-+
-+      pgd = pgd_offset_k(addr);
-+      pud = pud_offset(pgd, addr);
-+      pmd = pmd_offset(pud, addr);
-+      ptep = pte_offset_kernel(pmd, addr);
-+
-+      pte.pte = ptep->pte | _PAGE_RW;
-+      if (HYPERVISOR_update_va_mapping(addr, pte, 0))
-+              xen_l1_entry_update(ptep, pte); /* fallback */
-+
-+      if ((addr >= VMALLOC_START) && (addr < VMALLOC_END))
-+              make_page_writable(__va(pte_pfn(pte) << PAGE_SHIFT), feature);
-+}
-+
-+void make_pages_readonly(void *va, unsigned nr, unsigned int feature)
-+{
-+      if (xen_feature(feature))
-+              return;
-+
-+      while (nr-- != 0) {
-+              make_page_readonly(va, feature);
-+              va = (void*)((unsigned long)va + PAGE_SIZE);
-+      }
-+}
-+
-+void make_pages_writable(void *va, unsigned nr, unsigned int feature)
-+{
-+      if (xen_feature(feature))
-+              return;
-+
-+      while (nr-- != 0) {
-+              make_page_writable(va, feature);
-+              va = (void*)((unsigned long)va + PAGE_SIZE);
-+      }
-+}
-+
-+/*
-+ * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
-+ * physical space so we can cache the place of the first one and move
-+ * around without checking the pgd every time.
-+ */
-+
-+void show_mem(void)
-+{
-+      long i, total = 0, reserved = 0;
-+      long shared = 0, cached = 0;
-+      pg_data_t *pgdat;
-+      struct page *page;
-+
-+      printk(KERN_INFO "Mem-info:\n");
-+      show_free_areas();
-+      printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-+
-+      for_each_pgdat(pgdat) {
-+               for (i = 0; i < pgdat->node_spanned_pages; ++i) {
-+                      page = pfn_to_page(pgdat->node_start_pfn + i);
-+                      total++;
-+                      if (PageReserved(page))
-+                              reserved++;
-+                      else if (PageSwapCache(page))
-+                              cached++;
-+                      else if (page_count(page))
-+                              shared += page_count(page) - 1;
-+               }
-+      }
-+      printk(KERN_INFO "%lu pages of RAM\n", total);
-+      printk(KERN_INFO "%lu reserved pages\n",reserved);
-+      printk(KERN_INFO "%lu pages shared\n",shared);
-+      printk(KERN_INFO "%lu pages swap cached\n",cached);
-+}
-+
-+/* References to section boundaries */
-+
-+int after_bootmem;
-+
-+static void *spp_getpage(void)
-+{ 
-+      void *ptr;
-+      if (after_bootmem)
-+              ptr = (void *) get_zeroed_page(GFP_ATOMIC); 
-+      else
-+              ptr = alloc_bootmem_pages(PAGE_SIZE);
-+      if (!ptr || ((unsigned long)ptr & ~PAGE_MASK))
-+              panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":"");
-+
-+      Dprintk("spp_getpage %p\n", ptr);
-+      return ptr;
-+} 
-+
-+#define pgd_offset_u(address) (pgd_t *)(init_level4_user_pgt + pgd_index(address))
-+
-+static inline pud_t *pud_offset_u(unsigned long address)
-+{
-+      pud_t *pud = level3_user_pgt;
-+
-+      return pud + pud_index(address);
-+}
-+
-+static void set_pte_phys(unsigned long vaddr,
-+                       unsigned long phys, pgprot_t prot, int user_mode)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte, new_pte;
-+
-+      Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
-+
-+      pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
-+      if (pgd_none(*pgd)) {
-+              printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
-+              return;
-+      }
-+      pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
-+      if (pud_none(*pud)) {
-+              pmd = (pmd_t *) spp_getpage(); 
-+              make_page_readonly(pmd, XENFEAT_writable_page_tables);
-+              set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
-+              if (pmd != pmd_offset(pud, 0)) {
-+                      printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
-+                      return;
-+              }
-+      }
-+      pmd = pmd_offset(pud, vaddr);
-+      if (pmd_none(*pmd)) {
-+              pte = (pte_t *) spp_getpage();
-+              make_page_readonly(pte, XENFEAT_writable_page_tables);
-+              set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
-+              if (pte != pte_offset_kernel(pmd, 0)) {
-+                      printk("PAGETABLE BUG #02!\n");
-+                      return;
-+              }
-+      }
-+      if (pgprot_val(prot))
-+              new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
-+      else
-+              new_pte = __pte(0);
-+
-+      pte = pte_offset_kernel(pmd, vaddr);
-+      if (!pte_none(*pte) &&
-+          pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
-+              pte_ERROR(*pte);
-+      set_pte(pte, new_pte);
-+
-+      /*
-+       * It's enough to flush this one mapping.
-+       * (PGE mappings get flushed as well)
-+       */
-+      __flush_tlb_one(vaddr);
-+}
-+
-+static void set_pte_phys_ma(unsigned long vaddr,
-+                       unsigned long phys, pgprot_t prot)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte, new_pte;
-+
-+      Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
-+
-+      pgd = pgd_offset_k(vaddr);
-+      if (pgd_none(*pgd)) {
-+              printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
-+              return;
-+      }
-+      pud = pud_offset(pgd, vaddr);
-+      if (pud_none(*pud)) {
-+
-+              pmd = (pmd_t *) spp_getpage(); 
-+              make_page_readonly(pmd, XENFEAT_writable_page_tables);
-+
-+              set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
-+
-+              if (pmd != pmd_offset(pud, 0)) {
-+                      printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
-+                      return;
-+              }
-+      }
-+      pmd = pmd_offset(pud, vaddr);
-+
-+      if (pmd_none(*pmd)) {
-+              pte = (pte_t *) spp_getpage();
-+              make_page_readonly(pte, XENFEAT_writable_page_tables);
-+
-+              set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
-+              if (pte != pte_offset_kernel(pmd, 0)) {
-+                      printk("PAGETABLE BUG #02!\n");
-+                      return;
-+              }
-+      }
-+
-+      new_pte = pfn_pte_ma(phys >> PAGE_SHIFT, prot);
-+      pte = pte_offset_kernel(pmd, vaddr);
-+
-+      /* 
-+       * Note that the pte page is already RO, thus we want to use
-+       * xen_l1_entry_update(), not set_pte().
-+       */
-+      xen_l1_entry_update(pte, 
-+                          pfn_pte_ma(phys >> PAGE_SHIFT, prot));
-+
-+      /*
-+       * It's enough to flush this one mapping.
-+       * (PGE mappings get flushed as well)
-+       */
-+      __flush_tlb_one(vaddr);
-+}
-+
-+#define SET_FIXMAP_KERNEL 0
-+#define SET_FIXMAP_USER   1
-+
-+/* NOTE: this is meant to be run only at boot */
-+void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
-+{
-+      unsigned long address = __fix_to_virt(idx);
-+
-+      if (idx >= __end_of_fixed_addresses) {
-+              printk("Invalid __set_fixmap\n");
-+              return;
-+      }
-+      switch (idx) {
-+      case VSYSCALL_FIRST_PAGE:
-+              set_pte_phys(address, phys, prot, SET_FIXMAP_KERNEL);
-+              break;
-+      default:
-+              set_pte_phys_ma(address, phys, prot);
-+              break;
-+      }
-+}
-+
-+/*
-+ * At this point it only supports vsyscall area.
-+ */
-+void __set_fixmap_user (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
-+{
-+      unsigned long address = __fix_to_virt(idx);
-+
-+      if (idx >= __end_of_fixed_addresses) {
-+              printk("Invalid __set_fixmap\n");
-+              return;
-+      }
-+
-+      set_pte_phys(address, phys, prot, SET_FIXMAP_USER); 
-+}
-+
-+unsigned long __initdata table_start, table_end; 
-+
-+unsigned long get_machine_pfn(unsigned long addr)
-+{
-+      pud_t* pud = pud_offset_k(NULL, addr);
-+      pmd_t* pmd = pmd_offset(pud, addr);
-+      pte_t *pte = pte_offset_kernel(pmd, addr);
-+
-+      return pte_mfn(*pte);
-+} 
-+
-+static __meminit void *alloc_static_page(unsigned long *phys)
-+{
-+      unsigned long va = (start_pfn << PAGE_SHIFT) + __START_KERNEL_map;
-+
-+      if (after_bootmem) {
-+              void *adr = (void *)get_zeroed_page(GFP_ATOMIC);
-+
-+              *phys = __pa(adr);
-+              return adr;
-+      }
-+
-+      *phys = start_pfn << PAGE_SHIFT;
-+      start_pfn++;
-+      memset((void *)va, 0, PAGE_SIZE);
-+      return (void *)va;
-+} 
-+
-+#define PTE_SIZE PAGE_SIZE
-+
-+static inline void __set_pte(pte_t *dst, pte_t val)
-+{
-+      *dst = val;
-+}
-+
-+static inline int make_readonly(unsigned long paddr)
-+{
-+      int readonly = 0;
-+
-+      /* Make new page tables read-only. */
-+      if (!xen_feature(XENFEAT_writable_page_tables)
-+          && (paddr >= (table_start << PAGE_SHIFT))
-+          && (paddr < (table_end << PAGE_SHIFT)))
-+              readonly = 1;
-+      /* Make old page tables read-only. */
-+      if (!xen_feature(XENFEAT_writable_page_tables)
-+          && (paddr >= (xen_start_info->pt_base - __START_KERNEL_map))
-+          && (paddr < (start_pfn << PAGE_SHIFT)))
-+              readonly = 1;
-+
-+      /*
-+       * No need for writable mapping of kernel image. This also ensures that
-+       * page and descriptor tables embedded inside don't have writable
-+       * mappings. 
-+       */
-+      if ((paddr >= __pa_symbol(&_text)) && (paddr < __pa_symbol(&_end)))
-+              readonly = 1;
-+
-+      return readonly;
-+}
-+
-+static void __meminit
-+phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end)
-+{
-+      int i, k;
-+
-+      for (i = 0; i < PTRS_PER_PMD; pmd++, i++) {
-+              unsigned long pte_phys;
-+              pte_t *pte, *pte_save;
-+
-+              if (address >= end) {
-+                      for (; i < PTRS_PER_PMD; i++, pmd++)
-+                              set_pmd(pmd, __pmd(0));
-+                      break;
-+              }
-+              pte = alloc_static_page(&pte_phys);
-+              pte_save = pte;
-+              for (k = 0; k < PTRS_PER_PTE; pte++, k++, address += PTE_SIZE) {
-+                      if ((address >= end) ||
-+                          ((address >> PAGE_SHIFT) >=
-+                           xen_start_info->nr_pages)) { 
-+                              __set_pte(pte, __pte(0)); 
-+                              continue;
-+                      }
-+                      if (make_readonly(address)) {
-+                              __set_pte(pte, 
-+                                        __pte(address | (_KERNPG_TABLE & ~_PAGE_RW)));
-+                              continue;
-+                      }
-+                      __set_pte(pte, __pte(address | _KERNPG_TABLE));
-+              }
-+              pte = pte_save;
-+              early_make_page_readonly(pte, XENFEAT_writable_page_tables);
-+              set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE));
-+      }
-+}
-+
-+static void __meminit
-+phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end)
-+{
-+      pmd_t *pmd = pmd_offset(pud, (unsigned long)__va(address));
-+
-+      if (pmd_none(*pmd)) {
-+              spin_lock(&init_mm.page_table_lock);
-+              phys_pmd_init(pmd, address, end);
-+              spin_unlock(&init_mm.page_table_lock);
-+              __flush_tlb_all();
-+      }
-+}
-+
-+static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
-+{ 
-+      long i = pud_index(address);
-+
-+      pud = pud + i;
-+
-+      if (after_bootmem && pud_val(*pud)) {
-+              phys_pmd_update(pud, address, end);
-+              return;
-+      }
-+
-+      for (; i < PTRS_PER_PUD; pud++, i++) {
-+              unsigned long paddr, pmd_phys;
-+              pmd_t *pmd;
-+
-+              paddr = (address & PGDIR_MASK) + i*PUD_SIZE;
-+              if (paddr >= end)
-+                      break;
-+
-+              pmd = alloc_static_page(&pmd_phys);
-+              early_make_page_readonly(pmd, XENFEAT_writable_page_tables);
-+              spin_lock(&init_mm.page_table_lock);
-+              set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
-+              phys_pmd_init(pmd, paddr, end);
-+              spin_unlock(&init_mm.page_table_lock);
-+      }
-+      __flush_tlb();
-+} 
-+
-+void __init xen_init_pt(void)
-+{
-+      unsigned long addr, *page;
-+
-+      memset((void *)init_level4_pgt,   0, PAGE_SIZE);
-+      memset((void *)level3_kernel_pgt, 0, PAGE_SIZE);
-+      memset((void *)level2_kernel_pgt, 0, PAGE_SIZE);
-+
-+      /* Find the initial pte page that was built for us. */
-+      page = (unsigned long *)xen_start_info->pt_base;
-+      addr = page[pgd_index(__START_KERNEL_map)];
-+      addr_to_page(addr, page);
-+      addr = page[pud_index(__START_KERNEL_map)];
-+      addr_to_page(addr, page);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      /* On Xen 3.0.2 and older we may need to explicitly specify _PAGE_USER
-+         in kernel PTEs. We check that here. */
-+      if (HYPERVISOR_xen_version(XENVER_version, NULL) <= 0x30000) {
-+              unsigned long *pg;
-+              pte_t pte;
-+
-+              /* Mess with the initial mapping of page 0. It's not needed. */
-+              BUILD_BUG_ON(__START_KERNEL <= __START_KERNEL_map);
-+              addr = page[pmd_index(__START_KERNEL_map)];
-+              addr_to_page(addr, pg);
-+              pte.pte = pg[pte_index(__START_KERNEL_map)];
-+              BUG_ON(!(pte.pte & _PAGE_PRESENT));
-+
-+              /* If _PAGE_USER isn't set, we obviously do not need it. */
-+              if (pte.pte & _PAGE_USER) {
-+                      /* _PAGE_USER is needed, but is it set implicitly? */
-+                      pte.pte &= ~_PAGE_USER;
-+                      if ((HYPERVISOR_update_va_mapping(__START_KERNEL_map,
-+                                                        pte, 0) != 0) ||
-+                          !(pg[pte_index(__START_KERNEL_map)] & _PAGE_USER))
-+                              /* We need to explicitly specify _PAGE_USER. */
-+                              __kernel_page_user = _PAGE_USER;
-+              }
-+      }
-+#endif
-+
-+      /* Construct mapping of initial pte page in our own directories. */
-+      init_level4_pgt[pgd_index(__START_KERNEL_map)] = 
-+              mk_kernel_pgd(__pa_symbol(level3_kernel_pgt));
-+      level3_kernel_pgt[pud_index(__START_KERNEL_map)] = 
-+              __pud(__pa_symbol(level2_kernel_pgt) |
-+                    _KERNPG_TABLE);
-+      memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
-+
-+      early_make_page_readonly(init_level4_pgt,
-+                               XENFEAT_writable_page_tables);
-+      early_make_page_readonly(init_level4_user_pgt,
-+                               XENFEAT_writable_page_tables);
-+      early_make_page_readonly(level3_kernel_pgt,
-+                               XENFEAT_writable_page_tables);
-+      early_make_page_readonly(level3_user_pgt,
-+                               XENFEAT_writable_page_tables);
-+      early_make_page_readonly(level2_kernel_pgt,
-+                               XENFEAT_writable_page_tables);
-+
-+      xen_pgd_pin(__pa_symbol(init_level4_pgt));
-+      xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
-+
-+      set_pgd((pgd_t *)(init_level4_user_pgt + 511), 
-+              mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
-+}
-+
-+void __init extend_init_mapping(unsigned long tables_space)
-+{
-+      unsigned long va = __START_KERNEL_map;
-+      unsigned long phys, addr, *pte_page;
-+      pmd_t *pmd;
-+      pte_t *pte, new_pte;
-+      unsigned long *page = (unsigned long *)init_level4_pgt;
-+
-+      addr = page[pgd_index(va)];
-+      addr_to_page(addr, page);
-+      addr = page[pud_index(va)];
-+      addr_to_page(addr, page);
-+
-+      /* Kill mapping of low 1MB. */
-+      while (va < (unsigned long)&_text) {
-+              HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
-+              va += PAGE_SIZE;
-+      }
-+
-+      /* Ensure init mappings cover kernel text/data and initial tables. */
-+      while (va < (__START_KERNEL_map
-+                   + (start_pfn << PAGE_SHIFT)
-+                   + tables_space)) {
-+              pmd = (pmd_t *)&page[pmd_index(va)];
-+              if (pmd_none(*pmd)) {
-+                      pte_page = alloc_static_page(&phys);
-+                      early_make_page_readonly(
-+                              pte_page, XENFEAT_writable_page_tables);
-+                      set_pmd(pmd, __pmd(phys | _KERNPG_TABLE));
-+              } else {
-+                      addr = page[pmd_index(va)];
-+                      addr_to_page(addr, pte_page);
-+              }
-+              pte = (pte_t *)&pte_page[pte_index(va)];
-+              if (pte_none(*pte)) {
-+                      new_pte = pfn_pte(
-+                              (va - __START_KERNEL_map) >> PAGE_SHIFT, 
-+                              __pgprot(_KERNPG_TABLE));
-+                      xen_l1_entry_update(pte, new_pte);
-+              }
-+              va += PAGE_SIZE;
-+      }
-+
-+      /* Finally, blow away any spurious initial mappings. */
-+      while (1) {
-+              pmd = (pmd_t *)&page[pmd_index(va)];
-+              if (pmd_none(*pmd))
-+                      break;
-+              HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
-+              va += PAGE_SIZE;
-+      }
-+}
-+
-+static void __init find_early_table_space(unsigned long end)
-+{
-+      unsigned long puds, pmds, ptes, tables; 
-+
-+      puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
-+      pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
-+      ptes = (end + PTE_SIZE - 1) >> PAGE_SHIFT;
-+
-+      tables = round_up(puds * 8, PAGE_SIZE) + 
-+              round_up(pmds * 8, PAGE_SIZE) + 
-+              round_up(ptes * 8, PAGE_SIZE); 
-+
-+      extend_init_mapping(tables);
-+
-+      table_start = start_pfn;
-+      table_end = table_start + (tables>>PAGE_SHIFT);
-+
-+      early_printk("kernel direct mapping tables up to %lx @ %lx-%lx\n",
-+              end, table_start << PAGE_SHIFT, table_end << PAGE_SHIFT);
-+}
-+
-+/* Setup the direct mapping of the physical memory at PAGE_OFFSET.
-+   This runs before bootmem is initialized and gets pages directly from the 
-+   physical memory. To access them they are temporarily mapped. */
-+void __meminit init_memory_mapping(unsigned long start, unsigned long end)
-+{ 
-+      unsigned long next; 
-+
-+      Dprintk("init_memory_mapping\n");
-+
-+      /* 
-+       * Find space for the kernel direct mapping tables.
-+       * Later we should allocate these tables in the local node of the memory
-+       * mapped.  Unfortunately this is done currently before the nodes are 
-+       * discovered.
-+       */
-+      if (!after_bootmem)
-+              find_early_table_space(end);
-+
-+      start = (unsigned long)__va(start);
-+      end = (unsigned long)__va(end);
-+
-+      for (; start < end; start = next) {
-+              unsigned long pud_phys; 
-+              pgd_t *pgd = pgd_offset_k(start);
-+              pud_t *pud;
-+
-+              if (after_bootmem) {
-+                      pud = pud_offset_k(pgd, __PAGE_OFFSET);
-+                      make_page_readonly(pud, XENFEAT_writable_page_tables);
-+                      pud_phys = __pa(pud);
-+              } else {
-+                      pud = alloc_static_page(&pud_phys);
-+                      early_make_page_readonly(pud, XENFEAT_writable_page_tables);
-+              }
-+              next = start + PGDIR_SIZE;
-+              if (next > end) 
-+                      next = end; 
-+              phys_pud_init(pud, __pa(start), __pa(next));
-+              if (!after_bootmem)
-+                      set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
-+      }
-+
-+      if (!after_bootmem) {
-+              BUG_ON(start_pfn != table_end);
-+
-+              /* Re-vector virtual addresses pointing into the initial
-+                 mapping to the just-established permanent ones. */
-+              xen_start_info = __va(__pa(xen_start_info));
-+              xen_start_info->pt_base = (unsigned long)
-+                      __va(__pa(xen_start_info->pt_base));
-+              if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      phys_to_machine_mapping =
-+                              __va(__pa(xen_start_info->mfn_list));
-+                      xen_start_info->mfn_list = (unsigned long)
-+                              phys_to_machine_mapping;
-+              }
-+              if (xen_start_info->mod_start)
-+                      xen_start_info->mod_start = (unsigned long)
-+                              __va(__pa(xen_start_info->mod_start));
-+
-+              /* Destroy the Xen-created mappings beyond the kernel image as
-+               * well as the temporary mappings created above. Prevents
-+               * overlap with modules area (if init mapping is very big).
-+               */
-+              start = PAGE_ALIGN((unsigned long)_end);
-+              end   = __START_KERNEL_map + (table_end << PAGE_SHIFT);
-+              for (; start < end; start += PAGE_SIZE)
-+                      WARN_ON(HYPERVISOR_update_va_mapping(
-+                              start, __pte_ma(0), 0));
-+      }
-+
-+      __flush_tlb_all();
-+}
-+
-+void __cpuinit zap_low_mappings(int cpu)
-+{
-+      /* this is not required for Xen */
-+#if 0
-+      swap_low_mappings();
-+#endif
-+}
-+
-+/* Compute zone sizes for the DMA and DMA32 zones in a node. */
-+__init void
-+size_zones(unsigned long *z, unsigned long *h,
-+         unsigned long start_pfn, unsigned long end_pfn)
-+{
-+      int i;
-+#ifndef CONFIG_XEN
-+      unsigned long w;
-+#endif
-+
-+      for (i = 0; i < MAX_NR_ZONES; i++)
-+              z[i] = 0;
-+
-+#ifndef CONFIG_XEN
-+      if (start_pfn < MAX_DMA_PFN)
-+              z[ZONE_DMA] = MAX_DMA_PFN - start_pfn;
-+      if (start_pfn < MAX_DMA32_PFN) {
-+              unsigned long dma32_pfn = MAX_DMA32_PFN;
-+              if (dma32_pfn > end_pfn)
-+                      dma32_pfn = end_pfn;
-+              z[ZONE_DMA32] = dma32_pfn - start_pfn;
-+      }
-+      z[ZONE_NORMAL] = end_pfn - start_pfn;
-+
-+      /* Remove lower zones from higher ones. */
-+      w = 0;
-+      for (i = 0; i < MAX_NR_ZONES; i++) {
-+              if (z[i])
-+                      z[i] -= w;
-+              w += z[i];
-+      }
-+
-+      /* Compute holes */
-+      w = start_pfn;
-+      for (i = 0; i < MAX_NR_ZONES; i++) {
-+              unsigned long s = w;
-+              w += z[i];
-+              h[i] = e820_hole_size(s, w);
-+      }
-+
-+      /* Add the space pace needed for mem_map to the holes too. */
-+      for (i = 0; i < MAX_NR_ZONES; i++)
-+              h[i] += (z[i] * sizeof(struct page)) / PAGE_SIZE;
-+
-+      /* The 16MB DMA zone has the kernel and other misc mappings.
-+         Account them too */
-+      if (h[ZONE_DMA]) {
-+              h[ZONE_DMA] += dma_reserve;
-+              if (h[ZONE_DMA] >= z[ZONE_DMA]) {
-+                      printk(KERN_WARNING
-+                              "Kernel too large and filling up ZONE_DMA?\n");
-+                      h[ZONE_DMA] = z[ZONE_DMA];
-+              }
-+      }
-+#else
-+      z[ZONE_DMA] = end_pfn;
-+      for (i = 0; i < MAX_NR_ZONES; i++)
-+              h[i] = 0;
-+#endif
-+}
-+
-+#ifndef CONFIG_NUMA
-+void __init paging_init(void)
-+{
-+      unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES];
-+      int i;
-+
-+      memory_present(0, 0, end_pfn);
-+      sparse_init();
-+      size_zones(zones, holes, 0, end_pfn);
-+      free_area_init_node(0, NODE_DATA(0), zones,
-+                          __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
-+
-+      /* Switch to the real shared_info page, and clear the
-+       * dummy page. */
-+      set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-+      HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-+      memset(empty_zero_page, 0, sizeof(empty_zero_page));
-+
-+      init_mm.context.pinned = 1;
-+
-+      /* Setup mapping of lower 1st MB */
-+      for (i = 0; i < NR_FIX_ISAMAPS; i++)
-+              if (is_initial_xendomain())
-+                      set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
-+              else
-+                      __set_fixmap(FIX_ISAMAP_BEGIN - i,
-+                                   virt_to_mfn(empty_zero_page) << PAGE_SHIFT,
-+                                   PAGE_KERNEL_RO);
-+}
-+#endif
-+
-+/* Unmap a kernel mapping if it exists. This is useful to avoid prefetches
-+   from the CPU leading to inconsistent cache lines. address and size
-+   must be aligned to 2MB boundaries. 
-+   Does nothing when the mapping doesn't exist. */
-+void __init clear_kernel_mapping(unsigned long address, unsigned long size) 
-+{
-+      unsigned long end = address + size;
-+
-+      BUG_ON(address & ~LARGE_PAGE_MASK);
-+      BUG_ON(size & ~LARGE_PAGE_MASK); 
-+      
-+      for (; address < end; address += LARGE_PAGE_SIZE) { 
-+              pgd_t *pgd = pgd_offset_k(address);
-+              pud_t *pud;
-+              pmd_t *pmd;
-+              if (pgd_none(*pgd))
-+                      continue;
-+              pud = pud_offset(pgd, address);
-+              if (pud_none(*pud))
-+                      continue; 
-+              pmd = pmd_offset(pud, address);
-+              if (!pmd || pmd_none(*pmd))
-+                      continue; 
-+              if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { 
-+                      /* Could handle this, but it should not happen currently. */
-+                      printk(KERN_ERR 
-+             "clear_kernel_mapping: mapping has been split. will leak memory\n"); 
-+                      pmd_ERROR(*pmd); 
-+              }
-+              set_pmd(pmd, __pmd(0));                 
-+      }
-+      __flush_tlb_all();
-+} 
-+
-+/*
-+ * Memory hotplug specific functions
-+ * These are only for non-NUMA machines right now.
-+ */
-+#ifdef CONFIG_MEMORY_HOTPLUG
-+
-+void online_page(struct page *page)
-+{
-+      ClearPageReserved(page);
-+      set_page_count(page, 1);
-+      __free_page(page);
-+      totalram_pages++;
-+      num_physpages++;
-+}
-+
-+int add_memory(u64 start, u64 size)
-+{
-+      struct pglist_data *pgdat = NODE_DATA(0);
-+      struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2;
-+      unsigned long start_pfn = start >> PAGE_SHIFT;
-+      unsigned long nr_pages = size >> PAGE_SHIFT;
-+      int ret;
-+
-+      ret = __add_pages(zone, start_pfn, nr_pages);
-+      if (ret)
-+              goto error;
-+
-+      init_memory_mapping(start, (start + size -1));
-+
-+      return ret;
-+error:
-+      printk("%s: Problem encountered in __add_pages!\n", __func__);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(add_memory);
-+
-+int remove_memory(u64 start, u64 size)
-+{
-+      return -EINVAL;
-+}
-+EXPORT_SYMBOL_GPL(remove_memory);
-+
-+#endif
-+
-+static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
-+                       kcore_vsyscall;
-+
-+void __init mem_init(void)
-+{
-+      long codesize, reservedpages, datasize, initsize;
-+      unsigned long pfn;
-+
-+      contiguous_bitmap = alloc_bootmem_low_pages(
-+              (end_pfn + 2*BITS_PER_LONG) >> 3);
-+      BUG_ON(!contiguous_bitmap);
-+      memset(contiguous_bitmap, 0, (end_pfn + 2*BITS_PER_LONG) >> 3);
-+
-+#if defined(CONFIG_SWIOTLB)
-+      pci_swiotlb_init();     
-+#endif
-+      no_iommu_init();
-+
-+      /* How many end-of-memory variables you have, grandma! */
-+      max_low_pfn = end_pfn;
-+      max_pfn = end_pfn;
-+      num_physpages = end_pfn;
-+      high_memory = (void *) __va(end_pfn * PAGE_SIZE);
-+
-+      /* clear the zero-page */
-+      memset(empty_zero_page, 0, PAGE_SIZE);
-+
-+      reservedpages = 0;
-+
-+      /* this will put all low memory onto the freelists */
-+#ifdef CONFIG_NUMA
-+      totalram_pages = numa_free_all_bootmem();
-+#else
-+      totalram_pages = free_all_bootmem();
-+#endif
-+      /* XEN: init and count pages outside initial allocation. */
-+      for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
-+              ClearPageReserved(pfn_to_page(pfn));
-+              set_page_count(pfn_to_page(pfn), 1);
-+              totalram_pages++;
-+      }
-+      reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn);
-+
-+      after_bootmem = 1;
-+
-+      codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-+      datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-+      initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-+
-+      /* Register memory areas for /proc/kcore */
-+      kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
-+      kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 
-+                 VMALLOC_END-VMALLOC_START);
-+      kclist_add(&kcore_kernel, &_stext, _end - _stext);
-+      kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN);
-+      kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START, 
-+                               VSYSCALL_END - VSYSCALL_START);
-+
-+      printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)\n",
-+              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-+              end_pfn << (PAGE_SHIFT-10),
-+              codesize >> 10,
-+              reservedpages << (PAGE_SHIFT-10),
-+              datasize >> 10,
-+              initsize >> 10);
-+
-+#ifndef CONFIG_XEN
-+#ifdef CONFIG_SMP
-+      /*
-+       * Sync boot_level4_pgt mappings with the init_level4_pgt
-+       * except for the low identity mappings which are already zapped
-+       * in init_level4_pgt. This sync-up is essential for AP's bringup
-+       */
-+      memcpy(boot_level4_pgt+1, init_level4_pgt+1, (PTRS_PER_PGD-1)*sizeof(pgd_t));
-+#endif
-+#endif
-+}
-+
-+void free_initmem(void)
-+{
-+#ifdef __DO_LATER__
-+      /*
-+       * Some pages can be pinned, but some are not. Unpinning such pages 
-+       * triggers BUG(). 
-+       */
-+      unsigned long addr;
-+
-+      addr = (unsigned long)(&__init_begin);
-+      for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
-+              ClearPageReserved(virt_to_page(addr));
-+              set_page_count(virt_to_page(addr), 1);
-+              memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); 
-+              make_page_writable(
-+                      __va(__pa(addr)), XENFEAT_writable_page_tables);
-+              /*
-+               * Make pages from __PAGE_OFFSET address as well
-+               */
-+              make_page_writable(
-+                      (void *)addr, XENFEAT_writable_page_tables);
-+              free_page(addr);
-+              totalram_pages++;
-+      }
-+      memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin);
-+      printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10);
-+#endif
-+}
-+
-+#ifdef CONFIG_DEBUG_RODATA
-+
-+extern char __start_rodata, __end_rodata;
-+void mark_rodata_ro(void)
-+{
-+      unsigned long addr = (unsigned long)&__start_rodata;
-+
-+      for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
-+              change_page_attr_addr(addr, 1, PAGE_KERNEL_RO);
-+
-+      printk ("Write protecting the kernel read-only data: %luk\n",
-+                      (&__end_rodata - &__start_rodata) >> 10);
-+
-+      /*
-+       * change_page_attr_addr() requires a global_flush_tlb() call after it.
-+       * We do this after the printk so that if something went wrong in the
-+       * change, the printk gets out at least to give a better debug hint
-+       * of who is the culprit.
-+       */
-+      global_flush_tlb();
-+}
-+#endif
-+
-+#ifdef CONFIG_BLK_DEV_INITRD
-+void free_initrd_mem(unsigned long start, unsigned long end)
-+{
-+      if (start >= end)
-+              return;
-+      printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
-+      for (; start < end; start += PAGE_SIZE) {
-+              ClearPageReserved(virt_to_page(start));
-+              set_page_count(virt_to_page(start), 1);
-+              free_page(start);
-+              totalram_pages++;
-+      }
-+}
-+#endif
-+
-+void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 
-+{ 
-+      /* Should check here against the e820 map to avoid double free */ 
-+#ifdef CONFIG_NUMA
-+      int nid = phys_to_nid(phys);
-+      reserve_bootmem_node(NODE_DATA(nid), phys, len);
-+#else                 
-+      reserve_bootmem(phys, len);    
-+#endif
-+      if (phys+len <= MAX_DMA_PFN*PAGE_SIZE)
-+              dma_reserve += len / PAGE_SIZE;
-+}
-+
-+int kern_addr_valid(unsigned long addr) 
-+{ 
-+      unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT;
-+       pgd_t *pgd;
-+       pud_t *pud;
-+       pmd_t *pmd;
-+       pte_t *pte;
-+
-+      if (above != 0 && above != -1UL)
-+              return 0; 
-+      
-+      pgd = pgd_offset_k(addr);
-+      if (pgd_none(*pgd))
-+              return 0;
-+
-+      pud = pud_offset_k(pgd, addr);
-+      if (pud_none(*pud))
-+              return 0; 
-+
-+      pmd = pmd_offset(pud, addr);
-+      if (pmd_none(*pmd))
-+              return 0;
-+      if (pmd_large(*pmd))
-+              return pfn_valid(pmd_pfn(*pmd));
-+
-+      pte = pte_offset_kernel(pmd, addr);
-+      if (pte_none(*pte))
-+              return 0;
-+      return pfn_valid(pte_pfn(*pte));
-+}
-+
-+#ifdef CONFIG_SYSCTL
-+#include <linux/sysctl.h>
-+
-+extern int exception_trace, page_fault_trace;
-+
-+static ctl_table debug_table2[] = {
-+      { 99, "exception-trace", &exception_trace, sizeof(int), 0644, NULL,
-+        proc_dointvec },
-+      { 0, }
-+}; 
-+
-+static ctl_table debug_root_table2[] = { 
-+      { .ctl_name = CTL_DEBUG, .procname = "debug", .mode = 0555, 
-+         .child = debug_table2 }, 
-+      { 0 }, 
-+}; 
-+
-+static __init int x8664_sysctl_init(void)
-+{ 
-+      register_sysctl_table(debug_root_table2, 1);
-+      return 0;
-+}
-+__initcall(x8664_sysctl_init);
-+#endif
-+
-+/* A pseudo VMAs to allow ptrace access for the vsyscall page.   This only
-+   covers the 64bit vsyscall page now. 32bit has a real VMA now and does
-+   not need special handling anymore. */
-+
-+static struct vm_area_struct gate_vma = {
-+      .vm_start = VSYSCALL_START,
-+      .vm_end = VSYSCALL_END,
-+      .vm_page_prot = PAGE_READONLY
-+};
-+
-+struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
-+{
-+#ifdef CONFIG_IA32_EMULATION
-+      if (test_tsk_thread_flag(tsk, TIF_IA32))
-+              return NULL;
-+#endif
-+      return &gate_vma;
-+}
-+
-+int in_gate_area(struct task_struct *task, unsigned long addr)
-+{
-+      struct vm_area_struct *vma = get_gate_vma(task);
-+      if (!vma)
-+              return 0;
-+      return (addr >= vma->vm_start) && (addr < vma->vm_end);
-+}
-+
-+/* Use this when you have no reliable task/vma, typically from interrupt
-+ * context.  It is less reliable than using the task's vma and may give
-+ * false positives.
-+ */
-+int in_gate_area_no_task(unsigned long addr)
-+{
-+      return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
-+}
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/mm/pageattr-xen.c linux-2.6.16.33/arch/x86_64/mm/pageattr-xen.c
---- linux-2.6.16.33-noxen/arch/x86_64/mm/pageattr-xen.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/mm/pageattr-xen.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,408 @@
-+/* 
-+ * Copyright 2002 Andi Kleen, SuSE Labs. 
-+ * Thanks to Ben LaHaise for precious feedback.
-+ */ 
-+
-+#include <linux/config.h>
-+#include <linux/mm.h>
-+#include <linux/sched.h>
-+#include <linux/highmem.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <asm/uaccess.h>
-+#include <asm/processor.h>
-+#include <asm/tlbflush.h>
-+#include <asm/io.h>
-+
-+#ifdef CONFIG_XEN
-+#include <asm/pgalloc.h>
-+#include <asm/mmu_context.h>
-+
-+LIST_HEAD(mm_unpinned);
-+DEFINE_SPINLOCK(mm_unpinned_lock);
-+
-+static inline void mm_walk_set_prot(void *pt, pgprot_t flags)
-+{
-+      struct page *page = virt_to_page(pt);
-+      unsigned long pfn = page_to_pfn(page);
-+
-+      BUG_ON(HYPERVISOR_update_va_mapping(
-+                     (unsigned long)__va(pfn << PAGE_SHIFT),
-+                     pfn_pte(pfn, flags), 0));
-+}
-+
-+static void mm_walk(struct mm_struct *mm, pgprot_t flags)
-+{
-+      pgd_t       *pgd;
-+      pud_t       *pud;
-+      pmd_t       *pmd;
-+      pte_t       *pte;
-+      int          g,u,m;
-+
-+      pgd = mm->pgd;
-+      /*
-+       * Cannot iterate up to USER_PTRS_PER_PGD as these pagetables may not
-+       * be the 'current' task's pagetables (e.g., current may be 32-bit,
-+       * but the pagetables may be for a 64-bit task).
-+       * Subtracting 1 from TASK_SIZE64 means the loop limit is correct
-+       * regardless of whether TASK_SIZE64 is a multiple of PGDIR_SIZE.
-+       */
-+      for (g = 0; g <= ((TASK_SIZE64-1) / PGDIR_SIZE); g++, pgd++) {
-+              if (pgd_none(*pgd))
-+                      continue;
-+              pud = pud_offset(pgd, 0);
-+              if (PTRS_PER_PUD > 1) /* not folded */ 
-+                      mm_walk_set_prot(pud,flags);
-+              for (u = 0; u < PTRS_PER_PUD; u++, pud++) {
-+                      if (pud_none(*pud))
-+                              continue;
-+                      pmd = pmd_offset(pud, 0);
-+                      if (PTRS_PER_PMD > 1) /* not folded */ 
-+                              mm_walk_set_prot(pmd,flags);
-+                      for (m = 0; m < PTRS_PER_PMD; m++, pmd++) {
-+                              if (pmd_none(*pmd))
-+                                      continue;
-+                              pte = pte_offset_kernel(pmd,0);
-+                              mm_walk_set_prot(pte,flags);
-+                      }
-+              }
-+      }
-+}
-+
-+void mm_pin(struct mm_struct *mm)
-+{
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
-+
-+      spin_lock(&mm->page_table_lock);
-+
-+      mm_walk(mm, PAGE_KERNEL_RO);
-+      BUG_ON(HYPERVISOR_update_va_mapping(
-+                     (unsigned long)mm->pgd,
-+                     pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO),
-+                     UVMF_TLB_FLUSH));
-+      BUG_ON(HYPERVISOR_update_va_mapping(
-+                     (unsigned long)__user_pgd(mm->pgd),
-+                     pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, PAGE_KERNEL_RO),
-+                     UVMF_TLB_FLUSH));
-+      xen_pgd_pin(__pa(mm->pgd)); /* kernel */
-+      xen_pgd_pin(__pa(__user_pgd(mm->pgd))); /* user */
-+      mm->context.pinned = 1;
-+      spin_lock(&mm_unpinned_lock);
-+      list_del(&mm->context.unpinned);
-+      spin_unlock(&mm_unpinned_lock);
-+
-+      spin_unlock(&mm->page_table_lock);
-+}
-+
-+void mm_unpin(struct mm_struct *mm)
-+{
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
-+
-+      spin_lock(&mm->page_table_lock);
-+
-+      xen_pgd_unpin(__pa(mm->pgd));
-+      xen_pgd_unpin(__pa(__user_pgd(mm->pgd)));
-+      BUG_ON(HYPERVISOR_update_va_mapping(
-+                     (unsigned long)mm->pgd,
-+                     pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0));
-+      BUG_ON(HYPERVISOR_update_va_mapping(
-+                     (unsigned long)__user_pgd(mm->pgd),
-+                     pfn_pte(virt_to_phys(__user_pgd(mm->pgd))>>PAGE_SHIFT, PAGE_KERNEL), 0));
-+      mm_walk(mm, PAGE_KERNEL);
-+      xen_tlb_flush();
-+      mm->context.pinned = 0;
-+      spin_lock(&mm_unpinned_lock);
-+      list_add(&mm->context.unpinned, &mm_unpinned);
-+      spin_unlock(&mm_unpinned_lock);
-+
-+      spin_unlock(&mm->page_table_lock);
-+}
-+
-+void mm_pin_all(void)
-+{
-+      if (xen_feature(XENFEAT_writable_page_tables))
-+              return;
-+
-+      while (!list_empty(&mm_unpinned))       
-+              mm_pin(list_entry(mm_unpinned.next, struct mm_struct,
-+                                context.unpinned));
-+}
-+
-+void _arch_dup_mmap(struct mm_struct *mm)
-+{
-+    if (!mm->context.pinned)
-+        mm_pin(mm);
-+}
-+
-+void _arch_exit_mmap(struct mm_struct *mm)
-+{
-+    struct task_struct *tsk = current;
-+
-+    task_lock(tsk);
-+
-+    /*
-+     * We aggressively remove defunct pgd from cr3. We execute unmap_vmas()
-+     * *much* faster this way, as no tlb flushes means bigger wrpt batches.
-+     */
-+    if ( tsk->active_mm == mm )
-+    {
-+        tsk->active_mm = &init_mm;
-+        atomic_inc(&init_mm.mm_count);
-+
-+        switch_mm(mm, &init_mm, tsk);
-+
-+        atomic_dec(&mm->mm_count);
-+        BUG_ON(atomic_read(&mm->mm_count) == 0);
-+    }
-+
-+    task_unlock(tsk);
-+
-+    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) &&
-+         !mm->context.has_foreign_mappings )
-+        mm_unpin(mm);
-+}
-+
-+void pte_free(struct page *pte)
-+{
-+      unsigned long va = (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT);
-+
-+      if (!pte_write(*virt_to_ptep(va)))
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                      va, pfn_pte(page_to_pfn(pte), PAGE_KERNEL), 0));
-+      __free_page(pte);
-+}
-+#endif        /* CONFIG_XEN */
-+
-+static inline pte_t *lookup_address(unsigned long address) 
-+{ 
-+      pgd_t *pgd = pgd_offset_k(address);
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t *pte;
-+      if (pgd_none(*pgd))
-+              return NULL;
-+      pud = pud_offset(pgd, address);
-+      if (!pud_present(*pud))
-+              return NULL; 
-+      pmd = pmd_offset(pud, address);
-+      if (!pmd_present(*pmd))
-+              return NULL; 
-+      if (pmd_large(*pmd))
-+              return (pte_t *)pmd;
-+      pte = pte_offset_kernel(pmd, address);
-+      if (pte && !pte_present(*pte))
-+              pte = NULL; 
-+      return pte;
-+} 
-+
-+static struct page *split_large_page(unsigned long address, pgprot_t prot,
-+                                   pgprot_t ref_prot)
-+{ 
-+      int i; 
-+      unsigned long addr;
-+      struct page *base = alloc_pages(GFP_KERNEL, 0);
-+      pte_t *pbase;
-+      if (!base) 
-+              return NULL;
-+      address = __pa(address);
-+      addr = address & LARGE_PAGE_MASK; 
-+      pbase = (pte_t *)page_address(base);
-+      for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
-+              pbase[i] = pfn_pte(addr >> PAGE_SHIFT, 
-+                                 addr == address ? prot : ref_prot);
-+      }
-+      return base;
-+} 
-+
-+
-+static void flush_kernel_map(void *address) 
-+{
-+      if (0 && address && cpu_has_clflush) {
-+              /* is this worth it? */ 
-+              int i;
-+              for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) 
-+                      asm volatile("clflush (%0)" :: "r" (address + i)); 
-+      } else
-+              asm volatile("wbinvd":::"memory"); 
-+      if (address)
-+              __flush_tlb_one(address);
-+      else
-+              __flush_tlb_all();
-+}
-+
-+
-+static inline void flush_map(unsigned long address)
-+{     
-+      on_each_cpu(flush_kernel_map, (void *)address, 1, 1);
-+}
-+
-+struct deferred_page { 
-+      struct deferred_page *next; 
-+      struct page *fpage;
-+      unsigned long address;
-+}; 
-+static struct deferred_page *df_list; /* protected by init_mm.mmap_sem */
-+
-+static inline void save_page(unsigned long address, struct page *fpage)
-+{
-+      struct deferred_page *df;
-+      df = kmalloc(sizeof(struct deferred_page), GFP_KERNEL); 
-+      if (!df) {
-+              flush_map(address);
-+              __free_page(fpage);
-+      } else { 
-+              df->next = df_list;
-+              df->fpage = fpage;
-+              df->address = address;
-+              df_list = df;
-+      }                       
-+}
-+
-+/* 
-+ * No more special protections in this 2/4MB area - revert to a
-+ * large page again. 
-+ */
-+static void revert_page(unsigned long address, pgprot_t ref_prot)
-+{
-+      pgd_t *pgd;
-+      pud_t *pud;
-+      pmd_t *pmd;
-+      pte_t large_pte;
-+
-+      pgd = pgd_offset_k(address);
-+      BUG_ON(pgd_none(*pgd));
-+      pud = pud_offset(pgd,address);
-+      BUG_ON(pud_none(*pud));
-+      pmd = pmd_offset(pud, address);
-+      BUG_ON(pmd_val(*pmd) & _PAGE_PSE);
-+      pgprot_val(ref_prot) |= _PAGE_PSE;
-+      large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot);
-+      set_pte((pte_t *)pmd, large_pte);
-+}      
-+
-+static int
-+__change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
-+                                 pgprot_t ref_prot)
-+{ 
-+      pte_t *kpte; 
-+      struct page *kpte_page;
-+      unsigned kpte_flags;
-+      pgprot_t ref_prot2;
-+      kpte = lookup_address(address);
-+      if (!kpte) return 0;
-+      kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
-+      kpte_flags = pte_val(*kpte); 
-+      if (pgprot_val(prot) != pgprot_val(ref_prot)) { 
-+              if ((kpte_flags & _PAGE_PSE) == 0) { 
-+                      set_pte(kpte, pfn_pte(pfn, prot));
-+              } else {
-+                      /*
-+                       * split_large_page will take the reference for this change_page_attr
-+                       * on the split page.
-+                       */
-+
-+                      struct page *split;
-+                      ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE));
-+
-+                      split = split_large_page(address, prot, ref_prot2);
-+                      if (!split)
-+                              return -ENOMEM;
-+                      set_pte(kpte,mk_pte(split, ref_prot2));
-+                      kpte_page = split;
-+              }       
-+              get_page(kpte_page);
-+      } else if ((kpte_flags & _PAGE_PSE) == 0) { 
-+              set_pte(kpte, pfn_pte(pfn, ref_prot));
-+              __put_page(kpte_page);
-+      } else
-+              BUG();
-+
-+      /* on x86-64 the direct mapping set at boot is not using 4k pages */
-+      /*
-+       * ..., but the XEN guest kernels (currently) do:
-+       * If the pte was reserved, it means it was created at boot
-+       * time (not via split_large_page) and in turn we must not
-+       * replace it with a large page.
-+       */
-+#ifndef CONFIG_XEN
-+      BUG_ON(PageReserved(kpte_page));
-+#else
-+      if (!PageReserved(kpte_page))
-+#endif
-+              switch (page_count(kpte_page)) {
-+              case 1:
-+                      save_page(address, kpte_page);               
-+                      revert_page(address, ref_prot);
-+                      break;
-+              case 0:
-+                      BUG(); /* memleak and failed 2M page regeneration */
-+              }
-+      return 0;
-+} 
-+
-+/*
-+ * Change the page attributes of an page in the linear mapping.
-+ *
-+ * This should be used when a page is mapped with a different caching policy
-+ * than write-back somewhere - some CPUs do not like it when mappings with
-+ * different caching policies exist. This changes the page attributes of the
-+ * in kernel linear mapping too.
-+ * 
-+ * The caller needs to ensure that there are no conflicting mappings elsewhere.
-+ * This function only deals with the kernel linear map.
-+ * 
-+ * Caller must call global_flush_tlb() after this.
-+ */
-+int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
-+{
-+      int err = 0; 
-+      int i; 
-+
-+      down_write(&init_mm.mmap_sem);
-+      for (i = 0; i < numpages; i++, address += PAGE_SIZE) {
-+              unsigned long pfn = __pa(address) >> PAGE_SHIFT;
-+
-+              err = __change_page_attr(address, pfn, prot, PAGE_KERNEL);
-+              if (err) 
-+                      break; 
-+              /* Handle kernel mapping too which aliases part of the
-+               * lowmem */
-+              if (__pa(address) < KERNEL_TEXT_SIZE) {
-+                      unsigned long addr2;
-+                      pgprot_t prot2 = prot;
-+                      addr2 = __START_KERNEL_map + __pa(address);
-+                      pgprot_val(prot2) &= ~_PAGE_NX;
-+                      err = __change_page_attr(addr2, pfn, prot2, PAGE_KERNEL_EXEC);
-+              } 
-+      }       
-+      up_write(&init_mm.mmap_sem); 
-+      return err;
-+}
-+
-+/* Don't call this for MMIO areas that may not have a mem_map entry */
-+int change_page_attr(struct page *page, int numpages, pgprot_t prot)
-+{
-+      unsigned long addr = (unsigned long)page_address(page);
-+      return change_page_attr_addr(addr, numpages, prot);
-+}
-+
-+void global_flush_tlb(void)
-+{ 
-+      struct deferred_page *df, *next_df;
-+
-+      down_read(&init_mm.mmap_sem);
-+      df = xchg(&df_list, NULL);
-+      up_read(&init_mm.mmap_sem);
-+      flush_map((df && !df->next) ? df->address : 0);
-+      for (; df; df = next_df) { 
-+              next_df = df->next;
-+              if (df->fpage) 
-+                      __free_page(df->fpage);
-+              kfree(df);
-+      } 
-+} 
-+
-+EXPORT_SYMBOL(change_page_attr);
-+EXPORT_SYMBOL(global_flush_tlb);
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/oprofile/Makefile linux-2.6.16.33/arch/x86_64/oprofile/Makefile
---- linux-2.6.16.33-noxen/arch/x86_64/oprofile/Makefile        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/oprofile/Makefile      2007-01-08 15:00:45.000000000 +0000
-@@ -11,9 +11,15 @@
-       oprofilefs.o oprofile_stats.o \
-       timer_int.o )
-+ifdef CONFIG_XEN
-+XENOPROF_COMMON_OBJS = $(addprefix ../../../drivers/xen/xenoprof/, \
-+                       xenoprofile.o)
-+OPROFILE-y := xenoprof.o
-+else
- OPROFILE-y := init.o backtrace.o
- OPROFILE-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_p4.o \
-                                    op_model_ppro.o
- OPROFILE-$(CONFIG_X86_IO_APIC)    += nmi_timer_int.o 
--
--oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
-+endif
-+oprofile-y = $(DRIVER_OBJS) $(XENOPROF_COMMON_OBJS) \
-+           $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/pci/Makefile linux-2.6.16.33/arch/x86_64/pci/Makefile
---- linux-2.6.16.33-noxen/arch/x86_64/pci/Makefile     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/pci/Makefile   2007-01-08 15:00:45.000000000 +0000
-@@ -15,10 +15,22 @@
- obj-$(CONFIG_NUMA)    += k8-bus.o
-+# pcifront should be after mmconfig.o and direct.o as it should only
-+# take over if direct access to the PCI bus is unavailable
-+obj-$(CONFIG_XEN_PCIDEV_FRONTEND)     += pcifront.o
-+
- direct-y += ../../i386/pci/direct.o
- acpi-y   += ../../i386/pci/acpi.o
-+pcifront-y += ../../i386/pci/pcifront.o
- legacy-y += ../../i386/pci/legacy.o
- irq-y    += ../../i386/pci/irq.o
- common-y += ../../i386/pci/common.o
- fixup-y  += ../../i386/pci/fixup.o
- i386-y  += ../../i386/pci/i386.o
-+
-+ifdef CONFIG_XEN
-+irq-y         := ../../i386/pci/irq-xen.o
-+include $(srctree)/scripts/Makefile.xen
-+
-+obj-y := $(call cherrypickxen, $(obj-y))
-+endif
-diff -Nur linux-2.6.16.33-noxen/arch/x86_64/pci/mmconfig.c linux-2.6.16.33/arch/x86_64/pci/mmconfig.c
---- linux-2.6.16.33-noxen/arch/x86_64/pci/mmconfig.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/arch/x86_64/pci/mmconfig.c 2007-05-23 21:00:01.000000000 +0000
-@@ -9,11 +9,19 @@
- #include <linux/init.h>
- #include <linux/acpi.h>
- #include <linux/bitmap.h>
-+#include <asm/e820.h>
-+
- #include "pci.h"
--#define MMCONFIG_APER_SIZE (256*1024*1024)
-+/* aperture is up to 256MB but BIOS may reserve less */
-+#define MMCONFIG_APER_MIN     (2 * 1024*1024)
-+#define MMCONFIG_APER_MAX     (256 * 1024*1024)
-+
-+/* Verify the first 16 busses. We assume that systems with more busses
-+   get MCFG right. */
-+#define MAX_CHECK_BUS 16
--static DECLARE_BITMAP(fallback_slots, 32);
-+static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS);
- /* Static virtual mapping of the MMCONFIG aperture */
- struct mmcfg_virt {
-@@ -55,7 +63,8 @@
- static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
- {
-       char __iomem *addr;
--      if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), &fallback_slots))
-+      if (seg == 0 && bus < MAX_CHECK_BUS &&
-+              test_bit(32*bus + PCI_SLOT(devfn), fallback_slots))
-               return NULL;
-       addr = get_virt(seg, bus);
-       if (!addr)
-@@ -69,8 +78,10 @@
-       char __iomem *addr;
-       /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
--      if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
-+      if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
-+              *value = -1;
-               return -EINVAL;
-+      }
-       addr = pci_dev_base(seg, bus, devfn);
-       if (!addr)
-@@ -129,23 +140,56 @@
-    Normally this can be expressed in the MCFG by not listing them
-    and assigning suitable _SEGs, but this isn't implemented in some BIOS.
-    Instead try to discover all devices on bus 0 that are unreachable using MM
--   and fallback for them.
--   We only do this for bus 0/seg 0 */
-+   and fallback for them. */
- static __init void unreachable_devices(void)
- {
--      int i;
--      for (i = 0; i < 32; i++) {
--              u32 val1;
--              char __iomem *addr;
-+      int i, k;
-+      /* Use the max bus number from ACPI here? */
-+      for (k = 0; k < MAX_CHECK_BUS; k++) {
-+              for (i = 0; i < 32; i++) {
-+                      u32 val1;
-+                      char __iomem *addr;
-+
-+                      pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
-+                      if (val1 == 0xffffffff)
-+                              continue;
-+                      addr = pci_dev_base(0, k, PCI_DEVFN(i, 0));
-+                      if (addr == NULL|| readl(addr) != val1) {
-+                              set_bit(i + 32*k, fallback_slots);
-+                              printk(KERN_NOTICE
-+                              "PCI: No mmconfig possible on device %x:%x\n",
-+                                      k, i);
-+                      }
-+              }
-+      }
-+}
--              pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1);
--              if (val1 == 0xffffffff)
-+/* NB. Ripped from arch/x86_64/kernel/e820.c for this Xen bugfix patch. */
-+#ifdef CONFIG_XEN
-+extern struct e820map machine_e820;
-+#define e820 machine_e820
-+#endif
-+static int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
-+{
-+      int i;
-+      for (i = 0; i < e820.nr_map; i++) {
-+              struct e820entry *ei = &e820.map[i];
-+              if (type && ei->type != type)
-                       continue;
--              addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0));
--              if (addr == NULL|| readl(addr) != val1) {
--                      set_bit(i, &fallback_slots);
--              }
-+              /* is the region (part) in overlap with the current region ?*/
-+              if (ei->addr >= end || ei->addr + ei->size <= start)
-+                      continue;
-+
-+              /* if the region is at the beginning of <start,end> we move
-+               * start to the end of the region since it's ok until there
-+               */
-+              if (ei->addr <= start)
-+                      start = ei->addr + ei->size;
-+              /* if start is now at or beyond end, we're done, full coverage */
-+              if (start >= end)
-+                      return 1; /* we're done */
-       }
-+      return 0;
- }
- static int __init pci_mmcfg_init(void)
-@@ -161,6 +205,15 @@
-           (pci_mmcfg_config[0].base_address == 0))
-               return 0;
-+      if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
-+                      pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
-+                      E820_RESERVED)) {
-+              printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
-+                              pci_mmcfg_config[0].base_address);
-+              printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
-+              return 0;
-+      }
-+
-       /* RED-PEN i386 doesn't do _nocache right now */
-       pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
-       if (pci_mmcfg_virt == NULL) {
-@@ -169,7 +222,8 @@
-       }
-       for (i = 0; i < pci_mmcfg_config_num; ++i) {
-               pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
--              pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
-+              pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address,
-+                                                       MMCONFIG_APER_MAX);
-               if (!pci_mmcfg_virt[i].virt) {
-                       printk("PCI: Cannot map mmconfig aperture for segment %d\n",
-                              pci_mmcfg_config[i].pci_segment_group_number);
-diff -Nur linux-2.6.16.33-noxen/drivers/Makefile linux-2.6.16.33/drivers/Makefile
---- linux-2.6.16.33-noxen/drivers/Makefile     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/Makefile   2007-01-08 15:00:45.000000000 +0000
-@@ -34,6 +34,7 @@
- obj-$(CONFIG_NUBUS)           += nubus/
- obj-$(CONFIG_ATM)             += atm/
- obj-$(CONFIG_PPC_PMAC)                += macintosh/
-+obj-$(CONFIG_XEN)             += xen/
- obj-$(CONFIG_IDE)             += ide/
- obj-$(CONFIG_FC4)             += fc4/
- obj-$(CONFIG_SCSI)            += scsi/
-diff -Nur linux-2.6.16.33-noxen/drivers/acpi/Kconfig linux-2.6.16.33/drivers/acpi/Kconfig
---- linux-2.6.16.33-noxen/drivers/acpi/Kconfig 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/acpi/Kconfig       2007-01-08 15:00:45.000000000 +0000
-@@ -46,7 +46,7 @@
- config ACPI_SLEEP
-       bool "Sleep States"
--      depends on X86 && (!SMP || SUSPEND_SMP)
-+      depends on X86 && (!SMP || SUSPEND_SMP) && !XEN
-       depends on PM
-       default y
-       ---help---
-@@ -287,6 +287,7 @@
- config X86_PM_TIMER
-       bool "Power Management Timer Support" if EMBEDDED
-       depends on X86
-+      depends on !XEN
-       default y
-       help
-         The Power Management Timer is available on all ACPI-capable,
-diff -Nur linux-2.6.16.33-noxen/drivers/acpi/tables.c linux-2.6.16.33/drivers/acpi/tables.c
---- linux-2.6.16.33-noxen/drivers/acpi/tables.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/acpi/tables.c      2007-01-08 15:00:45.000000000 +0000
-@@ -572,6 +572,11 @@
-  * 
-  * result: sdt_entry[] is initialized
-  */
-+#if defined(CONFIG_X86_XEN) || defined(CONFIG_X86_64_XEN)
-+#define acpi_rsdp_phys_to_va(rsdp_phys) isa_bus_to_virt(rsdp_phys)
-+#else
-+#define acpi_rsdp_phys_to_va(rsdp_phys) __va(rsdp_phys)
-+#endif
- int __init acpi_table_init(void)
- {
-@@ -587,7 +592,7 @@
-               return -ENODEV;
-       }
--      rsdp = (struct acpi_table_rsdp *)__va(rsdp_phys);
-+      rsdp = (struct acpi_table_rsdp *)acpi_rsdp_phys_to_va(rsdp_phys);
-       if (!rsdp) {
-               printk(KERN_WARNING PREFIX "Unable to map RSDP\n");
-               return -ENODEV;
-diff -Nur linux-2.6.16.33-noxen/drivers/base/bus.c linux-2.6.16.33/drivers/base/bus.c
---- linux-2.6.16.33-noxen/drivers/base/bus.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/base/bus.c 2007-05-23 21:00:01.000000000 +0000
-@@ -188,6 +188,11 @@
-               up(&dev->sem);
-               if (dev->parent)
-                       up(&dev->parent->sem);
-+
-+              if (err > 0)            /* success */
-+                      err = count;
-+              else if (err == 0)      /* driver didn't accept device */
-+                      err = -ENODEV;
-       }
-       put_device(dev);
-       put_bus(bus);
-diff -Nur linux-2.6.16.33-noxen/drivers/block/aoe/aoenet.c linux-2.6.16.33/drivers/block/aoe/aoenet.c
---- linux-2.6.16.33-noxen/drivers/block/aoe/aoenet.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/block/aoe/aoenet.c 2007-05-23 21:00:01.000000000 +0000
-@@ -95,9 +95,8 @@
- static struct sk_buff *
- skb_check(struct sk_buff *skb)
- {
--      if (skb_is_nonlinear(skb))
-       if ((skb = skb_share_check(skb, GFP_ATOMIC)))
--      if (skb_linearize(skb, GFP_ATOMIC) < 0) {
-+      if (skb_linearize(skb)) {
-               dev_kfree_skb(skb);
-               return NULL;
-       }
-diff -Nur linux-2.6.16.33-noxen/drivers/char/mem.c linux-2.6.16.33/drivers/char/mem.c
---- linux-2.6.16.33-noxen/drivers/char/mem.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/mem.c 2007-01-08 15:00:45.000000000 +0000
-@@ -108,6 +108,7 @@
- }
- #endif
-+#ifndef ARCH_HAS_DEV_MEM
- /*
-  * This funcion reads the *physical* memory. The f_pos points directly to the 
-  * memory location. 
-@@ -232,6 +233,7 @@
-       *ppos += written;
-       return written;
- }
-+#endif
- #ifndef __HAVE_PHYS_MEM_ACCESS_PROT
- static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
-@@ -773,6 +775,7 @@
- #define open_kmem     open_mem
- #define open_oldmem   open_mem
-+#ifndef ARCH_HAS_DEV_MEM
- static struct file_operations mem_fops = {
-       .llseek         = memory_lseek,
-       .read           = read_mem,
-@@ -780,6 +783,9 @@
-       .mmap           = mmap_mem,
-       .open           = open_mem,
- };
-+#else
-+extern struct file_operations mem_fops;
-+#endif
- static struct file_operations kmem_fops = {
-       .llseek         = memory_lseek,
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/Kconfig linux-2.6.16.33/drivers/char/tpm/Kconfig
---- linux-2.6.16.33-noxen/drivers/char/tpm/Kconfig     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/Kconfig   2007-01-08 15:00:45.000000000 +0000
-@@ -20,9 +20,18 @@
-         Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
-         and CONFIG_PNPACPI.
-+config TCG_TIS
-+      tristate "TPM Interface Specification 1.2 Interface"
-+      depends on TCG_TPM
-+      ---help---
-+        If you have a TPM security chip that is compliant with the
-+        TCG TIS 1.2 TPM specification say Yes and it will be accessible
-+        from within Linux.  To compile this driver as a module, choose
-+        M here; the module will be called tpm_tis.
-+
- config TCG_NSC
-       tristate "National Semiconductor TPM Interface"
--      depends on TCG_TPM
-+      depends on TCG_TPM && PNPACPI
-       ---help---
-         If you have a TPM security chip from National Semicondutor 
-         say Yes and it will be accessible from within Linux.  To 
-@@ -49,5 +58,13 @@
-         Further information on this driver and the supported hardware
-         can be found at http://www.prosec.rub.de/tpm
--endmenu
-+config TCG_XEN
-+      tristate "XEN TPM Interface"
-+      depends on TCG_TPM && XEN
-+      ---help---
-+        If you want to make TPM support available to a Xen user domain,
-+        say Yes and it will be accessible from within Linux.
-+        To compile this driver as a module, choose M here; the module
-+        will be called tpm_xenu.
-+endmenu
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/Makefile linux-2.6.16.33/drivers/char/tpm/Makefile
---- linux-2.6.16.33-noxen/drivers/char/tpm/Makefile    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/Makefile  2007-01-08 15:00:45.000000000 +0000
-@@ -5,6 +5,9 @@
- ifdef CONFIG_ACPI
-       obj-$(CONFIG_TCG_TPM) += tpm_bios.o
- endif
-+obj-$(CONFIG_TCG_TIS) += tpm_tis.o
- obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
- obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
- obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
-+obj-$(CONFIG_TCG_XEN) += tpm_xenu.o
-+tpm_xenu-y = tpm_xen.o tpm_vtpm.o
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm.c linux-2.6.16.33/drivers/char/tpm/tpm.c
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm.c     2007-01-08 15:00:45.000000000 +0000
-@@ -30,14 +30,295 @@
- enum tpm_const {
-       TPM_MINOR = 224,        /* officially assigned */
-+#ifndef CONFIG_XEN
-       TPM_BUFSIZE = 2048,
-+#endif
-       TPM_NUM_DEVICES = 256,
--      TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
- };
-+enum tpm_duration {
-+      TPM_SHORT = 0,
-+      TPM_MEDIUM = 1,
-+      TPM_LONG = 2,
-+      TPM_UNDEFINED,
-+};
-+
-+#define TPM_MAX_ORDINAL 243
-+#define TPM_MAX_PROTECTED_ORDINAL 12
-+#define TPM_PROTECTED_ORDINAL_MASK 0xFF
-+
- static LIST_HEAD(tpm_chip_list);
- static DEFINE_SPINLOCK(driver_lock);
--static int dev_mask[TPM_NUM_MASK_ENTRIES];
-+static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
-+
-+/*
-+ * Array with one entry per ordinal defining the maximum amount
-+ * of time the chip could take to return the result.  The ordinal
-+ * designation of short, medium or long is defined in a table in
-+ * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
-+ * values of the SHORT, MEDIUM, and LONG durations are retrieved
-+ * from the chip during initialization with a call to tpm_get_timeouts.
-+ */
-+static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
-+      TPM_UNDEFINED,          /* 0 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 5 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 10 */
-+      TPM_SHORT,
-+};
-+
-+static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
-+      TPM_UNDEFINED,          /* 0 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 5 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 10 */
-+      TPM_SHORT,
-+      TPM_MEDIUM,
-+      TPM_LONG,
-+      TPM_LONG,
-+      TPM_MEDIUM,             /* 15 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_MEDIUM,
-+      TPM_LONG,
-+      TPM_SHORT,              /* 20 */
-+      TPM_SHORT,
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_SHORT,              /* 25 */
-+      TPM_SHORT,
-+      TPM_MEDIUM,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_MEDIUM,             /* 30 */
-+      TPM_LONG,
-+      TPM_MEDIUM,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,              /* 35 */
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_MEDIUM,             /* 40 */
-+      TPM_LONG,
-+      TPM_MEDIUM,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,              /* 45 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_LONG,
-+      TPM_MEDIUM,             /* 50 */
-+      TPM_MEDIUM,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 55 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_MEDIUM,             /* 60 */
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_MEDIUM,             /* 65 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 70 */
-+      TPM_SHORT,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 75 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_LONG,               /* 80 */
-+      TPM_UNDEFINED,
-+      TPM_MEDIUM,
-+      TPM_LONG,
-+      TPM_SHORT,
-+      TPM_UNDEFINED,          /* 85 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 90 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_UNDEFINED,          /* 95 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_MEDIUM,             /* 100 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 105 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 110 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,              /* 115 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_LONG,               /* 120 */
-+      TPM_LONG,
-+      TPM_MEDIUM,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,
-+      TPM_SHORT,              /* 125 */
-+      TPM_SHORT,
-+      TPM_LONG,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,              /* 130 */
-+      TPM_MEDIUM,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,
-+      TPM_MEDIUM,
-+      TPM_UNDEFINED,          /* 135 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 140 */
-+      TPM_SHORT,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 145 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 150 */
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_UNDEFINED,          /* 155 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 160 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 165 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_LONG,               /* 170 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 175 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_MEDIUM,             /* 180 */
-+      TPM_SHORT,
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,             /* 185 */
-+      TPM_SHORT,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 190 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 195 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 200 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,
-+      TPM_SHORT,              /* 205 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_MEDIUM,             /* 210 */
-+      TPM_UNDEFINED,
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_MEDIUM,
-+      TPM_UNDEFINED,          /* 215 */
-+      TPM_MEDIUM,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,
-+      TPM_SHORT,              /* 220 */
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_SHORT,
-+      TPM_UNDEFINED,          /* 225 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 230 */
-+      TPM_LONG,
-+      TPM_MEDIUM,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,          /* 235 */
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_UNDEFINED,
-+      TPM_SHORT,              /* 240 */
-+      TPM_UNDEFINED,
-+      TPM_MEDIUM,
-+};
- static void user_reader_timeout(unsigned long ptr)
- {
-@@ -46,28 +327,58 @@
-       schedule_work(&chip->work);
- }
--static void timeout_work(void * ptr)
-+static void timeout_work(void *ptr)
- {
-       struct tpm_chip *chip = ptr;
-       down(&chip->buffer_mutex);
-       atomic_set(&chip->data_pending, 0);
-+#ifndef CONFIG_XEN
-       memset(chip->data_buffer, 0, TPM_BUFSIZE);
-+#else
-+      memset(chip->data_buffer, 0, get_chip_buffersize(chip));
-+#endif
-       up(&chip->buffer_mutex);
- }
- /*
-+ * Returns max number of jiffies to wait
-+ */
-+unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
-+                                         u32 ordinal)
-+{
-+      int duration_idx = TPM_UNDEFINED;
-+      int duration = 0;
-+
-+      if (ordinal < TPM_MAX_ORDINAL)
-+              duration_idx = tpm_ordinal_duration[ordinal];
-+      else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
-+               TPM_MAX_PROTECTED_ORDINAL)
-+              duration_idx =
-+                  tpm_protected_ordinal_duration[ordinal &
-+                                                 TPM_PROTECTED_ORDINAL_MASK];
-+
-+      if (duration_idx != TPM_UNDEFINED)
-+              duration = chip->vendor.duration[duration_idx];
-+      if (duration <= 0)
-+              return 2 * 60 * HZ;
-+      else
-+              return duration;
-+}
-+EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
-+
-+/*
-  * Internal kernel interface to transmit TPM commands
-  */
- static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
-                           size_t bufsiz)
- {
-       ssize_t rc;
--      u32 count;
-+      u32 count, ordinal;
-       unsigned long stop;
-       count = be32_to_cpu(*((__be32 *) (buf + 2)));
--
-+      ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
-       if (count == 0)
-               return -ENODATA;
-       if (count > bufsiz) {
-@@ -78,21 +389,23 @@
-       down(&chip->tpm_mutex);
--      if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
-+      if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
-               dev_err(chip->dev,
-                       "tpm_transmit: tpm_send: error %zd\n", rc);
-               goto out;
-       }
--      stop = jiffies + 2 * 60 * HZ;
-+      if (chip->vendor.irq)
-+              goto out_recv;
-+
-+      stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
-       do {
--              u8 status = chip->vendor->status(chip);
--              if ((status & chip->vendor->req_complete_mask) ==
--                  chip->vendor->req_complete_val) {
-+              u8 status = chip->vendor.status(chip);
-+              if ((status & chip->vendor.req_complete_mask) ==
-+                  chip->vendor.req_complete_val)
-                       goto out_recv;
--              }
--              if ((status == chip->vendor->req_canceled)) {
-+              if ((status == chip->vendor.req_canceled)) {
-                       dev_err(chip->dev, "Operation Canceled\n");
-                       rc = -ECANCELED;
-                       goto out;
-@@ -102,14 +415,13 @@
-               rmb();
-       } while (time_before(jiffies, stop));
--
--      chip->vendor->cancel(chip);
-+      chip->vendor.cancel(chip);
-       dev_err(chip->dev, "Operation Timed out\n");
-       rc = -ETIME;
-       goto out;
- out_recv:
--      rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
-+      rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
-       if (rc < 0)
-               dev_err(chip->dev,
-                       "tpm_transmit: tpm_recv: error %zd\n", rc);
-@@ -119,17 +431,247 @@
- }
- #define TPM_DIGEST_SIZE 20
--#define CAP_PCR_RESULT_SIZE 18
--static const u8 cap_pcr[] = {
-+#define TPM_ERROR_SIZE 10
-+#define TPM_RET_CODE_IDX 6
-+#define TPM_GET_CAP_RET_SIZE_IDX 10
-+#define TPM_GET_CAP_RET_UINT32_1_IDX 14
-+#define TPM_GET_CAP_RET_UINT32_2_IDX 18
-+#define TPM_GET_CAP_RET_UINT32_3_IDX 22
-+#define TPM_GET_CAP_RET_UINT32_4_IDX 26
-+#define TPM_GET_CAP_PERM_DISABLE_IDX 16
-+#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
-+#define TPM_GET_CAP_RET_BOOL_1_IDX 14
-+#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
-+
-+#define TPM_CAP_IDX 13
-+#define TPM_CAP_SUBCAP_IDX 21
-+
-+enum tpm_capabilities {
-+      TPM_CAP_FLAG = 4,
-+      TPM_CAP_PROP = 5,
-+};
-+
-+enum tpm_sub_capabilities {
-+      TPM_CAP_PROP_PCR = 0x1,
-+      TPM_CAP_PROP_MANUFACTURER = 0x3,
-+      TPM_CAP_FLAG_PERM = 0x8,
-+      TPM_CAP_FLAG_VOL = 0x9,
-+      TPM_CAP_PROP_OWNER = 0x11,
-+      TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
-+      TPM_CAP_PROP_TIS_DURATION = 0x20,
-+};
-+
-+/*
-+ * This is a semi generic GetCapability command for use
-+ * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
-+ * and their associated sub_capabilities.
-+ */
-+
-+static const u8 tpm_cap[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 22,            /* length */
-       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
--      0, 0, 0, 5,
--      0, 0, 0, 4,
--      0, 0, 1, 1
-+      0, 0, 0, 0,             /* TPM_CAP_<TYPE> */
-+      0, 0, 0, 4,             /* TPM_CAP_SUB_<TYPE> size */
-+      0, 0, 1, 0              /* TPM_CAP_SUB_<TYPE> */
- };
--#define READ_PCR_RESULT_SIZE 30
-+static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
-+                          char *desc)
-+{
-+      int err;
-+
-+      len = tpm_transmit(chip, data, len);
-+      if (len <  0)
-+              return len;
-+      if (len == TPM_ERROR_SIZE) {
-+              err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
-+              dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
-+              return err;
-+      }
-+      return 0;
-+}
-+
-+void tpm_gen_interrupt(struct tpm_chip *chip)
-+{
-+      u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
-+      ssize_t rc;
-+
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_PROP;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attempting to determine the timeouts");
-+}
-+EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
-+
-+void tpm_get_timeouts(struct tpm_chip *chip)
-+{
-+      u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
-+      ssize_t rc;
-+      u32 timeout;
-+
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_PROP;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attempting to determine the timeouts");
-+      if (rc)
-+              goto duration;
-+
-+      if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
-+          != 4 * sizeof(u32))
-+              goto duration;
-+
-+      /* Don't overwrite default if value is 0 */
-+      timeout =
-+          be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
-+      if (timeout)
-+              chip->vendor.timeout_a = msecs_to_jiffies(timeout);
-+      timeout =
-+          be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
-+      if (timeout)
-+              chip->vendor.timeout_b = msecs_to_jiffies(timeout);
-+      timeout =
-+          be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
-+      if (timeout)
-+              chip->vendor.timeout_c = msecs_to_jiffies(timeout);
-+      timeout =
-+          be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
-+      if (timeout)
-+              chip->vendor.timeout_d = msecs_to_jiffies(timeout);
-+
-+duration:
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_PROP;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attempting to determine the durations");
-+      if (rc)
-+              return;
-+
-+      if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
-+          != 3 * sizeof(u32))
-+              return;
-+
-+      chip->vendor.duration[TPM_SHORT] =
-+          msecs_to_jiffies(be32_to_cpu
-+                           (*((__be32 *) (data +
-+                                          TPM_GET_CAP_RET_UINT32_1_IDX))));
-+      chip->vendor.duration[TPM_MEDIUM] =
-+          msecs_to_jiffies(be32_to_cpu
-+                           (*((__be32 *) (data +
-+                                          TPM_GET_CAP_RET_UINT32_2_IDX))));
-+      chip->vendor.duration[TPM_LONG] =
-+          msecs_to_jiffies(be32_to_cpu
-+                           (*((__be32 *) (data +
-+                                          TPM_GET_CAP_RET_UINT32_3_IDX))));
-+}
-+EXPORT_SYMBOL_GPL(tpm_get_timeouts);
-+
-+void tpm_continue_selftest(struct tpm_chip *chip)
-+{
-+      u8 data[] = {
-+              0, 193,                 /* TPM_TAG_RQU_COMMAND */
-+              0, 0, 0, 10,            /* length */
-+              0, 0, 0, 83,            /* TPM_ORD_GetCapability */
-+      };
-+
-+      tpm_transmit(chip, data, sizeof(data));
-+}
-+EXPORT_SYMBOL_GPL(tpm_continue_selftest);
-+
-+ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
-+                      char *buf)
-+{
-+      u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
-+      ssize_t rc;
-+
-+      struct tpm_chip *chip = dev_get_drvdata(dev);
-+      if (chip == NULL)
-+              return -ENODEV;
-+
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attemtping to determine the permanent state");
-+      if (rc)
-+              return 0;
-+      return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
-+}
-+EXPORT_SYMBOL_GPL(tpm_show_enabled);
-+
-+ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
-+                      char *buf)
-+{
-+      u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
-+      ssize_t rc;
-+
-+      struct tpm_chip *chip = dev_get_drvdata(dev);
-+      if (chip == NULL)
-+              return -ENODEV;
-+
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attemtping to determine the permanent state");
-+      if (rc)
-+              return 0;
-+      return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
-+}
-+EXPORT_SYMBOL_GPL(tpm_show_active);
-+
-+ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
-+                      char *buf)
-+{
-+      u8 data[sizeof(tpm_cap)];
-+      ssize_t rc;
-+
-+      struct tpm_chip *chip = dev_get_drvdata(dev);
-+      if (chip == NULL)
-+              return -ENODEV;
-+
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_PROP;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attempting to determine the owner state");
-+      if (rc)
-+              return 0;
-+      return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
-+}
-+EXPORT_SYMBOL_GPL(tpm_show_owned);
-+
-+ssize_t tpm_show_temp_deactivated(struct device * dev,
-+                              struct device_attribute * attr, char *buf)
-+{
-+      u8 data[sizeof(tpm_cap)];
-+      ssize_t rc;
-+
-+      struct tpm_chip *chip = dev_get_drvdata(dev);
-+      if (chip == NULL)
-+              return -ENODEV;
-+
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_FLAG;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attempting to determine the temporary state");
-+      if (rc)
-+              return 0;
-+      return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
-+}
-+EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
-+
- static const u8 pcrread[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 14,            /* length */
-@@ -140,8 +682,8 @@
- ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
-                     char *buf)
- {
--      u8 data[READ_PCR_RESULT_SIZE];
--      ssize_t len;
-+      u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
-+      ssize_t rc;
-       int i, j, num_pcrs;
-       __be32 index;
-       char *str = buf;
-@@ -150,29 +692,24 @@
-       if (chip == NULL)
-               return -ENODEV;
--      memcpy(data, cap_pcr, sizeof(cap_pcr));
--      if ((len = tpm_transmit(chip, data, sizeof(data)))
--          < CAP_PCR_RESULT_SIZE) {
--              dev_dbg(chip->dev, "A TPM error (%d) occurred "
--                              "attempting to determine the number of PCRS\n",
--                      be32_to_cpu(*((__be32 *) (data + 6))));
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_PROP;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attempting to determine the number of PCRS");
-+      if (rc)
-               return 0;
--      }
-       num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
--
-       for (i = 0; i < num_pcrs; i++) {
-               memcpy(data, pcrread, sizeof(pcrread));
-               index = cpu_to_be32(i);
-               memcpy(data + 10, &index, 4);
--              if ((len = tpm_transmit(chip, data, sizeof(data)))
--                  < READ_PCR_RESULT_SIZE){
--                      dev_dbg(chip->dev, "A TPM error (%d) occurred"
--                              " attempting to read PCR %d of %d\n",
--                              be32_to_cpu(*((__be32 *) (data + 6))),
--                              i, num_pcrs);
-+              rc = transmit_cmd(chip, data, sizeof(data),
-+                              "attempting to read a PCR");
-+              if (rc)
-                       goto out;
--              }
-               str += sprintf(str, "PCR-%02d: ", i);
-               for (j = 0; j < TPM_DIGEST_SIZE; j++)
-                       str += sprintf(str, "%02X ", *(data + 10 + j));
-@@ -194,7 +731,7 @@
-                      char *buf)
- {
-       u8 *data;
--      ssize_t len;
-+      ssize_t err;
-       int i, rc;
-       char *str = buf;
-@@ -208,14 +745,10 @@
-       memcpy(data, readpubek, sizeof(readpubek));
--      if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
--          READ_PUBEK_RESULT_SIZE) {
--              dev_dbg(chip->dev, "A TPM error (%d) occurred "
--                              "attempting to read the PUBEK\n",
--                          be32_to_cpu(*((__be32 *) (data + 6))));
--              rc = 0;
-+      err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
-+                      "attempting to read the PUBEK");
-+      if (err)
-               goto out;
--      }
-       /* 
-          ignore header 10 bytes
-@@ -245,36 +778,68 @@
-               if ((i + 1) % 16 == 0)
-                       str += sprintf(str, "\n");
-       }
--      rc = str - buf;
- out:
-+      rc = str - buf;
-       kfree(data);
-       return rc;
- }
- EXPORT_SYMBOL_GPL(tpm_show_pubek);
--#define CAP_VER_RESULT_SIZE 18
-+#define CAP_VERSION_1_1 6
-+#define CAP_VERSION_1_2 0x1A
-+#define CAP_VERSION_IDX 13
- static const u8 cap_version[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 18,            /* length */
-       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
--      0, 0, 0, 6,
-+      0, 0, 0, 0,
-       0, 0, 0, 0
- };
--#define CAP_MANUFACTURER_RESULT_SIZE 18
--static const u8 cap_manufacturer[] = {
--      0, 193,                 /* TPM_TAG_RQU_COMMAND */
--      0, 0, 0, 22,            /* length */
--      0, 0, 0, 101,           /* TPM_ORD_GetCapability */
--      0, 0, 0, 5,
--      0, 0, 0, 4,
--      0, 0, 1, 3
--};
--
- ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
-                     char *buf)
- {
--      u8 data[sizeof(cap_manufacturer)];
-+      u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
-+      ssize_t rc;
-+      char *str = buf;
-+
-+      struct tpm_chip *chip = dev_get_drvdata(dev);
-+      if (chip == NULL)
-+              return -ENODEV;
-+
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_PROP;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-+
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attempting to determine the manufacturer");
-+      if (rc)
-+              return 0;
-+
-+      str += sprintf(str, "Manufacturer: 0x%x\n",
-+                     be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
-+
-+      memcpy(data, cap_version, sizeof(cap_version));
-+      data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
-+      rc = transmit_cmd(chip, data, sizeof(data),
-+                      "attempting to determine the 1.1 version");
-+      if (rc)
-+              goto out;
-+
-+      str += sprintf(str,
-+                     "TCG version: %d.%d\nFirmware version: %d.%d\n",
-+                     (int) data[14], (int) data[15], (int) data[16],
-+                     (int) data[17]);
-+
-+out:
-+      return str - buf;
-+}
-+EXPORT_SYMBOL_GPL(tpm_show_caps);
-+
-+ssize_t tpm_show_caps_1_2(struct device * dev,
-+                        struct device_attribute * attr, char *buf)
-+{
-+      u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
-       ssize_t len;
-       char *str = buf;
-@@ -282,29 +847,40 @@
-       if (chip == NULL)
-               return -ENODEV;
--      memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
-+      memcpy(data, tpm_cap, sizeof(tpm_cap));
-+      data[TPM_CAP_IDX] = TPM_CAP_PROP;
-+      data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
--      if ((len = tpm_transmit(chip, data, sizeof(data))) <
--          CAP_MANUFACTURER_RESULT_SIZE)
--              return len;
-+      if ((len = tpm_transmit(chip, data, sizeof(data))) <=
-+          TPM_ERROR_SIZE) {
-+              dev_dbg(chip->dev, "A TPM error (%d) occurred "
-+                      "attempting to determine the manufacturer\n",
-+                      be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
-+              return 0;
-+      }
-       str += sprintf(str, "Manufacturer: 0x%x\n",
--                     be32_to_cpu(*((__be32 *) (data + 14))));
-+                     be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
-       memcpy(data, cap_version, sizeof(cap_version));
-+      data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
--      if ((len = tpm_transmit(chip, data, sizeof(data))) <
--          CAP_VER_RESULT_SIZE)
--              return len;
--
--      str +=
--          sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
--                  (int) data[14], (int) data[15], (int) data[16],
--                  (int) data[17]);
-+      if ((len = tpm_transmit(chip, data, sizeof(data))) <=
-+          TPM_ERROR_SIZE) {
-+              dev_err(chip->dev, "A TPM error (%d) occurred "
-+                      "attempting to determine the 1.2 version\n",
-+                      be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
-+              goto out;
-+      }
-+      str += sprintf(str,
-+                     "TCG version: %d.%d\nFirmware version: %d.%d\n",
-+                     (int) data[16], (int) data[17], (int) data[18],
-+                     (int) data[19]);
-+out:
-       return str - buf;
- }
--EXPORT_SYMBOL_GPL(tpm_show_caps);
-+EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
- ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
-                       const char *buf, size_t count)
-@@ -313,7 +889,7 @@
-       if (chip == NULL)
-               return 0;
--      chip->vendor->cancel(chip);
-+      chip->vendor.cancel(chip);
-       return count;
- }
- EXPORT_SYMBOL_GPL(tpm_store_cancel);
-@@ -329,7 +905,7 @@
-       spin_lock(&driver_lock);
-       list_for_each_entry(pos, &tpm_chip_list, list) {
--              if (pos->vendor->miscdev.minor == minor) {
-+              if (pos->vendor.miscdev.minor == minor) {
-                       chip = pos;
-                       break;
-               }
-@@ -351,7 +927,12 @@
-       spin_unlock(&driver_lock);
-+#ifndef CONFIG_XEN
-       chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
-+#else
-+      chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8),
-+                                  GFP_KERNEL);
-+#endif
-       if (chip->data_buffer == NULL) {
-               chip->num_opens--;
-               put_device(chip->dev);
-@@ -387,7 +968,7 @@
- EXPORT_SYMBOL_GPL(tpm_release);
- ssize_t tpm_write(struct file *file, const char __user *buf,
--                size_t size, loff_t * off)
-+                size_t size, loff_t *off)
- {
-       struct tpm_chip *chip = file->private_data;
-       int in_size = size, out_size;
-@@ -399,8 +980,13 @@
-       down(&chip->buffer_mutex);
-+#ifndef CONFIG_XEN
-       if (in_size > TPM_BUFSIZE)
-               in_size = TPM_BUFSIZE;
-+#else
-+      if (in_size > get_chip_buffersize(chip))
-+              in_size = get_chip_buffersize(chip);
-+#endif
-       if (copy_from_user
-           (chip->data_buffer, (void __user *) buf, in_size)) {
-@@ -409,9 +995,17 @@
-       }
-       /* atomic tpm command send and result receive */
-+#ifndef CONFIG_XEN
-       out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
-+#else
-+      out_size = tpm_transmit(chip, chip->data_buffer,
-+                              get_chip_buffersize(chip));
-+#endif
-       atomic_set(&chip->data_pending, out_size);
-+#ifdef CONFIG_XEN
-+      atomic_set(&chip->data_position, 0);
-+#endif
-       up(&chip->buffer_mutex);
-       /* Set a timeout by which the reader must come claim the result */
-@@ -419,29 +1013,59 @@
-       return in_size;
- }
--
- EXPORT_SYMBOL_GPL(tpm_write);
--ssize_t tpm_read(struct file * file, char __user *buf,
--               size_t size, loff_t * off)
-+ssize_t tpm_read(struct file *file, char __user *buf,
-+               size_t size, loff_t *off)
- {
-       struct tpm_chip *chip = file->private_data;
-       int ret_size;
-+#ifdef CONFIG_XEN
-+      int pos, pending = 0;
-+#endif
-+#ifndef CONFIG_XEN
-       del_singleshot_timer_sync(&chip->user_read_timer);
-       flush_scheduled_work();
-+#endif
-       ret_size = atomic_read(&chip->data_pending);
-+#ifndef CONFIG_XEN
-       atomic_set(&chip->data_pending, 0);
-+#endif
-       if (ret_size > 0) {     /* relay data */
-               if (size < ret_size)
-                       ret_size = size;
-+#ifdef CONFIG_XEN
-+              pos = atomic_read(&chip->data_position);
-+#endif
-               down(&chip->buffer_mutex);
-+#ifndef CONFIG_XEN
-               if (copy_to_user(buf, chip->data_buffer, ret_size))
-+#else
-+              if (copy_to_user(buf, &chip->data_buffer[pos], ret_size)) {
-+#endif
-                       ret_size = -EFAULT;
-+#ifdef CONFIG_XEN
-+              } else {
-+                      pending = atomic_read(&chip->data_pending) - ret_size;
-+                      if ( pending ) {
-+                              atomic_set(&chip->data_pending, pending);
-+                              atomic_set(&chip->data_position,
-+                                         pos+ret_size);
-+                      }
-+              }
-+#endif
-               up(&chip->buffer_mutex);
-       }
-+#ifdef CONFIG_XEN
-+      if ( ret_size <= 0 || pending == 0 ) {
-+              atomic_set(&chip->data_pending, 0);
-+              del_singleshot_timer_sync(&chip->user_read_timer);
-+              flush_scheduled_work();
-+      }
-+#endif
-       return ret_size;
- }
- EXPORT_SYMBOL_GPL(tpm_read);
-@@ -462,14 +1086,13 @@
-       spin_unlock(&driver_lock);
-       dev_set_drvdata(dev, NULL);
--      misc_deregister(&chip->vendor->miscdev);
--      kfree(chip->vendor->miscdev.name);
-+      misc_deregister(&chip->vendor.miscdev);
-+      kfree(chip->vendor.miscdev.name);
--      sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
-+      sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
-       tpm_bios_log_teardown(chip->bios_dir);
--      dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
--              ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
-+      clear_bit(chip->dev_num, dev_mask);
-       kfree(chip);
-@@ -520,18 +1143,18 @@
-  * upon errant exit from this function specific probe function should call
-  * pci_disable_device
-  */
--int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
-+struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
-+                                     *entry)
- {
- #define DEVNAME_SIZE 7
-       char *devname;
-       struct tpm_chip *chip;
--      int i, j;
-       /* Driver specific per-device data */
-       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-       if (chip == NULL)
--              return -ENOMEM;
-+              return NULL;
-       init_MUTEX(&chip->buffer_mutex);
-       init_MUTEX(&chip->tpm_mutex);
-@@ -543,45 +1166,37 @@
-       chip->user_read_timer.function = user_reader_timeout;
-       chip->user_read_timer.data = (unsigned long) chip;
--      chip->vendor = entry;
-+      memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
--      chip->dev_num = -1;
--
--      for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
--              for (j = 0; j < 8 * sizeof(int); j++)
--                      if ((dev_mask[i] & (1 << j)) == 0) {
--                              chip->dev_num =
--                                  i * TPM_NUM_MASK_ENTRIES + j;
--                              dev_mask[i] |= 1 << j;
--                              goto dev_num_search_complete;
--                      }
-+      chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
--dev_num_search_complete:
--      if (chip->dev_num < 0) {
-+      if (chip->dev_num >= TPM_NUM_DEVICES) {
-               dev_err(dev, "No available tpm device numbers\n");
-               kfree(chip);
--              return -ENODEV;
-+              return NULL;
-       } else if (chip->dev_num == 0)
--              chip->vendor->miscdev.minor = TPM_MINOR;
-+              chip->vendor.miscdev.minor = TPM_MINOR;
-       else
--              chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
-+              chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
-+
-+      set_bit(chip->dev_num, dev_mask);
-       devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
-       scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
--      chip->vendor->miscdev.name = devname;
-+      chip->vendor.miscdev.name = devname;
--      chip->vendor->miscdev.dev = dev;
-+      chip->vendor.miscdev.dev = dev;
-       chip->dev = get_device(dev);
--      if (misc_register(&chip->vendor->miscdev)) {
-+      if (misc_register(&chip->vendor.miscdev)) {
-               dev_err(chip->dev,
-                       "unable to misc_register %s, minor %d\n",
--                      chip->vendor->miscdev.name,
--                      chip->vendor->miscdev.minor);
-+                      chip->vendor.miscdev.name,
-+                      chip->vendor.miscdev.minor);
-               put_device(dev);
-+              clear_bit(chip->dev_num, dev_mask);
-               kfree(chip);
--              dev_mask[i] &= !(1 << j);
--              return -ENODEV;
-+              return NULL;
-       }
-       spin_lock(&driver_lock);
-@@ -592,11 +1207,11 @@
-       spin_unlock(&driver_lock);
--      sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
-+      sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
-       chip->bios_dir = tpm_bios_log_setup(devname);
--      return 0;
-+      return chip;
- }
- EXPORT_SYMBOL_GPL(tpm_register_hardware);
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm.h linux-2.6.16.33/drivers/char/tpm/tpm.h
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm.h     2007-01-08 15:00:45.000000000 +0000
-@@ -24,6 +24,14 @@
- #include <linux/fs.h>
- #include <linux/miscdevice.h>
- #include <linux/platform_device.h>
-+#include <linux/io.h>
-+
-+#ifdef CONFIG_XEN
-+enum tpm_bufsize {
-+      TPM_MIN_BUFFERSIZE = 2048,
-+      TPM_MAX_BUFFERSIZE = 64 * 1024,
-+};
-+#endif
- enum tpm_timeout {
-       TPM_TIMEOUT = 5,        /* msecs */
-@@ -41,18 +49,33 @@
-                               char *);
- extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
-                               char *);
-+extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
-+                              char *);
- extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
-                               const char *, size_t);
-+extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
-+                              char *);
-+extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
-+                              char *);
-+extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
-+                              char *);
-+extern ssize_t tpm_show_temp_deactivated(struct device *,
-+                                       struct device_attribute *attr, char *);
- struct tpm_chip;
- struct tpm_vendor_specific {
--      u8 req_complete_mask;
--      u8 req_complete_val;
--      u8 req_canceled;
-+      const u8 req_complete_mask;
-+      const u8 req_complete_val;
-+      const u8 req_canceled;
-+#ifdef CONFIG_XEN
-+      u32 buffersize;
-+#endif
-       void __iomem *iobase;           /* ioremapped address */
-       unsigned long base;             /* TPM base address */
-+      int irq;
-+
-       int region_size;
-       int have_region;
-@@ -62,6 +85,13 @@
-       u8 (*status) (struct tpm_chip *);
-       struct miscdevice miscdev;
-       struct attribute_group *attr_group;
-+      struct list_head list;
-+      int locality;
-+      unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
-+      unsigned long duration[3]; /* jiffies */
-+
-+      wait_queue_head_t read_queue;
-+      wait_queue_head_t int_queue;
- };
- struct tpm_chip {
-@@ -74,19 +104,27 @@
-       /* Data passed to and from the tpm via the read/write calls */
-       u8 *data_buffer;
-       atomic_t data_pending;
-+#ifdef CONFIG_XEN
-+      atomic_t data_position;
-+#endif
-       struct semaphore buffer_mutex;
-       struct timer_list user_read_timer;      /* user needs to claim result */
-       struct work_struct work;
-       struct semaphore tpm_mutex;     /* tpm is processing */
--      struct tpm_vendor_specific *vendor;
-+      struct tpm_vendor_specific vendor;
-       struct dentry **bios_dir;
-       struct list_head list;
-+#ifdef CONFIG_XEN
-+      void *priv;
-+#endif
- };
-+#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
-+
- static inline int tpm_read_index(int base, int index)
- {
-       outb(index, base);
-@@ -99,8 +137,35 @@
-       outb(value & 0xFF, base+1);
- }
--extern int tpm_register_hardware(struct device *,
--                               struct tpm_vendor_specific *);
-+#ifdef CONFIG_XEN
-+static inline u32 get_chip_buffersize(struct tpm_chip *chip)
-+{
-+      u32 size = chip->vendor.buffersize;
-+      if (size > TPM_MAX_BUFFERSIZE) {
-+              return TPM_MAX_BUFFERSIZE;
-+      } else if (size < TPM_MIN_BUFFERSIZE) {
-+              return TPM_MIN_BUFFERSIZE;
-+      }
-+      return size;
-+}
-+
-+static inline void *chip_get_private(const struct tpm_chip *chip)
-+{
-+      return chip->priv;
-+}
-+
-+static inline void chip_set_private(struct tpm_chip *chip, void *priv)
-+{
-+      chip->priv = priv;
-+}
-+#endif
-+
-+extern void tpm_get_timeouts(struct tpm_chip *);
-+extern void tpm_gen_interrupt(struct tpm_chip *);
-+extern void tpm_continue_selftest(struct tpm_chip *);
-+extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
-+extern struct tpm_chip* tpm_register_hardware(struct device *,
-+                               const struct tpm_vendor_specific *);
- extern int tpm_open(struct inode *, struct file *);
- extern int tpm_release(struct inode *, struct file *);
- extern ssize_t tpm_write(struct file *, const char __user *, size_t,
-@@ -114,7 +179,7 @@
- extern struct dentry ** tpm_bios_log_setup(char *);
- extern void tpm_bios_log_teardown(struct dentry **);
- #else
--static inline struct dentry* tpm_bios_log_setup(char *name)
-+static inline struct dentry ** tpm_bios_log_setup(char *name)
- {
-       return NULL;
- }
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_atmel.c linux-2.6.16.33/drivers/char/tpm/tpm_atmel.c
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_atmel.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_atmel.c       2007-05-23 21:00:01.000000000 +0000
-@@ -47,12 +47,12 @@
-               return -EIO;
-       for (i = 0; i < 6; i++) {
--              status = ioread8(chip->vendor->iobase + 1);
-+              status = ioread8(chip->vendor.iobase + 1);
-               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                       dev_err(chip->dev, "error reading header\n");
-                       return -EIO;
-               }
--              *buf++ = ioread8(chip->vendor->iobase);
-+              *buf++ = ioread8(chip->vendor.iobase);
-       }
-       /* size of the data received */
-@@ -63,7 +63,7 @@
-               dev_err(chip->dev,
-                       "Recv size(%d) less than available space\n", size);
-               for (; i < size; i++) { /* clear the waiting data anyway */
--                      status = ioread8(chip->vendor->iobase + 1);
-+                      status = ioread8(chip->vendor.iobase + 1);
-                       if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                               dev_err(chip->dev, "error reading data\n");
-                               return -EIO;
-@@ -74,16 +74,16 @@
-       /* read all the data available */
-       for (; i < size; i++) {
--              status = ioread8(chip->vendor->iobase + 1);
-+              status = ioread8(chip->vendor.iobase + 1);
-               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                       dev_err(chip->dev, "error reading data\n");
-                       return -EIO;
-               }
--              *buf++ = ioread8(chip->vendor->iobase);
-+              *buf++ = ioread8(chip->vendor.iobase);
-       }
-       /* make sure data available is gone */
--      status = ioread8(chip->vendor->iobase + 1);
-+      status = ioread8(chip->vendor.iobase + 1);
-       if (status & ATML_STATUS_DATA_AVAIL) {
-               dev_err(chip->dev, "data available is stuck\n");
-@@ -100,7 +100,7 @@
-       dev_dbg(chip->dev, "tpm_atml_send:\n");
-       for (i = 0; i < count; i++) {
-               dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
--              iowrite8(buf[i], chip->vendor->iobase);
-+              iowrite8(buf[i], chip->vendor.iobase);
-       }
-       return count;
-@@ -108,12 +108,12 @@
- static void tpm_atml_cancel(struct tpm_chip *chip)
- {
--      iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
-+      iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
- }
- static u8 tpm_atml_status(struct tpm_chip *chip)
- {
--      return ioread8(chip->vendor->iobase + 1);
-+      return ioread8(chip->vendor.iobase + 1);
- }
- static struct file_operations atmel_ops = {
-@@ -140,7 +140,7 @@
- static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
--static struct tpm_vendor_specific tpm_atmel = {
-+static const struct tpm_vendor_specific tpm_atmel = {
-       .recv = tpm_atml_recv,
-       .send = tpm_atml_send,
-       .cancel = tpm_atml_cancel,
-@@ -159,10 +159,10 @@
-       struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
-       if (chip) {
--              if (chip->vendor->have_region)
--                      atmel_release_region(chip->vendor->base,
--                                           chip->vendor->region_size);
--              atmel_put_base_addr(chip->vendor);
-+              if (chip->vendor.have_region)
-+                      atmel_release_region(chip->vendor.base,
-+                                           chip->vendor.region_size);
-+              atmel_put_base_addr(chip->vendor.iobase);
-               tpm_remove_hardware(chip->dev);
-               platform_device_unregister(pdev);
-       }
-@@ -179,18 +179,22 @@
- static int __init init_atmel(void)
- {
-       int rc = 0;
-+      void __iomem *iobase = NULL;
-+      int have_region, region_size;
-+      unsigned long base;
-+      struct  tpm_chip *chip;
-       driver_register(&atml_drv);
--      if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
-+      if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
-               rc = -ENODEV;
-               goto err_unreg_drv;
-       }
--      tpm_atmel.have_region =
-+      have_region =
-           (atmel_request_region
--           (tpm_atmel.base, tpm_atmel.region_size,
--            "tpm_atmel0") == NULL) ? 0 : 1;
-+           (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
-+
-       if (IS_ERR
-           (pdev =
-@@ -199,17 +203,25 @@
-               goto err_rel_reg;
-       }
--      if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
-+      if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
-+              rc = -ENODEV;
-               goto err_unreg_dev;
-+      }
-+
-+      chip->vendor.iobase = iobase;
-+      chip->vendor.base = base;
-+      chip->vendor.have_region = have_region;
-+      chip->vendor.region_size = region_size;
-+
-       return 0;
- err_unreg_dev:
-       platform_device_unregister(pdev);
- err_rel_reg:
--      atmel_put_base_addr(&tpm_atmel);
--      if (tpm_atmel.have_region)
--              atmel_release_region(tpm_atmel.base,
--                                   tpm_atmel.region_size);
-+      atmel_put_base_addr(iobase);
-+      if (have_region)
-+              atmel_release_region(base,
-+                                   region_size);
- err_unreg_drv:
-       driver_unregister(&atml_drv);
-       return rc;
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_atmel.h linux-2.6.16.33/drivers/char/tpm/tpm_atmel.h
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_atmel.h 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_atmel.h       2007-05-23 21:00:01.000000000 +0000
-@@ -28,13 +28,12 @@
- #define atmel_request_region request_mem_region
- #define atmel_release_region release_mem_region
--static inline void atmel_put_base_addr(struct tpm_vendor_specific
--                                       *vendor)
-+static inline void atmel_put_base_addr(void __iomem *iobase)
- {
--      iounmap(vendor->iobase);
-+      iounmap(iobase);
- }
--static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
-+static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
- {
-       struct device_node *dn;
-       unsigned long address, size;
-@@ -71,9 +70,9 @@
-       else
-               size = reg[naddrc];
--      vendor->base = address;
--      vendor->region_size = size;
--      return ioremap(vendor->base, vendor->region_size);
-+      *base = address;
-+      *region_size = size;
-+      return ioremap(*base, *region_size);
- }
- #else
- #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
-@@ -106,14 +105,12 @@
-       return 0;
- }
--static inline void atmel_put_base_addr(struct tpm_vendor_specific
--                                       *vendor)
-+static inline void atmel_put_base_addr(void __iomem *iobase)
- {
- }
- /* Determine where to talk to device */
--static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
--                                       *vendor)
-+static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
- {
-       int lo, hi;
-@@ -123,9 +120,9 @@
-       lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
-       hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
--      vendor->base = (hi << 8) | lo;
--      vendor->region_size = 2;
-+      *base = (hi << 8) | lo;
-+      *region_size = 2;
--      return ioport_map(vendor->base, vendor->region_size);
-+      return ioport_map(*base, *region_size);
- }
- #endif
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_bios.c linux-2.6.16.33/drivers/char/tpm/tpm_bios.c
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_bios.c  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_bios.c        2007-05-23 21:00:01.000000000 +0000
-@@ -29,6 +29,11 @@
- #define MAX_TEXT_EVENT                1000    /* Max event string length */
- #define ACPI_TCPA_SIG         "TCPA"  /* 0x41504354 /'TCPA' */
-+enum bios_platform_class {
-+      BIOS_CLIENT = 0x00,
-+      BIOS_SERVER = 0x01,
-+};
-+
- struct tpm_bios_log {
-       void *bios_event_log;
-       void *bios_event_log_end;
-@@ -36,9 +41,18 @@
- struct acpi_tcpa {
-       struct acpi_table_header hdr;
--      u16 reserved;
--      u32 log_max_len __attribute__ ((packed));
--      u32 log_start_addr __attribute__ ((packed));
-+      u16 platform_class;
-+      union {
-+              struct client_hdr {
-+                      u32 log_max_len __attribute__ ((packed));
-+                      u64 log_start_addr __attribute__ ((packed));
-+              } client;
-+              struct server_hdr {
-+                      u16 reserved;
-+                      u64 log_max_len __attribute__ ((packed));
-+                      u64 log_start_addr __attribute__ ((packed));
-+              } server;
-+      };
- };
- struct tcpa_event {
-@@ -91,6 +105,12 @@
-       "Non-Host Info"
- };
-+struct tcpa_pc_event {
-+      u32 event_id;
-+      u32 event_size;
-+      u8 event_data[0];
-+};
-+
- enum tcpa_pc_event_ids {
-       SMBIOS = 1,
-       BIS_CERT,
-@@ -100,14 +120,15 @@
-       NVRAM,
-       OPTION_ROM_EXEC,
-       OPTION_ROM_CONFIG,
--      OPTION_ROM_MICROCODE,
-+      OPTION_ROM_MICROCODE = 10,
-       S_CRTM_VERSION,
-       S_CRTM_CONTENTS,
-       POST_CONTENTS,
-+      HOST_TABLE_OF_DEVICES,
- };
- static const char* tcpa_pc_event_id_strings[] = {
--      ""
-+      "",
-       "SMBIOS",
-       "BIS Certificate",
-       "POST BIOS ",
-@@ -116,10 +137,12 @@
-       "NVRAM",
-       "Option ROM",
-       "Option ROM config",
--      "Option ROM microcode",
-+      "",
-+      "Option ROM microcode ",
-       "S-CRTM Version",
--      "S-CRTM Contents",
--      "S-CRTM POST Contents",
-+      "S-CRTM Contents ",
-+      "POST Contents ",
-+      "Table of Devices",
- };
- /* returns pointer to start of pos. entry of tcg log */
-@@ -191,7 +214,7 @@
-       const char *name = "";
-       char data[40] = "";
-       int i, n_len = 0, d_len = 0;
--      u32 event_id;
-+      struct tcpa_pc_event *pc_event;
-       switch(event->event_type) {
-       case PREBOOT:
-@@ -220,31 +243,32 @@
-               }
-               break;
-       case EVENT_TAG:
--              event_id = be32_to_cpu(*((u32 *)event_entry));
-+              pc_event = (struct tcpa_pc_event *)event_entry;
-               /* ToDo Row data -> Base64 */
--              switch (event_id) {
-+              switch (pc_event->event_id) {
-               case SMBIOS:
-               case BIS_CERT:
-               case CMOS:
-               case NVRAM:
-               case OPTION_ROM_EXEC:
-               case OPTION_ROM_CONFIG:
--              case OPTION_ROM_MICROCODE:
-               case S_CRTM_VERSION:
--              case S_CRTM_CONTENTS:
--              case POST_CONTENTS:
--                      name = tcpa_pc_event_id_strings[event_id];
-+                      name = tcpa_pc_event_id_strings[pc_event->event_id];
-                       n_len = strlen(name);
-                       break;
-+              /* hash data */
-               case POST_BIOS_ROM:
-               case ESCD:
--                      name = tcpa_pc_event_id_strings[event_id];
-+              case OPTION_ROM_MICROCODE:
-+              case S_CRTM_CONTENTS:
-+              case POST_CONTENTS:
-+                      name = tcpa_pc_event_id_strings[pc_event->event_id];
-                       n_len = strlen(name);
-                       for (i = 0; i < 20; i++)
--                              d_len += sprintf(data, "%02x",
--                                              event_entry[8 + i]);
-+                              d_len += sprintf(&data[2*i], "%02x",
-+                                              pc_event->event_data[i]);
-                       break;
-               default:
-                       break;
-@@ -260,52 +284,13 @@
- static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
- {
-+      struct tcpa_event *event = v;
-+      char *data = v;
-+      int i;
--      char *eventname;
--      char data[4];
--      u32 help;
--      int i, len;
--      struct tcpa_event *event = (struct tcpa_event *) v;
--      unsigned char *event_entry =
--          (unsigned char *) (v + sizeof(struct tcpa_event));
--
--      eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
--      if (!eventname) {
--              printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
--                     __func__);
--              return -ENOMEM;
--      }
--
--      /* 1st: PCR used is in little-endian format (4 bytes) */
--      help = le32_to_cpu(event->pcr_index);
--      memcpy(data, &help, 4);
--      for (i = 0; i < 4; i++)
--              seq_putc(m, data[i]);
--
--      /* 2nd: SHA1 (20 bytes) */
--      for (i = 0; i < 20; i++)
--              seq_putc(m, event->pcr_value[i]);
--
--      /* 3rd: event type identifier (4 bytes) */
--      help = le32_to_cpu(event->event_type);
--      memcpy(data, &help, 4);
--      for (i = 0; i < 4; i++)
-+      for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
-               seq_putc(m, data[i]);
--      len = 0;
--
--      len += get_event_name(eventname, event, event_entry);
--
--      /* 4th:  filename <= 255 + \'0' delimiter */
--      if (len > TCG_EVENT_NAME_LEN_MAX)
--              len = TCG_EVENT_NAME_LEN_MAX;
--
--      for (i = 0; i < len; i++)
--              seq_putc(m, eventname[i]);
--
--      /* 5th: delimiter */
--      seq_putc(m, '\0');
--
-       return 0;
- }
-@@ -353,6 +338,7 @@
-       /* 4th: eventname <= max + \'0' delimiter */
-       seq_printf(m, " %s\n", eventname);
-+      kfree(eventname);
-       return 0;
- }
-@@ -376,6 +362,7 @@
-       struct acpi_tcpa *buff;
-       acpi_status status;
-       struct acpi_table_header *virt;
-+      u64 len, start;
-       if (log->bios_event_log != NULL) {
-               printk(KERN_ERR
-@@ -396,27 +383,37 @@
-               return -EIO;
-       }
--      if (buff->log_max_len == 0) {
-+      switch(buff->platform_class) {
-+      case BIOS_SERVER:
-+              len = buff->server.log_max_len;
-+              start = buff->server.log_start_addr;
-+              break;
-+      case BIOS_CLIENT:
-+      default:
-+              len = buff->client.log_max_len;
-+              start = buff->client.log_start_addr;
-+              break;
-+      }
-+      if (!len) {
-               printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
-               return -EIO;
-       }
-       /* malloc EventLog space */
--      log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
-+      log->bios_event_log = kmalloc(len, GFP_KERNEL);
-       if (!log->bios_event_log) {
--              printk
--                  ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
--                   __func__);
-+              printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
-+                      __func__);
-               return -ENOMEM;
-       }
--      log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
-+      log->bios_event_log_end = log->bios_event_log + len;
--      acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
-+      acpi_os_map_memory(start, len, (void *) &virt);
--      memcpy(log->bios_event_log, virt, buff->log_max_len);
-+      memcpy(log->bios_event_log, virt, len);
--      acpi_os_unmap_memory(virt, buff->log_max_len);
-+      acpi_os_unmap_memory(virt, len);
-       return 0;
- }
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_infineon.c linux-2.6.16.33/drivers/char/tpm/tpm_infineon.c
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_infineon.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_infineon.c    2007-05-23 21:00:01.000000000 +0000
-@@ -15,6 +15,7 @@
-  * License.
-  */
-+#include <linux/init.h>
- #include <linux/pnp.h>
- #include "tpm.h"
-@@ -104,7 +105,7 @@
-       if (clear_wrfifo) {
-               for (i = 0; i < 4096; i++) {
--                      status = inb(chip->vendor->base + WRFIFO);
-+                      status = inb(chip->vendor.base + WRFIFO);
-                       if (status == 0xff) {
-                               if (check == 5)
-                                       break;
-@@ -124,8 +125,8 @@
-        */
-       i = 0;
-       do {
--              status = inb(chip->vendor->base + RDFIFO);
--              status = inb(chip->vendor->base + STAT);
-+              status = inb(chip->vendor.base + RDFIFO);
-+              status = inb(chip->vendor.base + STAT);
-               i++;
-               if (i == TPM_MAX_TRIES)
-                       return -EIO;
-@@ -138,7 +139,7 @@
-       int status;
-       int i;
-       for (i = 0; i < TPM_MAX_TRIES; i++) {
--              status = inb(chip->vendor->base + STAT);
-+              status = inb(chip->vendor.base + STAT);
-               /* check the status-register if wait_for_bit is set */
-               if (status & 1 << wait_for_bit)
-                       break;
-@@ -157,7 +158,7 @@
- static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
- {
-       wait(chip, STAT_XFE);
--      outb(sendbyte, chip->vendor->base + WRFIFO);
-+      outb(sendbyte, chip->vendor.base + WRFIFO);
- }
-     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
-@@ -204,7 +205,7 @@
-               ret = wait(chip, STAT_RDA);
-               if (ret)
-                       return -EIO;
--              buf[i] = inb(chip->vendor->base + RDFIFO);
-+              buf[i] = inb(chip->vendor.base + RDFIFO);
-       }
-       if (buf[0] != TPM_VL_VER) {
-@@ -219,7 +220,7 @@
-               for (i = 0; i < size; i++) {
-                       wait(chip, STAT_RDA);
--                      buf[i] = inb(chip->vendor->base + RDFIFO);
-+                      buf[i] = inb(chip->vendor.base + RDFIFO);
-               }
-               if ((size == 0x6D00) && (buf[1] == 0x80)) {
-@@ -268,7 +269,7 @@
-       u8 count_high, count_low, count_4, count_3, count_2, count_1;
-       /* Disabling Reset, LP and IRQC */
--      outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
-+      outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
-       ret = empty_fifo(chip, 1);
-       if (ret) {
-@@ -319,7 +320,7 @@
- static u8 tpm_inf_status(struct tpm_chip *chip)
- {
--      return inb(chip->vendor->base + STAT);
-+      return inb(chip->vendor.base + STAT);
- }
- static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
-@@ -346,7 +347,7 @@
-       .release = tpm_release,
- };
--static struct tpm_vendor_specific tpm_inf = {
-+static const struct tpm_vendor_specific tpm_inf = {
-       .recv = tpm_inf_recv,
-       .send = tpm_inf_send,
-       .cancel = tpm_inf_cancel,
-@@ -375,6 +376,7 @@
-       int version[2];
-       int productid[2];
-       char chipname[20];
-+      struct tpm_chip *chip;
-       /* read IO-ports through PnP */
-       if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
-@@ -395,14 +397,13 @@
-                       goto err_last;
-               }
-               /* publish my base address and request region */
--              tpm_inf.base = TPM_INF_BASE;
-               if (request_region
--                  (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
-+                  (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
-                       rc = -EINVAL;
-                       goto err_last;
-               }
--              if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
--                              "tpm_infineon0") == NULL) {
-+              if (request_region
-+                  (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
-                       rc = -EINVAL;
-                       goto err_last;
-               }
-@@ -442,9 +443,9 @@
-               /* configure TPM with IO-ports */
-               outb(IOLIMH, TPM_INF_ADDR);
--              outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
-+              outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
-               outb(IOLIML, TPM_INF_ADDR);
--              outb((tpm_inf.base & 0xff), TPM_INF_DATA);
-+              outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
-               /* control if IO-ports are set correctly */
-               outb(IOLIMH, TPM_INF_ADDR);
-@@ -452,10 +453,10 @@
-               outb(IOLIML, TPM_INF_ADDR);
-               iol = inb(TPM_INF_DATA);
--              if ((ioh << 8 | iol) != tpm_inf.base) {
-+              if ((ioh << 8 | iol) != TPM_INF_BASE) {
-                       dev_err(&dev->dev,
--                              "Could not set IO-ports to 0x%lx\n",
--                              tpm_inf.base);
-+                              "Could not set IO-ports to 0x%x\n",
-+                              TPM_INF_BASE);
-                       rc = -EIO;
-                       goto err_release_region;
-               }
-@@ -466,15 +467,15 @@
-               outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
-               /* disable RESET, LP and IRQC */
--              outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
-+              outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
-               /* Finally, we're done, print some infos */
-               dev_info(&dev->dev, "TPM found: "
-                        "config base 0x%x, "
-                        "io base 0x%x, "
--                       "chip version %02x%02x, "
--                       "vendor id %x%x (Infineon), "
--                       "product id %02x%02x"
-+                       "chip version 0x%02x%02x, "
-+                       "vendor id 0x%x%x (Infineon), "
-+                       "product id 0x%02x%02x"
-                        "%s\n",
-                        TPM_INF_ADDR,
-                        TPM_INF_BASE,
-@@ -482,11 +483,10 @@
-                        vendorid[0], vendorid[1],
-                        productid[0], productid[1], chipname);
--              rc = tpm_register_hardware(&dev->dev, &tpm_inf);
--              if (rc < 0) {
--                      rc = -ENODEV;
-+              if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
-                       goto err_release_region;
-               }
-+              chip->vendor.base = TPM_INF_BASE;
-               return 0;
-       } else {
-               rc = -ENODEV;
-@@ -494,7 +494,7 @@
-       }
- err_release_region:
--      release_region(tpm_inf.base, TPM_INF_PORT_LEN);
-+      release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
-       release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
- err_last:
-@@ -506,7 +506,8 @@
-       struct tpm_chip *chip = pnp_get_drvdata(dev);
-       if (chip) {
--              release_region(chip->vendor->base, TPM_INF_PORT_LEN);
-+              release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
-+              release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
-               tpm_remove_hardware(chip->dev);
-       }
- }
-@@ -520,7 +521,7 @@
-       },
-       .id_table = tpm_pnp_tbl,
-       .probe = tpm_inf_pnp_probe,
--      .remove = tpm_inf_pnp_remove,
-+      .remove = __devexit_p(tpm_inf_pnp_remove),
- };
- static int __init init_inf(void)
-@@ -538,5 +539,5 @@
- MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
- MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
--MODULE_VERSION("1.7");
-+MODULE_VERSION("1.8");
- MODULE_LICENSE("GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_nsc.c linux-2.6.16.33/drivers/char/tpm/tpm_nsc.c
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_nsc.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_nsc.c 2007-05-23 21:00:01.000000000 +0000
-@@ -71,7 +71,7 @@
-       unsigned long stop;
-       /* status immediately available check */
--      *data = inb(chip->vendor->base + NSC_STATUS);
-+      *data = inb(chip->vendor.base + NSC_STATUS);
-       if ((*data & mask) == val)
-               return 0;
-@@ -79,7 +79,7 @@
-       stop = jiffies + 10 * HZ;
-       do {
-               msleep(TPM_TIMEOUT);
--              *data = inb(chip->vendor->base + 1);
-+              *data = inb(chip->vendor.base + 1);
-               if ((*data & mask) == val)
-                       return 0;
-       }
-@@ -94,9 +94,9 @@
-       unsigned long stop;
-       /* status immediately available check */
--      status = inb(chip->vendor->base + NSC_STATUS);
-+      status = inb(chip->vendor.base + NSC_STATUS);
-       if (status & NSC_STATUS_OBF)
--              status = inb(chip->vendor->base + NSC_DATA);
-+              status = inb(chip->vendor.base + NSC_DATA);
-       if (status & NSC_STATUS_RDY)
-               return 0;
-@@ -104,9 +104,9 @@
-       stop = jiffies + 100;
-       do {
-               msleep(TPM_TIMEOUT);
--              status = inb(chip->vendor->base + NSC_STATUS);
-+              status = inb(chip->vendor.base + NSC_STATUS);
-               if (status & NSC_STATUS_OBF)
--                      status = inb(chip->vendor->base + NSC_DATA);
-+                      status = inb(chip->vendor.base + NSC_DATA);
-               if (status & NSC_STATUS_RDY)
-                       return 0;
-       }
-@@ -132,7 +132,7 @@
-               return -EIO;
-       }
-       if ((data =
--           inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
-+           inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
-               dev_err(chip->dev, "not in normal mode (0x%x)\n",
-                       data);
-               return -EIO;
-@@ -148,7 +148,7 @@
-               }
-               if (data & NSC_STATUS_F0)
-                       break;
--              *p = inb(chip->vendor->base + NSC_DATA);
-+              *p = inb(chip->vendor.base + NSC_DATA);
-       }
-       if ((data & NSC_STATUS_F0) == 0 &&
-@@ -156,7 +156,7 @@
-               dev_err(chip->dev, "F0 not set\n");
-               return -EIO;
-       }
--      if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
-+      if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
-               dev_err(chip->dev,
-                       "expected end of command(0x%x)\n", data);
-               return -EIO;
-@@ -182,7 +182,7 @@
-        * fix it. Not sure why this is needed, we followed the flow
-        * chart in the manual to the letter.
-        */
--      outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
-+      outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
-       if (nsc_wait_for_ready(chip) != 0)
-               return -EIO;
-@@ -192,7 +192,7 @@
-               return -EIO;
-       }
--      outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
-+      outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
-       if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
-               dev_err(chip->dev, "IBR timeout\n");
-               return -EIO;
-@@ -204,26 +204,26 @@
-                               "IBF timeout (while writing data)\n");
-                       return -EIO;
-               }
--              outb(buf[i], chip->vendor->base + NSC_DATA);
-+              outb(buf[i], chip->vendor.base + NSC_DATA);
-       }
-       if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
-               dev_err(chip->dev, "IBF timeout\n");
-               return -EIO;
-       }
--      outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
-+      outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
-       return count;
- }
- static void tpm_nsc_cancel(struct tpm_chip *chip)
- {
--      outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
-+      outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
- }
- static u8 tpm_nsc_status(struct tpm_chip *chip)
- {
--      return inb(chip->vendor->base + NSC_STATUS);
-+      return inb(chip->vendor.base + NSC_STATUS);
- }
- static struct file_operations nsc_ops = {
-@@ -250,7 +250,7 @@
- static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
--static struct tpm_vendor_specific tpm_nsc = {
-+static const struct tpm_vendor_specific tpm_nsc = {
-       .recv = tpm_nsc_recv,
-       .send = tpm_nsc_send,
-       .cancel = tpm_nsc_cancel,
-@@ -268,7 +268,7 @@
- {
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       if ( chip ) {
--              release_region(chip->vendor->base, 2);
-+              release_region(chip->vendor.base, 2);
-               tpm_remove_hardware(chip->dev);
-       }
- }
-@@ -286,7 +286,8 @@
-       int rc = 0;
-       int lo, hi;
-       int nscAddrBase = TPM_ADDR;
--
-+      struct tpm_chip *chip;
-+      unsigned long base;
-       /* verify that it is a National part (SID) */
-       if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
-@@ -300,7 +301,7 @@
-       hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
-       lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
--      tpm_nsc.base = (hi<<8) | lo;
-+      base = (hi<<8) | lo;
-       /* enable the DPM module */
-       tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
-@@ -320,13 +321,15 @@
-       if ((rc = platform_device_register(pdev)) < 0)
-               goto err_free_dev;
--      if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
-+      if (request_region(base, 2, "tpm_nsc0") == NULL ) {
-               rc = -EBUSY;
-               goto err_unreg_dev;
-       }
--      if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
-+      if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
-+              rc = -ENODEV;
-               goto err_rel_reg;
-+      }
-       dev_dbg(&pdev->dev, "NSC TPM detected\n");
-       dev_dbg(&pdev->dev,
-@@ -361,10 +364,12 @@
-                "NSC TPM revision %d\n",
-                tpm_read_index(nscAddrBase, 0x27) & 0x1F);
-+      chip->vendor.base = base;
-+
-       return 0;
- err_rel_reg:
--      release_region(tpm_nsc.base, 2);
-+      release_region(base, 2);
- err_unreg_dev:
-       platform_device_unregister(pdev);
- err_free_dev:
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_tis.c linux-2.6.16.33/drivers/char/tpm/tpm_tis.c
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_tis.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_tis.c 2007-05-23 21:00:01.000000000 +0000
-@@ -0,0 +1,665 @@
-+/*
-+ * Copyright (C) 2005, 2006 IBM Corporation
-+ *
-+ * Authors:
-+ * Leendert van Doorn <leendert@watson.ibm.com>
-+ * Kylene Hall <kjhall@us.ibm.com>
-+ *
-+ * Device driver for TCG/TCPA TPM (trusted platform module).
-+ * Specifications at www.trustedcomputinggroup.org
-+ *
-+ * This device driver implements the TPM interface as defined in
-+ * the TCG TPM Interface Spec version 1.2, revision 1.0.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/pnp.h>
-+#include <linux/interrupt.h>
-+#include <linux/wait.h>
-+#include "tpm.h"
-+
-+#define TPM_HEADER_SIZE 10
-+
-+enum tis_access {
-+      TPM_ACCESS_VALID = 0x80,
-+      TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
-+      TPM_ACCESS_REQUEST_PENDING = 0x04,
-+      TPM_ACCESS_REQUEST_USE = 0x02,
-+};
-+
-+enum tis_status {
-+      TPM_STS_VALID = 0x80,
-+      TPM_STS_COMMAND_READY = 0x40,
-+      TPM_STS_GO = 0x20,
-+      TPM_STS_DATA_AVAIL = 0x10,
-+      TPM_STS_DATA_EXPECT = 0x08,
-+};
-+
-+enum tis_int_flags {
-+      TPM_GLOBAL_INT_ENABLE = 0x80000000,
-+      TPM_INTF_BURST_COUNT_STATIC = 0x100,
-+      TPM_INTF_CMD_READY_INT = 0x080,
-+      TPM_INTF_INT_EDGE_FALLING = 0x040,
-+      TPM_INTF_INT_EDGE_RISING = 0x020,
-+      TPM_INTF_INT_LEVEL_LOW = 0x010,
-+      TPM_INTF_INT_LEVEL_HIGH = 0x008,
-+      TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
-+      TPM_INTF_STS_VALID_INT = 0x002,
-+      TPM_INTF_DATA_AVAIL_INT = 0x001,
-+};
-+
-+enum tis_defaults {
-+      TIS_MEM_BASE = 0xFED40000,
-+      TIS_MEM_LEN = 0x5000,
-+      TIS_SHORT_TIMEOUT = 750,        /* ms */
-+      TIS_LONG_TIMEOUT = 2000,        /* 2 sec */
-+};
-+
-+#define       TPM_ACCESS(l)                   (0x0000 | ((l) << 12))
-+#define       TPM_INT_ENABLE(l)               (0x0008 | ((l) << 12))
-+#define       TPM_INT_VECTOR(l)               (0x000C | ((l) << 12))
-+#define       TPM_INT_STATUS(l)               (0x0010 | ((l) << 12))
-+#define       TPM_INTF_CAPS(l)                (0x0014 | ((l) << 12))
-+#define       TPM_STS(l)                      (0x0018 | ((l) << 12))
-+#define       TPM_DATA_FIFO(l)                (0x0024 | ((l) << 12))
-+
-+#define       TPM_DID_VID(l)                  (0x0F00 | ((l) << 12))
-+#define       TPM_RID(l)                      (0x0F04 | ((l) << 12))
-+
-+static LIST_HEAD(tis_chips);
-+static DEFINE_SPINLOCK(tis_lock);
-+
-+static int check_locality(struct tpm_chip *chip, int l)
-+{
-+      if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
-+           (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
-+          (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
-+              return chip->vendor.locality = l;
-+
-+      return -1;
-+}
-+
-+static void release_locality(struct tpm_chip *chip, int l, int force)
-+{
-+      if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
-+                    (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
-+          (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
-+              iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
-+                       chip->vendor.iobase + TPM_ACCESS(l));
-+}
-+
-+static int request_locality(struct tpm_chip *chip, int l)
-+{
-+      unsigned long stop;
-+      long rc;
-+
-+      if (check_locality(chip, l) >= 0)
-+              return l;
-+
-+      iowrite8(TPM_ACCESS_REQUEST_USE,
-+               chip->vendor.iobase + TPM_ACCESS(l));
-+
-+      if (chip->vendor.irq) {
-+              rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
-+                                                    (check_locality
-+                                                     (chip, l) >= 0),
-+                                                    chip->vendor.timeout_a);
-+              if (rc > 0)
-+                      return l;
-+
-+      } else {
-+              /* wait for burstcount */
-+              stop = jiffies + chip->vendor.timeout_a;
-+              do {
-+                      if (check_locality(chip, l) >= 0)
-+                              return l;
-+                      msleep(TPM_TIMEOUT);
-+              }
-+              while (time_before(jiffies, stop));
-+      }
-+      return -1;
-+}
-+
-+static u8 tpm_tis_status(struct tpm_chip *chip)
-+{
-+      return ioread8(chip->vendor.iobase +
-+                     TPM_STS(chip->vendor.locality));
-+}
-+
-+static void tpm_tis_ready(struct tpm_chip *chip)
-+{
-+      /* this causes the current command to be aborted */
-+      iowrite8(TPM_STS_COMMAND_READY,
-+               chip->vendor.iobase + TPM_STS(chip->vendor.locality));
-+}
-+
-+static int get_burstcount(struct tpm_chip *chip)
-+{
-+      unsigned long stop;
-+      int burstcnt;
-+
-+      /* wait for burstcount */
-+      /* which timeout value, spec has 2 answers (c & d) */
-+      stop = jiffies + chip->vendor.timeout_d;
-+      do {
-+              burstcnt = ioread8(chip->vendor.iobase +
-+                                 TPM_STS(chip->vendor.locality) + 1);
-+              burstcnt += ioread8(chip->vendor.iobase +
-+                                  TPM_STS(chip->vendor.locality) +
-+                                  2) << 8;
-+              if (burstcnt)
-+                      return burstcnt;
-+              msleep(TPM_TIMEOUT);
-+      } while (time_before(jiffies, stop));
-+      return -EBUSY;
-+}
-+
-+static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
-+                       wait_queue_head_t *queue)
-+{
-+      unsigned long stop;
-+      long rc;
-+      u8 status;
-+
-+      /* check current status */
-+      status = tpm_tis_status(chip);
-+      if ((status & mask) == mask)
-+              return 0;
-+
-+      if (chip->vendor.irq) {
-+              rc = wait_event_interruptible_timeout(*queue,
-+                                                    ((tpm_tis_status
-+                                                      (chip) & mask) ==
-+                                                     mask), timeout);
-+              if (rc > 0)
-+                      return 0;
-+      } else {
-+              stop = jiffies + timeout;
-+              do {
-+                      msleep(TPM_TIMEOUT);
-+                      status = tpm_tis_status(chip);
-+                      if ((status & mask) == mask)
-+                              return 0;
-+              } while (time_before(jiffies, stop));
-+      }
-+      return -ETIME;
-+}
-+
-+static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
-+{
-+      int size = 0, burstcnt;
-+      while (size < count &&
-+             wait_for_stat(chip,
-+                           TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-+                           chip->vendor.timeout_c,
-+                           &chip->vendor.read_queue)
-+             == 0) {
-+              burstcnt = get_burstcount(chip);
-+              for (; burstcnt > 0 && size < count; burstcnt--)
-+                      buf[size++] = ioread8(chip->vendor.iobase +
-+                                            TPM_DATA_FIFO(chip->vendor.
-+                                                          locality));
-+      }
-+      return size;
-+}
-+
-+static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
-+{
-+      int size = 0;
-+      int expected, status;
-+
-+      if (count < TPM_HEADER_SIZE) {
-+              size = -EIO;
-+              goto out;
-+      }
-+
-+      /* read first 10 bytes, including tag, paramsize, and result */
-+      if ((size =
-+           recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
-+              dev_err(chip->dev, "Unable to read header\n");
-+              goto out;
-+      }
-+
-+      expected = be32_to_cpu(*(__be32 *) (buf + 2));
-+      if (expected > count) {
-+              size = -EIO;
-+              goto out;
-+      }
-+
-+      if ((size +=
-+           recv_data(chip, &buf[TPM_HEADER_SIZE],
-+                     expected - TPM_HEADER_SIZE)) < expected) {
-+              dev_err(chip->dev, "Unable to read remainder of result\n");
-+              size = -ETIME;
-+              goto out;
-+      }
-+
-+      wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
-+                    &chip->vendor.int_queue);
-+      status = tpm_tis_status(chip);
-+      if (status & TPM_STS_DATA_AVAIL) {      /* retry? */
-+              dev_err(chip->dev, "Error left over data\n");
-+              size = -EIO;
-+              goto out;
-+      }
-+
-+out:
-+      tpm_tis_ready(chip);
-+      release_locality(chip, chip->vendor.locality, 0);
-+      return size;
-+}
-+
-+/*
-+ * If interrupts are used (signaled by an irq set in the vendor structure)
-+ * tpm.c can skip polling for the data to be available as the interrupt is
-+ * waited for here
-+ */
-+static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
-+{
-+      int rc, status, burstcnt;
-+      size_t count = 0;
-+      u32 ordinal;
-+
-+      if (request_locality(chip, 0) < 0)
-+              return -EBUSY;
-+
-+      status = tpm_tis_status(chip);
-+      if ((status & TPM_STS_COMMAND_READY) == 0) {
-+              tpm_tis_ready(chip);
-+              if (wait_for_stat
-+                  (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
-+                   &chip->vendor.int_queue) < 0) {
-+                      rc = -ETIME;
-+                      goto out_err;
-+              }
-+      }
-+
-+      while (count < len - 1) {
-+              burstcnt = get_burstcount(chip);
-+              for (; burstcnt > 0 && count < len - 1; burstcnt--) {
-+                      iowrite8(buf[count], chip->vendor.iobase +
-+                               TPM_DATA_FIFO(chip->vendor.locality));
-+                      count++;
-+              }
-+
-+              wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
-+                            &chip->vendor.int_queue);
-+              status = tpm_tis_status(chip);
-+              if ((status & TPM_STS_DATA_EXPECT) == 0) {
-+                      rc = -EIO;
-+                      goto out_err;
-+              }
-+      }
-+
-+      /* write last byte */
-+      iowrite8(buf[count],
-+               chip->vendor.iobase +
-+               TPM_DATA_FIFO(chip->vendor.locality));
-+      wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
-+                    &chip->vendor.int_queue);
-+      status = tpm_tis_status(chip);
-+      if ((status & TPM_STS_DATA_EXPECT) != 0) {
-+              rc = -EIO;
-+              goto out_err;
-+      }
-+
-+      /* go and do it */
-+      iowrite8(TPM_STS_GO,
-+               chip->vendor.iobase + TPM_STS(chip->vendor.locality));
-+
-+      if (chip->vendor.irq) {
-+              ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
-+              if (wait_for_stat
-+                  (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-+                   tpm_calc_ordinal_duration(chip, ordinal),
-+                   &chip->vendor.read_queue) < 0) {
-+                      rc = -ETIME;
-+                      goto out_err;
-+              }
-+      }
-+      return len;
-+out_err:
-+      tpm_tis_ready(chip);
-+      release_locality(chip, chip->vendor.locality, 0);
-+      return rc;
-+}
-+
-+static struct file_operations tis_ops = {
-+      .owner = THIS_MODULE,
-+      .llseek = no_llseek,
-+      .open = tpm_open,
-+      .read = tpm_read,
-+      .write = tpm_write,
-+      .release = tpm_release,
-+};
-+
-+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
-+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
-+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
-+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
-+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
-+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
-+                 NULL);
-+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
-+static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
-+
-+static struct attribute *tis_attrs[] = {
-+      &dev_attr_pubek.attr,
-+      &dev_attr_pcrs.attr,
-+      &dev_attr_enabled.attr,
-+      &dev_attr_active.attr,
-+      &dev_attr_owned.attr,
-+      &dev_attr_temp_deactivated.attr,
-+      &dev_attr_caps.attr,
-+      &dev_attr_cancel.attr, NULL,
-+};
-+
-+static struct attribute_group tis_attr_grp = {
-+      .attrs = tis_attrs
-+};
-+
-+static struct tpm_vendor_specific tpm_tis = {
-+      .status = tpm_tis_status,
-+      .recv = tpm_tis_recv,
-+      .send = tpm_tis_send,
-+      .cancel = tpm_tis_ready,
-+      .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-+      .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-+      .req_canceled = TPM_STS_COMMAND_READY,
-+      .attr_group = &tis_attr_grp,
-+      .miscdev = {
-+                  .fops = &tis_ops,},
-+};
-+
-+static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct tpm_chip *chip = (struct tpm_chip *) dev_id;
-+      u32 interrupt;
-+
-+      interrupt = ioread32(chip->vendor.iobase +
-+                           TPM_INT_STATUS(chip->vendor.locality));
-+
-+      if (interrupt == 0)
-+              return IRQ_NONE;
-+
-+      chip->vendor.irq = irq;
-+
-+      /* Clear interrupts handled with TPM_EOI */
-+      iowrite32(interrupt,
-+                chip->vendor.iobase +
-+                TPM_INT_STATUS(chip->vendor.locality));
-+      return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct tpm_chip *chip = (struct tpm_chip *) dev_id;
-+      u32 interrupt;
-+      int i;
-+
-+      interrupt = ioread32(chip->vendor.iobase +
-+                           TPM_INT_STATUS(chip->vendor.locality));
-+
-+      if (interrupt == 0)
-+              return IRQ_NONE;
-+
-+      if (interrupt & TPM_INTF_DATA_AVAIL_INT)
-+              wake_up_interruptible(&chip->vendor.read_queue);
-+      if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
-+              for (i = 0; i < 5; i++)
-+                      if (check_locality(chip, i) >= 0)
-+                              break;
-+      if (interrupt &
-+          (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
-+           TPM_INTF_CMD_READY_INT))
-+              wake_up_interruptible(&chip->vendor.int_queue);
-+
-+      /* Clear interrupts handled with TPM_EOI */
-+      iowrite32(interrupt,
-+                chip->vendor.iobase +
-+                TPM_INT_STATUS(chip->vendor.locality));
-+      return IRQ_HANDLED;
-+}
-+
-+static int interrupts = 1;
-+module_param(interrupts, bool, 0444);
-+MODULE_PARM_DESC(interrupts, "Enable interrupts");
-+
-+static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
-+                                    const struct pnp_device_id *pnp_id)
-+{
-+      u32 vendor, intfcaps, intmask;
-+      int rc, i;
-+      unsigned long start, len;
-+      struct tpm_chip *chip;
-+
-+      start = pnp_mem_start(pnp_dev, 0);
-+      len = pnp_mem_len(pnp_dev, 0);
-+
-+      if (!start)
-+              start = TIS_MEM_BASE;
-+      if (!len)
-+              len = TIS_MEM_LEN;
-+
-+      if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
-+              return -ENODEV;
-+
-+      chip->vendor.iobase = ioremap(start, len);
-+      if (!chip->vendor.iobase) {
-+              rc = -EIO;
-+              goto out_err;
-+      }
-+
-+      vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
-+
-+      /* Default timeouts */
-+      chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-+      chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
-+      chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-+      chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-+
-+      dev_info(&pnp_dev->dev,
-+               "1.2 TPM (device-id 0x%X, rev-id %d)\n",
-+               vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
-+
-+      /* Figure out the capabilities */
-+      intfcaps =
-+          ioread32(chip->vendor.iobase +
-+                   TPM_INTF_CAPS(chip->vendor.locality));
-+      dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
-+              intfcaps);
-+      if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
-+              dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
-+      if (intfcaps & TPM_INTF_CMD_READY_INT)
-+              dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
-+      if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
-+              dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
-+      if (intfcaps & TPM_INTF_INT_EDGE_RISING)
-+              dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
-+      if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
-+              dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
-+      if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
-+              dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
-+      if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
-+              dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
-+      if (intfcaps & TPM_INTF_STS_VALID_INT)
-+              dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
-+      if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
-+              dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
-+
-+      if (request_locality(chip, 0) != 0) {
-+              rc = -ENODEV;
-+              goto out_err;
-+      }
-+
-+      /* INTERRUPT Setup */
-+      init_waitqueue_head(&chip->vendor.read_queue);
-+      init_waitqueue_head(&chip->vendor.int_queue);
-+
-+      intmask =
-+          ioread32(chip->vendor.iobase +
-+                   TPM_INT_ENABLE(chip->vendor.locality));
-+
-+      intmask |= TPM_INTF_CMD_READY_INT
-+          | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
-+          | TPM_INTF_STS_VALID_INT;
-+
-+      iowrite32(intmask,
-+                chip->vendor.iobase +
-+                TPM_INT_ENABLE(chip->vendor.locality));
-+      if (interrupts) {
-+              chip->vendor.irq =
-+                  ioread8(chip->vendor.iobase +
-+                          TPM_INT_VECTOR(chip->vendor.locality));
-+
-+              for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
-+                      iowrite8(i, chip->vendor.iobase +
-+                                  TPM_INT_VECTOR(chip->vendor.locality));
-+                      if (request_irq
-+                          (i, tis_int_probe, SA_SHIRQ,
-+                           chip->vendor.miscdev.name, chip) != 0) {
-+                              dev_info(chip->dev,
-+                                       "Unable to request irq: %d for probe\n",
-+                                       i);
-+                              continue;
-+                      }
-+
-+                      /* Clear all existing */
-+                      iowrite32(ioread32
-+                                (chip->vendor.iobase +
-+                                 TPM_INT_STATUS(chip->vendor.locality)),
-+                                chip->vendor.iobase +
-+                                TPM_INT_STATUS(chip->vendor.locality));
-+
-+                      /* Turn on */
-+                      iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
-+                                chip->vendor.iobase +
-+                                TPM_INT_ENABLE(chip->vendor.locality));
-+
-+                      /* Generate Interrupts */
-+                      tpm_gen_interrupt(chip);
-+
-+                      /* Turn off */
-+                      iowrite32(intmask,
-+                                chip->vendor.iobase +
-+                                TPM_INT_ENABLE(chip->vendor.locality));
-+                      free_irq(i, chip);
-+              }
-+      }
-+      if (chip->vendor.irq) {
-+              iowrite8(chip->vendor.irq,
-+                       chip->vendor.iobase +
-+                       TPM_INT_VECTOR(chip->vendor.locality));
-+              if (request_irq
-+                  (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
-+                   chip->vendor.miscdev.name, chip) != 0) {
-+                      dev_info(chip->dev,
-+                               "Unable to request irq: %d for use\n",
-+                               chip->vendor.irq);
-+                      chip->vendor.irq = 0;
-+              } else {
-+                      /* Clear all existing */
-+                      iowrite32(ioread32
-+                                (chip->vendor.iobase +
-+                                 TPM_INT_STATUS(chip->vendor.locality)),
-+                                chip->vendor.iobase +
-+                                TPM_INT_STATUS(chip->vendor.locality));
-+
-+                      /* Turn on */
-+                      iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
-+                                chip->vendor.iobase +
-+                                TPM_INT_ENABLE(chip->vendor.locality));
-+              }
-+      }
-+
-+      INIT_LIST_HEAD(&chip->vendor.list);
-+      spin_lock(&tis_lock);
-+      list_add(&chip->vendor.list, &tis_chips);
-+      spin_unlock(&tis_lock);
-+
-+      tpm_get_timeouts(chip);
-+      tpm_continue_selftest(chip);
-+
-+      return 0;
-+out_err:
-+      if (chip->vendor.iobase)
-+              iounmap(chip->vendor.iobase);
-+      tpm_remove_hardware(chip->dev);
-+      return rc;
-+}
-+
-+static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
-+{
-+      return tpm_pm_suspend(&dev->dev, msg);
-+}
-+
-+static int tpm_tis_pnp_resume(struct pnp_dev *dev)
-+{
-+      return tpm_pm_resume(&dev->dev);
-+}
-+
-+static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
-+      {"PNP0C31", 0},         /* TPM */
-+      {"ATM1200", 0},         /* Atmel */
-+      {"IFX0102", 0},         /* Infineon */
-+      {"BCM0101", 0},         /* Broadcom */
-+      {"NSC1200", 0},         /* National */
-+      /* Add new here */
-+      {"", 0},                /* User Specified */
-+      {"", 0}                 /* Terminator */
-+};
-+
-+static struct pnp_driver tis_pnp_driver = {
-+      .name = "tpm_tis",
-+      .id_table = tpm_pnp_tbl,
-+      .probe = tpm_tis_pnp_init,
-+      .suspend = tpm_tis_pnp_suspend,
-+      .resume = tpm_tis_pnp_resume,
-+};
-+
-+#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
-+module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
-+                  sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
-+MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
-+
-+static int __init init_tis(void)
-+{
-+      return pnp_register_driver(&tis_pnp_driver);
-+}
-+
-+static void __exit cleanup_tis(void)
-+{
-+      struct tpm_vendor_specific *i, *j;
-+      struct tpm_chip *chip;
-+      spin_lock(&tis_lock);
-+      list_for_each_entry_safe(i, j, &tis_chips, list) {
-+              chip = to_tpm_chip(i);
-+              iowrite32(~TPM_GLOBAL_INT_ENABLE &
-+                        ioread32(chip->vendor.iobase +
-+                                 TPM_INT_ENABLE(chip->vendor.
-+                                                locality)),
-+                        chip->vendor.iobase +
-+                        TPM_INT_ENABLE(chip->vendor.locality));
-+              release_locality(chip, chip->vendor.locality, 1);
-+              if (chip->vendor.irq)
-+                      free_irq(chip->vendor.irq, chip);
-+              iounmap(i->iobase);
-+              list_del(&i->list);
-+              tpm_remove_hardware(chip->dev);
-+      }
-+      spin_unlock(&tis_lock);
-+      pnp_unregister_driver(&tis_pnp_driver);
-+}
-+
-+module_init(init_tis);
-+module_exit(cleanup_tis);
-+MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
-+MODULE_DESCRIPTION("TPM Driver");
-+MODULE_VERSION("2.0");
-+MODULE_LICENSE("GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_vtpm.c linux-2.6.16.33/drivers/char/tpm/tpm_vtpm.c
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_vtpm.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_vtpm.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,547 @@
-+/*
-+ * Copyright (C) 2006 IBM Corporation
-+ *
-+ * Authors:
-+ * Stefan Berger <stefanb@us.ibm.com>
-+ *
-+ * Generic device driver part for device drivers in a virtualized
-+ * environment.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ *
-+ */
-+
-+#include <asm/uaccess.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include "tpm.h"
-+#include "tpm_vtpm.h"
-+
-+/* read status bits */
-+enum {
-+      STATUS_BUSY = 0x01,
-+      STATUS_DATA_AVAIL = 0x02,
-+      STATUS_READY = 0x04
-+};
-+
-+struct transmission {
-+      struct list_head next;
-+
-+      unsigned char *request;
-+      size_t  request_len;
-+      size_t  request_buflen;
-+
-+      unsigned char *response;
-+      size_t  response_len;
-+      size_t  response_buflen;
-+
-+      unsigned int flags;
-+};
-+
-+enum {
-+      TRANSMISSION_FLAG_WAS_QUEUED = 0x1
-+};
-+
-+
-+enum {
-+      DATAEX_FLAG_QUEUED_ONLY = 0x1
-+};
-+
-+
-+/* local variables */
-+
-+/* local function prototypes */
-+static int _vtpm_send_queued(struct tpm_chip *chip);
-+
-+
-+/* =============================================================
-+ * Some utility functions
-+ * =============================================================
-+ */
-+static void vtpm_state_init(struct vtpm_state *vtpms)
-+{
-+      vtpms->current_request = NULL;
-+      spin_lock_init(&vtpms->req_list_lock);
-+      init_waitqueue_head(&vtpms->req_wait_queue);
-+      INIT_LIST_HEAD(&vtpms->queued_requests);
-+
-+      vtpms->current_response = NULL;
-+      spin_lock_init(&vtpms->resp_list_lock);
-+      init_waitqueue_head(&vtpms->resp_wait_queue);
-+
-+      vtpms->disconnect_time = jiffies;
-+}
-+
-+
-+static inline struct transmission *transmission_alloc(void)
-+{
-+      return kzalloc(sizeof(struct transmission), GFP_ATOMIC);
-+}
-+
-+static unsigned char *
-+transmission_set_req_buffer(struct transmission *t,
-+                            unsigned char *buffer, size_t len)
-+{
-+      if (t->request_buflen < len) {
-+              kfree(t->request);
-+              t->request = kmalloc(len, GFP_KERNEL);
-+              if (!t->request) {
-+                      t->request_buflen = 0;
-+                      return NULL;
-+              }
-+              t->request_buflen = len;
-+      }
-+
-+      memcpy(t->request, buffer, len);
-+      t->request_len = len;
-+
-+      return t->request;
-+}
-+
-+static unsigned char *
-+transmission_set_res_buffer(struct transmission *t,
-+                            const unsigned char *buffer, size_t len)
-+{
-+      if (t->response_buflen < len) {
-+              kfree(t->response);
-+              t->response = kmalloc(len, GFP_ATOMIC);
-+              if (!t->response) {
-+                      t->response_buflen = 0;
-+                      return NULL;
-+              }
-+              t->response_buflen = len;
-+      }
-+
-+      memcpy(t->response, buffer, len);
-+      t->response_len = len;
-+
-+      return t->response;
-+}
-+
-+static inline void transmission_free(struct transmission *t)
-+{
-+      kfree(t->request);
-+      kfree(t->response);
-+      kfree(t);
-+}
-+
-+/* =============================================================
-+ * Interface with the lower layer driver
-+ * =============================================================
-+ */
-+/*
-+ * Lower layer uses this function to make a response available.
-+ */
-+int vtpm_vd_recv(const struct tpm_chip *chip,
-+                 const unsigned char *buffer, size_t count,
-+                 void *ptr)
-+{
-+      unsigned long flags;
-+      int ret_size = 0;
-+      struct transmission *t;
-+      struct vtpm_state *vtpms;
-+
-+      vtpms = (struct vtpm_state *)chip_get_private(chip);
-+
-+      /*
-+       * The list with requests must contain one request
-+       * only and the element there must be the one that
-+       * was passed to me from the front-end.
-+       */
-+      spin_lock_irqsave(&vtpms->resp_list_lock, flags);
-+      if (vtpms->current_request != ptr) {
-+              spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
-+              return 0;
-+      }
-+
-+      if ((t = vtpms->current_request)) {
-+              transmission_free(t);
-+              vtpms->current_request = NULL;
-+      }
-+
-+      t = transmission_alloc();
-+      if (t) {
-+              if (!transmission_set_res_buffer(t, buffer, count)) {
-+                      transmission_free(t);
-+                      spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
-+                      return -ENOMEM;
-+              }
-+              ret_size = count;
-+              vtpms->current_response = t;
-+              wake_up_interruptible(&vtpms->resp_wait_queue);
-+      }
-+      spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
-+
-+      return ret_size;
-+}
-+
-+
-+/*
-+ * Lower layer indicates its status (connected/disconnected)
-+ */
-+void vtpm_vd_status(const struct tpm_chip *chip, u8 vd_status)
-+{
-+      struct vtpm_state *vtpms;
-+
-+      vtpms = (struct vtpm_state *)chip_get_private(chip);
-+
-+      vtpms->vd_status = vd_status;
-+      if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
-+              vtpms->disconnect_time = jiffies;
-+      }
-+}
-+
-+/* =============================================================
-+ * Interface with the generic TPM driver
-+ * =============================================================
-+ */
-+static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
-+{
-+      int rc = 0;
-+      unsigned long flags;
-+      struct vtpm_state *vtpms;
-+
-+      vtpms = (struct vtpm_state *)chip_get_private(chip);
-+
-+      /*
-+       * Check if the previous operation only queued the command
-+       * In this case there won't be a response, so I just
-+       * return from here and reset that flag. In any other
-+       * case I should receive a response from the back-end.
-+       */
-+      spin_lock_irqsave(&vtpms->resp_list_lock, flags);
-+      if ((vtpms->flags & DATAEX_FLAG_QUEUED_ONLY) != 0) {
-+              vtpms->flags &= ~DATAEX_FLAG_QUEUED_ONLY;
-+              spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
-+              /*
-+               * The first few commands (measurements) must be
-+               * queued since it might not be possible to talk to the
-+               * TPM, yet.
-+               * Return a response of up to 30 '0's.
-+               */
-+
-+              count = min_t(size_t, count, 30);
-+              memset(buf, 0x0, count);
-+              return count;
-+      }
-+      /*
-+       * Check whether something is in the responselist and if
-+       * there's nothing in the list wait for something to appear.
-+       */
-+
-+      if (!vtpms->current_response) {
-+              spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
-+              interruptible_sleep_on_timeout(&vtpms->resp_wait_queue,
-+                                             1000);
-+              spin_lock_irqsave(&vtpms->resp_list_lock ,flags);
-+      }
-+
-+      if (vtpms->current_response) {
-+              struct transmission *t = vtpms->current_response;
-+              vtpms->current_response = NULL;
-+              rc = min(count, t->response_len);
-+              memcpy(buf, t->response, rc);
-+              transmission_free(t);
-+      }
-+
-+      spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
-+      return rc;
-+}
-+
-+static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
-+{
-+      int rc = 0;
-+      unsigned long flags;
-+      struct transmission *t = transmission_alloc();
-+      struct vtpm_state *vtpms;
-+
-+      vtpms = (struct vtpm_state *)chip_get_private(chip);
-+
-+      if (!t)
-+              return -ENOMEM;
-+      /*
-+       * If there's a current request, it must be the
-+       * previous request that has timed out.
-+       */
-+      spin_lock_irqsave(&vtpms->req_list_lock, flags);
-+      if (vtpms->current_request != NULL) {
-+              printk("WARNING: Sending although there is a request outstanding.\n"
-+                     "         Previous request must have timed out.\n");
-+              transmission_free(vtpms->current_request);
-+              vtpms->current_request = NULL;
-+      }
-+      spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
-+
-+      /*
-+       * Queue the packet if the driver below is not
-+       * ready, yet, or there is any packet already
-+       * in the queue.
-+       * If the driver below is ready, unqueue all
-+       * packets first before sending our current
-+       * packet.
-+       * For each unqueued packet, except for the
-+       * last (=current) packet, call the function
-+       * tpm_xen_recv to wait for the response to come
-+       * back.
-+       */
-+      if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
-+              if (time_after(jiffies,
-+                             vtpms->disconnect_time + HZ * 10)) {
-+                      rc = -ENOENT;
-+              } else {
-+                      goto queue_it;
-+              }
-+      } else {
-+              /*
-+               * Send all queued packets.
-+               */
-+              if (_vtpm_send_queued(chip) == 0) {
-+
-+                      vtpms->current_request = t;
-+
-+                      rc = vtpm_vd_send(vtpms->tpm_private,
-+                                        buf,
-+                                        count,
-+                                        t);
-+                      /*
-+                       * The generic TPM driver will call
-+                       * the function to receive the response.
-+                       */
-+                      if (rc < 0) {
-+                              vtpms->current_request = NULL;
-+                              goto queue_it;
-+                      }
-+              } else {
-+queue_it:
-+                      if (!transmission_set_req_buffer(t, buf, count)) {
-+                              transmission_free(t);
-+                              rc = -ENOMEM;
-+                              goto exit;
-+                      }
-+                      /*
-+                       * An error occurred. Don't event try
-+                       * to send the current request. Just
-+                       * queue it.
-+                       */
-+                      spin_lock_irqsave(&vtpms->req_list_lock, flags);
-+                      vtpms->flags |= DATAEX_FLAG_QUEUED_ONLY;
-+                      list_add_tail(&t->next, &vtpms->queued_requests);
-+                      spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
-+              }
-+      }
-+
-+exit:
-+      return rc;
-+}
-+
-+
-+/*
-+ * Send all queued requests.
-+ */
-+static int _vtpm_send_queued(struct tpm_chip *chip)
-+{
-+      int rc;
-+      int error = 0;
-+      long flags;
-+      unsigned char buffer[1];
-+      struct vtpm_state *vtpms;
-+      vtpms = (struct vtpm_state *)chip_get_private(chip);
-+
-+      spin_lock_irqsave(&vtpms->req_list_lock, flags);
-+
-+      while (!list_empty(&vtpms->queued_requests)) {
-+              /*
-+               * Need to dequeue them.
-+               * Read the result into a dummy buffer.
-+               */
-+              struct transmission *qt = (struct transmission *)
-+                                        vtpms->queued_requests.next;
-+              list_del(&qt->next);
-+              vtpms->current_request = qt;
-+              spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
-+
-+              rc = vtpm_vd_send(vtpms->tpm_private,
-+                                qt->request,
-+                                qt->request_len,
-+                                qt);
-+
-+              if (rc < 0) {
-+                      spin_lock_irqsave(&vtpms->req_list_lock, flags);
-+                      if ((qt = vtpms->current_request) != NULL) {
-+                              /*
-+                               * requeue it at the beginning
-+                               * of the list
-+                               */
-+                              list_add(&qt->next,
-+                                       &vtpms->queued_requests);
-+                      }
-+                      vtpms->current_request = NULL;
-+                      error = 1;
-+                      break;
-+              }
-+              /*
-+               * After this point qt is not valid anymore!
-+               * It is freed when the front-end is delivering
-+               * the data by calling tpm_recv
-+               */
-+              /*
-+               * Receive response into provided dummy buffer
-+               */
-+              rc = vtpm_recv(chip, buffer, sizeof(buffer));
-+              spin_lock_irqsave(&vtpms->req_list_lock, flags);
-+      }
-+
-+      spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
-+
-+      return error;
-+}
-+
-+static void vtpm_cancel(struct tpm_chip *chip)
-+{
-+      unsigned long flags;
-+      struct vtpm_state *vtpms = (struct vtpm_state *)chip_get_private(chip);
-+
-+      spin_lock_irqsave(&vtpms->resp_list_lock,flags);
-+
-+      if (!vtpms->current_response && vtpms->current_request) {
-+              spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
-+              interruptible_sleep_on(&vtpms->resp_wait_queue);
-+              spin_lock_irqsave(&vtpms->resp_list_lock,flags);
-+      }
-+
-+      if (vtpms->current_response) {
-+              struct transmission *t = vtpms->current_response;
-+              vtpms->current_response = NULL;
-+              transmission_free(t);
-+      }
-+
-+      spin_unlock_irqrestore(&vtpms->resp_list_lock,flags);
-+}
-+
-+static u8 vtpm_status(struct tpm_chip *chip)
-+{
-+      u8 rc = 0;
-+      unsigned long flags;
-+      struct vtpm_state *vtpms;
-+
-+      vtpms = (struct vtpm_state *)chip_get_private(chip);
-+
-+      spin_lock_irqsave(&vtpms->resp_list_lock, flags);
-+      /*
-+       * Data are available if:
-+       *  - there's a current response
-+       *  - the last packet was queued only (this is fake, but necessary to
-+       *      get the generic TPM layer to call the receive function.)
-+       */
-+      if (vtpms->current_response ||
-+          0 != (vtpms->flags & DATAEX_FLAG_QUEUED_ONLY)) {
-+              rc = STATUS_DATA_AVAIL;
-+      } else if (!vtpms->current_response && !vtpms->current_request) {
-+              rc = STATUS_READY;
-+      }
-+
-+      spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
-+      return rc;
-+}
-+
-+static struct file_operations vtpm_ops = {
-+      .owner = THIS_MODULE,
-+      .llseek = no_llseek,
-+      .open = tpm_open,
-+      .read = tpm_read,
-+      .write = tpm_write,
-+      .release = tpm_release,
-+};
-+
-+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
-+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
-+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
-+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
-+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
-+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
-+                 NULL);
-+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
-+static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
-+
-+static struct attribute *vtpm_attrs[] = {
-+      &dev_attr_pubek.attr,
-+      &dev_attr_pcrs.attr,
-+      &dev_attr_enabled.attr,
-+      &dev_attr_active.attr,
-+      &dev_attr_owned.attr,
-+      &dev_attr_temp_deactivated.attr,
-+      &dev_attr_caps.attr,
-+      &dev_attr_cancel.attr,
-+      NULL,
-+};
-+
-+static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs };
-+
-+#define TPM_LONG_TIMEOUT   (10 * 60 * HZ)
-+
-+static struct tpm_vendor_specific tpm_vtpm = {
-+      .recv = vtpm_recv,
-+      .send = vtpm_send,
-+      .cancel = vtpm_cancel,
-+      .status = vtpm_status,
-+      .req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
-+      .req_complete_val  = STATUS_DATA_AVAIL,
-+      .req_canceled = STATUS_READY,
-+      .attr_group = &vtpm_attr_grp,
-+      .miscdev = {
-+              .fops = &vtpm_ops,
-+      },
-+      .duration = {
-+              TPM_LONG_TIMEOUT,
-+              TPM_LONG_TIMEOUT,
-+              TPM_LONG_TIMEOUT,
-+      },
-+};
-+
-+struct tpm_chip *init_vtpm(struct device *dev,
-+                           struct tpm_virtual_device *tvd,
-+                           struct tpm_private *tp)
-+{
-+      long rc;
-+      struct tpm_chip *chip;
-+      struct vtpm_state *vtpms;
-+
-+      vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
-+      if (!vtpms)
-+              return ERR_PTR(-ENOMEM);
-+
-+      vtpm_state_init(vtpms);
-+      vtpms->tpmvd = tvd;
-+      vtpms->tpm_private = tp;
-+
-+      if (tvd)
-+              tpm_vtpm.buffersize = tvd->max_tx_size;
-+
-+      chip = tpm_register_hardware(dev, &tpm_vtpm);
-+      if (!chip) {
-+              rc = -ENODEV;
-+              goto err_free_mem;
-+      }
-+
-+      chip_set_private(chip, vtpms);
-+
-+      return chip;
-+
-+err_free_mem:
-+      kfree(vtpms);
-+
-+      return ERR_PTR(rc);
-+}
-+
-+void cleanup_vtpm(struct device *dev)
-+{
-+      struct tpm_chip *chip = dev_get_drvdata(dev);
-+      struct vtpm_state *vtpms = (struct vtpm_state*)chip_get_private(chip);
-+      tpm_remove_hardware(dev);
-+      kfree(vtpms);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_vtpm.h linux-2.6.16.33/drivers/char/tpm/tpm_vtpm.h
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_vtpm.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_vtpm.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,68 @@
-+#ifndef TPM_VTPM_H
-+#define TPM_VTPM_H
-+
-+struct tpm_chip;
-+struct tpm_private;
-+
-+struct tpm_virtual_device {
-+      /*
-+       * This field indicates the maximum size the driver can
-+       * transfer in one chunk. It is filled in by the front-end
-+       * driver and should be propagated to the generic tpm driver
-+       * for allocation of buffers.
-+       */
-+      unsigned int max_tx_size;
-+};
-+
-+struct vtpm_state {
-+      struct transmission *current_request;
-+      spinlock_t           req_list_lock;
-+      wait_queue_head_t    req_wait_queue;
-+
-+      struct list_head     queued_requests;
-+
-+      struct transmission *current_response;
-+      spinlock_t           resp_list_lock;
-+      wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
-+
-+      u8                   vd_status;
-+      u8                   flags;
-+
-+      unsigned long        disconnect_time;
-+
-+      struct tpm_virtual_device *tpmvd;
-+
-+      /*
-+       * The following is a private structure of the underlying
-+       * driver. It is passed as parameter in the send function.
-+       */
-+      struct tpm_private *tpm_private;
-+};
-+
-+
-+enum vdev_status {
-+      TPM_VD_STATUS_DISCONNECTED = 0x0,
-+      TPM_VD_STATUS_CONNECTED = 0x1
-+};
-+
-+/* this function is called from tpm_vtpm.c */
-+int vtpm_vd_send(struct tpm_private * tp,
-+                 const u8 * buf, size_t count, void *ptr);
-+
-+/* these functions are offered by tpm_vtpm.c */
-+struct tpm_chip *init_vtpm(struct device *,
-+                           struct tpm_virtual_device *,
-+                           struct tpm_private *);
-+void cleanup_vtpm(struct device *);
-+int vtpm_vd_recv(const struct tpm_chip* chip,
-+                 const unsigned char *buffer, size_t count, void *ptr);
-+void vtpm_vd_status(const struct tpm_chip *, u8 status);
-+
-+static inline struct tpm_private *tpm_private_from_dev(struct device *dev)
-+{
-+      struct tpm_chip *chip = dev_get_drvdata(dev);
-+      struct vtpm_state *vtpms = chip_get_private(chip);
-+      return vtpms->tpm_private;
-+}
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tpm/tpm_xen.c linux-2.6.16.33/drivers/char/tpm/tpm_xen.c
---- linux-2.6.16.33-noxen/drivers/char/tpm/tpm_xen.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tpm/tpm_xen.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,760 @@
-+/*
-+ * Copyright (c) 2005, IBM Corporation
-+ *
-+ * Author: Stefan Berger, stefanb@us.ibm.com
-+ * Grant table support: Mahadevan Gomathisankaran
-+ *
-+ * This code has been derived from drivers/xen/netfront/netfront.c
-+ *
-+ * Copyright (c) 2002-2004, K A Fraser
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/errno.h>
-+#include <linux/err.h>
-+#include <linux/interrupt.h>
-+#include <linux/mutex.h>
-+#include <asm/uaccess.h>
-+#include <xen/evtchn.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/interface/io/tpmif.h>
-+#include <xen/gnttab.h>
-+#include <xen/xenbus.h>
-+#include "tpm.h"
-+#include "tpm_vtpm.h"
-+
-+#undef DEBUG
-+
-+/* local structures */
-+struct tpm_private {
-+      struct tpm_chip *chip;
-+
-+      tpmif_tx_interface_t *tx;
-+      atomic_t refcnt;
-+      unsigned int evtchn;
-+      unsigned int irq;
-+      u8 is_connected;
-+      u8 is_suspended;
-+
-+      spinlock_t tx_lock;
-+
-+      struct tx_buffer *tx_buffers[TPMIF_TX_RING_SIZE];
-+
-+      atomic_t tx_busy;
-+      void *tx_remember;
-+
-+      domid_t backend_id;
-+      wait_queue_head_t wait_q;
-+
-+      struct xenbus_device *dev;
-+      int ring_ref;
-+};
-+
-+struct tx_buffer {
-+      unsigned int size;      // available space in data
-+      unsigned int len;       // used space in data
-+      unsigned char *data;    // pointer to a page
-+};
-+
-+
-+/* locally visible variables */
-+static grant_ref_t gref_head;
-+static struct tpm_private *my_priv;
-+
-+/* local function prototypes */
-+static irqreturn_t tpmif_int(int irq,
-+                             void *tpm_priv,
-+                             struct pt_regs *ptregs);
-+static void tpmif_rx_action(unsigned long unused);
-+static int tpmif_connect(struct xenbus_device *dev,
-+                         struct tpm_private *tp,
-+                         domid_t domid);
-+static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
-+static int tpmif_allocate_tx_buffers(struct tpm_private *tp);
-+static void tpmif_free_tx_buffers(struct tpm_private *tp);
-+static void tpmif_set_connected_state(struct tpm_private *tp,
-+                                      u8 newstate);
-+static int tpm_xmit(struct tpm_private *tp,
-+                    const u8 * buf, size_t count, int userbuffer,
-+                    void *remember);
-+static void destroy_tpmring(struct tpm_private *tp);
-+void __exit tpmif_exit(void);
-+
-+#define DPRINTK(fmt, args...) \
-+    pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
-+#define IPRINTK(fmt, args...) \
-+    printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
-+#define WPRINTK(fmt, args...) \
-+    printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
-+
-+#define GRANT_INVALID_REF     0
-+
-+
-+static inline int
-+tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
-+               int isuserbuffer)
-+{
-+      int copied = len;
-+
-+      if (len > txb->size) {
-+              copied = txb->size;
-+      }
-+      if (isuserbuffer) {
-+              if (copy_from_user(txb->data, src, copied))
-+                      return -EFAULT;
-+      } else {
-+              memcpy(txb->data, src, copied);
-+      }
-+      txb->len = len;
-+      return copied;
-+}
-+
-+static inline struct tx_buffer *tx_buffer_alloc(void)
-+{
-+      struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
-+                                      GFP_KERNEL);
-+
-+      if (txb) {
-+              txb->len = 0;
-+              txb->size = PAGE_SIZE;
-+              txb->data = (unsigned char *)__get_free_page(GFP_KERNEL);
-+              if (txb->data == NULL) {
-+                      kfree(txb);
-+                      txb = NULL;
-+              }
-+      }
-+      return txb;
-+}
-+
-+
-+static inline void tx_buffer_free(struct tx_buffer *txb)
-+{
-+      if (txb) {
-+              free_page((long)txb->data);
-+              kfree(txb);
-+      }
-+}
-+
-+/**************************************************************
-+ Utility function for the tpm_private structure
-+**************************************************************/
-+static inline void tpm_private_init(struct tpm_private *tp)
-+{
-+      spin_lock_init(&tp->tx_lock);
-+      init_waitqueue_head(&tp->wait_q);
-+      atomic_set(&tp->refcnt, 1);
-+}
-+
-+static inline void tpm_private_put(void)
-+{
-+      if ( atomic_dec_and_test(&my_priv->refcnt)) {
-+              tpmif_free_tx_buffers(my_priv);
-+              kfree(my_priv);
-+              my_priv = NULL;
-+      }
-+}
-+
-+static struct tpm_private *tpm_private_get(void)
-+{
-+      int err;
-+      if (!my_priv) {
-+              my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
-+              if (my_priv) {
-+                      tpm_private_init(my_priv);
-+                      err = tpmif_allocate_tx_buffers(my_priv);
-+                      if (err < 0) {
-+                              tpm_private_put();
-+                      }
-+              }
-+      } else {
-+              atomic_inc(&my_priv->refcnt);
-+      }
-+      return my_priv;
-+}
-+
-+/**************************************************************
-+
-+ The interface to let the tpm plugin register its callback
-+ function and send data to another partition using this module
-+
-+**************************************************************/
-+
-+static DEFINE_MUTEX(suspend_lock);
-+/*
-+ * Send data via this module by calling this function
-+ */
-+int vtpm_vd_send(struct tpm_private *tp,
-+                 const u8 * buf, size_t count, void *ptr)
-+{
-+      int sent;
-+
-+      mutex_lock(&suspend_lock);
-+      sent = tpm_xmit(tp, buf, count, 0, ptr);
-+      mutex_unlock(&suspend_lock);
-+
-+      return sent;
-+}
-+
-+/**************************************************************
-+ XENBUS support code
-+**************************************************************/
-+
-+static int setup_tpmring(struct xenbus_device *dev,
-+                         struct tpm_private *tp)
-+{
-+      tpmif_tx_interface_t *sring;
-+      int err;
-+
-+      tp->ring_ref = GRANT_INVALID_REF;
-+
-+      sring = (void *)__get_free_page(GFP_KERNEL);
-+      if (!sring) {
-+              xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
-+              return -ENOMEM;
-+      }
-+      tp->tx = sring;
-+
-+      err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
-+      if (err < 0) {
-+              free_page((unsigned long)sring);
-+              tp->tx = NULL;
-+              xenbus_dev_fatal(dev, err, "allocating grant reference");
-+              goto fail;
-+      }
-+      tp->ring_ref = err;
-+
-+      err = tpmif_connect(dev, tp, dev->otherend_id);
-+      if (err)
-+              goto fail;
-+
-+      return 0;
-+fail:
-+      destroy_tpmring(tp);
-+      return err;
-+}
-+
-+
-+static void destroy_tpmring(struct tpm_private *tp)
-+{
-+      tpmif_set_connected_state(tp, 0);
-+
-+      if (tp->ring_ref != GRANT_INVALID_REF) {
-+              gnttab_end_foreign_access(tp->ring_ref, 0,
-+                                        (unsigned long)tp->tx);
-+              tp->ring_ref = GRANT_INVALID_REF;
-+              tp->tx = NULL;
-+      }
-+
-+      if (tp->irq)
-+              unbind_from_irqhandler(tp->irq, tp);
-+
-+      tp->evtchn = tp->irq = 0;
-+}
-+
-+
-+static int talk_to_backend(struct xenbus_device *dev,
-+                           struct tpm_private *tp)
-+{
-+      const char *message = NULL;
-+      int err;
-+      struct xenbus_transaction xbt;
-+
-+      err = setup_tpmring(dev, tp);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "setting up ring");
-+              goto out;
-+      }
-+
-+again:
-+      err = xenbus_transaction_start(&xbt);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "starting transaction");
-+              goto destroy_tpmring;
-+      }
-+
-+      err = xenbus_printf(xbt, dev->nodename,
-+                          "ring-ref","%u", tp->ring_ref);
-+      if (err) {
-+              message = "writing ring-ref";
-+              goto abort_transaction;
-+      }
-+
-+      err = xenbus_printf(xbt, dev->nodename,
-+                          "event-channel", "%u", tp->evtchn);
-+      if (err) {
-+              message = "writing event-channel";
-+              goto abort_transaction;
-+      }
-+
-+      err = xenbus_transaction_end(xbt, 0);
-+      if (err == -EAGAIN)
-+              goto again;
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "completing transaction");
-+              goto destroy_tpmring;
-+      }
-+
-+      xenbus_switch_state(dev, XenbusStateConnected);
-+
-+      return 0;
-+
-+abort_transaction:
-+      xenbus_transaction_end(xbt, 1);
-+      if (message)
-+              xenbus_dev_error(dev, err, "%s", message);
-+destroy_tpmring:
-+      destroy_tpmring(tp);
-+out:
-+      return err;
-+}
-+
-+/**
-+ * Callback received when the backend's state changes.
-+ */
-+static void backend_changed(struct xenbus_device *dev,
-+                          enum xenbus_state backend_state)
-+{
-+      struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
-+      DPRINTK("\n");
-+
-+      switch (backend_state) {
-+      case XenbusStateInitialising:
-+      case XenbusStateInitWait:
-+      case XenbusStateInitialised:
-+      case XenbusStateUnknown:
-+              break;
-+
-+      case XenbusStateConnected:
-+              tpmif_set_connected_state(tp, 1);
-+              break;
-+
-+      case XenbusStateClosing:
-+              tpmif_set_connected_state(tp, 0);
-+              xenbus_frontend_closed(dev);
-+              break;
-+
-+      case XenbusStateClosed:
-+              tpmif_set_connected_state(tp, 0);
-+              if (tp->is_suspended == 0)
-+                      device_unregister(&dev->dev);
-+              xenbus_frontend_closed(dev);
-+              break;
-+      }
-+}
-+
-+struct tpm_virtual_device tvd = {
-+      .max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
-+};
-+
-+static int tpmfront_probe(struct xenbus_device *dev,
-+                          const struct xenbus_device_id *id)
-+{
-+      int err;
-+      int handle;
-+      struct tpm_private *tp = tpm_private_get();
-+
-+      if (!tp)
-+              return -ENOMEM;
-+
-+      tp->chip = init_vtpm(&dev->dev, &tvd, tp);
-+
-+      if (IS_ERR(tp->chip)) {
-+              return PTR_ERR(tp->chip);
-+      }
-+
-+      err = xenbus_scanf(XBT_NIL, dev->nodename,
-+                         "handle", "%i", &handle);
-+      if (XENBUS_EXIST_ERR(err))
-+              return err;
-+
-+      if (err < 0) {
-+              xenbus_dev_fatal(dev,err,"reading virtual-device");
-+              return err;
-+      }
-+
-+      tp->dev = dev;
-+
-+      err = talk_to_backend(dev, tp);
-+      if (err) {
-+              tpm_private_put();
-+              return err;
-+      }
-+      return 0;
-+}
-+
-+
-+static int tpmfront_remove(struct xenbus_device *dev)
-+{
-+      struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
-+      destroy_tpmring(tp);
-+      cleanup_vtpm(&dev->dev);
-+      return 0;
-+}
-+
-+static int tpmfront_suspend(struct xenbus_device *dev)
-+{
-+      struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
-+      u32 ctr;
-+      /* lock, so no app can send */
-+      mutex_lock(&suspend_lock);
-+      tp->is_suspended = 1;
-+
-+      for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 300; ctr++) {
-+              if ((ctr % 10) == 0)
-+                      printk("TPM-FE [INFO]: Waiting for outstanding "
-+                             "request.\n");
-+              /*
-+               * Wait for a request to be responded to.
-+               */
-+              interruptible_sleep_on_timeout(&tp->wait_q, 100);
-+      }
-+      xenbus_switch_state(dev, XenbusStateClosing);
-+
-+      if (atomic_read(&tp->tx_busy)) {
-+              /*
-+               * A temporary work-around.
-+               */
-+              printk("TPM-FE [WARNING]: Resetting busy flag.");
-+              atomic_set(&tp->tx_busy, 0);
-+      }
-+
-+      return 0;
-+}
-+
-+static int tpmfront_resume(struct xenbus_device *dev)
-+{
-+      struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
-+      destroy_tpmring(tp);
-+      return talk_to_backend(dev, tp);
-+}
-+
-+static int tpmif_connect(struct xenbus_device *dev,
-+                         struct tpm_private *tp,
-+                         domid_t domid)
-+{
-+      int err;
-+
-+      tp->backend_id = domid;
-+
-+      err = xenbus_alloc_evtchn(dev, &tp->evtchn);
-+      if (err)
-+              return err;
-+
-+      err = bind_evtchn_to_irqhandler(tp->evtchn,
-+                                      tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
-+                                      tp);
-+      if (err <= 0) {
-+              WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
-+              return err;
-+      }
-+
-+      tp->irq = err;
-+      return 0;
-+}
-+
-+static struct xenbus_device_id tpmfront_ids[] = {
-+      { "vtpm" },
-+      { "" }
-+};
-+
-+static struct xenbus_driver tpmfront = {
-+      .name = "vtpm",
-+      .owner = THIS_MODULE,
-+      .ids = tpmfront_ids,
-+      .probe = tpmfront_probe,
-+      .remove =  tpmfront_remove,
-+      .resume = tpmfront_resume,
-+      .otherend_changed = backend_changed,
-+      .suspend = tpmfront_suspend,
-+};
-+
-+static void __init init_tpm_xenbus(void)
-+{
-+      xenbus_register_frontend(&tpmfront);
-+}
-+
-+static void __exit exit_tpm_xenbus(void)
-+{
-+      xenbus_unregister_driver(&tpmfront);
-+}
-+
-+static int tpmif_allocate_tx_buffers(struct tpm_private *tp)
-+{
-+      unsigned int i;
-+
-+      for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
-+              tp->tx_buffers[i] = tx_buffer_alloc();
-+              if (!tp->tx_buffers[i]) {
-+                      tpmif_free_tx_buffers(tp);
-+                      return -ENOMEM;
-+              }
-+      }
-+      return 0;
-+}
-+
-+static void tpmif_free_tx_buffers(struct tpm_private *tp)
-+{
-+      unsigned int i;
-+
-+      for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
-+              tx_buffer_free(tp->tx_buffers[i]);
-+      }
-+}
-+
-+static void tpmif_rx_action(unsigned long priv)
-+{
-+      struct tpm_private *tp = (struct tpm_private *)priv;
-+
-+      int i = 0;
-+      unsigned int received;
-+      unsigned int offset = 0;
-+      u8 *buffer;
-+      tpmif_tx_request_t *tx;
-+      tx = &tp->tx->ring[i].req;
-+
-+      atomic_set(&tp->tx_busy, 0);
-+      wake_up_interruptible(&tp->wait_q);
-+
-+      received = tx->size;
-+
-+      buffer = kmalloc(received, GFP_ATOMIC);
-+      if (NULL == buffer) {
-+              goto exit;
-+      }
-+
-+      for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
-+              struct tx_buffer *txb = tp->tx_buffers[i];
-+              tpmif_tx_request_t *tx;
-+              unsigned int tocopy;
-+
-+              tx = &tp->tx->ring[i].req;
-+              tocopy = tx->size;
-+              if (tocopy > PAGE_SIZE) {
-+                      tocopy = PAGE_SIZE;
-+              }
-+
-+              memcpy(&buffer[offset], txb->data, tocopy);
-+
-+              gnttab_release_grant_reference(&gref_head, tx->ref);
-+
-+              offset += tocopy;
-+      }
-+
-+      vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember);
-+      kfree(buffer);
-+
-+exit:
-+
-+      return;
-+}
-+
-+
-+static irqreturn_t tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
-+{
-+      struct tpm_private *tp = tpm_priv;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&tp->tx_lock, flags);
-+      tpmif_rx_tasklet.data = (unsigned long)tp;
-+      tasklet_schedule(&tpmif_rx_tasklet);
-+      spin_unlock_irqrestore(&tp->tx_lock, flags);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+
-+static int tpm_xmit(struct tpm_private *tp,
-+                    const u8 * buf, size_t count, int isuserbuffer,
-+                    void *remember)
-+{
-+      tpmif_tx_request_t *tx;
-+      TPMIF_RING_IDX i;
-+      unsigned int offset = 0;
-+
-+      spin_lock_irq(&tp->tx_lock);
-+
-+      if (unlikely(atomic_read(&tp->tx_busy))) {
-+              printk("tpm_xmit: There's an outstanding request/response "
-+                     "on the way!\n");
-+              spin_unlock_irq(&tp->tx_lock);
-+              return -EBUSY;
-+      }
-+
-+      if (tp->is_connected != 1) {
-+              spin_unlock_irq(&tp->tx_lock);
-+              return -EIO;
-+      }
-+
-+      for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
-+              struct tx_buffer *txb = tp->tx_buffers[i];
-+              int copied;
-+
-+              if (NULL == txb) {
-+                      DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
-+                              "Not transmitting anything!\n", i);
-+                      spin_unlock_irq(&tp->tx_lock);
-+                      return -EFAULT;
-+              }
-+              copied = tx_buffer_copy(txb, &buf[offset], count,
-+                                      isuserbuffer);
-+              if (copied < 0) {
-+                      /* An error occurred */
-+                      spin_unlock_irq(&tp->tx_lock);
-+                      return copied;
-+              }
-+              count -= copied;
-+              offset += copied;
-+
-+              tx = &tp->tx->ring[i].req;
-+
-+              tx->addr = virt_to_machine(txb->data);
-+              tx->size = txb->len;
-+
-+              DPRINTK("First 4 characters sent by TPM-FE are 0x%02x 0x%02x 0x%02x 0x%02x\n",
-+                      txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
-+
-+              /* get the granttable reference for this page */
-+              tx->ref = gnttab_claim_grant_reference(&gref_head);
-+
-+              if (-ENOSPC == tx->ref) {
-+                      spin_unlock_irq(&tp->tx_lock);
-+                      DPRINTK(" Grant table claim reference failed in func:%s line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
-+                      return -ENOSPC;
-+              }
-+              gnttab_grant_foreign_access_ref( tx->ref,
-+                                               tp->backend_id,
-+                                               (tx->addr >> PAGE_SHIFT),
-+                                               0 /*RW*/);
-+              wmb();
-+      }
-+
-+      atomic_set(&tp->tx_busy, 1);
-+      tp->tx_remember = remember;
-+
-+      mb();
-+
-+      DPRINTK("Notifying backend via event channel %d\n",
-+              tp->evtchn);
-+
-+      notify_remote_via_irq(tp->irq);
-+
-+      spin_unlock_irq(&tp->tx_lock);
-+      return offset;
-+}
-+
-+
-+static void tpmif_notify_upperlayer(struct tpm_private *tp)
-+{
-+      /*
-+       * Notify upper layer about the state of the connection
-+       * to the BE.
-+       */
-+      if (tp->is_connected) {
-+              vtpm_vd_status(tp->chip, TPM_VD_STATUS_CONNECTED);
-+      } else {
-+              vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED);
-+      }
-+}
-+
-+
-+static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
-+{
-+      /*
-+       * Don't notify upper layer if we are in suspend mode and
-+       * should disconnect - assumption is that we will resume
-+       * The mutex keeps apps from sending.
-+       */
-+      if (is_connected == 0 && tp->is_suspended == 1) {
-+              return;
-+      }
-+
-+      /*
-+       * Unlock the mutex if we are connected again
-+       * after being suspended - now resuming.
-+       * This also removes the suspend state.
-+       */
-+      if (is_connected == 1 && tp->is_suspended == 1) {
-+              tp->is_suspended = 0;
-+              /* unlock, so apps can resume sending */
-+              mutex_unlock(&suspend_lock);
-+      }
-+
-+      if (is_connected != tp->is_connected) {
-+              tp->is_connected = is_connected;
-+              tpmif_notify_upperlayer(tp);
-+      }
-+}
-+
-+
-+
-+/* =================================================================
-+ * Initialization function.
-+ * =================================================================
-+ */
-+
-+
-+static int __init tpmif_init(void)
-+{
-+      long rc = 0;
-+      struct tpm_private *tp;
-+
-+      if (is_initial_xendomain())
-+              return -EPERM;
-+
-+      tp = tpm_private_get();
-+      if (!tp) {
-+              rc = -ENOMEM;
-+              goto failexit;
-+      }
-+
-+      IPRINTK("Initialising the vTPM driver.\n");
-+      if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
-+                                           &gref_head ) < 0) {
-+              rc = -EFAULT;
-+              goto gnttab_alloc_failed;
-+      }
-+
-+      init_tpm_xenbus();
-+      return 0;
-+
-+gnttab_alloc_failed:
-+      tpm_private_put();
-+failexit:
-+
-+      return (int)rc;
-+}
-+
-+
-+void __exit tpmif_exit(void)
-+{
-+      exit_tpm_xenbus();
-+      tpm_private_put();
-+      gnttab_free_grant_references(gref_head);
-+}
-+
-+module_init(tpmif_init);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/char/tty_io.c linux-2.6.16.33/drivers/char/tty_io.c
---- linux-2.6.16.33-noxen/drivers/char/tty_io.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/char/tty_io.c      2007-01-08 15:00:45.000000000 +0000
-@@ -132,6 +132,8 @@
-    vt.c for deeply disgusting hack reasons */
- DECLARE_MUTEX(tty_sem);
-+int console_use_vt = 1;
-+
- #ifdef CONFIG_UNIX98_PTYS
- extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
- extern int pty_limit;         /* Config limit on Unix98 ptys */
-@@ -2054,7 +2056,7 @@
-               goto got_driver;
-       }
- #ifdef CONFIG_VT
--      if (device == MKDEV(TTY_MAJOR,0)) {
-+      if (console_use_vt && (device == MKDEV(TTY_MAJOR,0))) {
-               extern struct tty_driver *console_driver;
-               driver = console_driver;
-               index = fg_console;
-@@ -3245,6 +3247,8 @@
- #endif
- #ifdef CONFIG_VT
-+      if (!console_use_vt)
-+              goto out_vt;
-       cdev_init(&vc0_cdev, &console_fops);
-       if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
-           register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
-@@ -3253,6 +3257,7 @@
-       class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
-       vty_init();
-+ out_vt:
- #endif
-       return 0;
- }
-diff -Nur linux-2.6.16.33-noxen/drivers/firmware/Kconfig linux-2.6.16.33/drivers/firmware/Kconfig
---- linux-2.6.16.33-noxen/drivers/firmware/Kconfig     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/firmware/Kconfig   2007-01-08 15:00:45.000000000 +0000
-@@ -8,7 +8,7 @@
- config EDD
-       tristate "BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
--      depends on !IA64
-+      depends on !IA64 && !XEN
-       help
-         Say Y or M here if you want to enable BIOS Enhanced Disk Drive
-         Services real mode BIOS calls to determine which disk
-diff -Nur linux-2.6.16.33-noxen/drivers/ide/ide-lib.c linux-2.6.16.33/drivers/ide/ide-lib.c
---- linux-2.6.16.33-noxen/drivers/ide/ide-lib.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/ide/ide-lib.c      2007-05-23 21:00:01.000000000 +0000
-@@ -410,10 +410,10 @@
- {
-       u64 addr = BLK_BOUNCE_HIGH;     /* dma64_addr_t */
--      if (!PCI_DMA_BUS_IS_PHYS) {
--              addr = BLK_BOUNCE_ANY;
--      } else if (on && drive->media == ide_disk) {
--              if (HWIF(drive)->pci_dev)
-+      if (on && drive->media == ide_disk) {
-+              if (!PCI_DMA_BUS_IS_PHYS)
-+                      addr = BLK_BOUNCE_ANY;
-+              else if (HWIF(drive)->pci_dev)
-                       addr = HWIF(drive)->pci_dev->dma_mask;
-       }
-diff -Nur linux-2.6.16.33-noxen/drivers/infiniband/ulp/ipoib/ipoib_multicast.c linux-2.6.16.33/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
---- linux-2.6.16.33-noxen/drivers/infiniband/ulp/ipoib/ipoib_multicast.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/infiniband/ulp/ipoib/ipoib_multicast.c     2007-05-23 21:00:01.000000000 +0000
-@@ -821,7 +821,8 @@
-       ipoib_mcast_stop_thread(dev, 0);
--      spin_lock_irqsave(&dev->xmit_lock, flags);
-+      local_irq_save(flags);
-+      netif_tx_lock(dev);
-       spin_lock(&priv->lock);
-       /*
-@@ -896,7 +897,8 @@
-       }
-       spin_unlock(&priv->lock);
--      spin_unlock_irqrestore(&dev->xmit_lock, flags);
-+      netif_tx_unlock(dev);
-+      local_irq_restore(flags);
-       /* We have to cancel outside of the spinlock */
-       list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
-diff -Nur linux-2.6.16.33-noxen/drivers/media/dvb/dvb-core/dvb_net.c linux-2.6.16.33/drivers/media/dvb/dvb-core/dvb_net.c
---- linux-2.6.16.33-noxen/drivers/media/dvb/dvb-core/dvb_net.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/media/dvb/dvb-core/dvb_net.c       2007-05-23 21:00:01.000000000 +0000
-@@ -1053,7 +1053,7 @@
-       dvb_net_feed_stop(dev);
-       priv->rx_mode = RX_MODE_UNI;
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       if (dev->flags & IFF_PROMISC) {
-               dprintk("%s: promiscuous mode\n", dev->name);
-@@ -1078,7 +1078,7 @@
-               }
-       }
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       dvb_net_feed_start(dev);
- }
-diff -Nur linux-2.6.16.33-noxen/drivers/net/8139cp.c linux-2.6.16.33/drivers/net/8139cp.c
---- linux-2.6.16.33-noxen/drivers/net/8139cp.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/8139cp.c       2007-05-23 21:00:01.000000000 +0000
-@@ -794,7 +794,7 @@
-       entry = cp->tx_head;
-       eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
-       if (dev->features & NETIF_F_TSO)
--              mss = skb_shinfo(skb)->tso_size;
-+              mss = skb_shinfo(skb)->gso_size;
-       if (skb_shinfo(skb)->nr_frags == 0) {
-               struct cp_desc *txd = &cp->tx_ring[entry];
-diff -Nur linux-2.6.16.33-noxen/drivers/net/bnx2.c linux-2.6.16.33/drivers/net/bnx2.c
---- linux-2.6.16.33-noxen/drivers/net/bnx2.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/bnx2.c 2007-05-23 21:00:01.000000000 +0000
-@@ -1593,7 +1593,7 @@
-               skb = tx_buf->skb;
- #ifdef BCM_TSO 
-               /* partial BD completions possible with TSO packets */
--              if (skb_shinfo(skb)->tso_size) {
-+              if (skb_is_gso(skb)) {
-                       u16 last_idx, last_ring_idx;
-                       last_idx = sw_cons +
-@@ -1948,7 +1948,7 @@
-       return 1;
- }
--/* Called with rtnl_lock from vlan functions and also dev->xmit_lock
-+/* Called with rtnl_lock from vlan functions and also netif_tx_lock
-  * from set_multicast.
-  */
- static void
-@@ -4403,7 +4403,7 @@
- }
- #endif
--/* Called with dev->xmit_lock.
-+/* Called with netif_tx_lock.
-  * hard_start_xmit is pseudo-lockless - a lock is only required when
-  * the tx queue is full. This way, we get the benefit of lockless
-  * operations most of the time without the complexities to handle
-@@ -4441,7 +4441,7 @@
-                       (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
-       }
- #ifdef BCM_TSO 
--      if ((mss = skb_shinfo(skb)->tso_size) &&
-+      if ((mss = skb_shinfo(skb)->gso_size) &&
-               (skb->len > (bp->dev->mtu + ETH_HLEN))) {
-               u32 tcp_opt_len, ip_tcp_len;
-diff -Nur linux-2.6.16.33-noxen/drivers/net/bonding/bond_main.c linux-2.6.16.33/drivers/net/bonding/bond_main.c
---- linux-2.6.16.33-noxen/drivers/net/bonding/bond_main.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/bonding/bond_main.c    2007-05-23 21:00:01.000000000 +0000
-@@ -1145,8 +1145,7 @@
- }
- #define BOND_INTERSECT_FEATURES \
--      (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
--      NETIF_F_TSO|NETIF_F_UFO)
-+      (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
- /* 
-  * Compute the common dev->feature set available to all slaves.  Some
-@@ -1164,9 +1163,7 @@
-               features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
-       if ((features & NETIF_F_SG) && 
--          !(features & (NETIF_F_IP_CSUM |
--                        NETIF_F_NO_CSUM |
--                        NETIF_F_HW_CSUM)))
-+          !(features & NETIF_F_ALL_CSUM))
-               features &= ~NETIF_F_SG;
-       /* 
-@@ -4147,7 +4144,7 @@
-        */
-       bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
--      /* don't acquire bond device's xmit_lock when 
-+      /* don't acquire bond device's netif_tx_lock when
-        * transmitting */
-       bond_dev->features |= NETIF_F_LLTX;
-diff -Nur linux-2.6.16.33-noxen/drivers/net/chelsio/sge.c linux-2.6.16.33/drivers/net/chelsio/sge.c
---- linux-2.6.16.33-noxen/drivers/net/chelsio/sge.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/chelsio/sge.c  2007-05-23 21:00:01.000000000 +0000
-@@ -1419,7 +1419,7 @@
-       struct cpl_tx_pkt *cpl;
- #ifdef NETIF_F_TSO
--      if (skb_shinfo(skb)->tso_size) {
-+      if (skb_is_gso(skb)) {
-               int eth_type;
-               struct cpl_tx_pkt_lso *hdr;
-@@ -1434,7 +1434,7 @@
-               hdr->ip_hdr_words = skb->nh.iph->ihl;
-               hdr->tcp_hdr_words = skb->h.th->doff;
-               hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
--                                              skb_shinfo(skb)->tso_size));
-+                                              skb_shinfo(skb)->gso_size));
-               hdr->len = htonl(skb->len - sizeof(*hdr));
-               cpl = (struct cpl_tx_pkt *)hdr;
-               sge->stats.tx_lso_pkts++;
-diff -Nur linux-2.6.16.33-noxen/drivers/net/e1000/e1000_main.c linux-2.6.16.33/drivers/net/e1000/e1000_main.c
---- linux-2.6.16.33-noxen/drivers/net/e1000/e1000_main.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/e1000/e1000_main.c     2007-05-23 21:00:01.000000000 +0000
-@@ -2526,7 +2526,7 @@
-       uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
-       int err;
--      if (skb_shinfo(skb)->tso_size) {
-+      if (skb_is_gso(skb)) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (err)
-@@ -2534,7 +2534,7 @@
-               }
-               hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
--              mss = skb_shinfo(skb)->tso_size;
-+              mss = skb_shinfo(skb)->gso_size;
-               if (skb->protocol == ntohs(ETH_P_IP)) {
-                       skb->nh.iph->tot_len = 0;
-                       skb->nh.iph->check = 0;
-@@ -2651,7 +2651,7 @@
-                * tso gets written back prematurely before the data is fully
-                * DMAd to the controller */
-               if (!skb->data_len && tx_ring->last_tx_tso &&
--                              !skb_shinfo(skb)->tso_size) {
-+                  !skb_is_gso(skb)) {
-                       tx_ring->last_tx_tso = 0;
-                       size -= 4;
-               }
-@@ -2893,7 +2893,7 @@
-       }
- #ifdef NETIF_F_TSO
--      mss = skb_shinfo(skb)->tso_size;
-+      mss = skb_shinfo(skb)->gso_size;
-       /* The controller does a simple calculation to 
-        * make sure there is enough room in the FIFO before
-        * initiating the DMA for each buffer.  The calc is:
-@@ -2934,8 +2934,7 @@
- #ifdef NETIF_F_TSO
-       /* Controller Erratum workaround */
--      if (!skb->data_len && tx_ring->last_tx_tso &&
--              !skb_shinfo(skb)->tso_size)
-+      if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
-               count++;
- #endif
-diff -Nur linux-2.6.16.33-noxen/drivers/net/forcedeth.c linux-2.6.16.33/drivers/net/forcedeth.c
---- linux-2.6.16.33-noxen/drivers/net/forcedeth.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/forcedeth.c    2007-05-23 21:00:01.000000000 +0000
-@@ -482,9 +482,9 @@
-  * critical parts:
-  * - rx is (pseudo-) lockless: it relies on the single-threading provided
-  *    by the arch code for interrupts.
-- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
-+ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission
-  *    needs dev->priv->lock :-(
-- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
-+ * - set_multicast_list: preparation lockless, relies on netif_tx_lock.
-  */
- /* in dev: base, irq */
-@@ -1016,7 +1016,7 @@
- /*
-  * nv_start_xmit: dev->hard_start_xmit function
-- * Called with dev->xmit_lock held.
-+ * Called with netif_tx_lock held.
-  */
- static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
- {
-@@ -1105,8 +1105,8 @@
-       np->tx_skbuff[nr] = skb;
- #ifdef NETIF_F_TSO
--      if (skb_shinfo(skb)->tso_size)
--              tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
-+      if (skb_is_gso(skb))
-+              tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT);
-       else
- #endif
-       tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
-@@ -1203,7 +1203,7 @@
- /*
-  * nv_tx_timeout: dev->tx_timeout function
-- * Called with dev->xmit_lock held.
-+ * Called with netif_tx_lock held.
-  */
- static void nv_tx_timeout(struct net_device *dev)
- {
-@@ -1524,7 +1524,7 @@
-                * Changing the MTU is a rare event, it shouldn't matter.
-                */
-               disable_irq(dev->irq);
--              spin_lock_bh(&dev->xmit_lock);
-+              netif_tx_lock_bh(dev);
-               spin_lock(&np->lock);
-               /* stop engines */
-               nv_stop_rx(dev);
-@@ -1559,7 +1559,7 @@
-               nv_start_rx(dev);
-               nv_start_tx(dev);
-               spin_unlock(&np->lock);
--              spin_unlock_bh(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
-               enable_irq(dev->irq);
-       }
-       return 0;
-@@ -1594,7 +1594,7 @@
-       memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
-       if (netif_running(dev)) {
--              spin_lock_bh(&dev->xmit_lock);
-+              netif_tx_lock_bh(dev);
-               spin_lock_irq(&np->lock);
-               /* stop rx engine */
-@@ -1606,7 +1606,7 @@
-               /* restart rx engine */
-               nv_start_rx(dev);
-               spin_unlock_irq(&np->lock);
--              spin_unlock_bh(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
-       } else {
-               nv_copy_mac_to_hw(dev);
-       }
-@@ -1615,7 +1615,7 @@
- /*
-  * nv_set_multicast: dev->set_multicast function
-- * Called with dev->xmit_lock held.
-+ * Called with netif_tx_lock held.
-  */
- static void nv_set_multicast(struct net_device *dev)
- {
-diff -Nur linux-2.6.16.33-noxen/drivers/net/hamradio/6pack.c linux-2.6.16.33/drivers/net/hamradio/6pack.c
---- linux-2.6.16.33-noxen/drivers/net/hamradio/6pack.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/hamradio/6pack.c       2007-05-23 21:00:01.000000000 +0000
-@@ -308,9 +308,9 @@
- {
-       struct sockaddr_ax25 *sa = addr;
--      spin_lock_irq(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
--      spin_unlock_irq(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       return 0;
- }
-@@ -767,9 +767,9 @@
-                       break;
-               }
--              spin_lock_irq(&dev->xmit_lock);
-+              netif_tx_lock_bh(dev);
-               memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
--              spin_unlock_irq(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
-               err = 0;
-               break;
-diff -Nur linux-2.6.16.33-noxen/drivers/net/hamradio/mkiss.c linux-2.6.16.33/drivers/net/hamradio/mkiss.c
---- linux-2.6.16.33-noxen/drivers/net/hamradio/mkiss.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/hamradio/mkiss.c       2007-05-23 21:00:01.000000000 +0000
-@@ -357,9 +357,9 @@
- {
-       struct sockaddr_ax25 *sa = addr;
--      spin_lock_irq(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
--      spin_unlock_irq(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       return 0;
- }
-@@ -886,9 +886,9 @@
-                       break;
-               }
--              spin_lock_irq(&dev->xmit_lock);
-+              netif_tx_lock_bh(dev);
-               memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
--              spin_unlock_irq(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
-               err = 0;
-               break;
-diff -Nur linux-2.6.16.33-noxen/drivers/net/ifb.c linux-2.6.16.33/drivers/net/ifb.c
---- linux-2.6.16.33-noxen/drivers/net/ifb.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/ifb.c  2007-05-23 21:00:01.000000000 +0000
-@@ -76,13 +76,13 @@
-       dp->st_task_enter++;
-       if ((skb = skb_peek(&dp->tq)) == NULL) {
-               dp->st_txq_refl_try++;
--              if (spin_trylock(&_dev->xmit_lock)) {
-+              if (netif_tx_trylock(_dev)) {
-                       dp->st_rxq_enter++;
-                       while ((skb = skb_dequeue(&dp->rq)) != NULL) {
-                               skb_queue_tail(&dp->tq, skb);
-                               dp->st_rx2tx_tran++;
-                       }
--                      spin_unlock(&_dev->xmit_lock);
-+                      netif_tx_unlock(_dev);
-               } else {
-                       /* reschedule */
-                       dp->st_rxq_notenter++;
-@@ -110,7 +110,7 @@
-               }
-       }
--      if (spin_trylock(&_dev->xmit_lock)) {
-+      if (netif_tx_trylock(_dev)) {
-               dp->st_rxq_check++;
-               if ((skb = skb_peek(&dp->rq)) == NULL) {
-                       dp->tasklet_pending = 0;
-@@ -118,10 +118,10 @@
-                               netif_wake_queue(_dev);
-               } else {
-                       dp->st_rxq_rsch++;
--                      spin_unlock(&_dev->xmit_lock);
-+                      netif_tx_unlock(_dev);
-                       goto resched;
-               }
--              spin_unlock(&_dev->xmit_lock);
-+              netif_tx_unlock(_dev);
-       } else {
- resched:
-               dp->tasklet_pending = 1;
-diff -Nur linux-2.6.16.33-noxen/drivers/net/irda/vlsi_ir.c linux-2.6.16.33/drivers/net/irda/vlsi_ir.c
---- linux-2.6.16.33-noxen/drivers/net/irda/vlsi_ir.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/irda/vlsi_ir.c 2007-05-23 21:00:01.000000000 +0000
-@@ -959,7 +959,7 @@
-                           ||  (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec))
-                               break;
-                       udelay(100);
--                      /* must not sleep here - we are called under xmit_lock! */
-+                      /* must not sleep here - called under netif_tx_lock! */
-               }
-       }
-diff -Nur linux-2.6.16.33-noxen/drivers/net/ixgb/ixgb_main.c linux-2.6.16.33/drivers/net/ixgb/ixgb_main.c
---- linux-2.6.16.33-noxen/drivers/net/ixgb/ixgb_main.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/ixgb/ixgb_main.c       2007-05-23 21:00:01.000000000 +0000
-@@ -1163,7 +1163,7 @@
-       uint16_t ipcse, tucse, mss;
-       int err;
--      if(likely(skb_shinfo(skb)->tso_size)) {
-+      if (likely(skb_is_gso(skb))) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (err)
-@@ -1171,7 +1171,7 @@
-               }
-               hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
--              mss = skb_shinfo(skb)->tso_size;
-+              mss = skb_shinfo(skb)->gso_size;
-               skb->nh.iph->tot_len = 0;
-               skb->nh.iph->check = 0;
-               skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
-diff -Nur linux-2.6.16.33-noxen/drivers/net/loopback.c linux-2.6.16.33/drivers/net/loopback.c
---- linux-2.6.16.33-noxen/drivers/net/loopback.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/loopback.c     2007-05-23 21:00:01.000000000 +0000
-@@ -74,7 +74,7 @@
-       struct iphdr *iph = skb->nh.iph;
-       struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
-       unsigned int doffset = (iph->ihl + th->doff) * 4;
--      unsigned int mtu = skb_shinfo(skb)->tso_size + doffset;
-+      unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
-       unsigned int offset = 0;
-       u32 seq = ntohl(th->seq);
-       u16 id  = ntohs(iph->id);
-@@ -139,7 +139,7 @@
- #endif
- #ifdef LOOPBACK_TSO
--      if (skb_shinfo(skb)->tso_size) {
-+      if (skb_is_gso(skb)) {
-               BUG_ON(skb->protocol != htons(ETH_P_IP));
-               BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
-diff -Nur linux-2.6.16.33-noxen/drivers/net/mv643xx_eth.c linux-2.6.16.33/drivers/net/mv643xx_eth.c
---- linux-2.6.16.33-noxen/drivers/net/mv643xx_eth.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/mv643xx_eth.c  2007-05-23 21:00:01.000000000 +0000
-@@ -1107,7 +1107,7 @@
- #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
-       if (has_tiny_unaligned_frags(skb)) {
--              if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
-+              if (__skb_linearize(skb)) {
-                       stats->tx_dropped++;
-                       printk(KERN_DEBUG "%s: failed to linearize tiny "
-                                       "unaligned fragment\n", dev->name);
-diff -Nur linux-2.6.16.33-noxen/drivers/net/natsemi.c linux-2.6.16.33/drivers/net/natsemi.c
---- linux-2.6.16.33-noxen/drivers/net/natsemi.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/natsemi.c      2007-05-23 21:00:01.000000000 +0000
-@@ -323,12 +323,12 @@
- The rx process only runs in the interrupt handler. Access from outside
- the interrupt handler is only permitted after disable_irq().
--The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap
-+The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap
- is set, then access is permitted under spin_lock_irq(&np->lock).
- Thus configuration functions that want to access everything must call
-       disable_irq(dev->irq);
--      spin_lock_bh(dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       spin_lock_irq(&np->lock);
- IV. Notes
-diff -Nur linux-2.6.16.33-noxen/drivers/net/r8169.c linux-2.6.16.33/drivers/net/r8169.c
---- linux-2.6.16.33-noxen/drivers/net/r8169.c  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/r8169.c        2007-05-23 21:00:01.000000000 +0000
-@@ -2171,7 +2171,7 @@
- static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
- {
-       if (dev->features & NETIF_F_TSO) {
--              u32 mss = skb_shinfo(skb)->tso_size;
-+              u32 mss = skb_shinfo(skb)->gso_size;
-               if (mss)
-                       return LargeSend | ((mss & MSSMask) << MSSShift);
-diff -Nur linux-2.6.16.33-noxen/drivers/net/s2io.c linux-2.6.16.33/drivers/net/s2io.c
---- linux-2.6.16.33-noxen/drivers/net/s2io.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/s2io.c 2007-05-23 21:00:01.000000000 +0000
-@@ -3522,8 +3522,8 @@
-       txdp->Control_1 = 0;
-       txdp->Control_2 = 0;
- #ifdef NETIF_F_TSO
--      mss = skb_shinfo(skb)->tso_size;
--      if (mss) {
-+      mss = skb_shinfo(skb)->gso_size;
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) {
-               txdp->Control_1 |= TXD_TCP_LSO_EN;
-               txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
-       }
-@@ -3543,10 +3543,10 @@
-       }
-       frg_len = skb->len - skb->data_len;
--      if (skb_shinfo(skb)->ufo_size) {
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) {
-               int ufo_size;
--              ufo_size = skb_shinfo(skb)->ufo_size;
-+              ufo_size = skb_shinfo(skb)->gso_size;
-               ufo_size &= ~7;
-               txdp->Control_1 |= TXD_UFO_EN;
-               txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
-@@ -3572,7 +3572,7 @@
-       txdp->Host_Control = (unsigned long) skb;
-       txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
--      if (skb_shinfo(skb)->ufo_size)
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
-               txdp->Control_1 |= TXD_UFO_EN;
-       frg_cnt = skb_shinfo(skb)->nr_frags;
-@@ -3587,12 +3587,12 @@
-                   (sp->pdev, frag->page, frag->page_offset,
-                    frag->size, PCI_DMA_TODEVICE);
-               txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
--              if (skb_shinfo(skb)->ufo_size)
-+              if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
-                       txdp->Control_1 |= TXD_UFO_EN;
-       }
-       txdp->Control_1 |= TXD_GATHER_CODE_LAST;
--      if (skb_shinfo(skb)->ufo_size)
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
-               frg_cnt++; /* as Txd0 was used for inband header */
-       tx_fifo = mac_control->tx_FIFO_start[queue];
-@@ -3606,7 +3606,7 @@
-       if (mss)
-               val64 |= TX_FIFO_SPECIAL_FUNC;
- #endif
--      if (skb_shinfo(skb)->ufo_size)
-+      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
-               val64 |= TX_FIFO_SPECIAL_FUNC;
-       writeq(val64, &tx_fifo->List_Control);
-diff -Nur linux-2.6.16.33-noxen/drivers/net/sky2.c linux-2.6.16.33/drivers/net/sky2.c
---- linux-2.6.16.33-noxen/drivers/net/sky2.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/sky2.c 2007-05-23 21:00:01.000000000 +0000
-@@ -1141,7 +1141,7 @@
-       count = sizeof(dma_addr_t) / sizeof(u32);
-       count += skb_shinfo(skb)->nr_frags * count;
--      if (skb_shinfo(skb)->tso_size)
-+      if (skb_is_gso(skb))
-               ++count;
-       if (skb->ip_summed == CHECKSUM_HW)
-@@ -1213,7 +1213,7 @@
-       }
-       /* Check for TCP Segmentation Offload */
--      mss = skb_shinfo(skb)->tso_size;
-+      mss = skb_shinfo(skb)->gso_size;
-       if (mss != 0) {
-               /* just drop the packet if non-linear expansion fails */
-               if (skb_header_cloned(skb) &&
-diff -Nur linux-2.6.16.33-noxen/drivers/net/sky2.c~ linux-2.6.16.33/drivers/net/sky2.c~
---- linux-2.6.16.33-noxen/drivers/net/sky2.c~  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/sky2.c~        2007-05-23 21:00:01.000000000 +0000
-@@ -0,0 +1,3425 @@
-+/*
-+ * New driver for Marvell Yukon 2 chipset.
-+ * Based on earlier sk98lin, and skge driver.
-+ *
-+ * This driver intentionally does not support all the features
-+ * of the original driver such as link fail-over and link management because
-+ * those should be done at higher levels.
-+ *
-+ * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/crc32.h>
-+#include <linux/kernel.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/netdevice.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ethtool.h>
-+#include <linux/pci.h>
-+#include <linux/ip.h>
-+#include <linux/tcp.h>
-+#include <linux/in.h>
-+#include <linux/delay.h>
-+#include <linux/workqueue.h>
-+#include <linux/if_vlan.h>
-+#include <linux/prefetch.h>
-+#include <linux/mii.h>
-+
-+#include <asm/irq.h>
-+
-+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-+#define SKY2_VLAN_TAG_USED 1
-+#endif
-+
-+#include "sky2.h"
-+
-+#define DRV_NAME              "sky2"
-+#define DRV_VERSION           "0.15"
-+#define PFX                   DRV_NAME " "
-+
-+/*
-+ * The Yukon II chipset takes 64 bit command blocks (called list elements)
-+ * that are organized into three (receive, transmit, status) different rings
-+ * similar to Tigon3. A transmit can require several elements;
-+ * a receive requires one (or two if using 64 bit dma).
-+ */
-+
-+#define is_ec_a1(hw) \
-+      unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \
-+               (hw)->chip_rev == CHIP_REV_YU_EC_A1)
-+
-+#define RX_LE_SIZE            512
-+#define RX_LE_BYTES           (RX_LE_SIZE*sizeof(struct sky2_rx_le))
-+#define RX_MAX_PENDING                (RX_LE_SIZE/2 - 2)
-+#define RX_DEF_PENDING                RX_MAX_PENDING
-+#define RX_SKB_ALIGN          8
-+
-+#define TX_RING_SIZE          512
-+#define TX_DEF_PENDING                (TX_RING_SIZE - 1)
-+#define TX_MIN_PENDING                64
-+#define MAX_SKB_TX_LE         (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS)
-+
-+#define STATUS_RING_SIZE      2048    /* 2 ports * (TX + 2*RX) */
-+#define STATUS_LE_BYTES               (STATUS_RING_SIZE*sizeof(struct sky2_status_le))
-+#define ETH_JUMBO_MTU         9000
-+#define TX_WATCHDOG           (5 * HZ)
-+#define NAPI_WEIGHT           64
-+#define PHY_RETRIES           1000
-+
-+static const u32 default_msg =
-+    NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
-+    | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
-+    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
-+
-+static int debug = -1;                /* defaults above */
-+module_param(debug, int, 0);
-+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
-+
-+static int copybreak __read_mostly = 256;
-+module_param(copybreak, int, 0);
-+MODULE_PARM_DESC(copybreak, "Receive copy threshold");
-+
-+static const struct pci_device_id sky2_id_table[] = {
-+      { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) },
-+      { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) },
-+      { 0 }
-+};
-+
-+MODULE_DEVICE_TABLE(pci, sky2_id_table);
-+
-+/* Avoid conditionals by using array */
-+static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
-+static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
-+
-+/* This driver supports yukon2 chipset only */
-+static const char *yukon2_name[] = {
-+      "XL",           /* 0xb3 */
-+      "EC Ultra",     /* 0xb4 */
-+      "UNKNOWN",      /* 0xb5 */
-+      "EC",           /* 0xb6 */
-+      "FE",           /* 0xb7 */
-+};
-+
-+/* Access to external PHY */
-+static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
-+{
-+      int i;
-+
-+      gma_write16(hw, port, GM_SMI_DATA, val);
-+      gma_write16(hw, port, GM_SMI_CTRL,
-+                  GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
-+
-+      for (i = 0; i < PHY_RETRIES; i++) {
-+              if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
-+                      return 0;
-+              udelay(1);
-+      }
-+
-+      printk(KERN_WARNING PFX "%s: phy write timeout\n", hw->dev[port]->name);
-+      return -ETIMEDOUT;
-+}
-+
-+static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
-+{
-+      int i;
-+
-+      gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV)
-+                  | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
-+
-+      for (i = 0; i < PHY_RETRIES; i++) {
-+              if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) {
-+                      *val = gma_read16(hw, port, GM_SMI_DATA);
-+                      return 0;
-+              }
-+
-+              udelay(1);
-+      }
-+
-+      return -ETIMEDOUT;
-+}
-+
-+static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
-+{
-+      u16 v;
-+
-+      if (__gm_phy_read(hw, port, reg, &v) != 0)
-+              printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
-+      return v;
-+}
-+
-+static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
-+{
-+      u16 power_control;
-+      u32 reg1;
-+      int vaux;
-+      int ret = 0;
-+
-+      pr_debug("sky2_set_power_state %d\n", state);
-+      sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-+
-+      power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_PMC);
-+      vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
-+              (power_control & PCI_PM_CAP_PME_D3cold);
-+
-+      power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL);
-+
-+      power_control |= PCI_PM_CTRL_PME_STATUS;
-+      power_control &= ~(PCI_PM_CTRL_STATE_MASK);
-+
-+      switch (state) {
-+      case PCI_D0:
-+              /* switch power to VCC (WA for VAUX problem) */
-+              sky2_write8(hw, B0_POWER_CTRL,
-+                          PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
-+
-+              /* disable Core Clock Division, */
-+              sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
-+
-+              if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
-+                      /* enable bits are inverted */
-+                      sky2_write8(hw, B2_Y2_CLK_GATE,
-+                                  Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
-+                                  Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
-+                                  Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
-+              else
-+                      sky2_write8(hw, B2_Y2_CLK_GATE, 0);
-+
-+              /* Turn off phy power saving */
-+              reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
-+              reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
-+
-+              /* looks like this XL is back asswards .. */
-+              if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) {
-+                      reg1 |= PCI_Y2_PHY1_COMA;
-+                      if (hw->ports > 1)
-+                              reg1 |= PCI_Y2_PHY2_COMA;
-+              }
-+
-+              if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
-+                      sky2_pci_write32(hw, PCI_DEV_REG3, 0);
-+                      reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
-+                      reg1 &= P_ASPM_CONTROL_MSK;
-+                      sky2_pci_write32(hw, PCI_DEV_REG4, reg1);
-+                      sky2_pci_write32(hw, PCI_DEV_REG5, 0);
-+              }
-+
-+              sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-+
-+              break;
-+
-+      case PCI_D3hot:
-+      case PCI_D3cold:
-+              /* Turn on phy power saving */
-+              reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
-+              if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
-+                      reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
-+              else
-+                      reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
-+              sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-+
-+              if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
-+                      sky2_write8(hw, B2_Y2_CLK_GATE, 0);
-+              else
-+                      /* enable bits are inverted */
-+                      sky2_write8(hw, B2_Y2_CLK_GATE,
-+                                  Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
-+                                  Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
-+                                  Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
-+
-+              /* switch power to VAUX */
-+              if (vaux && state != PCI_D3cold)
-+                      sky2_write8(hw, B0_POWER_CTRL,
-+                                  (PC_VAUX_ENA | PC_VCC_ENA |
-+                                   PC_VAUX_ON | PC_VCC_OFF));
-+              break;
-+      default:
-+              printk(KERN_ERR PFX "Unknown power state %d\n", state);
-+              ret = -1;
-+      }
-+
-+      sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control);
-+      sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-+      return ret;
-+}
-+
-+static void sky2_phy_reset(struct sky2_hw *hw, unsigned port)
-+{
-+      u16 reg;
-+
-+      /* disable all GMAC IRQ's */
-+      sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
-+      /* disable PHY IRQs */
-+      gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
-+
-+      gma_write16(hw, port, GM_MC_ADDR_H1, 0);        /* clear MC hash */
-+      gma_write16(hw, port, GM_MC_ADDR_H2, 0);
-+      gma_write16(hw, port, GM_MC_ADDR_H3, 0);
-+      gma_write16(hw, port, GM_MC_ADDR_H4, 0);
-+
-+      reg = gma_read16(hw, port, GM_RX_CTRL);
-+      reg |= GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA;
-+      gma_write16(hw, port, GM_RX_CTRL, reg);
-+}
-+
-+static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
-+{
-+      struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
-+      u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
-+
-+      if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) {
-+              u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
-+
-+              ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
-+                         PHY_M_EC_MAC_S_MSK);
-+              ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
-+
-+              if (hw->chip_id == CHIP_ID_YUKON_EC)
-+                      ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
-+              else
-+                      ectrl |= PHY_M_EC_M_DSC(2) | PHY_M_EC_S_DSC(3);
-+
-+              gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
-+      }
-+
-+      ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
-+      if (sky2_is_copper(hw)) {
-+              if (hw->chip_id == CHIP_ID_YUKON_FE) {
-+                      /* enable automatic crossover */
-+                      ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
-+              } else {
-+                      /* disable energy detect */
-+                      ctrl &= ~PHY_M_PC_EN_DET_MSK;
-+
-+                      /* enable automatic crossover */
-+                      ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
-+
-+                      if (sky2->autoneg == AUTONEG_ENABLE &&
-+                          hw->chip_id == CHIP_ID_YUKON_XL) {
-+                              ctrl &= ~PHY_M_PC_DSC_MSK;
-+                              ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
-+                      }
-+              }
-+      } else {
-+              /* workaround for deviation #4.88 (CRC errors) */
-+              /* disable Automatic Crossover */
-+
-+              ctrl &= ~PHY_M_PC_MDIX_MSK;
-+      }
-+
-+      gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
-+
-+      /* special setup for PHY 88E1112 Fiber */
-+      if (hw->chip_id == CHIP_ID_YUKON_XL && !sky2_is_copper(hw)) {
-+              pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
-+
-+              /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
-+              ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
-+              ctrl &= ~PHY_M_MAC_MD_MSK;
-+              ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
-+              gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
-+
-+              if (hw->pmd_type  == 'P') {
-+                      /* select page 1 to access Fiber registers */
-+                      gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
-+
-+                      /* for SFP-module set SIGDET polarity to low */
-+                      ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
-+                      ctrl |= PHY_M_FIB_SIGD_POL;
-+                      gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
-+              }
-+
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
-+      }
-+
-+      ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
-+      if (sky2->autoneg == AUTONEG_DISABLE)
-+              ctrl &= ~PHY_CT_ANE;
-+      else
-+              ctrl |= PHY_CT_ANE;
-+
-+      ctrl |= PHY_CT_RESET;
-+      gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
-+
-+      ctrl = 0;
-+      ct1000 = 0;
-+      adv = PHY_AN_CSMA;
-+
-+      if (sky2->autoneg == AUTONEG_ENABLE) {
-+              if (sky2_is_copper(hw)) {
-+                      if (sky2->advertising & ADVERTISED_1000baseT_Full)
-+                              ct1000 |= PHY_M_1000C_AFD;
-+                      if (sky2->advertising & ADVERTISED_1000baseT_Half)
-+                              ct1000 |= PHY_M_1000C_AHD;
-+                      if (sky2->advertising & ADVERTISED_100baseT_Full)
-+                              adv |= PHY_M_AN_100_FD;
-+                      if (sky2->advertising & ADVERTISED_100baseT_Half)
-+                              adv |= PHY_M_AN_100_HD;
-+                      if (sky2->advertising & ADVERTISED_10baseT_Full)
-+                              adv |= PHY_M_AN_10_FD;
-+                      if (sky2->advertising & ADVERTISED_10baseT_Half)
-+                              adv |= PHY_M_AN_10_HD;
-+              } else {        /* special defines for FIBER (88E1040S only) */
-+                      if (sky2->advertising & ADVERTISED_1000baseT_Full)
-+                              adv |= PHY_M_AN_1000X_AFD;
-+                      if (sky2->advertising & ADVERTISED_1000baseT_Half)
-+                              adv |= PHY_M_AN_1000X_AHD;
-+              }
-+
-+              /* Set Flow-control capabilities */
-+              if (sky2->tx_pause && sky2->rx_pause)
-+                      adv |= PHY_AN_PAUSE_CAP;        /* symmetric */
-+              else if (sky2->rx_pause && !sky2->tx_pause)
-+                      adv |= PHY_AN_PAUSE_ASYM | PHY_AN_PAUSE_CAP;
-+              else if (!sky2->rx_pause && sky2->tx_pause)
-+                      adv |= PHY_AN_PAUSE_ASYM;       /* local */
-+
-+              /* Restart Auto-negotiation */
-+              ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
-+      } else {
-+              /* forced speed/duplex settings */
-+              ct1000 = PHY_M_1000C_MSE;
-+
-+              if (sky2->duplex == DUPLEX_FULL)
-+                      ctrl |= PHY_CT_DUP_MD;
-+
-+              switch (sky2->speed) {
-+              case SPEED_1000:
-+                      ctrl |= PHY_CT_SP1000;
-+                      break;
-+              case SPEED_100:
-+                      ctrl |= PHY_CT_SP100;
-+                      break;
-+              }
-+
-+              ctrl |= PHY_CT_RESET;
-+      }
-+
-+      if (hw->chip_id != CHIP_ID_YUKON_FE)
-+              gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
-+
-+      gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
-+      gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
-+
-+      /* Setup Phy LED's */
-+      ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
-+      ledover = 0;
-+
-+      switch (hw->chip_id) {
-+      case CHIP_ID_YUKON_FE:
-+              /* on 88E3082 these bits are at 11..9 (shifted left) */
-+              ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
-+
-+              ctrl = gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR);
-+
-+              /* delete ACT LED control bits */
-+              ctrl &= ~PHY_M_FELP_LED1_MSK;
-+              /* change ACT LED control to blink mode */
-+              ctrl |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
-+              gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
-+              break;
-+
-+      case CHIP_ID_YUKON_XL:
-+              pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
-+
-+              /* select page 3 to access LED control register */
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
-+
-+              /* set LED Function Control register */
-+              gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) |     /* LINK/ACT */
-+                                                         PHY_M_LEDC_INIT_CTRL(7) |    /* 10 Mbps */
-+                                                         PHY_M_LEDC_STA1_CTRL(7) |    /* 100 Mbps */
-+                                                         PHY_M_LEDC_STA0_CTRL(7)));   /* 1000 Mbps */
-+
-+              /* set Polarity Control register */
-+              gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
-+                           (PHY_M_POLC_LS1_P_MIX(4) |
-+                            PHY_M_POLC_IS0_P_MIX(4) |
-+                            PHY_M_POLC_LOS_CTRL(2) |
-+                            PHY_M_POLC_INIT_CTRL(2) |
-+                            PHY_M_POLC_STA1_CTRL(2) |
-+                            PHY_M_POLC_STA0_CTRL(2)));
-+
-+              /* restore page register */
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
-+              break;
-+
-+      default:
-+              /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
-+              ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
-+              /* turn off the Rx LED (LED_RX) */
-+              ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
-+      }
-+
-+      if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) {
-+              /* apply fixes in PHY AFE */
-+              gm_phy_write(hw, port, 22, 255);
-+              /* increase differential signal amplitude in 10BASE-T */
-+              gm_phy_write(hw, port, 24, 0xaa99);
-+              gm_phy_write(hw, port, 23, 0x2011);
-+
-+              /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
-+              gm_phy_write(hw, port, 24, 0xa204);
-+              gm_phy_write(hw, port, 23, 0x2002);
-+
-+              /* set page register to 0 */
-+              gm_phy_write(hw, port, 22, 0);
-+      } else {
-+              gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
-+
-+              if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
-+                      /* turn on 100 Mbps LED (LED_LINK100) */
-+                      ledover |= PHY_M_LED_MO_100(MO_LED_ON);
-+              }
-+
-+              if (ledover)
-+                      gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
-+
-+      }
-+      /* Enable phy interrupt on auto-negotiation complete (or link up) */
-+      if (sky2->autoneg == AUTONEG_ENABLE)
-+              gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
-+      else
-+              gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
-+}
-+
-+/* Force a renegotiation */
-+static void sky2_phy_reinit(struct sky2_port *sky2)
-+{
-+      down(&sky2->phy_sema);
-+      sky2_phy_init(sky2->hw, sky2->port);
-+      up(&sky2->phy_sema);
-+}
-+
-+static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
-+{
-+      struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
-+      u16 reg;
-+      int i;
-+      const u8 *addr = hw->dev[port]->dev_addr;
-+
-+      sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
-+      sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE);
-+
-+      sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
-+
-+      if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 && port == 1) {
-+              /* WA DEV_472 -- looks like crossed wires on port 2 */
-+              /* clear GMAC 1 Control reset */
-+              sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR);
-+              do {
-+                      sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
-+                      sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
-+              } while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
-+                       gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
-+                       gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
-+      }
-+
-+      if (sky2->autoneg == AUTONEG_DISABLE) {
-+              reg = gma_read16(hw, port, GM_GP_CTRL);
-+              reg |= GM_GPCR_AU_ALL_DIS;
-+              gma_write16(hw, port, GM_GP_CTRL, reg);
-+              gma_read16(hw, port, GM_GP_CTRL);
-+
-+              switch (sky2->speed) {
-+              case SPEED_1000:
-+                      reg &= ~GM_GPCR_SPEED_100;
-+                      reg |= GM_GPCR_SPEED_1000;
-+                      break;
-+              case SPEED_100:
-+                      reg &= ~GM_GPCR_SPEED_1000;
-+                      reg |= GM_GPCR_SPEED_100;
-+                      break;
-+              case SPEED_10:
-+                      reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
-+                      break;
-+              }
-+
-+              if (sky2->duplex == DUPLEX_FULL)
-+                      reg |= GM_GPCR_DUP_FULL;
-+      } else
-+              reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
-+
-+      if (!sky2->tx_pause && !sky2->rx_pause) {
-+              sky2_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
-+              reg |=
-+                  GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
-+      } else if (sky2->tx_pause && !sky2->rx_pause) {
-+              /* disable Rx flow-control */
-+              reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
-+      }
-+
-+      gma_write16(hw, port, GM_GP_CTRL, reg);
-+
-+      sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
-+
-+      down(&sky2->phy_sema);
-+      sky2_phy_init(hw, port);
-+      up(&sky2->phy_sema);
-+
-+      /* MIB clear */
-+      reg = gma_read16(hw, port, GM_PHY_ADDR);
-+      gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
-+
-+      for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4)
-+              gma_read16(hw, port, i);
-+      gma_write16(hw, port, GM_PHY_ADDR, reg);
-+
-+      /* transmit control */
-+      gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
-+
-+      /* receive control reg: unicast + multicast + no FCS  */
-+      gma_write16(hw, port, GM_RX_CTRL,
-+                  GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
-+
-+      /* transmit flow control */
-+      gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
-+
-+      /* transmit parameter */
-+      gma_write16(hw, port, GM_TX_PARAM,
-+                  TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
-+                  TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
-+                  TX_IPG_JAM_DATA(TX_IPG_JAM_DEF) |
-+                  TX_BACK_OFF_LIM(TX_BOF_LIM_DEF));
-+
-+      /* serial mode register */
-+      reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
-+              GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
-+
-+      if (hw->dev[port]->mtu > ETH_DATA_LEN)
-+              reg |= GM_SMOD_JUMBO_ENA;
-+
-+      gma_write16(hw, port, GM_SERIAL_MODE, reg);
-+
-+      /* virtual address for data */
-+      gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
-+
-+      /* physical address: used for pause frames */
-+      gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
-+
-+      /* ignore counter overflows */
-+      gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
-+      gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
-+      gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
-+
-+      /* Configure Rx MAC FIFO */
-+      sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
-+      sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
-+                   GMF_OPER_ON | GMF_RX_F_FL_ON);
-+
-+      /* Flush Rx MAC FIFO on any flow control or error */
-+      sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
-+
-+      /* Set threshold to 0xa (64 bytes)
-+       *  ASF disabled so no need to do WA dev #4.30
-+       */
-+      sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
-+
-+      /* Configure Tx MAC FIFO */
-+      sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
-+      sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
-+
-+      if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
-+              sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
-+              sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
-+              if (hw->dev[port]->mtu > ETH_DATA_LEN) {
-+                      /* set Tx GMAC FIFO Almost Empty Threshold */
-+                      sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), 0x180);
-+                      /* Disable Store & Forward mode for TX */
-+                      sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
-+              }
-+      }
-+
-+}
-+
-+/* Assign Ram Buffer allocation.
-+ * start and end are in units of 4k bytes
-+ * ram registers are in units of 64bit words
-+ */
-+static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
-+{
-+      u32 start, end;
-+
-+      start = startk * 4096/8;
-+      end = (endk * 4096/8) - 1;
-+
-+      sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
-+      sky2_write32(hw, RB_ADDR(q, RB_START), start);
-+      sky2_write32(hw, RB_ADDR(q, RB_END), end);
-+      sky2_write32(hw, RB_ADDR(q, RB_WP), start);
-+      sky2_write32(hw, RB_ADDR(q, RB_RP), start);
-+
-+      if (q == Q_R1 || q == Q_R2) {
-+              u32 space = (endk - startk) * 4096/8;
-+              u32 tp = space - space/4;
-+
-+              /* On receive queue's set the thresholds
-+               * give receiver priority when > 3/4 full
-+               * send pause when down to 2K
-+               */
-+              sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
-+              sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
-+
-+              tp = space - 2048/8;
-+              sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
-+              sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
-+      } else {
-+              /* Enable store & forward on Tx queue's because
-+               * Tx FIFO is only 1K on Yukon
-+               */
-+              sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
-+      }
-+
-+      sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
-+      sky2_read8(hw, RB_ADDR(q, RB_CTRL));
-+}
-+
-+/* Setup Bus Memory Interface */
-+static void sky2_qset(struct sky2_hw *hw, u16 q)
-+{
-+      sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_RESET);
-+      sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_OPER_INIT);
-+      sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_FIFO_OP_ON);
-+      sky2_write32(hw, Q_ADDR(q, Q_WM),  BMU_WM_DEFAULT);
-+}
-+
-+/* Setup prefetch unit registers. This is the interface between
-+ * hardware and driver list elements
-+ */
-+static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
-+                                    u64 addr, u32 last)
-+{
-+      sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
-+      sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
-+      sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), addr >> 32);
-+      sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), (u32) addr);
-+      sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
-+      sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
-+
-+      sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
-+}
-+
-+static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
-+{
-+      struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
-+
-+      sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE;
-+      return le;
-+}
-+
-+/*
-+ * This is a workaround code taken from SysKonnect sk98lin driver
-+ * to deal with chip bug on Yukon EC rev 0 in the wraparound case.
-+ */
-+static void sky2_put_idx(struct sky2_hw *hw, unsigned q,
-+                              u16 idx, u16 *last, u16 size)
-+{
-+      wmb();
-+      if (is_ec_a1(hw) && idx < *last) {
-+              u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
-+
-+              if (hwget == 0) {
-+                      /* Start prefetching again */
-+                      sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0);
-+                      goto setnew;
-+              }
-+
-+              if (hwget == size - 1) {
-+                      /* set watermark to one list element */
-+                      sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8);
-+
-+                      /* set put index to first list element */
-+                      sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0);
-+              } else          /* have hardware go to end of list */
-+                      sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX),
-+                                   size - 1);
-+      } else {
-+setnew:
-+              sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
-+      }
-+      *last = idx;
-+      mmiowb();
-+}
-+
-+
-+static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
-+{
-+      struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
-+      sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE;
-+      return le;
-+}
-+
-+/* Return high part of DMA address (could be 32 or 64 bit) */
-+static inline u32 high32(dma_addr_t a)
-+{
-+      return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
-+}
-+
-+/* Build description to hardware about buffer */
-+static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
-+{
-+      struct sky2_rx_le *le;
-+      u32 hi = high32(map);
-+      u16 len = sky2->rx_bufsize;
-+
-+      if (sky2->rx_addr64 != hi) {
-+              le = sky2_next_rx(sky2);
-+              le->addr = cpu_to_le32(hi);
-+              le->ctrl = 0;
-+              le->opcode = OP_ADDR64 | HW_OWNER;
-+              sky2->rx_addr64 = high32(map + len);
-+      }
-+
-+      le = sky2_next_rx(sky2);
-+      le->addr = cpu_to_le32((u32) map);
-+      le->length = cpu_to_le16(len);
-+      le->ctrl = 0;
-+      le->opcode = OP_PACKET | HW_OWNER;
-+}
-+
-+
-+/* Tell chip where to start receive checksum.
-+ * Actually has two checksums, but set both same to avoid possible byte
-+ * order problems.
-+ */
-+static void rx_set_checksum(struct sky2_port *sky2)
-+{
-+      struct sky2_rx_le *le;
-+
-+      le = sky2_next_rx(sky2);
-+      le->addr = (ETH_HLEN << 16) | ETH_HLEN;
-+      le->ctrl = 0;
-+      le->opcode = OP_TCPSTART | HW_OWNER;
-+
-+      sky2_write32(sky2->hw,
-+                   Q_ADDR(rxqaddr[sky2->port], Q_CSR),
-+                   sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
-+
-+}
-+
-+/*
-+ * The RX Stop command will not work for Yukon-2 if the BMU does not
-+ * reach the end of packet and since we can't make sure that we have
-+ * incoming data, we must reset the BMU while it is not doing a DMA
-+ * transfer. Since it is possible that the RX path is still active,
-+ * the RX RAM buffer will be stopped first, so any possible incoming
-+ * data will not trigger a DMA. After the RAM buffer is stopped, the
-+ * BMU is polled until any DMA in progress is ended and only then it
-+ * will be reset.
-+ */
-+static void sky2_rx_stop(struct sky2_port *sky2)
-+{
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned rxq = rxqaddr[sky2->port];
-+      int i;
-+
-+      /* disable the RAM Buffer receive queue */
-+      sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD);
-+
-+      for (i = 0; i < 0xffff; i++)
-+              if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL))
-+                  == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
-+                      goto stopped;
-+
-+      printk(KERN_WARNING PFX "%s: receiver stop failed\n",
-+             sky2->netdev->name);
-+stopped:
-+      sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);
-+
-+      /* reset the Rx prefetch unit */
-+      sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
-+}
-+
-+/* Clean out receive buffer area, assumes receiver hardware stopped */
-+static void sky2_rx_clean(struct sky2_port *sky2)
-+{
-+      unsigned i;
-+
-+      memset(sky2->rx_le, 0, RX_LE_BYTES);
-+      for (i = 0; i < sky2->rx_pending; i++) {
-+              struct ring_info *re = sky2->rx_ring + i;
-+
-+              if (re->skb) {
-+                      pci_unmap_single(sky2->hw->pdev,
-+                                       re->mapaddr, sky2->rx_bufsize,
-+                                       PCI_DMA_FROMDEVICE);
-+                      kfree_skb(re->skb);
-+                      re->skb = NULL;
-+              }
-+      }
-+}
-+
-+/* Basic MII support */
-+static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-+{
-+      struct mii_ioctl_data *data = if_mii(ifr);
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      int err = -EOPNOTSUPP;
-+
-+      if (!netif_running(dev))
-+              return -ENODEV; /* Phy still in reset */
-+
-+      switch(cmd) {
-+      case SIOCGMIIPHY:
-+              data->phy_id = PHY_ADDR_MARV;
-+
-+              /* fallthru */
-+      case SIOCGMIIREG: {
-+              u16 val = 0;
-+
-+              down(&sky2->phy_sema);
-+              err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val);
-+              up(&sky2->phy_sema);
-+
-+              data->val_out = val;
-+              break;
-+      }
-+
-+      case SIOCSMIIREG:
-+              if (!capable(CAP_NET_ADMIN))
-+                      return -EPERM;
-+
-+              down(&sky2->phy_sema);
-+              err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
-+                                 data->val_in);
-+              up(&sky2->phy_sema);
-+              break;
-+      }
-+      return err;
-+}
-+
-+#ifdef SKY2_VLAN_TAG_USED
-+static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      u16 port = sky2->port;
-+
-+      spin_lock_bh(&sky2->tx_lock);
-+
-+      sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
-+      sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
-+      sky2->vlgrp = grp;
-+
-+      spin_unlock_bh(&sky2->tx_lock);
-+}
-+
-+static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      u16 port = sky2->port;
-+
-+      spin_lock_bh(&sky2->tx_lock);
-+
-+      sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
-+      sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
-+      if (sky2->vlgrp)
-+              sky2->vlgrp->vlan_devices[vid] = NULL;
-+
-+      spin_unlock_bh(&sky2->tx_lock);
-+}
-+#endif
-+
-+/*
-+ * It appears the hardware has a bug in the FIFO logic that
-+ * cause it to hang if the FIFO gets overrun and the receive buffer
-+ * is not aligned. Also dev_alloc_skb() won't align properly if slab
-+ * debugging is enabled.
-+ */
-+static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask)
-+{
-+      struct sk_buff *skb;
-+
-+      skb = __dev_alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
-+      if (likely(skb)) {
-+              unsigned long p = (unsigned long) skb->data;
-+              skb_reserve(skb,
-+                      ((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p);
-+      }
-+
-+      return skb;
-+}
-+
-+/*
-+ * Allocate and setup receiver buffer pool.
-+ * In case of 64 bit dma, there are 2X as many list elements
-+ * available as ring entries
-+ * and need to reserve one list element so we don't wrap around.
-+ */
-+static int sky2_rx_start(struct sky2_port *sky2)
-+{
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned rxq = rxqaddr[sky2->port];
-+      int i;
-+
-+      sky2->rx_put = sky2->rx_next = 0;
-+      sky2_qset(hw, rxq);
-+
-+      if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) {
-+              /* MAC Rx RAM Read is controlled by hardware */
-+              sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS);
-+      }
-+
-+      sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
-+
-+      rx_set_checksum(sky2);
-+      for (i = 0; i < sky2->rx_pending; i++) {
-+              struct ring_info *re = sky2->rx_ring + i;
-+
-+              re->skb = sky2_alloc_skb(sky2->rx_bufsize, GFP_KERNEL);
-+              if (!re->skb)
-+                      goto nomem;
-+
-+              re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
-+                                           sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-+              sky2_rx_add(sky2, re->mapaddr);
-+      }
-+
-+      /* Truncate oversize frames */
-+      sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8);
-+      sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
-+
-+      /* Tell chip about available buffers */
-+      sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
-+      sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX));
-+      return 0;
-+nomem:
-+      sky2_rx_clean(sky2);
-+      return -ENOMEM;
-+}
-+
-+/* Bring up network interface. */
-+static int sky2_up(struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      u32 ramsize, rxspace;
-+      int err = -ENOMEM;
-+
-+      if (netif_msg_ifup(sky2))
-+              printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
-+
-+      /* must be power of 2 */
-+      sky2->tx_le = pci_alloc_consistent(hw->pdev,
-+                                         TX_RING_SIZE *
-+                                         sizeof(struct sky2_tx_le),
-+                                         &sky2->tx_le_map);
-+      if (!sky2->tx_le)
-+              goto err_out;
-+
-+      sky2->tx_ring = kcalloc(TX_RING_SIZE, sizeof(struct tx_ring_info),
-+                              GFP_KERNEL);
-+      if (!sky2->tx_ring)
-+              goto err_out;
-+      sky2->tx_prod = sky2->tx_cons = 0;
-+
-+      sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
-+                                         &sky2->rx_le_map);
-+      if (!sky2->rx_le)
-+              goto err_out;
-+      memset(sky2->rx_le, 0, RX_LE_BYTES);
-+
-+      sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
-+                              GFP_KERNEL);
-+      if (!sky2->rx_ring)
-+              goto err_out;
-+
-+      sky2_mac_init(hw, port);
-+
-+      /* Determine available ram buffer space (in 4K blocks).
-+       * Note: not sure about the FE setting below yet
-+       */
-+      if (hw->chip_id == CHIP_ID_YUKON_FE)
-+              ramsize = 4;
-+      else
-+              ramsize = sky2_read8(hw, B2_E_0);
-+
-+      /* Give transmitter one third (rounded up) */
-+      rxspace = ramsize - (ramsize + 2) / 3;
-+
-+      sky2_ramset(hw, rxqaddr[port], 0, rxspace);
-+      sky2_ramset(hw, txqaddr[port], rxspace, ramsize);
-+
-+      /* Make sure SyncQ is disabled */
-+      sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
-+                  RB_RST_SET);
-+
-+      sky2_qset(hw, txqaddr[port]);
-+
-+      /* Set almost empty threshold */
-+      if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1)
-+              sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
-+
-+      sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
-+                         TX_RING_SIZE - 1);
-+
-+      err = sky2_rx_start(sky2);
-+      if (err)
-+              goto err_out;
-+
-+      /* Enable interrupts from phy/mac for port */
-+      spin_lock_irq(&hw->hw_lock);
-+      hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
-+      sky2_write32(hw, B0_IMSK, hw->intr_mask);
-+      spin_unlock_irq(&hw->hw_lock);
-+      return 0;
-+
-+err_out:
-+      if (sky2->rx_le) {
-+              pci_free_consistent(hw->pdev, RX_LE_BYTES,
-+                                  sky2->rx_le, sky2->rx_le_map);
-+              sky2->rx_le = NULL;
-+      }
-+      if (sky2->tx_le) {
-+              pci_free_consistent(hw->pdev,
-+                                  TX_RING_SIZE * sizeof(struct sky2_tx_le),
-+                                  sky2->tx_le, sky2->tx_le_map);
-+              sky2->tx_le = NULL;
-+      }
-+      kfree(sky2->tx_ring);
-+      kfree(sky2->rx_ring);
-+
-+      sky2->tx_ring = NULL;
-+      sky2->rx_ring = NULL;
-+      return err;
-+}
-+
-+/* Modular subtraction in ring */
-+static inline int tx_dist(unsigned tail, unsigned head)
-+{
-+      return (head - tail) % TX_RING_SIZE;
-+}
-+
-+/* Number of list elements available for next tx */
-+static inline int tx_avail(const struct sky2_port *sky2)
-+{
-+      return sky2->tx_pending - tx_dist(sky2->tx_cons, sky2->tx_prod);
-+}
-+
-+/* Estimate of number of transmit list elements required */
-+static unsigned tx_le_req(const struct sk_buff *skb)
-+{
-+      unsigned count;
-+
-+      count = sizeof(dma_addr_t) / sizeof(u32);
-+      count += skb_shinfo(skb)->nr_frags * count;
-+
-+      if (skb_shinfo(skb)->gso_size)
-+              ++count;
-+
-+      if (skb->ip_summed == CHECKSUM_HW)
-+              ++count;
-+
-+      return count;
-+}
-+
-+/*
-+ * Put one packet in ring for transmit.
-+ * A single packet can generate multiple list elements, and
-+ * the number of ring elements will probably be less than the number
-+ * of list elements used.
-+ *
-+ * No BH disabling for tx_lock here (like tg3)
-+ */
-+static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      struct sky2_tx_le *le = NULL;
-+      struct tx_ring_info *re;
-+      unsigned i, len;
-+      int avail;
-+      dma_addr_t mapping;
-+      u32 addr64;
-+      u16 mss;
-+      u8 ctrl;
-+
-+      /* No BH disabling for tx_lock here.  We are running in BH disabled
-+       * context and TX reclaim runs via poll inside of a software
-+       * interrupt, and no related locks in IRQ processing.
-+       */
-+      if (!spin_trylock(&sky2->tx_lock))
-+              return NETDEV_TX_LOCKED;
-+
-+      if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
-+              /* There is a known but harmless race with lockless tx
-+               * and netif_stop_queue.
-+               */
-+              if (!netif_queue_stopped(dev)) {
-+                      netif_stop_queue(dev);
-+                      if (net_ratelimit())
-+                              printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
-+                                     dev->name);
-+              }
-+              spin_unlock(&sky2->tx_lock);
-+
-+              return NETDEV_TX_BUSY;
-+      }
-+
-+      if (unlikely(netif_msg_tx_queued(sky2)))
-+              printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
-+                     dev->name, sky2->tx_prod, skb->len);
-+
-+      len = skb_headlen(skb);
-+      mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
-+      addr64 = high32(mapping);
-+
-+      re = sky2->tx_ring + sky2->tx_prod;
-+
-+      /* Send high bits if changed or crosses boundary */
-+      if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
-+              le = get_tx_le(sky2);
-+              le->tx.addr = cpu_to_le32(addr64);
-+              le->ctrl = 0;
-+              le->opcode = OP_ADDR64 | HW_OWNER;
-+              sky2->tx_addr64 = high32(mapping + len);
-+      }
-+
-+      /* Check for TCP Segmentation Offload */
-+      mss = skb_shinfo(skb)->gso_size;
-+      if (mss != 0) {
-+              /* just drop the packet if non-linear expansion fails */
-+              if (skb_header_cloned(skb) &&
-+                  pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
-+                      dev_kfree_skb_any(skb);
-+                      goto out_unlock;
-+              }
-+
-+              mss += ((skb->h.th->doff - 5) * 4);     /* TCP options */
-+              mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr);
-+              mss += ETH_HLEN;
-+      }
-+
-+      if (mss != sky2->tx_last_mss) {
-+              le = get_tx_le(sky2);
-+              le->tx.tso.size = cpu_to_le16(mss);
-+              le->tx.tso.rsvd = 0;
-+              le->opcode = OP_LRGLEN | HW_OWNER;
-+              le->ctrl = 0;
-+              sky2->tx_last_mss = mss;
-+      }
-+
-+      ctrl = 0;
-+#ifdef SKY2_VLAN_TAG_USED
-+      /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
-+      if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
-+              if (!le) {
-+                      le = get_tx_le(sky2);
-+                      le->tx.addr = 0;
-+                      le->opcode = OP_VLAN|HW_OWNER;
-+                      le->ctrl = 0;
-+              } else
-+                      le->opcode |= OP_VLAN;
-+              le->length = cpu_to_be16(vlan_tx_tag_get(skb));
-+              ctrl |= INS_VLAN;
-+      }
-+#endif
-+
-+      /* Handle TCP checksum offload */
-+      if (skb->ip_summed == CHECKSUM_HW) {
-+              u16 hdr = skb->h.raw - skb->data;
-+              u16 offset = hdr + skb->csum;
-+
-+              ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
-+              if (skb->nh.iph->protocol == IPPROTO_UDP)
-+                      ctrl |= UDPTCP;
-+
-+              le = get_tx_le(sky2);
-+              le->tx.csum.start = cpu_to_le16(hdr);
-+              le->tx.csum.offset = cpu_to_le16(offset);
-+              le->length = 0; /* initial checksum value */
-+              le->ctrl = 1;   /* one packet */
-+              le->opcode = OP_TCPLISW | HW_OWNER;
-+      }
-+
-+      le = get_tx_le(sky2);
-+      le->tx.addr = cpu_to_le32((u32) mapping);
-+      le->length = cpu_to_le16(len);
-+      le->ctrl = ctrl;
-+      le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
-+
-+      /* Record the transmit mapping info */
-+      re->skb = skb;
-+      pci_unmap_addr_set(re, mapaddr, mapping);
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+              struct tx_ring_info *fre;
-+
-+              mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
-+                                     frag->size, PCI_DMA_TODEVICE);
-+              addr64 = high32(mapping);
-+              if (addr64 != sky2->tx_addr64) {
-+                      le = get_tx_le(sky2);
-+                      le->tx.addr = cpu_to_le32(addr64);
-+                      le->ctrl = 0;
-+                      le->opcode = OP_ADDR64 | HW_OWNER;
-+                      sky2->tx_addr64 = addr64;
-+              }
-+
-+              le = get_tx_le(sky2);
-+              le->tx.addr = cpu_to_le32((u32) mapping);
-+              le->length = cpu_to_le16(frag->size);
-+              le->ctrl = ctrl;
-+              le->opcode = OP_BUFFER | HW_OWNER;
-+
-+              fre = sky2->tx_ring
-+                  + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE;
-+              pci_unmap_addr_set(fre, mapaddr, mapping);
-+      }
-+
-+      re->idx = sky2->tx_prod;
-+      le->ctrl |= EOP;
-+
-+      avail = tx_avail(sky2);
-+      if (mss != 0 || avail < TX_MIN_PENDING) {
-+              le->ctrl |= FRC_STAT;
-+              if (avail <= MAX_SKB_TX_LE)
-+                      netif_stop_queue(dev);
-+      }
-+
-+      sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod,
-+                   &sky2->tx_last_put, TX_RING_SIZE);
-+
-+out_unlock:
-+      spin_unlock(&sky2->tx_lock);
-+
-+      dev->trans_start = jiffies;
-+      return NETDEV_TX_OK;
-+}
-+
-+/*
-+ * Free ring elements from starting at tx_cons until "done"
-+ *
-+ * NB: the hardware will tell us about partial completion of multi-part
-+ *     buffers; these are deferred until completion.
-+ */
-+static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
-+{
-+      struct net_device *dev = sky2->netdev;
-+      struct pci_dev *pdev = sky2->hw->pdev;
-+      u16 nxt, put;
-+      unsigned i;
-+
-+      BUG_ON(done >= TX_RING_SIZE);
-+
-+      if (unlikely(netif_msg_tx_done(sky2)))
-+              printk(KERN_DEBUG "%s: tx done, up to %u\n",
-+                     dev->name, done);
-+
-+      for (put = sky2->tx_cons; put != done; put = nxt) {
-+              struct tx_ring_info *re = sky2->tx_ring + put;
-+              struct sk_buff *skb = re->skb;
-+
-+              nxt = re->idx;
-+              BUG_ON(nxt >= TX_RING_SIZE);
-+              prefetch(sky2->tx_ring + nxt);
-+
-+              /* Check for partial status */
-+              if (tx_dist(put, done) < tx_dist(put, nxt))
-+                      break;
-+
-+              skb = re->skb;
-+              pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
-+                               skb_headlen(skb), PCI_DMA_TODEVICE);
-+
-+              for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+                      struct tx_ring_info *fre;
-+                      fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE;
-+                      pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
-+                                     skb_shinfo(skb)->frags[i].size,
-+                                     PCI_DMA_TODEVICE);
-+              }
-+
-+              dev_kfree_skb_any(skb);
-+      }
-+
-+      sky2->tx_cons = put;
-+      if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE)
-+              netif_wake_queue(dev);
-+}
-+
-+/* Cleanup all untransmitted buffers, assume transmitter not running */
-+static void sky2_tx_clean(struct sky2_port *sky2)
-+{
-+      spin_lock_bh(&sky2->tx_lock);
-+      sky2_tx_complete(sky2, sky2->tx_prod);
-+      spin_unlock_bh(&sky2->tx_lock);
-+}
-+
-+/* Network shutdown */
-+static int sky2_down(struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      u16 ctrl;
-+
-+      /* Never really got started! */
-+      if (!sky2->tx_le)
-+              return 0;
-+
-+      if (netif_msg_ifdown(sky2))
-+              printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
-+
-+      /* Stop more packets from being queued */
-+      netif_stop_queue(dev);
-+
-+      /* Disable port IRQ */
-+      spin_lock_irq(&hw->hw_lock);
-+      hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
-+      sky2_write32(hw, B0_IMSK, hw->intr_mask);
-+      spin_unlock_irq(&hw->hw_lock);
-+
-+      flush_scheduled_work();
-+
-+      sky2_phy_reset(hw, port);
-+
-+      /* Stop transmitter */
-+      sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP);
-+      sky2_read32(hw, Q_ADDR(txqaddr[port], Q_CSR));
-+
-+      sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
-+                   RB_RST_SET | RB_DIS_OP_MD);
-+
-+      ctrl = gma_read16(hw, port, GM_GP_CTRL);
-+      ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
-+      gma_write16(hw, port, GM_GP_CTRL, ctrl);
-+
-+      sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
-+
-+      /* Workaround shared GMAC reset */
-+      if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0
-+            && port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
-+              sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
-+
-+      /* Disable Force Sync bit and Enable Alloc bit */
-+      sky2_write8(hw, SK_REG(port, TXA_CTRL),
-+                  TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-+
-+      /* Stop Interval Timer and Limit Counter of Tx Arbiter */
-+      sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
-+      sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
-+
-+      /* Reset the PCI FIFO of the async Tx queue */
-+      sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
-+                   BMU_RST_SET | BMU_FIFO_RST);
-+
-+      /* Reset the Tx prefetch units */
-+      sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
-+                   PREF_UNIT_RST_SET);
-+
-+      sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
-+
-+      sky2_rx_stop(sky2);
-+
-+      sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
-+      sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
-+
-+      /* turn off LED's */
-+      sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
-+
-+      synchronize_irq(hw->pdev->irq);
-+
-+      sky2_tx_clean(sky2);
-+      sky2_rx_clean(sky2);
-+
-+      pci_free_consistent(hw->pdev, RX_LE_BYTES,
-+                          sky2->rx_le, sky2->rx_le_map);
-+      kfree(sky2->rx_ring);
-+
-+      pci_free_consistent(hw->pdev,
-+                          TX_RING_SIZE * sizeof(struct sky2_tx_le),
-+                          sky2->tx_le, sky2->tx_le_map);
-+      kfree(sky2->tx_ring);
-+
-+      sky2->tx_le = NULL;
-+      sky2->rx_le = NULL;
-+
-+      sky2->rx_ring = NULL;
-+      sky2->tx_ring = NULL;
-+
-+      return 0;
-+}
-+
-+static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
-+{
-+      if (!sky2_is_copper(hw))
-+              return SPEED_1000;
-+
-+      if (hw->chip_id == CHIP_ID_YUKON_FE)
-+              return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10;
-+
-+      switch (aux & PHY_M_PS_SPEED_MSK) {
-+      case PHY_M_PS_SPEED_1000:
-+              return SPEED_1000;
-+      case PHY_M_PS_SPEED_100:
-+              return SPEED_100;
-+      default:
-+              return SPEED_10;
-+      }
-+}
-+
-+static void sky2_link_up(struct sky2_port *sky2)
-+{
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      u16 reg;
-+
-+      /* Enable Transmit FIFO Underrun */
-+      sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
-+
-+      reg = gma_read16(hw, port, GM_GP_CTRL);
-+      if (sky2->autoneg == AUTONEG_DISABLE) {
-+              reg |= GM_GPCR_AU_ALL_DIS;
-+
-+              /* Is write/read necessary?  Copied from sky2_mac_init */
-+              gma_write16(hw, port, GM_GP_CTRL, reg);
-+              gma_read16(hw, port, GM_GP_CTRL);
-+
-+              switch (sky2->speed) {
-+              case SPEED_1000:
-+                      reg &= ~GM_GPCR_SPEED_100;
-+                      reg |= GM_GPCR_SPEED_1000;
-+                      break;
-+              case SPEED_100:
-+                      reg &= ~GM_GPCR_SPEED_1000;
-+                      reg |= GM_GPCR_SPEED_100;
-+                      break;
-+              case SPEED_10:
-+                      reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
-+                      break;
-+              }
-+      } else
-+              reg &= ~GM_GPCR_AU_ALL_DIS;
-+
-+      if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE)
-+              reg |= GM_GPCR_DUP_FULL;
-+
-+      /* enable Rx/Tx */
-+      reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
-+      gma_write16(hw, port, GM_GP_CTRL, reg);
-+      gma_read16(hw, port, GM_GP_CTRL);
-+
-+      gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
-+
-+      netif_carrier_on(sky2->netdev);
-+      netif_wake_queue(sky2->netdev);
-+
-+      /* Turn on link LED */
-+      sky2_write8(hw, SK_REG(port, LNK_LED_REG),
-+                  LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
-+
-+      if (hw->chip_id == CHIP_ID_YUKON_XL) {
-+              u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
-+
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
-+              gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) |      /* LINK/ACT */
-+                           PHY_M_LEDC_INIT_CTRL(sky2->speed ==
-+                                                SPEED_10 ? 7 : 0) |
-+                           PHY_M_LEDC_STA1_CTRL(sky2->speed ==
-+                                                SPEED_100 ? 7 : 0) |
-+                           PHY_M_LEDC_STA0_CTRL(sky2->speed ==
-+                                                SPEED_1000 ? 7 : 0));
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
-+      }
-+
-+      if (netif_msg_link(sky2))
-+              printk(KERN_INFO PFX
-+                     "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
-+                     sky2->netdev->name, sky2->speed,
-+                     sky2->duplex == DUPLEX_FULL ? "full" : "half",
-+                     (sky2->tx_pause && sky2->rx_pause) ? "both" :
-+                     sky2->tx_pause ? "tx" : sky2->rx_pause ? "rx" : "none");
-+}
-+
-+static void sky2_link_down(struct sky2_port *sky2)
-+{
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      u16 reg;
-+
-+      gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
-+
-+      reg = gma_read16(hw, port, GM_GP_CTRL);
-+      reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
-+      gma_write16(hw, port, GM_GP_CTRL, reg);
-+      gma_read16(hw, port, GM_GP_CTRL);       /* PCI post */
-+
-+      if (sky2->rx_pause && !sky2->tx_pause) {
-+              /* restore Asymmetric Pause bit */
-+              gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
-+                           gm_phy_read(hw, port, PHY_MARV_AUNE_ADV)
-+                           | PHY_M_AN_ASP);
-+      }
-+
-+      netif_carrier_off(sky2->netdev);
-+      netif_stop_queue(sky2->netdev);
-+
-+      /* Turn on link LED */
-+      sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
-+
-+      if (netif_msg_link(sky2))
-+              printk(KERN_INFO PFX "%s: Link is down.\n", sky2->netdev->name);
-+      sky2_phy_init(hw, port);
-+}
-+
-+static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
-+{
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      u16 lpa;
-+
-+      lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
-+
-+      if (lpa & PHY_M_AN_RF) {
-+              printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name);
-+              return -1;
-+      }
-+
-+      if (hw->chip_id != CHIP_ID_YUKON_FE &&
-+          gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
-+              printk(KERN_ERR PFX "%s: master/slave fault",
-+                     sky2->netdev->name);
-+              return -1;
-+      }
-+
-+      if (!(aux & PHY_M_PS_SPDUP_RES)) {
-+              printk(KERN_ERR PFX "%s: speed/duplex mismatch",
-+                     sky2->netdev->name);
-+              return -1;
-+      }
-+
-+      sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
-+
-+      sky2->speed = sky2_phy_speed(hw, aux);
-+
-+      /* Pause bits are offset (9..8) */
-+      if (hw->chip_id == CHIP_ID_YUKON_XL)
-+              aux >>= 6;
-+
-+      sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0;
-+      sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0;
-+
-+      if ((sky2->tx_pause || sky2->rx_pause)
-+          && !(sky2->speed < SPEED_1000 && sky2->duplex == DUPLEX_HALF))
-+              sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
-+      else
-+              sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
-+
-+      return 0;
-+}
-+
-+/*
-+ * Interrupt from PHY are handled outside of interrupt context
-+ * because accessing phy registers requires spin wait which might
-+ * cause excess interrupt latency.
-+ */
-+static void sky2_phy_task(void *arg)
-+{
-+      struct sky2_port *sky2 = arg;
-+      struct sky2_hw *hw = sky2->hw;
-+      u16 istatus, phystat;
-+
-+      down(&sky2->phy_sema);
-+      istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT);
-+      phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT);
-+
-+      if (netif_msg_intr(sky2))
-+              printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
-+                     sky2->netdev->name, istatus, phystat);
-+
-+      if (istatus & PHY_M_IS_AN_COMPL) {
-+              if (sky2_autoneg_done(sky2, phystat) == 0)
-+                      sky2_link_up(sky2);
-+              goto out;
-+      }
-+
-+      if (istatus & PHY_M_IS_LSP_CHANGE)
-+              sky2->speed = sky2_phy_speed(hw, phystat);
-+
-+      if (istatus & PHY_M_IS_DUP_CHANGE)
-+              sky2->duplex =
-+                  (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
-+
-+      if (istatus & PHY_M_IS_LST_CHANGE) {
-+              if (phystat & PHY_M_PS_LINK_UP)
-+                      sky2_link_up(sky2);
-+              else
-+                      sky2_link_down(sky2);
-+      }
-+out:
-+      up(&sky2->phy_sema);
-+
-+      spin_lock_irq(&hw->hw_lock);
-+      hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2;
-+      sky2_write32(hw, B0_IMSK, hw->intr_mask);
-+      spin_unlock_irq(&hw->hw_lock);
-+}
-+
-+
-+/* Transmit timeout is only called if we are running, carries is up
-+ * and tx queue is full (stopped).
-+ */
-+static void sky2_tx_timeout(struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned txq = txqaddr[sky2->port];
-+      u16 ridx;
-+
-+      /* Maybe we just missed an status interrupt */
-+      spin_lock(&sky2->tx_lock);
-+      ridx = sky2_read16(hw,
-+                         sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX);
-+      sky2_tx_complete(sky2, ridx);
-+      spin_unlock(&sky2->tx_lock);
-+
-+      if (!netif_queue_stopped(dev)) {
-+              if (net_ratelimit())
-+                      pr_info(PFX "transmit interrupt missed? recovered\n");
-+              return;
-+      }
-+
-+      if (netif_msg_timer(sky2))
-+              printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
-+
-+      sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
-+      sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
-+
-+      sky2_tx_clean(sky2);
-+
-+      sky2_qset(hw, txq);
-+      sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
-+}
-+
-+
-+#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
-+/* Want receive buffer size to be multiple of 64 bits
-+ * and incl room for vlan and truncation
-+ */
-+static inline unsigned sky2_buf_size(int mtu)
-+{
-+      return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
-+}
-+
-+static int sky2_change_mtu(struct net_device *dev, int new_mtu)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      int err;
-+      u16 ctl, mode;
-+
-+      if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
-+              return -EINVAL;
-+
-+      if (hw->chip_id == CHIP_ID_YUKON_EC_U && new_mtu > ETH_DATA_LEN)
-+              return -EINVAL;
-+
-+      if (!netif_running(dev)) {
-+              dev->mtu = new_mtu;
-+              return 0;
-+      }
-+
-+      sky2_write32(hw, B0_IMSK, 0);
-+
-+      dev->trans_start = jiffies;     /* prevent tx timeout */
-+      netif_stop_queue(dev);
-+      netif_poll_disable(hw->dev[0]);
-+
-+      ctl = gma_read16(hw, sky2->port, GM_GP_CTRL);
-+      gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
-+      sky2_rx_stop(sky2);
-+      sky2_rx_clean(sky2);
-+
-+      dev->mtu = new_mtu;
-+      sky2->rx_bufsize = sky2_buf_size(new_mtu);
-+      mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
-+              GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
-+
-+      if (dev->mtu > ETH_DATA_LEN)
-+              mode |= GM_SMOD_JUMBO_ENA;
-+
-+      gma_write16(hw, sky2->port, GM_SERIAL_MODE, mode);
-+
-+      sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD);
-+
-+      err = sky2_rx_start(sky2);
-+      sky2_write32(hw, B0_IMSK, hw->intr_mask);
-+
-+      if (err)
-+              dev_close(dev);
-+      else {
-+              gma_write16(hw, sky2->port, GM_GP_CTRL, ctl);
-+
-+              netif_poll_enable(hw->dev[0]);
-+              netif_wake_queue(dev);
-+      }
-+
-+      return err;
-+}
-+
-+/*
-+ * Receive one packet.
-+ * For small packets or errors, just reuse existing skb.
-+ * For larger packets, get new buffer.
-+ */
-+static struct sk_buff *sky2_receive(struct sky2_port *sky2,
-+                                  u16 length, u32 status)
-+{
-+      struct ring_info *re = sky2->rx_ring + sky2->rx_next;
-+      struct sk_buff *skb = NULL;
-+
-+      if (unlikely(netif_msg_rx_status(sky2)))
-+              printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
-+                     sky2->netdev->name, sky2->rx_next, status, length);
-+
-+      sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
-+      prefetch(sky2->rx_ring + sky2->rx_next);
-+
-+      if (status & GMR_FS_ANY_ERR)
-+              goto error;
-+
-+      if (!(status & GMR_FS_RX_OK))
-+              goto resubmit;
-+
-+      if (length > sky2->netdev->mtu + ETH_HLEN)
-+              goto oversize;
-+
-+      if (length < copybreak) {
-+              skb = dev_alloc_skb(length + 2);
-+              if (!skb)
-+                      goto resubmit;
-+
-+              skb_reserve(skb, 2);
-+              pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr,
-+                                          length, PCI_DMA_FROMDEVICE);
-+              memcpy(skb->data, re->skb->data, length);
-+              skb->ip_summed = re->skb->ip_summed;
-+              skb->csum = re->skb->csum;
-+              pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr,
-+                                             length, PCI_DMA_FROMDEVICE);
-+      } else {
-+              struct sk_buff *nskb;
-+
-+              nskb = sky2_alloc_skb(sky2->rx_bufsize, GFP_ATOMIC);
-+              if (!nskb)
-+                      goto resubmit;
-+
-+              skb = re->skb;
-+              re->skb = nskb;
-+              pci_unmap_single(sky2->hw->pdev, re->mapaddr,
-+                               sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-+              prefetch(skb->data);
-+
-+              re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
-+                                           sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
-+      }
-+
-+      skb_put(skb, length);
-+resubmit:
-+      re->skb->ip_summed = CHECKSUM_NONE;
-+      sky2_rx_add(sky2, re->mapaddr);
-+
-+      /* Tell receiver about new buffers. */
-+      sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put,
-+                   &sky2->rx_last_put, RX_LE_SIZE);
-+
-+      return skb;
-+
-+oversize:
-+      ++sky2->net_stats.rx_over_errors;
-+      goto resubmit;
-+
-+error:
-+      ++sky2->net_stats.rx_errors;
-+
-+      if (netif_msg_rx_err(sky2) && net_ratelimit())
-+              printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n",
-+                     sky2->netdev->name, status, length);
-+
-+      if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE))
-+              sky2->net_stats.rx_length_errors++;
-+      if (status & GMR_FS_FRAGMENT)
-+              sky2->net_stats.rx_frame_errors++;
-+      if (status & GMR_FS_CRC_ERR)
-+              sky2->net_stats.rx_crc_errors++;
-+      if (status & GMR_FS_RX_FF_OV)
-+              sky2->net_stats.rx_fifo_errors++;
-+
-+      goto resubmit;
-+}
-+
-+/*
-+ * Check for transmit complete
-+ */
-+#define TX_NO_STATUS  0xffff
-+
-+static void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
-+{
-+      if (last != TX_NO_STATUS) {
-+              struct net_device *dev = hw->dev[port];
-+              if (dev && netif_running(dev)) {
-+                      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+                      spin_lock(&sky2->tx_lock);
-+                      sky2_tx_complete(sky2, last);
-+                      spin_unlock(&sky2->tx_lock);
-+              }
-+      }
-+}
-+
-+/*
-+ * Both ports share the same status interrupt, therefore there is only
-+ * one poll routine.
-+ */
-+static int sky2_poll(struct net_device *dev0, int *budget)
-+{
-+      struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
-+      unsigned int to_do = min(dev0->quota, *budget);
-+      unsigned int work_done = 0;
-+      u16 hwidx;
-+      u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
-+
-+      sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-+
-+      /*
-+       * Kick the STAT_LEV_TIMER_CTRL timer.
-+       * This fixes my hangs on Yukon-EC (0xb6) rev 1.
-+       * The if clause is there to start the timer only if it has been
-+       * configured correctly and not been disabled via ethtool.
-+       */
-+      if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) {
-+              sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
-+              sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
-+      }
-+
-+      hwidx = sky2_read16(hw, STAT_PUT_IDX);
-+      BUG_ON(hwidx >= STATUS_RING_SIZE);
-+      rmb();
-+
-+      while (hwidx != hw->st_idx) {
-+              struct sky2_status_le *le  = hw->st_le + hw->st_idx;
-+              struct net_device *dev;
-+              struct sky2_port *sky2;
-+              struct sk_buff *skb;
-+              u32 status;
-+              u16 length;
-+
-+              le = hw->st_le + hw->st_idx;
-+              hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
-+              prefetch(hw->st_le + hw->st_idx);
-+
-+              BUG_ON(le->link >= 2);
-+              dev = hw->dev[le->link];
-+              if (dev == NULL || !netif_running(dev))
-+                      continue;
-+
-+              sky2 = netdev_priv(dev);
-+              status = le32_to_cpu(le->status);
-+              length = le16_to_cpu(le->length);
-+
-+              switch (le->opcode & ~HW_OWNER) {
-+              case OP_RXSTAT:
-+                      skb = sky2_receive(sky2, length, status);
-+                      if (!skb)
-+                              break;
-+
-+                      skb->dev = dev;
-+                      skb->protocol = eth_type_trans(skb, dev);
-+                      dev->last_rx = jiffies;
-+
-+#ifdef SKY2_VLAN_TAG_USED
-+                      if (sky2->vlgrp && (status & GMR_FS_VLAN)) {
-+                              vlan_hwaccel_receive_skb(skb,
-+                                                       sky2->vlgrp,
-+                                                       be16_to_cpu(sky2->rx_tag));
-+                      } else
-+#endif
-+                              netif_receive_skb(skb);
-+
-+                      if (++work_done >= to_do)
-+                              goto exit_loop;
-+                      break;
-+
-+#ifdef SKY2_VLAN_TAG_USED
-+              case OP_RXVLAN:
-+                      sky2->rx_tag = length;
-+                      break;
-+
-+              case OP_RXCHKSVLAN:
-+                      sky2->rx_tag = length;
-+                      /* fall through */
-+#endif
-+              case OP_RXCHKS:
-+                      skb = sky2->rx_ring[sky2->rx_next].skb;
-+                      skb->ip_summed = CHECKSUM_HW;
-+                      skb->csum = le16_to_cpu(status);
-+                      break;
-+
-+              case OP_TXINDEXLE:
-+                      /* TX index reports status for both ports */
-+                      tx_done[0] = status & 0xffff;
-+                      tx_done[1] = ((status >> 24) & 0xff)
-+                              | (u16)(length & 0xf) << 8;
-+                      break;
-+
-+              default:
-+                      if (net_ratelimit())
-+                              printk(KERN_WARNING PFX
-+                                     "unknown status opcode 0x%x\n", le->opcode);
-+                      break;
-+              }
-+      }
-+
-+exit_loop:
-+      sky2_tx_check(hw, 0, tx_done[0]);
-+      sky2_tx_check(hw, 1, tx_done[1]);
-+
-+      if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
-+              sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
-+              sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
-+      }
-+
-+      if (likely(work_done < to_do)) {
-+              spin_lock_irq(&hw->hw_lock);
-+              __netif_rx_complete(dev0);
-+
-+              hw->intr_mask |= Y2_IS_STAT_BMU;
-+              sky2_write32(hw, B0_IMSK, hw->intr_mask);
-+              spin_unlock_irq(&hw->hw_lock);
-+
-+              return 0;
-+      } else {
-+              *budget -= work_done;
-+              dev0->quota -= work_done;
-+              return 1;
-+      }
-+}
-+
-+static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
-+{
-+      struct net_device *dev = hw->dev[port];
-+
-+      if (net_ratelimit())
-+              printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
-+                     dev->name, status);
-+
-+      if (status & Y2_IS_PAR_RD1) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR PFX "%s: ram data read parity error\n",
-+                             dev->name);
-+              /* Clear IRQ */
-+              sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
-+      }
-+
-+      if (status & Y2_IS_PAR_WR1) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR PFX "%s: ram data write parity error\n",
-+                             dev->name);
-+
-+              sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
-+      }
-+
-+      if (status & Y2_IS_PAR_MAC1) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
-+              sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
-+      }
-+
-+      if (status & Y2_IS_PAR_RX1) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
-+              sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
-+      }
-+
-+      if (status & Y2_IS_TCP_TXA1) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR PFX "%s: TCP segmentation error\n",
-+                             dev->name);
-+              sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
-+      }
-+}
-+
-+static void sky2_hw_intr(struct sky2_hw *hw)
-+{
-+      u32 status = sky2_read32(hw, B0_HWE_ISRC);
-+
-+      if (status & Y2_IS_TIST_OV)
-+              sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
-+
-+      if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
-+              u16 pci_err;
-+
-+              pci_err = sky2_pci_read16(hw, PCI_STATUS);
-+              if (net_ratelimit())
-+                      printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
-+                             pci_name(hw->pdev), pci_err);
-+
-+              sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-+              sky2_pci_write16(hw, PCI_STATUS,
-+                                    pci_err | PCI_STATUS_ERROR_BITS);
-+              sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-+      }
-+
-+      if (status & Y2_IS_PCI_EXP) {
-+              /* PCI-Express uncorrectable Error occurred */
-+              u32 pex_err;
-+
-+              pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
-+
-+              if (net_ratelimit())
-+                      printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
-+                             pci_name(hw->pdev), pex_err);
-+
-+              /* clear the interrupt */
-+              sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-+              sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
-+                                     0xffffffffUL);
-+              sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-+
-+              if (pex_err & PEX_FATAL_ERRORS) {
-+                      u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
-+                      hwmsk &= ~Y2_IS_PCI_EXP;
-+                      sky2_write32(hw, B0_HWE_IMSK, hwmsk);
-+              }
-+      }
-+
-+      if (status & Y2_HWE_L1_MASK)
-+              sky2_hw_error(hw, 0, status);
-+      status >>= 8;
-+      if (status & Y2_HWE_L1_MASK)
-+              sky2_hw_error(hw, 1, status);
-+}
-+
-+static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
-+{
-+      struct net_device *dev = hw->dev[port];
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      u8 status = sky2_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
-+
-+      if (netif_msg_intr(sky2))
-+              printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n",
-+                     dev->name, status);
-+
-+      if (status & GM_IS_RX_FF_OR) {
-+              ++sky2->net_stats.rx_fifo_errors;
-+              sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
-+      }
-+
-+      if (status & GM_IS_TX_FF_UR) {
-+              ++sky2->net_stats.tx_fifo_errors;
-+              sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
-+      }
-+}
-+
-+static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
-+{
-+      struct net_device *dev = hw->dev[port];
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
-+      sky2_write32(hw, B0_IMSK, hw->intr_mask);
-+
-+      schedule_work(&sky2->phy_task);
-+}
-+
-+static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct sky2_hw *hw = dev_id;
-+      struct net_device *dev0 = hw->dev[0];
-+      u32 status;
-+
-+      status = sky2_read32(hw, B0_Y2_SP_ISRC2);
-+      if (status == 0 || status == ~0)
-+              return IRQ_NONE;
-+
-+      spin_lock(&hw->hw_lock);
-+      if (status & Y2_IS_HW_ERR)
-+              sky2_hw_intr(hw);
-+
-+      /* Do NAPI for Rx and Tx status */
-+      if (status & Y2_IS_STAT_BMU) {
-+              hw->intr_mask &= ~Y2_IS_STAT_BMU;
-+              sky2_write32(hw, B0_IMSK, hw->intr_mask);
-+
-+              if (likely(__netif_rx_schedule_prep(dev0))) {
-+                      prefetch(&hw->st_le[hw->st_idx]);
-+                      __netif_rx_schedule(dev0);
-+              }
-+      }
-+
-+      if (status & Y2_IS_IRQ_PHY1)
-+              sky2_phy_intr(hw, 0);
-+
-+      if (status & Y2_IS_IRQ_PHY2)
-+              sky2_phy_intr(hw, 1);
-+
-+      if (status & Y2_IS_IRQ_MAC1)
-+              sky2_mac_intr(hw, 0);
-+
-+      if (status & Y2_IS_IRQ_MAC2)
-+              sky2_mac_intr(hw, 1);
-+
-+      sky2_write32(hw, B0_Y2_SP_ICR, 2);
-+
-+      spin_unlock(&hw->hw_lock);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+static void sky2_netpoll(struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      sky2_intr(sky2->hw->pdev->irq, sky2->hw, NULL);
-+}
-+#endif
-+
-+/* Chip internal frequency for clock calculations */
-+static inline u32 sky2_mhz(const struct sky2_hw *hw)
-+{
-+      switch (hw->chip_id) {
-+      case CHIP_ID_YUKON_EC:
-+      case CHIP_ID_YUKON_EC_U:
-+              return 125;     /* 125 Mhz */
-+      case CHIP_ID_YUKON_FE:
-+              return 100;     /* 100 Mhz */
-+      default:                /* YUKON_XL */
-+              return 156;     /* 156 Mhz */
-+      }
-+}
-+
-+static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us)
-+{
-+      return sky2_mhz(hw) * us;
-+}
-+
-+static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
-+{
-+      return clk / sky2_mhz(hw);
-+}
-+
-+
-+static int sky2_reset(struct sky2_hw *hw)
-+{
-+      u16 status;
-+      u8 t8;
-+      int i;
-+
-+      sky2_write8(hw, B0_CTST, CS_RST_CLR);
-+
-+      hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
-+      if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) {
-+              printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n",
-+                     pci_name(hw->pdev), hw->chip_id);
-+              return -EOPNOTSUPP;
-+      }
-+
-+      /* disable ASF */
-+      if (hw->chip_id <= CHIP_ID_YUKON_EC) {
-+              sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
-+              sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
-+      }
-+
-+      /* do a SW reset */
-+      sky2_write8(hw, B0_CTST, CS_RST_SET);
-+      sky2_write8(hw, B0_CTST, CS_RST_CLR);
-+
-+      /* clear PCI errors, if any */
-+      status = sky2_pci_read16(hw, PCI_STATUS);
-+
-+      sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-+      sky2_pci_write16(hw, PCI_STATUS, status | PCI_STATUS_ERROR_BITS);
-+
-+
-+      sky2_write8(hw, B0_CTST, CS_MRST_CLR);
-+
-+      /* clear any PEX errors */
-+      if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) 
-+              sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
-+
-+
-+      hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
-+      hw->ports = 1;
-+      t8 = sky2_read8(hw, B2_Y2_HW_RES);
-+      if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
-+              if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
-+                      ++hw->ports;
-+      }
-+      hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
-+
-+      sky2_set_power_state(hw, PCI_D0);
-+
-+      for (i = 0; i < hw->ports; i++) {
-+              sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
-+              sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
-+      }
-+
-+      sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-+
-+      /* Clear I2C IRQ noise */
-+      sky2_write32(hw, B2_I2C_IRQ, 1);
-+
-+      /* turn off hardware timer (unused) */
-+      sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
-+      sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
-+
-+      sky2_write8(hw, B0_Y2LED, LED_STAT_ON);
-+
-+      /* Turn off descriptor polling */
-+      sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
-+
-+      /* Turn off receive timestamp */
-+      sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
-+      sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
-+
-+      /* enable the Tx Arbiters */
-+      for (i = 0; i < hw->ports; i++)
-+              sky2_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
-+
-+      /* Initialize ram interface */
-+      for (i = 0; i < hw->ports; i++) {
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
-+
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
-+              sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
-+      }
-+
-+      sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
-+
-+      for (i = 0; i < hw->ports; i++)
-+              sky2_phy_reset(hw, i);
-+
-+      memset(hw->st_le, 0, STATUS_LE_BYTES);
-+      hw->st_idx = 0;
-+
-+      sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
-+      sky2_write32(hw, STAT_CTRL, SC_STAT_RST_CLR);
-+
-+      sky2_write32(hw, STAT_LIST_ADDR_LO, hw->st_dma);
-+      sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);
-+
-+      /* Set the list last index */
-+      sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
-+
-+      /* These status setup values are copied from SysKonnect's driver */
-+      if (is_ec_a1(hw)) {
-+              /* WA for dev. #4.3 */
-+              sky2_write16(hw, STAT_TX_IDX_TH, 0xfff);        /* Tx Threshold */
-+
-+              /* set Status-FIFO watermark */
-+              sky2_write8(hw, STAT_FIFO_WM, 0x21);    /* WA for dev. #4.18 */
-+
-+              /* set Status-FIFO ISR watermark */
-+              sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07);        /* WA for dev. #4.18 */
-+              sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000));
-+      } else {
-+              sky2_write16(hw, STAT_TX_IDX_TH, 10);
-+              sky2_write8(hw, STAT_FIFO_WM, 16);
-+
-+              /* set Status-FIFO ISR watermark */
-+              if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
-+                      sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
-+              else
-+                      sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
-+
-+              sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
-+              sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7));
-+      }
-+
-+      /* enable status unit */
-+      sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
-+
-+      sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
-+      sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
-+      sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
-+
-+      return 0;
-+}
-+
-+static u32 sky2_supported_modes(const struct sky2_hw *hw)
-+{
-+      if (sky2_is_copper(hw)) {
-+              u32 modes = SUPPORTED_10baseT_Half
-+                      | SUPPORTED_10baseT_Full
-+                      | SUPPORTED_100baseT_Half
-+                      | SUPPORTED_100baseT_Full
-+                      | SUPPORTED_Autoneg | SUPPORTED_TP;
-+
-+              if (hw->chip_id != CHIP_ID_YUKON_FE)
-+                      modes |= SUPPORTED_1000baseT_Half
-+                              | SUPPORTED_1000baseT_Full;
-+              return modes;
-+      } else
-+              return  SUPPORTED_1000baseT_Half
-+                      | SUPPORTED_1000baseT_Full
-+                      | SUPPORTED_Autoneg
-+                      | SUPPORTED_FIBRE;
-+}
-+
-+static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+
-+      ecmd->transceiver = XCVR_INTERNAL;
-+      ecmd->supported = sky2_supported_modes(hw);
-+      ecmd->phy_address = PHY_ADDR_MARV;
-+      if (sky2_is_copper(hw)) {
-+              ecmd->supported = SUPPORTED_10baseT_Half
-+                  | SUPPORTED_10baseT_Full
-+                  | SUPPORTED_100baseT_Half
-+                  | SUPPORTED_100baseT_Full
-+                  | SUPPORTED_1000baseT_Half
-+                  | SUPPORTED_1000baseT_Full
-+                  | SUPPORTED_Autoneg | SUPPORTED_TP;
-+              ecmd->port = PORT_TP;
-+              ecmd->speed = sky2->speed;
-+      } else {
-+              ecmd->speed = SPEED_1000;
-+              ecmd->port = PORT_FIBRE;
-+      }
-+
-+      ecmd->advertising = sky2->advertising;
-+      ecmd->autoneg = sky2->autoneg;
-+      ecmd->duplex = sky2->duplex;
-+      return 0;
-+}
-+
-+static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      const struct sky2_hw *hw = sky2->hw;
-+      u32 supported = sky2_supported_modes(hw);
-+
-+      if (ecmd->autoneg == AUTONEG_ENABLE) {
-+              ecmd->advertising = supported;
-+              sky2->duplex = -1;
-+              sky2->speed = -1;
-+      } else {
-+              u32 setting;
-+
-+              switch (ecmd->speed) {
-+              case SPEED_1000:
-+                      if (ecmd->duplex == DUPLEX_FULL)
-+                              setting = SUPPORTED_1000baseT_Full;
-+                      else if (ecmd->duplex == DUPLEX_HALF)
-+                              setting = SUPPORTED_1000baseT_Half;
-+                      else
-+                              return -EINVAL;
-+                      break;
-+              case SPEED_100:
-+                      if (ecmd->duplex == DUPLEX_FULL)
-+                              setting = SUPPORTED_100baseT_Full;
-+                      else if (ecmd->duplex == DUPLEX_HALF)
-+                              setting = SUPPORTED_100baseT_Half;
-+                      else
-+                              return -EINVAL;
-+                      break;
-+
-+              case SPEED_10:
-+                      if (ecmd->duplex == DUPLEX_FULL)
-+                              setting = SUPPORTED_10baseT_Full;
-+                      else if (ecmd->duplex == DUPLEX_HALF)
-+                              setting = SUPPORTED_10baseT_Half;
-+                      else
-+                              return -EINVAL;
-+                      break;
-+              default:
-+                      return -EINVAL;
-+              }
-+
-+              if ((setting & supported) == 0)
-+                      return -EINVAL;
-+
-+              sky2->speed = ecmd->speed;
-+              sky2->duplex = ecmd->duplex;
-+      }
-+
-+      sky2->autoneg = ecmd->autoneg;
-+      sky2->advertising = ecmd->advertising;
-+
-+      if (netif_running(dev))
-+              sky2_phy_reinit(sky2);
-+
-+      return 0;
-+}
-+
-+static void sky2_get_drvinfo(struct net_device *dev,
-+                           struct ethtool_drvinfo *info)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      strcpy(info->driver, DRV_NAME);
-+      strcpy(info->version, DRV_VERSION);
-+      strcpy(info->fw_version, "N/A");
-+      strcpy(info->bus_info, pci_name(sky2->hw->pdev));
-+}
-+
-+static const struct sky2_stat {
-+      char name[ETH_GSTRING_LEN];
-+      u16 offset;
-+} sky2_stats[] = {
-+      { "tx_bytes",      GM_TXO_OK_HI },
-+      { "rx_bytes",      GM_RXO_OK_HI },
-+      { "tx_broadcast",  GM_TXF_BC_OK },
-+      { "rx_broadcast",  GM_RXF_BC_OK },
-+      { "tx_multicast",  GM_TXF_MC_OK },
-+      { "rx_multicast",  GM_RXF_MC_OK },
-+      { "tx_unicast",    GM_TXF_UC_OK },
-+      { "rx_unicast",    GM_RXF_UC_OK },
-+      { "tx_mac_pause",  GM_TXF_MPAUSE },
-+      { "rx_mac_pause",  GM_RXF_MPAUSE },
-+      { "collisions",    GM_TXF_SNG_COL },
-+      { "late_collision",GM_TXF_LAT_COL },
-+      { "aborted",       GM_TXF_ABO_COL },
-+      { "multi_collisions", GM_TXF_MUL_COL },
-+      { "fifo_underrun", GM_TXE_FIFO_UR },
-+      { "fifo_overflow", GM_RXE_FIFO_OV },
-+      { "rx_toolong",    GM_RXF_LNG_ERR },
-+      { "rx_jabber",     GM_RXF_JAB_PKT },
-+      { "rx_runt",       GM_RXE_FRAG },
-+      { "rx_too_long",   GM_RXF_LNG_ERR },
-+      { "rx_fcs_error",   GM_RXF_FCS_ERR },
-+};
-+
-+static u32 sky2_get_rx_csum(struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      return sky2->rx_csum;
-+}
-+
-+static int sky2_set_rx_csum(struct net_device *dev, u32 data)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      sky2->rx_csum = data;
-+
-+      sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
-+                   data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
-+
-+      return 0;
-+}
-+
-+static u32 sky2_get_msglevel(struct net_device *netdev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(netdev);
-+      return sky2->msg_enable;
-+}
-+
-+static int sky2_nway_reset(struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      if (sky2->autoneg != AUTONEG_ENABLE)
-+              return -EINVAL;
-+
-+      sky2_phy_reinit(sky2);
-+
-+      return 0;
-+}
-+
-+static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count)
-+{
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      int i;
-+
-+      data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
-+          | (u64) gma_read32(hw, port, GM_TXO_OK_LO);
-+      data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
-+          | (u64) gma_read32(hw, port, GM_RXO_OK_LO);
-+
-+      for (i = 2; i < count; i++)
-+              data[i] = (u64) gma_read32(hw, port, sky2_stats[i].offset);
-+}
-+
-+static void sky2_set_msglevel(struct net_device *netdev, u32 value)
-+{
-+      struct sky2_port *sky2 = netdev_priv(netdev);
-+      sky2->msg_enable = value;
-+}
-+
-+static int sky2_get_stats_count(struct net_device *dev)
-+{
-+      return ARRAY_SIZE(sky2_stats);
-+}
-+
-+static void sky2_get_ethtool_stats(struct net_device *dev,
-+                                 struct ethtool_stats *stats, u64 * data)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      sky2_phy_stats(sky2, data, ARRAY_SIZE(sky2_stats));
-+}
-+
-+static void sky2_get_strings(struct net_device *dev, u32 stringset, u8 * data)
-+{
-+      int i;
-+
-+      switch (stringset) {
-+      case ETH_SS_STATS:
-+              for (i = 0; i < ARRAY_SIZE(sky2_stats); i++)
-+                      memcpy(data + i * ETH_GSTRING_LEN,
-+                             sky2_stats[i].name, ETH_GSTRING_LEN);
-+              break;
-+      }
-+}
-+
-+/* Use hardware MIB variables for critical path statistics and
-+ * transmit feedback not reported at interrupt.
-+ * Other errors are accounted for in interrupt handler.
-+ */
-+static struct net_device_stats *sky2_get_stats(struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      u64 data[13];
-+
-+      sky2_phy_stats(sky2, data, ARRAY_SIZE(data));
-+
-+      sky2->net_stats.tx_bytes = data[0];
-+      sky2->net_stats.rx_bytes = data[1];
-+      sky2->net_stats.tx_packets = data[2] + data[4] + data[6];
-+      sky2->net_stats.rx_packets = data[3] + data[5] + data[7];
-+      sky2->net_stats.multicast = data[5] + data[7];
-+      sky2->net_stats.collisions = data[10];
-+      sky2->net_stats.tx_aborted_errors = data[12];
-+
-+      return &sky2->net_stats;
-+}
-+
-+static int sky2_set_mac_address(struct net_device *dev, void *p)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      const struct sockaddr *addr = p;
-+
-+      if (!is_valid_ether_addr(addr->sa_data))
-+              return -EADDRNOTAVAIL;
-+
-+      memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-+      memcpy_toio(hw->regs + B2_MAC_1 + port * 8,
-+                  dev->dev_addr, ETH_ALEN);
-+      memcpy_toio(hw->regs + B2_MAC_2 + port * 8,
-+                  dev->dev_addr, ETH_ALEN);
-+
-+      /* virtual address for data */
-+      gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
-+
-+      /* physical address: used for pause frames */
-+      gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
-+
-+      return 0;
-+}
-+
-+static void sky2_set_multicast(struct net_device *dev)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      struct dev_mc_list *list = dev->mc_list;
-+      u16 reg;
-+      u8 filter[8];
-+
-+      memset(filter, 0, sizeof(filter));
-+
-+      reg = gma_read16(hw, port, GM_RX_CTRL);
-+      reg |= GM_RXCR_UCF_ENA;
-+
-+      if (dev->flags & IFF_PROMISC)   /* promiscuous */
-+              reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
-+      else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16)     /* all multicast */
-+              memset(filter, 0xff, sizeof(filter));
-+      else if (dev->mc_count == 0)    /* no multicast */
-+              reg &= ~GM_RXCR_MCF_ENA;
-+      else {
-+              int i;
-+              reg |= GM_RXCR_MCF_ENA;
-+
-+              for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
-+                      u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
-+                      filter[bit / 8] |= 1 << (bit % 8);
-+              }
-+      }
-+
-+      gma_write16(hw, port, GM_MC_ADDR_H1,
-+                  (u16) filter[0] | ((u16) filter[1] << 8));
-+      gma_write16(hw, port, GM_MC_ADDR_H2,
-+                  (u16) filter[2] | ((u16) filter[3] << 8));
-+      gma_write16(hw, port, GM_MC_ADDR_H3,
-+                  (u16) filter[4] | ((u16) filter[5] << 8));
-+      gma_write16(hw, port, GM_MC_ADDR_H4,
-+                  (u16) filter[6] | ((u16) filter[7] << 8));
-+
-+      gma_write16(hw, port, GM_RX_CTRL, reg);
-+}
-+
-+/* Can have one global because blinking is controlled by
-+ * ethtool and that is always under RTNL mutex
-+ */
-+static void sky2_led(struct sky2_hw *hw, unsigned port, int on)
-+{
-+      u16 pg;
-+
-+      switch (hw->chip_id) {
-+      case CHIP_ID_YUKON_XL:
-+              pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
-+              gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
-+                           on ? (PHY_M_LEDC_LOS_CTRL(1) |
-+                                 PHY_M_LEDC_INIT_CTRL(7) |
-+                                 PHY_M_LEDC_STA1_CTRL(7) |
-+                                 PHY_M_LEDC_STA0_CTRL(7))
-+                           : 0);
-+
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
-+              break;
-+
-+      default:
-+              gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
-+              gm_phy_write(hw, port, PHY_MARV_LED_OVER,
-+                           on ? PHY_M_LED_MO_DUP(MO_LED_ON) |
-+                           PHY_M_LED_MO_10(MO_LED_ON) |
-+                           PHY_M_LED_MO_100(MO_LED_ON) |
-+                           PHY_M_LED_MO_1000(MO_LED_ON) |
-+                           PHY_M_LED_MO_RX(MO_LED_ON)
-+                           : PHY_M_LED_MO_DUP(MO_LED_OFF) |
-+                           PHY_M_LED_MO_10(MO_LED_OFF) |
-+                           PHY_M_LED_MO_100(MO_LED_OFF) |
-+                           PHY_M_LED_MO_1000(MO_LED_OFF) |
-+                           PHY_M_LED_MO_RX(MO_LED_OFF));
-+
-+      }
-+}
-+
-+/* blink LED's for finding board */
-+static int sky2_phys_id(struct net_device *dev, u32 data)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      unsigned port = sky2->port;
-+      u16 ledctrl, ledover = 0;
-+      long ms;
-+      int interrupted;
-+      int onoff = 1;
-+
-+      if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))
-+              ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT);
-+      else
-+              ms = data * 1000;
-+
-+      /* save initial values */
-+      down(&sky2->phy_sema);
-+      if (hw->chip_id == CHIP_ID_YUKON_XL) {
-+              u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
-+              ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
-+      } else {
-+              ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL);
-+              ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER);
-+      }
-+
-+      interrupted = 0;
-+      while (!interrupted && ms > 0) {
-+              sky2_led(hw, port, onoff);
-+              onoff = !onoff;
-+
-+              up(&sky2->phy_sema);
-+              interrupted = msleep_interruptible(250);
-+              down(&sky2->phy_sema);
-+
-+              ms -= 250;
-+      }
-+
-+      /* resume regularly scheduled programming */
-+      if (hw->chip_id == CHIP_ID_YUKON_XL) {
-+              u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
-+              gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl);
-+              gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
-+      } else {
-+              gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
-+              gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
-+      }
-+      up(&sky2->phy_sema);
-+
-+      return 0;
-+}
-+
-+static void sky2_get_pauseparam(struct net_device *dev,
-+                              struct ethtool_pauseparam *ecmd)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      ecmd->tx_pause = sky2->tx_pause;
-+      ecmd->rx_pause = sky2->rx_pause;
-+      ecmd->autoneg = sky2->autoneg;
-+}
-+
-+static int sky2_set_pauseparam(struct net_device *dev,
-+                             struct ethtool_pauseparam *ecmd)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      int err = 0;
-+
-+      sky2->autoneg = ecmd->autoneg;
-+      sky2->tx_pause = ecmd->tx_pause != 0;
-+      sky2->rx_pause = ecmd->rx_pause != 0;
-+
-+      sky2_phy_reinit(sky2);
-+
-+      return err;
-+}
-+
-+#ifdef CONFIG_PM
-+static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      wol->supported = WAKE_MAGIC;
-+      wol->wolopts = sky2->wol ? WAKE_MAGIC : 0;
-+}
-+
-+static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+
-+      if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
-+              return -EOPNOTSUPP;
-+
-+      sky2->wol = wol->wolopts == WAKE_MAGIC;
-+
-+      if (sky2->wol) {
-+              memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN);
-+
-+              sky2_write16(hw, WOL_CTRL_STAT,
-+                           WOL_CTL_ENA_PME_ON_MAGIC_PKT |
-+                           WOL_CTL_ENA_MAGIC_PKT_UNIT);
-+      } else
-+              sky2_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT);
-+
-+      return 0;
-+}
-+#endif
-+
-+static int sky2_get_coalesce(struct net_device *dev,
-+                           struct ethtool_coalesce *ecmd)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+
-+      if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_STOP)
-+              ecmd->tx_coalesce_usecs = 0;
-+      else {
-+              u32 clks = sky2_read32(hw, STAT_TX_TIMER_INI);
-+              ecmd->tx_coalesce_usecs = sky2_clk2us(hw, clks);
-+      }
-+      ecmd->tx_max_coalesced_frames = sky2_read16(hw, STAT_TX_IDX_TH);
-+
-+      if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_STOP)
-+              ecmd->rx_coalesce_usecs = 0;
-+      else {
-+              u32 clks = sky2_read32(hw, STAT_LEV_TIMER_INI);
-+              ecmd->rx_coalesce_usecs = sky2_clk2us(hw, clks);
-+      }
-+      ecmd->rx_max_coalesced_frames = sky2_read8(hw, STAT_FIFO_WM);
-+
-+      if (sky2_read8(hw, STAT_ISR_TIMER_CTRL) == TIM_STOP)
-+              ecmd->rx_coalesce_usecs_irq = 0;
-+      else {
-+              u32 clks = sky2_read32(hw, STAT_ISR_TIMER_INI);
-+              ecmd->rx_coalesce_usecs_irq = sky2_clk2us(hw, clks);
-+      }
-+
-+      ecmd->rx_max_coalesced_frames_irq = sky2_read8(hw, STAT_FIFO_ISR_WM);
-+
-+      return 0;
-+}
-+
-+/* Note: this affect both ports */
-+static int sky2_set_coalesce(struct net_device *dev,
-+                           struct ethtool_coalesce *ecmd)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      struct sky2_hw *hw = sky2->hw;
-+      const u32 tmin = sky2_clk2us(hw, 1);
-+      const u32 tmax = 5000;
-+
-+      if (ecmd->tx_coalesce_usecs != 0 &&
-+          (ecmd->tx_coalesce_usecs < tmin || ecmd->tx_coalesce_usecs > tmax))
-+              return -EINVAL;
-+
-+      if (ecmd->rx_coalesce_usecs != 0 &&
-+          (ecmd->rx_coalesce_usecs < tmin || ecmd->rx_coalesce_usecs > tmax))
-+              return -EINVAL;
-+
-+      if (ecmd->rx_coalesce_usecs_irq != 0 &&
-+          (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax))
-+              return -EINVAL;
-+
-+      if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1)
-+              return -EINVAL;
-+      if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING)
-+              return -EINVAL;
-+      if (ecmd->rx_max_coalesced_frames_irq >RX_MAX_PENDING)
-+              return -EINVAL;
-+
-+      if (ecmd->tx_coalesce_usecs == 0)
-+              sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
-+      else {
-+              sky2_write32(hw, STAT_TX_TIMER_INI,
-+                           sky2_us2clk(hw, ecmd->tx_coalesce_usecs));
-+              sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
-+      }
-+      sky2_write16(hw, STAT_TX_IDX_TH, ecmd->tx_max_coalesced_frames);
-+
-+      if (ecmd->rx_coalesce_usecs == 0)
-+              sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
-+      else {
-+              sky2_write32(hw, STAT_LEV_TIMER_INI,
-+                           sky2_us2clk(hw, ecmd->rx_coalesce_usecs));
-+              sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
-+      }
-+      sky2_write8(hw, STAT_FIFO_WM, ecmd->rx_max_coalesced_frames);
-+
-+      if (ecmd->rx_coalesce_usecs_irq == 0)
-+              sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
-+      else {
-+              sky2_write32(hw, STAT_ISR_TIMER_INI,
-+                           sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
-+              sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
-+      }
-+      sky2_write8(hw, STAT_FIFO_ISR_WM, ecmd->rx_max_coalesced_frames_irq);
-+      return 0;
-+}
-+
-+static void sky2_get_ringparam(struct net_device *dev,
-+                             struct ethtool_ringparam *ering)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      ering->rx_max_pending = RX_MAX_PENDING;
-+      ering->rx_mini_max_pending = 0;
-+      ering->rx_jumbo_max_pending = 0;
-+      ering->tx_max_pending = TX_RING_SIZE - 1;
-+
-+      ering->rx_pending = sky2->rx_pending;
-+      ering->rx_mini_pending = 0;
-+      ering->rx_jumbo_pending = 0;
-+      ering->tx_pending = sky2->tx_pending;
-+}
-+
-+static int sky2_set_ringparam(struct net_device *dev,
-+                            struct ethtool_ringparam *ering)
-+{
-+      struct sky2_port *sky2 = netdev_priv(dev);
-+      int err = 0;
-+
-+      if (ering->rx_pending > RX_MAX_PENDING ||
-+          ering->rx_pending < 8 ||
-+          ering->tx_pending < MAX_SKB_TX_LE ||
-+          ering->tx_pending > TX_RING_SIZE - 1)
-+              return -EINVAL;
-+
-+      if (netif_running(dev))
-+              sky2_down(dev);
-+
-+      sky2->rx_pending = ering->rx_pending;
-+      sky2->tx_pending = ering->tx_pending;
-+
-+      if (netif_running(dev)) {
-+              err = sky2_up(dev);
-+              if (err)
-+                      dev_close(dev);
-+              else
-+                      sky2_set_multicast(dev);
-+      }
-+
-+      return err;
-+}
-+
-+static int sky2_get_regs_len(struct net_device *dev)
-+{
-+      return 0x4000;
-+}
-+
-+/*
-+ * Returns copy of control register region
-+ * Note: access to the RAM address register set will cause timeouts.
-+ */
-+static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
-+                        void *p)
-+{
-+      const struct sky2_port *sky2 = netdev_priv(dev);
-+      const void __iomem *io = sky2->hw->regs;
-+
-+      BUG_ON(regs->len < B3_RI_WTO_R1);
-+      regs->version = 1;
-+      memset(p, 0, regs->len);
-+
-+      memcpy_fromio(p, io, B3_RAM_ADDR);
-+
-+      memcpy_fromio(p + B3_RI_WTO_R1,
-+                    io + B3_RI_WTO_R1,
-+                    regs->len - B3_RI_WTO_R1);
-+}
-+
-+static struct ethtool_ops sky2_ethtool_ops = {
-+      .get_settings = sky2_get_settings,
-+      .set_settings = sky2_set_settings,
-+      .get_drvinfo = sky2_get_drvinfo,
-+      .get_msglevel = sky2_get_msglevel,
-+      .set_msglevel = sky2_set_msglevel,
-+      .nway_reset   = sky2_nway_reset,
-+      .get_regs_len = sky2_get_regs_len,
-+      .get_regs = sky2_get_regs,
-+      .get_link = ethtool_op_get_link,
-+      .get_sg = ethtool_op_get_sg,
-+      .set_sg = ethtool_op_set_sg,
-+      .get_tx_csum = ethtool_op_get_tx_csum,
-+      .set_tx_csum = ethtool_op_set_tx_csum,
-+      .get_tso = ethtool_op_get_tso,
-+      .set_tso = ethtool_op_set_tso,
-+      .get_rx_csum = sky2_get_rx_csum,
-+      .set_rx_csum = sky2_set_rx_csum,
-+      .get_strings = sky2_get_strings,
-+      .get_coalesce = sky2_get_coalesce,
-+      .set_coalesce = sky2_set_coalesce,
-+      .get_ringparam = sky2_get_ringparam,
-+      .set_ringparam = sky2_set_ringparam,
-+      .get_pauseparam = sky2_get_pauseparam,
-+      .set_pauseparam = sky2_set_pauseparam,
-+#ifdef CONFIG_PM
-+      .get_wol = sky2_get_wol,
-+      .set_wol = sky2_set_wol,
-+#endif
-+      .phys_id = sky2_phys_id,
-+      .get_stats_count = sky2_get_stats_count,
-+      .get_ethtool_stats = sky2_get_ethtool_stats,
-+      .get_perm_addr  = ethtool_op_get_perm_addr,
-+};
-+
-+/* Initialize network device */
-+static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
-+                                                   unsigned port, int highmem)
-+{
-+      struct sky2_port *sky2;
-+      struct net_device *dev = alloc_etherdev(sizeof(*sky2));
-+
-+      if (!dev) {
-+              printk(KERN_ERR "sky2 etherdev alloc failed");
-+              return NULL;
-+      }
-+
-+      SET_MODULE_OWNER(dev);
-+      SET_NETDEV_DEV(dev, &hw->pdev->dev);
-+      dev->irq = hw->pdev->irq;
-+      dev->open = sky2_up;
-+      dev->stop = sky2_down;
-+      dev->do_ioctl = sky2_ioctl;
-+      dev->hard_start_xmit = sky2_xmit_frame;
-+      dev->get_stats = sky2_get_stats;
-+      dev->set_multicast_list = sky2_set_multicast;
-+      dev->set_mac_address = sky2_set_mac_address;
-+      dev->change_mtu = sky2_change_mtu;
-+      SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
-+      dev->tx_timeout = sky2_tx_timeout;
-+      dev->watchdog_timeo = TX_WATCHDOG;
-+      if (port == 0)
-+              dev->poll = sky2_poll;
-+      dev->weight = NAPI_WEIGHT;
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+      dev->poll_controller = sky2_netpoll;
-+#endif
-+
-+      sky2 = netdev_priv(dev);
-+      sky2->netdev = dev;
-+      sky2->hw = hw;
-+      sky2->msg_enable = netif_msg_init(debug, default_msg);
-+
-+      spin_lock_init(&sky2->tx_lock);
-+      /* Auto speed and flow control */
-+      sky2->autoneg = AUTONEG_ENABLE;
-+      sky2->tx_pause = 1;
-+      sky2->rx_pause = 1;
-+      sky2->duplex = -1;
-+      sky2->speed = -1;
-+      sky2->advertising = sky2_supported_modes(hw);
-+
-+      /* Receive checksum disabled for Yukon XL
-+       * because of observed problems with incorrect
-+       * values when multiple packets are received in one interrupt
-+       */
-+      sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
-+
-+      INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2);
-+      init_MUTEX(&sky2->phy_sema);
-+      sky2->tx_pending = TX_DEF_PENDING;
-+      sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING;
-+      sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
-+
-+      hw->dev[port] = dev;
-+
-+      sky2->port = port;
-+
-+      dev->features |= NETIF_F_LLTX;
-+      if (hw->chip_id != CHIP_ID_YUKON_EC_U)
-+              dev->features |= NETIF_F_TSO;
-+      if (highmem)
-+              dev->features |= NETIF_F_HIGHDMA;
-+      dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-+
-+#ifdef SKY2_VLAN_TAG_USED
-+      dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-+      dev->vlan_rx_register = sky2_vlan_rx_register;
-+      dev->vlan_rx_kill_vid = sky2_vlan_rx_kill_vid;
-+#endif
-+
-+      /* read the mac address */
-+      memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
-+      memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-+
-+      /* device is off until link detection */
-+      netif_carrier_off(dev);
-+      netif_stop_queue(dev);
-+
-+      return dev;
-+}
-+
-+static void __devinit sky2_show_addr(struct net_device *dev)
-+{
-+      const struct sky2_port *sky2 = netdev_priv(dev);
-+
-+      if (netif_msg_probe(sky2))
-+              printk(KERN_INFO PFX "%s: addr %02x:%02x:%02x:%02x:%02x:%02x\n",
-+                     dev->name,
-+                     dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-+                     dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
-+}
-+
-+static int __devinit sky2_probe(struct pci_dev *pdev,
-+                              const struct pci_device_id *ent)
-+{
-+      struct net_device *dev, *dev1 = NULL;
-+      struct sky2_hw *hw;
-+      int err, pm_cap, using_dac = 0;
-+
-+      err = pci_enable_device(pdev);
-+      if (err) {
-+              printk(KERN_ERR PFX "%s cannot enable PCI device\n",
-+                     pci_name(pdev));
-+              goto err_out;
-+      }
-+
-+      err = pci_request_regions(pdev, DRV_NAME);
-+      if (err) {
-+              printk(KERN_ERR PFX "%s cannot obtain PCI resources\n",
-+                     pci_name(pdev));
-+              goto err_out;
-+      }
-+
-+      pci_set_master(pdev);
-+
-+      /* Find power-management capability. */
-+      pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
-+      if (pm_cap == 0) {
-+              printk(KERN_ERR PFX "Cannot find PowerManagement capability, "
-+                     "aborting.\n");
-+              err = -EIO;
-+              goto err_out_free_regions;
-+      }
-+
-+      if (sizeof(dma_addr_t) > sizeof(u32) &&
-+          !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
-+              using_dac = 1;
-+              err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
-+              if (err < 0) {
-+                      printk(KERN_ERR PFX "%s unable to obtain 64 bit DMA "
-+                             "for consistent allocations\n", pci_name(pdev));
-+                      goto err_out_free_regions;
-+              }
-+
-+      } else {
-+              err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-+              if (err) {
-+                      printk(KERN_ERR PFX "%s no usable DMA configuration\n",
-+                             pci_name(pdev));
-+                      goto err_out_free_regions;
-+              }
-+      }
-+
-+      err = -ENOMEM;
-+      hw = kzalloc(sizeof(*hw), GFP_KERNEL);
-+      if (!hw) {
-+              printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
-+                     pci_name(pdev));
-+              goto err_out_free_regions;
-+      }
-+
-+      hw->pdev = pdev;
-+
-+      hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
-+      if (!hw->regs) {
-+              printk(KERN_ERR PFX "%s: cannot map device registers\n",
-+                     pci_name(pdev));
-+              goto err_out_free_hw;
-+      }
-+      hw->pm_cap = pm_cap;
-+      spin_lock_init(&hw->hw_lock);
-+
-+#ifdef __BIG_ENDIAN
-+      /* byte swap descriptors in hardware */
-+      {
-+              u32 reg;
-+
-+              reg = sky2_pci_read32(hw, PCI_DEV_REG2);
-+              reg |= PCI_REV_DESC;
-+              sky2_pci_write32(hw, PCI_DEV_REG2, reg);
-+      }
-+#endif
-+
-+      /* ring for status responses */
-+      hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
-+                                       &hw->st_dma);
-+      if (!hw->st_le)
-+              goto err_out_iounmap;
-+
-+      err = sky2_reset(hw);
-+      if (err)
-+              goto err_out_iounmap;
-+
-+      printk(KERN_INFO PFX "v%s addr 0x%lx irq %d Yukon-%s (0x%x) rev %d\n",
-+             DRV_VERSION, pci_resource_start(pdev, 0), pdev->irq,
-+             yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL],
-+             hw->chip_id, hw->chip_rev);
-+
-+      dev = sky2_init_netdev(hw, 0, using_dac);
-+      if (!dev)
-+              goto err_out_free_pci;
-+
-+      err = register_netdev(dev);
-+      if (err) {
-+              printk(KERN_ERR PFX "%s: cannot register net device\n",
-+                     pci_name(pdev));
-+              goto err_out_free_netdev;
-+      }
-+
-+      sky2_show_addr(dev);
-+
-+      if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) {
-+              if (register_netdev(dev1) == 0)
-+                      sky2_show_addr(dev1);
-+              else {
-+                      /* Failure to register second port need not be fatal */
-+                      printk(KERN_WARNING PFX
-+                             "register of second port failed\n");
-+                      hw->dev[1] = NULL;
-+                      free_netdev(dev1);
-+              }
-+      }
-+
-+      err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
-+      if (err) {
-+              printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
-+                     pci_name(pdev), pdev->irq);
-+              goto err_out_unregister;
-+      }
-+
-+      hw->intr_mask = Y2_IS_BASE;
-+      sky2_write32(hw, B0_IMSK, hw->intr_mask);
-+
-+      pci_set_drvdata(pdev, hw);
-+
-+      return 0;
-+
-+err_out_unregister:
-+      if (dev1) {
-+              unregister_netdev(dev1);
-+              free_netdev(dev1);
-+      }
-+      unregister_netdev(dev);
-+err_out_free_netdev:
-+      free_netdev(dev);
-+err_out_free_pci:
-+      sky2_write8(hw, B0_CTST, CS_RST_SET);
-+      pci_free_consistent(hw->pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
-+err_out_iounmap:
-+      iounmap(hw->regs);
-+err_out_free_hw:
-+      kfree(hw);
-+err_out_free_regions:
-+      pci_release_regions(pdev);
-+      pci_disable_device(pdev);
-+err_out:
-+      return err;
-+}
-+
-+static void __devexit sky2_remove(struct pci_dev *pdev)
-+{
-+      struct sky2_hw *hw = pci_get_drvdata(pdev);
-+      struct net_device *dev0, *dev1;
-+
-+      if (!hw)
-+              return;
-+
-+      dev0 = hw->dev[0];
-+      dev1 = hw->dev[1];
-+      if (dev1)
-+              unregister_netdev(dev1);
-+      unregister_netdev(dev0);
-+
-+      sky2_write32(hw, B0_IMSK, 0);
-+      sky2_set_power_state(hw, PCI_D3hot);
-+      sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
-+      sky2_write8(hw, B0_CTST, CS_RST_SET);
-+      sky2_read8(hw, B0_CTST);
-+
-+      free_irq(pdev->irq, hw);
-+      pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
-+      pci_release_regions(pdev);
-+      pci_disable_device(pdev);
-+
-+      if (dev1)
-+              free_netdev(dev1);
-+      free_netdev(dev0);
-+      iounmap(hw->regs);
-+      kfree(hw);
-+
-+      pci_set_drvdata(pdev, NULL);
-+}
-+
-+#ifdef CONFIG_PM
-+static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
-+{
-+      struct sky2_hw *hw = pci_get_drvdata(pdev);
-+      int i;
-+
-+      for (i = 0; i < 2; i++) {
-+              struct net_device *dev = hw->dev[i];
-+
-+              if (dev) {
-+                      if (!netif_running(dev))
-+                              continue;
-+
-+                      sky2_down(dev);
-+                      netif_device_detach(dev);
-+              }
-+      }
-+
-+      return sky2_set_power_state(hw, pci_choose_state(pdev, state));
-+}
-+
-+static int sky2_resume(struct pci_dev *pdev)
-+{
-+      struct sky2_hw *hw = pci_get_drvdata(pdev);
-+      int i, err;
-+
-+      pci_restore_state(pdev);
-+      pci_enable_wake(pdev, PCI_D0, 0);
-+      err = sky2_set_power_state(hw, PCI_D0);
-+      if (err)
-+              goto out;
-+
-+      err = sky2_reset(hw);
-+      if (err)
-+              goto out;
-+
-+      for (i = 0; i < 2; i++) {
-+              struct net_device *dev = hw->dev[i];
-+              if (dev && netif_running(dev)) {
-+                      netif_device_attach(dev);
-+                      err = sky2_up(dev);
-+                      if (err) {
-+                              printk(KERN_ERR PFX "%s: could not up: %d\n",
-+                                     dev->name, err);
-+                              dev_close(dev);
-+                              break;
-+                      }
-+              }
-+      }
-+out:
-+      return err;
-+}
-+#endif
-+
-+static struct pci_driver sky2_driver = {
-+      .name = DRV_NAME,
-+      .id_table = sky2_id_table,
-+      .probe = sky2_probe,
-+      .remove = __devexit_p(sky2_remove),
-+#ifdef CONFIG_PM
-+      .suspend = sky2_suspend,
-+      .resume = sky2_resume,
-+#endif
-+};
-+
-+static int __init sky2_init_module(void)
-+{
-+      return pci_register_driver(&sky2_driver);
-+}
-+
-+static void __exit sky2_cleanup_module(void)
-+{
-+      pci_unregister_driver(&sky2_driver);
-+}
-+
-+module_init(sky2_init_module);
-+module_exit(sky2_cleanup_module);
-+
-+MODULE_DESCRIPTION("Marvell Yukon 2 Gigabit Ethernet driver");
-+MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-diff -Nur linux-2.6.16.33-noxen/drivers/net/tg3.c linux-2.6.16.33/drivers/net/tg3.c
---- linux-2.6.16.33-noxen/drivers/net/tg3.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/tg3.c  2007-05-23 21:00:01.000000000 +0000
-@@ -3664,7 +3664,7 @@
- #if TG3_TSO_SUPPORT != 0
-       mss = 0;
-       if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
--          (mss = skb_shinfo(skb)->tso_size) != 0) {
-+          (mss = skb_shinfo(skb)->gso_size) != 0) {
-               int tcp_opt_len, ip_tcp_len;
-               if (skb_header_cloned(skb) &&
-diff -Nur linux-2.6.16.33-noxen/drivers/net/tulip/winbond-840.c linux-2.6.16.33/drivers/net/tulip/winbond-840.c
---- linux-2.6.16.33-noxen/drivers/net/tulip/winbond-840.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/tulip/winbond-840.c    2007-05-23 21:00:01.000000000 +0000
-@@ -1605,11 +1605,11 @@
-  * - get_stats:
-  *    spin_lock_irq(np->lock), doesn't touch hw if not present
-  * - hard_start_xmit:
-- *    netif_stop_queue + spin_unlock_wait(&dev->xmit_lock);
-+ *    synchronize_irq + netif_tx_disable;
-  * - tx_timeout:
-- *    netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
-+ *    netif_device_detach + netif_tx_disable;
-  * - set_multicast_list
-- *    netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
-+ *    netif_device_detach + netif_tx_disable;
-  * - interrupt handler
-  *    doesn't touch hw if not present, synchronize_irq waits for
-  *    running instances of the interrupt handler.
-@@ -1635,11 +1635,10 @@
-               netif_device_detach(dev);
-               update_csr6(dev, 0);
-               iowrite32(0, ioaddr + IntrEnable);
--              netif_stop_queue(dev);
-               spin_unlock_irq(&np->lock);
--              spin_unlock_wait(&dev->xmit_lock);
-               synchronize_irq(dev->irq);
-+              netif_tx_disable(dev);
-       
-               np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
-diff -Nur linux-2.6.16.33-noxen/drivers/net/typhoon.c linux-2.6.16.33/drivers/net/typhoon.c
---- linux-2.6.16.33-noxen/drivers/net/typhoon.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/typhoon.c      2007-05-23 21:00:01.000000000 +0000
-@@ -340,7 +340,7 @@
- #endif
- #if defined(NETIF_F_TSO)
--#define skb_tso_size(x)               (skb_shinfo(x)->tso_size)
-+#define skb_tso_size(x)               (skb_shinfo(x)->gso_size)
- #define TSO_NUM_DESCRIPTORS   2
- #define TSO_OFFLOAD_ON                TYPHOON_OFFLOAD_TCP_SEGMENT
- #else
-@@ -805,7 +805,7 @@
-        * If problems develop with TSO, check this first.
-        */
-       numDesc = skb_shinfo(skb)->nr_frags + 1;
--      if(skb_tso_size(skb))
-+      if (skb_is_gso(skb))
-               numDesc++;
-       /* When checking for free space in the ring, we need to also
-@@ -845,7 +845,7 @@
-                               TYPHOON_TX_PF_VLAN_TAG_SHIFT);
-       }
--      if(skb_tso_size(skb)) {
-+      if (skb_is_gso(skb)) {
-               first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT;
-               first_txd->numDesc++;
-diff -Nur linux-2.6.16.33-noxen/drivers/net/via-velocity.c linux-2.6.16.33/drivers/net/via-velocity.c
---- linux-2.6.16.33-noxen/drivers/net/via-velocity.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/via-velocity.c 2007-05-23 21:00:01.000000000 +0000
-@@ -1905,6 +1905,13 @@
-       int pktlen = skb->len;
-+#ifdef VELOCITY_ZERO_COPY_SUPPORT
-+      if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
-+              kfree_skb(skb);
-+              return 0;
-+      }
-+#endif
-+
-       spin_lock_irqsave(&vptr->lock, flags);
-       index = vptr->td_curr[qnum];
-@@ -1920,8 +1927,6 @@
-        */
-       if (pktlen < ETH_ZLEN) {
-               /* Cannot occur until ZC support */
--              if(skb_linearize(skb, GFP_ATOMIC))
--                      return 0; 
-               pktlen = ETH_ZLEN;
-               memcpy(tdinfo->buf, skb->data, skb->len);
-               memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
-@@ -1939,7 +1944,6 @@
-               int nfrags = skb_shinfo(skb)->nr_frags;
-               tdinfo->skb = skb;
-               if (nfrags > 6) {
--                      skb_linearize(skb, GFP_ATOMIC);
-                       memcpy(tdinfo->buf, skb->data, skb->len);
-                       tdinfo->skb_dma[0] = tdinfo->buf_dma;
-                       td_ptr->tdesc0.pktsize = 
-diff -Nur linux-2.6.16.33-noxen/drivers/net/wireless/orinoco.c linux-2.6.16.33/drivers/net/wireless/orinoco.c
---- linux-2.6.16.33-noxen/drivers/net/wireless/orinoco.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/net/wireless/orinoco.c     2007-05-23 21:00:01.000000000 +0000
-@@ -1835,7 +1835,9 @@
-       /* Set promiscuity / multicast*/
-       priv->promiscuous = 0;
-       priv->mc_count = 0;
--      __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
-+
-+      /* FIXME: what about netif_tx_lock */
-+      __orinoco_set_multicast_list(dev);
-       return 0;
- }
-diff -Nur linux-2.6.16.33-noxen/drivers/oprofile/buffer_sync.c linux-2.6.16.33/drivers/oprofile/buffer_sync.c
---- linux-2.6.16.33-noxen/drivers/oprofile/buffer_sync.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/oprofile/buffer_sync.c     2007-05-23 21:00:01.000000000 +0000
-@@ -6,6 +6,10 @@
-  *
-  * @author John Levon <levon@movementarian.org>
-  *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ *
-  * This is the core of the buffer management. Each
-  * CPU buffer is processed and entered into the
-  * global event buffer. Such processing is necessary
-@@ -38,6 +42,7 @@
- static DEFINE_SPINLOCK(task_mortuary);
- static void process_task_mortuary(void);
-+static int cpu_current_domain[NR_CPUS];
- /* Take ownership of the task struct and place it on the
-  * list for processing. Only after two full buffer syncs
-@@ -146,6 +151,11 @@
- int sync_start(void)
- {
-       int err;
-+      int i;
-+
-+      for (i = 0; i < NR_CPUS; i++) {
-+              cpu_current_domain[i] = COORDINATOR_DOMAIN;
-+      }
-       start_cpu_work();
-@@ -275,15 +285,31 @@
-       last_cookie = INVALID_COOKIE;
- }
--static void add_kernel_ctx_switch(unsigned int in_kernel)
-+static void add_cpu_mode_switch(unsigned int cpu_mode)
- {
-       add_event_entry(ESCAPE_CODE);
--      if (in_kernel)
--              add_event_entry(KERNEL_ENTER_SWITCH_CODE); 
--      else
--              add_event_entry(KERNEL_EXIT_SWITCH_CODE); 
-+      switch (cpu_mode) {
-+      case CPU_MODE_USER:
-+              add_event_entry(USER_ENTER_SWITCH_CODE);
-+              break;
-+      case CPU_MODE_KERNEL:
-+              add_event_entry(KERNEL_ENTER_SWITCH_CODE);
-+              break;
-+      case CPU_MODE_XEN:
-+              add_event_entry(XEN_ENTER_SWITCH_CODE);
-+              break;
-+      default:
-+              break;
-+      }
- }
-- 
-+
-+static void add_domain_switch(unsigned long domain_id)
-+{
-+      add_event_entry(ESCAPE_CODE);
-+      add_event_entry(DOMAIN_SWITCH_CODE);
-+      add_event_entry(domain_id);
-+}
-+
- static void
- add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
- {
-@@ -348,9 +374,9 @@
-  * for later lookup from userspace.
-  */
- static int
--add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
-+add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
- {
--      if (in_kernel) {
-+      if (cpu_mode >= CPU_MODE_KERNEL) {
-               add_sample_entry(s->eip, s->event);
-               return 1;
-       } else if (mm) {
-@@ -496,15 +522,21 @@
-       struct mm_struct *mm = NULL;
-       struct task_struct * new;
-       unsigned long cookie = 0;
--      int in_kernel = 1;
-+      int cpu_mode = 1;
-       unsigned int i;
-       sync_buffer_state state = sb_buffer_start;
-       unsigned long available;
-+      int domain_switch = 0;
-       down(&buffer_sem);
-  
-       add_cpu_switch(cpu);
-+      /* We need to assign the first samples in this CPU buffer to the
-+         same domain that we were processing at the last sync_buffer */
-+      if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
-+              add_domain_switch(cpu_current_domain[cpu]);
-+      }
-       /* Remember, only we can modify tail_pos */
-       available = get_slots(cpu_buf);
-@@ -512,16 +544,18 @@
-       for (i = 0; i < available; ++i) {
-               struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
-  
--              if (is_code(s->eip)) {
--                      if (s->event <= CPU_IS_KERNEL) {
--                              /* kernel/userspace switch */
--                              in_kernel = s->event;
-+              if (is_code(s->eip) && !domain_switch) {
-+                      if (s->event <= CPU_MODE_XEN) {
-+                              /* xen/kernel/userspace switch */
-+                              cpu_mode = s->event;
-                               if (state == sb_buffer_start)
-                                       state = sb_sample_start;
--                              add_kernel_ctx_switch(s->event);
-+                              add_cpu_mode_switch(s->event);
-                       } else if (s->event == CPU_TRACE_BEGIN) {
-                               state = sb_bt_start;
-                               add_trace_begin();
-+                      } else if (s->event == CPU_DOMAIN_SWITCH) {
-+                                      domain_switch = 1;                              
-                       } else {
-                               struct mm_struct * oldmm = mm;
-@@ -535,11 +569,21 @@
-                               add_user_ctx_switch(new, cookie);
-                       }
-               } else {
--                      if (state >= sb_bt_start &&
--                          !add_sample(mm, s, in_kernel)) {
--                              if (state == sb_bt_start) {
--                                      state = sb_bt_ignore;
--                                      atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-+                      if (domain_switch) {
-+                              cpu_current_domain[cpu] = s->eip;
-+                              add_domain_switch(s->eip);
-+                              domain_switch = 0;
-+                      } else {
-+                              if (cpu_current_domain[cpu] !=
-+                                  COORDINATOR_DOMAIN) {
-+                                      add_sample_entry(s->eip, s->event);
-+                              }
-+                              else  if (state >= sb_bt_start &&
-+                                  !add_sample(mm, s, cpu_mode)) {
-+                                      if (state == sb_bt_start) {
-+                                              state = sb_bt_ignore;
-+                                              atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-+                                      }
-                               }
-                       }
-               }
-@@ -548,6 +592,11 @@
-       }
-       release_mm(mm);
-+      /* We reset domain to COORDINATOR at each CPU switch */
-+      if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
-+              add_domain_switch(COORDINATOR_DOMAIN);
-+      }
-+
-       mark_done(cpu);
-       up(&buffer_sem);
-diff -Nur linux-2.6.16.33-noxen/drivers/oprofile/cpu_buffer.c linux-2.6.16.33/drivers/oprofile/cpu_buffer.c
---- linux-2.6.16.33-noxen/drivers/oprofile/cpu_buffer.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/oprofile/cpu_buffer.c      2007-05-23 21:00:01.000000000 +0000
-@@ -6,6 +6,10 @@
-  *
-  * @author John Levon <levon@movementarian.org>
-  *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ *
-  * Each CPU has a local buffer that stores PC value/event
-  * pairs. We also log context switches when we notice them.
-  * Eventually each CPU's buffer is processed into the global
-@@ -34,6 +38,8 @@
- #define DEFAULT_TIMER_EXPIRE (HZ / 10)
- static int work_enabled;
-+static int32_t current_domain = COORDINATOR_DOMAIN;
-+
- void free_cpu_buffers(void)
- {
-       int i;
-@@ -58,7 +64,7 @@
-                       goto fail;
-  
-               b->last_task = NULL;
--              b->last_is_kernel = -1;
-+              b->last_cpu_mode = -1;
-               b->tracing = 0;
-               b->buffer_size = buffer_size;
-               b->tail_pos = 0;
-@@ -114,7 +120,7 @@
-        * collected will populate the buffer with proper
-        * values to initialize the buffer
-        */
--      cpu_buf->last_is_kernel = -1;
-+      cpu_buf->last_cpu_mode = -1;
-       cpu_buf->last_task = NULL;
- }
-@@ -164,13 +170,13 @@
-  * because of the head/tail separation of the writer and reader
-  * of the CPU buffer.
-  *
-- * is_kernel is needed because on some architectures you cannot
-+ * cpu_mode is needed because on some architectures you cannot
-  * tell if you are in kernel or user space simply by looking at
-- * pc. We tag this in the buffer by generating kernel enter/exit
-- * events whenever is_kernel changes
-+ * pc. We tag this in the buffer by generating kernel/user (and xen)
-+ *  enter events whenever cpu_mode changes
-  */
- static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
--                    int is_kernel, unsigned long event)
-+                    int cpu_mode, unsigned long event)
- {
-       struct task_struct * task;
-@@ -181,18 +187,18 @@
-               return 0;
-       }
--      is_kernel = !!is_kernel;
--
-       task = current;
-       /* notice a switch from user->kernel or vice versa */
--      if (cpu_buf->last_is_kernel != is_kernel) {
--              cpu_buf->last_is_kernel = is_kernel;
--              add_code(cpu_buf, is_kernel);
-+      if (cpu_buf->last_cpu_mode != cpu_mode) {
-+              cpu_buf->last_cpu_mode = cpu_mode;
-+              add_code(cpu_buf, cpu_mode);
-       }
--
-+      
-       /* notice a task switch */
--      if (cpu_buf->last_task != task) {
-+      /* if not processing other domain samples */
-+      if ((cpu_buf->last_task != task) &&
-+          (current_domain == COORDINATOR_DOMAIN)) {
-               cpu_buf->last_task = task;
-               add_code(cpu_buf, (unsigned long)task);
-       }
-@@ -269,6 +275,25 @@
-       add_sample(cpu_buf, pc, 0);
- }
-+int oprofile_add_domain_switch(int32_t domain_id)
-+{
-+      struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()];
-+
-+      /* should have space for switching into and out of domain 
-+         (2 slots each) plus one sample and one cpu mode switch */
-+      if (((nr_available_slots(cpu_buf) < 6) && 
-+           (domain_id != COORDINATOR_DOMAIN)) ||
-+          (nr_available_slots(cpu_buf) < 2))
-+              return 0;
-+
-+      add_code(cpu_buf, CPU_DOMAIN_SWITCH);
-+      add_sample(cpu_buf, domain_id, 0);
-+
-+      current_domain = domain_id;
-+
-+      return 1;
-+}
-+
- /*
-  * This serves to avoid cpu buffer overflow, and makes sure
-  * the task mortuary progresses
-diff -Nur linux-2.6.16.33-noxen/drivers/oprofile/cpu_buffer.h linux-2.6.16.33/drivers/oprofile/cpu_buffer.h
---- linux-2.6.16.33-noxen/drivers/oprofile/cpu_buffer.h        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/oprofile/cpu_buffer.h      2007-05-23 21:00:01.000000000 +0000
-@@ -36,7 +36,7 @@
-       volatile unsigned long tail_pos;
-       unsigned long buffer_size;
-       struct task_struct * last_task;
--      int last_is_kernel;
-+      int last_cpu_mode;
-       int tracing;
-       struct op_sample * buffer;
-       unsigned long sample_received;
-@@ -51,7 +51,10 @@
- void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
- /* transient events for the CPU buffer -> event buffer */
--#define CPU_IS_KERNEL 1
--#define CPU_TRACE_BEGIN 2
-+#define CPU_MODE_USER           0
-+#define CPU_MODE_KERNEL         1
-+#define CPU_MODE_XEN            2
-+#define CPU_TRACE_BEGIN         3
-+#define CPU_DOMAIN_SWITCH       4
- #endif /* OPROFILE_CPU_BUFFER_H */
-diff -Nur linux-2.6.16.33-noxen/drivers/oprofile/event_buffer.h linux-2.6.16.33/drivers/oprofile/event_buffer.h
---- linux-2.6.16.33-noxen/drivers/oprofile/event_buffer.h      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/oprofile/event_buffer.h    2007-05-23 21:00:01.000000000 +0000
-@@ -29,15 +29,20 @@
- #define CPU_SWITCH_CODE               2
- #define COOKIE_SWITCH_CODE            3
- #define KERNEL_ENTER_SWITCH_CODE      4
--#define KERNEL_EXIT_SWITCH_CODE               5
-+#define USER_ENTER_SWITCH_CODE                5
- #define MODULE_LOADED_CODE            6
- #define CTX_TGID_CODE                 7
- #define TRACE_BEGIN_CODE              8
- #define TRACE_END_CODE                        9
-+#define XEN_ENTER_SWITCH_CODE         10
-+#define DOMAIN_SWITCH_CODE            11
-  
- #define INVALID_COOKIE ~0UL
- #define NO_COOKIE 0UL
-+/* Constant used to refer to coordinator domain (Xen) */
-+#define COORDINATOR_DOMAIN -1
-+
- /* add data to the event buffer */
- void add_event_entry(unsigned long data);
-  
-diff -Nur linux-2.6.16.33-noxen/drivers/oprofile/oprof.c linux-2.6.16.33/drivers/oprofile/oprof.c
---- linux-2.6.16.33-noxen/drivers/oprofile/oprof.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/oprofile/oprof.c   2007-05-23 21:00:01.000000000 +0000
-@@ -5,6 +5,10 @@
-  * @remark Read the file COPYING
-  *
-  * @author John Levon <levon@movementarian.org>
-+ *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-  */
- #include <linux/kernel.h>
-@@ -19,7 +23,7 @@
- #include "cpu_buffer.h"
- #include "buffer_sync.h"
- #include "oprofile_stats.h"
-- 
-+
- struct oprofile_operations oprofile_ops;
- unsigned long oprofile_started;
-@@ -33,6 +37,32 @@
-  */
- static int timer = 0;
-+int oprofile_set_active(int active_domains[], unsigned int adomains)
-+{
-+      int err;
-+
-+      if (!oprofile_ops.set_active)
-+              return -EINVAL;
-+
-+      down(&start_sem);
-+      err = oprofile_ops.set_active(active_domains, adomains);
-+      up(&start_sem);
-+      return err;
-+}
-+
-+int oprofile_set_passive(int passive_domains[], unsigned int pdomains)
-+{
-+      int err;
-+
-+      if (!oprofile_ops.set_passive)
-+              return -EINVAL;
-+
-+      down(&start_sem);
-+      err = oprofile_ops.set_passive(passive_domains, pdomains);
-+      up(&start_sem);
-+      return err;
-+}
-+
- int oprofile_setup(void)
- {
-       int err;
-diff -Nur linux-2.6.16.33-noxen/drivers/oprofile/oprof.h linux-2.6.16.33/drivers/oprofile/oprof.h
---- linux-2.6.16.33-noxen/drivers/oprofile/oprof.h     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/oprofile/oprof.h   2007-05-23 21:00:01.000000000 +0000
-@@ -35,5 +35,8 @@
- void oprofile_timer_init(struct oprofile_operations * ops);
- int oprofile_set_backtrace(unsigned long depth);
-+
-+int oprofile_set_active(int active_domains[], unsigned int adomains);
-+int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
-  
- #endif /* OPROF_H */
-diff -Nur linux-2.6.16.33-noxen/drivers/oprofile/oprofile_files.c linux-2.6.16.33/drivers/oprofile/oprofile_files.c
---- linux-2.6.16.33-noxen/drivers/oprofile/oprofile_files.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/oprofile/oprofile_files.c  2007-05-23 21:00:01.000000000 +0000
-@@ -5,15 +5,21 @@
-  * @remark Read the file COPYING
-  *
-  * @author John Levon <levon@movementarian.org>
-+ *
-+ * Modified by Aravind Menon for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.     
-  */
- #include <linux/fs.h>
- #include <linux/oprofile.h>
-+#include <asm/uaccess.h>
-+#include <linux/ctype.h>
- #include "event_buffer.h"
- #include "oprofile_stats.h"
- #include "oprof.h"
-- 
-+
- unsigned long fs_buffer_size = 131072;
- unsigned long fs_cpu_buffer_size = 8192;
- unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-@@ -117,11 +123,202 @@
- static struct file_operations dump_fops = {
-       .write          = dump_write,
- };
-- 
-+
-+#define TMPBUFSIZE 512
-+
-+static unsigned int adomains = 0;
-+static int active_domains[MAX_OPROF_DOMAINS + 1];
-+static DEFINE_MUTEX(adom_mutex);
-+
-+static ssize_t adomain_write(struct file * file, char const __user * buf, 
-+                           size_t count, loff_t * offset)
-+{
-+      char *tmpbuf;
-+      char *startp, *endp;
-+      int i;
-+      unsigned long val;
-+      ssize_t retval = count;
-+      
-+      if (*offset)
-+              return -EINVAL; 
-+      if (count > TMPBUFSIZE - 1)
-+              return -EINVAL;
-+
-+      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
-+              return -ENOMEM;
-+
-+      if (copy_from_user(tmpbuf, buf, count)) {
-+              kfree(tmpbuf);
-+              return -EFAULT;
-+      }
-+      tmpbuf[count] = 0;
-+
-+      mutex_lock(&adom_mutex);
-+
-+      startp = tmpbuf;
-+      /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
-+      for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
-+              val = simple_strtoul(startp, &endp, 0);
-+              if (endp == startp)
-+                      break;
-+              while (ispunct(*endp) || isspace(*endp))
-+                      endp++;
-+              active_domains[i] = val;
-+              if (active_domains[i] != val)
-+                      /* Overflow, force error below */
-+                      i = MAX_OPROF_DOMAINS + 1;
-+              startp = endp;
-+      }
-+      /* Force error on trailing junk */
-+      adomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
-+
-+      kfree(tmpbuf);
-+
-+      if (adomains > MAX_OPROF_DOMAINS
-+          || oprofile_set_active(active_domains, adomains)) {
-+              adomains = 0;
-+              retval = -EINVAL;
-+      }
-+
-+      mutex_unlock(&adom_mutex);
-+      return retval;
-+}
-+
-+static ssize_t adomain_read(struct file * file, char __user * buf, 
-+                          size_t count, loff_t * offset)
-+{
-+      char * tmpbuf;
-+      size_t len;
-+      int i;
-+      ssize_t retval;
-+
-+      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
-+              return -ENOMEM;
-+
-+      mutex_lock(&adom_mutex);
-+
-+      len = 0;
-+      for (i = 0; i < adomains; i++)
-+              len += snprintf(tmpbuf + len,
-+                              len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
-+                              "%u ", active_domains[i]);
-+      WARN_ON(len > TMPBUFSIZE);
-+      if (len != 0 && len <= TMPBUFSIZE)
-+              tmpbuf[len-1] = '\n';
-+
-+      mutex_unlock(&adom_mutex);
-+
-+      retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
-+
-+      kfree(tmpbuf);
-+      return retval;
-+}
-+
-+
-+static struct file_operations active_domain_ops = {
-+      .read           = adomain_read,
-+      .write          = adomain_write,
-+};
-+
-+static unsigned int pdomains = 0;
-+static int passive_domains[MAX_OPROF_DOMAINS];
-+static DEFINE_MUTEX(pdom_mutex);
-+
-+static ssize_t pdomain_write(struct file * file, char const __user * buf, 
-+                           size_t count, loff_t * offset)
-+{
-+      char *tmpbuf;
-+      char *startp, *endp;
-+      int i;
-+      unsigned long val;
-+      ssize_t retval = count;
-+      
-+      if (*offset)
-+              return -EINVAL; 
-+      if (count > TMPBUFSIZE - 1)
-+              return -EINVAL;
-+
-+      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
-+              return -ENOMEM;
-+
-+      if (copy_from_user(tmpbuf, buf, count)) {
-+              kfree(tmpbuf);
-+              return -EFAULT;
-+      }
-+      tmpbuf[count] = 0;
-+
-+      mutex_lock(&pdom_mutex);
-+
-+      startp = tmpbuf;
-+      /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
-+      for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
-+              val = simple_strtoul(startp, &endp, 0);
-+              if (endp == startp)
-+                      break;
-+              while (ispunct(*endp) || isspace(*endp))
-+                      endp++;
-+              passive_domains[i] = val;
-+              if (passive_domains[i] != val)
-+                      /* Overflow, force error below */
-+                      i = MAX_OPROF_DOMAINS + 1;
-+              startp = endp;
-+      }
-+      /* Force error on trailing junk */
-+      pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
-+
-+      kfree(tmpbuf);
-+
-+      if (pdomains > MAX_OPROF_DOMAINS
-+          || oprofile_set_passive(passive_domains, pdomains)) {
-+              pdomains = 0;
-+              retval = -EINVAL;
-+      }
-+
-+      mutex_unlock(&pdom_mutex);
-+      return retval;
-+}
-+
-+static ssize_t pdomain_read(struct file * file, char __user * buf, 
-+                          size_t count, loff_t * offset)
-+{
-+      char * tmpbuf;
-+      size_t len;
-+      int i;
-+      ssize_t retval;
-+
-+      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
-+              return -ENOMEM;
-+
-+      mutex_lock(&pdom_mutex);
-+
-+      len = 0;
-+      for (i = 0; i < pdomains; i++)
-+              len += snprintf(tmpbuf + len,
-+                              len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
-+                              "%u ", passive_domains[i]);
-+      WARN_ON(len > TMPBUFSIZE);
-+      if (len != 0 && len <= TMPBUFSIZE)
-+              tmpbuf[len-1] = '\n';
-+
-+      mutex_unlock(&pdom_mutex);
-+
-+      retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
-+
-+      kfree(tmpbuf);
-+      return retval;
-+}
-+
-+static struct file_operations passive_domain_ops = {
-+      .read           = pdomain_read,
-+      .write          = pdomain_write,
-+};
-+
- void oprofile_create_files(struct super_block * sb, struct dentry * root)
- {
-       oprofilefs_create_file(sb, root, "enable", &enable_fops);
-       oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
-+      oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
-+      oprofilefs_create_file(sb, root, "passive_domains", &passive_domain_ops);
-       oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
-       oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
-       oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
-diff -Nur linux-2.6.16.33-noxen/drivers/pci/Kconfig linux-2.6.16.33/drivers/pci/Kconfig
---- linux-2.6.16.33-noxen/drivers/pci/Kconfig  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/pci/Kconfig        2007-01-08 15:00:45.000000000 +0000
-@@ -5,6 +5,7 @@
-       bool "Message Signaled Interrupts (MSI and MSI-X)"
-       depends on PCI
-       depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64
-+      depends on !XEN
-       help
-          This allows device drivers to enable MSI (Message Signaled
-          Interrupts).  Message Signaled Interrupts enable a device to
-diff -Nur linux-2.6.16.33-noxen/drivers/s390/net/qeth_eddp.c linux-2.6.16.33/drivers/s390/net/qeth_eddp.c
---- linux-2.6.16.33-noxen/drivers/s390/net/qeth_eddp.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/s390/net/qeth_eddp.c       2007-05-23 21:00:01.000000000 +0000
-@@ -421,7 +421,7 @@
-        }
-       tcph = eddp->skb->h.th;
-       while (eddp->skb_offset < eddp->skb->len) {
--              data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
-+              data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
-                              (int)(eddp->skb->len - eddp->skb_offset));
-               /* prepare qdio hdr */
-               if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
-@@ -516,20 +516,20 @@
-       
-       QETH_DBF_TEXT(trace, 5, "eddpcanp");
-       /* can we put multiple skbs in one page? */
--      skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
-+      skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
-       if (skbs_per_page > 1){
--              ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
-+              ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
-                                skbs_per_page + 1;
-               ctx->elements_per_skb = 1;
-       } else {
-               /* no -> how many elements per skb? */
--              ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
-+              ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
-                                    PAGE_SIZE) >> PAGE_SHIFT;
-               ctx->num_pages = ctx->elements_per_skb *
--                               (skb_shinfo(skb)->tso_segs + 1);
-+                               (skb_shinfo(skb)->gso_segs + 1);
-       }
-       ctx->num_elements = ctx->elements_per_skb *
--                          (skb_shinfo(skb)->tso_segs + 1);
-+                          (skb_shinfo(skb)->gso_segs + 1);
- }
- static inline struct qeth_eddp_context *
-diff -Nur linux-2.6.16.33-noxen/drivers/s390/net/qeth_main.c linux-2.6.16.33/drivers/s390/net/qeth_main.c
---- linux-2.6.16.33-noxen/drivers/s390/net/qeth_main.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/s390/net/qeth_main.c       2007-05-23 21:00:01.000000000 +0000
-@@ -4454,7 +4454,7 @@
-       queue = card->qdio.out_qs
-               [qeth_get_priority_queue(card, skb, ipv, cast_type)];
--      if (skb_shinfo(skb)->tso_size)
-+      if (skb_is_gso(skb))
-               large_send = card->options.large_send;
-       /*are we able to do TSO ? If so ,prepare and send it from here */
-@@ -4501,8 +4501,7 @@
-               card->stats.tx_packets++;
-               card->stats.tx_bytes += skb->len;
- #ifdef CONFIG_QETH_PERF_STATS
--              if (skb_shinfo(skb)->tso_size &&
--                 !(large_send == QETH_LARGE_SEND_NO)) {
-+              if (skb_is_gso(skb) && !(large_send == QETH_LARGE_SEND_NO)) {
-                       card->perf_stats.large_send_bytes += skb->len;
-                       card->perf_stats.large_send_cnt++;
-               }
-diff -Nur linux-2.6.16.33-noxen/drivers/s390/net/qeth_tso.h linux-2.6.16.33/drivers/s390/net/qeth_tso.h
---- linux-2.6.16.33-noxen/drivers/s390/net/qeth_tso.h  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/s390/net/qeth_tso.h        2007-05-23 21:00:01.000000000 +0000
-@@ -51,7 +51,7 @@
-       hdr->ext.hdr_version = 1;
-       hdr->ext.hdr_len     = 28;
-       /*insert non-fix values */
--      hdr->ext.mss = skb_shinfo(skb)->tso_size;
-+      hdr->ext.mss = skb_shinfo(skb)->gso_size;
-       hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
-       hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
-                                      sizeof(struct qeth_hdr_tso));
-diff -Nur linux-2.6.16.33-noxen/drivers/serial/Kconfig linux-2.6.16.33/drivers/serial/Kconfig
---- linux-2.6.16.33-noxen/drivers/serial/Kconfig       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/serial/Kconfig     2007-01-08 15:00:45.000000000 +0000
-@@ -11,6 +11,7 @@
- config SERIAL_8250
-       tristate "8250/16550 and compatible serial support"
-       depends on (BROKEN || !SPARC)
-+      depends on !XEN_DISABLE_SERIAL
-       select SERIAL_CORE
-       ---help---
-         This selects whether you want to include the driver for the standard
-diff -Nur linux-2.6.16.33-noxen/drivers/video/Kconfig linux-2.6.16.33/drivers/video/Kconfig
---- linux-2.6.16.33-noxen/drivers/video/Kconfig        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/drivers/video/Kconfig      2007-01-08 15:00:45.000000000 +0000
-@@ -495,7 +495,7 @@
- config VIDEO_SELECT
-       bool
--      depends on (FB = y) && X86
-+      depends on (FB = y) && X86 && !XEN
-       default y
- config FB_SGIVW
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/Kconfig linux-2.6.16.33/drivers/xen/Kconfig
---- linux-2.6.16.33-noxen/drivers/xen/Kconfig  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/Kconfig        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,283 @@
-+#
-+# This Kconfig describe xen options
-+#
-+
-+mainmenu "Xen Configuration"
-+
-+config XEN
-+      bool
-+      default y if X86_XEN || X86_64_XEN
-+      help
-+        This is the Linux Xen port.
-+
-+if XEN
-+config XEN_INTERFACE_VERSION
-+      hex
-+      default 0x00030203
-+
-+menu "XEN"
-+
-+config XEN_PRIVILEGED_GUEST
-+      bool "Privileged Guest (domain 0)"
-+      depends XEN
-+      default n
-+      help
-+        Support for privileged operation (domain 0)
-+
-+config XEN_UNPRIVILEGED_GUEST
-+      bool
-+      default !XEN_PRIVILEGED_GUEST
-+
-+config XEN_PRIVCMD
-+      bool
-+      depends on PROC_FS
-+      default y
-+
-+config XEN_XENBUS_DEV
-+      bool
-+      depends on PROC_FS
-+      default y
-+
-+config XEN_BACKEND
-+        tristate "Backend driver support"
-+        default y
-+        help
-+          Support for backend device drivers that provide I/O services
-+          to other virtual machines.
-+
-+config XEN_BLKDEV_BACKEND
-+      tristate "Block-device backend driver"
-+        depends on XEN_BACKEND
-+      default y
-+      help
-+        The block-device backend driver allows the kernel to export its
-+        block devices to other guests via a high-performance shared-memory
-+        interface.
-+
-+config XEN_BLKDEV_TAP
-+      tristate "Block-device tap backend driver"
-+      depends on XEN_BACKEND
-+      default XEN_PRIVILEGED_GUEST
-+      help
-+        The block tap driver is an alternative to the block back driver 
-+          and allows VM block requests to be redirected to userspace through
-+          a device interface.  The tap allows user-space development of 
-+          high-performance block backends, where disk images may be implemented
-+          as files, in memory, or on other hosts across the network.  This 
-+        driver can safely coexist with the existing blockback driver.
-+
-+config XEN_NETDEV_BACKEND
-+      tristate "Network-device backend driver"
-+        depends on XEN_BACKEND && NET
-+      default y
-+      help
-+        The network-device backend driver allows the kernel to export its
-+        network devices to other guests via a high-performance shared-memory
-+        interface.
-+
-+config XEN_NETDEV_PIPELINED_TRANSMITTER
-+      bool "Pipelined transmitter (DANGEROUS)"
-+      depends on XEN_NETDEV_BACKEND
-+      default n
-+      help
-+        If the net backend is a dumb domain, such as a transparent Ethernet
-+        bridge with no local IP interface, it is safe to say Y here to get
-+        slightly lower network overhead.
-+        If the backend has a local IP interface; or may be doing smart things
-+        like reassembling packets to perform firewall filtering; or if you
-+        are unsure; or if you experience network hangs when this option is
-+        enabled; then you must say N here.
-+
-+config XEN_NETDEV_LOOPBACK
-+      tristate "Network-device loopback driver"
-+      depends on XEN_NETDEV_BACKEND
-+      default y
-+      help
-+        A two-interface loopback device to emulate a local netfront-netback
-+        connection.
-+
-+config XEN_PCIDEV_BACKEND
-+      tristate "PCI-device backend driver"
-+      depends on PCI && XEN_BACKEND
-+      default XEN_PRIVILEGED_GUEST
-+      help
-+        The PCI device backend driver allows the kernel to export arbitrary
-+        PCI devices to other guests. If you select this to be a module, you
-+        will need to make sure no other driver has bound to the device(s)
-+        you want to make visible to other guests.
-+
-+choice
-+      prompt "PCI Backend Mode"
-+      depends on XEN_PCIDEV_BACKEND
-+      default XEN_PCIDEV_BACKEND_VPCI
-+
-+config XEN_PCIDEV_BACKEND_VPCI
-+      bool "Virtual PCI"
-+      ---help---
-+        This PCI Backend hides the true PCI topology and makes the frontend
-+        think there is a single PCI bus with only the exported devices on it.
-+        For example, a device at 03:05.0 will be re-assigned to 00:00.0. A
-+        second device at 02:1a.1 will be re-assigned to 00:01.1.
-+
-+config XEN_PCIDEV_BACKEND_PASS
-+      bool "Passthrough"
-+      ---help---
-+        This PCI Backend provides a real view of the PCI topology to the
-+        frontend (for example, a device at 06:01.b will still appear at
-+        06:01.b to the frontend). This is similar to how Xen 2.0.x exposed
-+        PCI devices to its driver domains. This may be required for drivers
-+        which depend on finding their hardward in certain bus/slot
-+        locations.
-+
-+config XEN_PCIDEV_BACKEND_SLOT
-+      bool "Slot"
-+      ---help---
-+        This PCI Backend hides the true PCI topology and makes the frontend
-+        think there is a single PCI bus with only the exported devices on it.
-+        Contrary to the virtual PCI backend, a function becomes a new slot.
-+        For example, a device at 03:05.2 will be re-assigned to 00:00.0. A
-+        second device at 02:1a.1 will be re-assigned to 00:01.0.
-+
-+endchoice
-+
-+config XEN_PCIDEV_BE_DEBUG
-+      bool "PCI Backend Debugging"
-+      depends on XEN_PCIDEV_BACKEND
-+      default n
-+
-+config XEN_TPMDEV_BACKEND
-+      tristate "TPM-device backend driver"
-+        depends on XEN_BACKEND
-+      default n
-+      help
-+        The TPM-device backend driver
-+
-+config XEN_BLKDEV_FRONTEND
-+      tristate "Block-device frontend driver"
-+      depends on XEN
-+      default y
-+      help
-+        The block-device frontend driver allows the kernel to access block
-+        devices mounted within another guest OS. Unless you are building a
-+        dedicated device-driver domain, or your master control domain
-+        (domain 0), then you almost certainly want to say Y here.
-+
-+config XEN_NETDEV_FRONTEND
-+      tristate "Network-device frontend driver"
-+      depends on XEN && NET
-+      default y
-+      help
-+        The network-device frontend driver allows the kernel to access
-+        network interfaces within another guest OS. Unless you are building a
-+        dedicated device-driver domain, or your master control domain
-+        (domain 0), then you almost certainly want to say Y here.
-+
-+config XEN_FRAMEBUFFER
-+      tristate "Framebuffer-device frontend driver"
-+      depends on XEN && FB
-+      select FB_CFB_FILLRECT
-+      select FB_CFB_COPYAREA
-+      select FB_CFB_IMAGEBLIT
-+      default y
-+      help
-+        The framebuffer-device frontend drivers allows the kernel to create a
-+        virtual framebuffer.  This framebuffer can be viewed in another
-+        domain.  Unless this domain has access to a real video card, you
-+        probably want to say Y here.
-+
-+config XEN_KEYBOARD
-+      tristate "Keyboard-device frontend driver"
-+      depends on XEN && XEN_FRAMEBUFFER && INPUT
-+      default y
-+      help
-+        The keyboard-device frontend driver allows the kernel to create a
-+        virtual keyboard.  This keyboard can then be driven by another
-+        domain.  If you've said Y to CONFIG_XEN_FRAMEBUFFER, you probably
-+        want to say Y here.
-+
-+config XEN_SCRUB_PAGES
-+      bool "Scrub memory before freeing it to Xen"
-+      default y
-+      help
-+        Erase memory contents before freeing it back to Xen's global
-+        pool. This ensures that any secrets contained within that
-+        memory (e.g., private keys) cannot be found by other guests that
-+        may be running on the machine. Most people will want to say Y here.
-+        If security is not a concern then you may increase performance by
-+        saying N.
-+
-+config XEN_DISABLE_SERIAL
-+      bool "Disable serial port drivers"
-+      default y
-+      help
-+        Disable serial port drivers, allowing the Xen console driver
-+        to provide a serial console at ttyS0.
-+
-+config XEN_SYSFS
-+      tristate "Export Xen attributes in sysfs"
-+      depends on SYSFS
-+      default y
-+      help
-+        Xen hypervisor attributes will show up under /sys/hypervisor/.
-+
-+choice
-+      prompt "Xen version compatibility"
-+      default XEN_COMPAT_030002_AND_LATER
-+
-+      config XEN_COMPAT_030002_AND_LATER
-+              bool "3.0.2 and later"
-+
-+      config XEN_COMPAT_LATEST_ONLY
-+              bool "no compatibility code"
-+
-+endchoice
-+
-+config XEN_COMPAT_030002
-+      bool
-+      default XEN_COMPAT_030002_AND_LATER
-+
-+endmenu
-+
-+config HAVE_ARCH_ALLOC_SKB
-+      bool
-+      default y
-+
-+config HAVE_ARCH_DEV_ALLOC_SKB
-+      bool
-+      default y
-+
-+config HAVE_IRQ_IGNORE_UNHANDLED
-+      bool
-+      default y
-+
-+config NO_IDLE_HZ
-+      bool
-+      default y
-+
-+config XEN_UTIL
-+      bool
-+      default y
-+
-+config XEN_BALLOON
-+      bool
-+      default y
-+
-+config XEN_DEVMEM
-+      bool
-+      default y
-+
-+config XEN_SKBUFF
-+      bool
-+      default y
-+      depends on NET
-+
-+config XEN_REBOOT
-+      bool
-+      default y
-+
-+config XEN_SMPBOOT
-+      bool
-+      default y
-+      depends on SMP
-+
-+endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/Makefile linux-2.6.16.33/drivers/xen/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,19 @@
-+obj-y += core/
-+obj-y += console/
-+obj-y += evtchn/
-+obj-y += privcmd/
-+obj-y += xenbus/
-+
-+obj-$(CONFIG_XEN_UTIL)                        += util.o
-+obj-$(CONFIG_XEN_BALLOON)             += balloon/
-+obj-$(CONFIG_XEN_DEVMEM)              += char/
-+obj-$(CONFIG_XEN_BLKDEV_BACKEND)      += blkback/
-+obj-$(CONFIG_XEN_BLKDEV_TAP)          += blktap/
-+obj-$(CONFIG_XEN_NETDEV_BACKEND)      += netback/
-+obj-$(CONFIG_XEN_TPMDEV_BACKEND)      += tpmback/
-+obj-$(CONFIG_XEN_BLKDEV_FRONTEND)     += blkfront/
-+obj-$(CONFIG_XEN_NETDEV_FRONTEND)     += netfront/
-+obj-$(CONFIG_XEN_PCIDEV_BACKEND)      += pciback/
-+obj-$(CONFIG_XEN_PCIDEV_FRONTEND)     += pcifront/
-+obj-$(CONFIG_XEN_FRAMEBUFFER)         += fbfront/
-+obj-$(CONFIG_XEN_KEYBOARD)            += fbfront/
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/balloon/Makefile linux-2.6.16.33/drivers/xen/balloon/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/balloon/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/balloon/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2 @@
-+
-+obj-y := balloon.o sysfs.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/balloon/balloon.c linux-2.6.16.33/drivers/xen/balloon/balloon.c
---- linux-2.6.16.33-noxen/drivers/xen/balloon/balloon.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/balloon/balloon.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,625 @@
-+/******************************************************************************
-+ * 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
-+ * Copyright (c) 2005 Dan M. Smith, IBM Corporation
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/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 <xen/xen_proc.h>
-+#include <asm/hypervisor.h>
-+#include <xen/balloon.h>
-+#include <xen/interface/memory.h>
-+#include <asm/pgalloc.h>
-+#include <asm/pgtable.h>
-+#include <asm/uaccess.h>
-+#include <asm/tlb.h>
-+#include <linux/list.h>
-+#include <xen/xenbus.h>
-+#include "common.h"
-+
-+#ifdef CONFIG_PROC_FS
-+static struct proc_dir_entry *balloon_pde;
-+#endif
-+
-+static DECLARE_MUTEX(balloon_mutex);
-+
-+/*
-+ * Protects atomic reservation decrease/increase against concurrent increases.
-+ * Also protects non-atomic updates of current_pages and driver_pages, and
-+ * balloon lists.
-+ */
-+DEFINE_SPINLOCK(balloon_lock);
-+
-+struct balloon_stats balloon_stats;
-+
-+/* We increase/decrease in batches which fit in a page */
-+static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)];
-+
-+/* VM /proc information for memory */
-+extern unsigned long totalram_pages;
-+
-+/* List of ballooned pages, threaded through the mem_map array. */
-+static LIST_HEAD(ballooned_pages);
-+
-+/* 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;
-+
-+/* When ballooning out (allocating memory to return to Xen) we don't really 
-+   want the kernel to try too hard since that can trigger the oom killer. */
-+#define GFP_BALLOON \
-+      (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
-+
-+#define PAGE_TO_LIST(p) (&(p)->lru)
-+#define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
-+#define UNLIST_PAGE(p)                                \
-+      do {                                    \
-+              list_del(PAGE_TO_LIST(p));      \
-+              PAGE_TO_LIST(p)->next = NULL;   \
-+              PAGE_TO_LIST(p)->prev = NULL;   \
-+      } while(0)
-+
-+#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)
-+{
-+      /* Lowmem is re-populated first, so highmem pages go at list tail. */
-+      if (PageHighMem(page)) {
-+              list_add_tail(PAGE_TO_LIST(page), &ballooned_pages);
-+              bs.balloon_high++;
-+      } else {
-+              list_add(PAGE_TO_LIST(page), &ballooned_pages);
-+              bs.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))
-+              bs.balloon_high--;
-+      else
-+              bs.balloon_low--;
-+
-+      return page;
-+}
-+
-+static struct page *balloon_first_page(void)
-+{
-+      if (list_empty(&ballooned_pages))
-+              return NULL;
-+      return LIST_TO_PAGE(ballooned_pages.next);
-+}
-+
-+static struct page *balloon_next_page(struct page *page)
-+{
-+      struct list_head *next = PAGE_TO_LIST(page)->next;
-+      if (next == &ballooned_pages)
-+              return NULL;
-+      return LIST_TO_PAGE(next);
-+}
-+
-+static void balloon_alarm(unsigned long unused)
-+{
-+      schedule_work(&balloon_worker);
-+}
-+
-+static unsigned long current_target(void)
-+{
-+      unsigned long target = min(bs.target_pages, bs.hard_limit);
-+      if (target > (bs.current_pages + bs.balloon_low + bs.balloon_high))
-+              target = bs.current_pages + bs.balloon_low + bs.balloon_high;
-+      return target;
-+}
-+
-+static int increase_reservation(unsigned long nr_pages)
-+{
-+      unsigned long  pfn, i, flags;
-+      struct page   *page;
-+      long           rc;
-+      struct xen_memory_reservation reservation = {
-+              .address_bits = 0,
-+              .extent_order = 0,
-+              .domid        = DOMID_SELF
-+      };
-+
-+      if (nr_pages > ARRAY_SIZE(frame_list))
-+              nr_pages = ARRAY_SIZE(frame_list);
-+
-+      balloon_lock(flags);
-+
-+      page = balloon_first_page();
-+      for (i = 0; i < nr_pages; i++) {
-+              BUG_ON(page == NULL);
-+              frame_list[i] = page_to_pfn(page);;
-+              page = balloon_next_page(page);
-+      }
-+
-+      set_xen_guest_handle(reservation.extent_start, frame_list);
-+      reservation.nr_extents   = nr_pages;
-+      rc = HYPERVISOR_memory_op(
-+              XENMEM_populate_physmap, &reservation);
-+      if (rc < nr_pages) {
-+              if (rc > 0) {
-+                      int ret;
-+
-+                      /* We hit the Xen hard limit: reprobe. */
-+                      reservation.nr_extents = rc;
-+                      ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-+                                      &reservation);
-+                      BUG_ON(ret != rc);
-+              }
-+              if (rc >= 0)
-+                      bs.hard_limit = (bs.current_pages + rc -
-+                                       bs.driver_pages);
-+              goto out;
-+      }
-+
-+      for (i = 0; i < nr_pages; i++) {
-+              page = balloon_retrieve();
-+              BUG_ON(page == NULL);
-+
-+              pfn = page_to_pfn(page);
-+              BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) &&
-+                     phys_to_machine_mapping_valid(pfn));
-+
-+              set_phys_to_machine(pfn, frame_list[i]);
-+
-+              /* Link back into the page tables if not highmem. */
-+              if (pfn < max_low_pfn) {
-+                      int ret;
-+                      ret = HYPERVISOR_update_va_mapping(
-+                              (unsigned long)__va(pfn << PAGE_SHIFT),
-+                              pfn_pte_ma(frame_list[i], PAGE_KERNEL),
-+                              0);
-+                      BUG_ON(ret);
-+              }
-+
-+              /* Relinquish the page back to the allocator. */
-+              ClearPageReserved(page);
-+              set_page_count(page, 1);
-+              __free_page(page);
-+      }
-+
-+      bs.current_pages += nr_pages;
-+      totalram_pages = bs.current_pages;
-+
-+ out:
-+      balloon_unlock(flags);
-+
-+      return 0;
-+}
-+
-+static int decrease_reservation(unsigned long nr_pages)
-+{
-+      unsigned long  pfn, i, flags;
-+      struct page   *page;
-+      void          *v;
-+      int            need_sleep = 0;
-+      int ret;
-+      struct xen_memory_reservation reservation = {
-+              .address_bits = 0,
-+              .extent_order = 0,
-+              .domid        = DOMID_SELF
-+      };
-+
-+      if (nr_pages > ARRAY_SIZE(frame_list))
-+              nr_pages = ARRAY_SIZE(frame_list);
-+
-+      for (i = 0; i < nr_pages; i++) {
-+              if ((page = alloc_page(GFP_BALLOON)) == NULL) {
-+                      nr_pages = i;
-+                      need_sleep = 1;
-+                      break;
-+              }
-+
-+              pfn = page_to_pfn(page);
-+              frame_list[i] = pfn_to_mfn(pfn);
-+
-+              if (!PageHighMem(page)) {
-+                      v = phys_to_virt(pfn << PAGE_SHIFT);
-+                      scrub_pages(v, 1);
-+                      ret = HYPERVISOR_update_va_mapping(
-+                              (unsigned long)v, __pte_ma(0), 0);
-+                      BUG_ON(ret);
-+              }
-+#ifdef CONFIG_XEN_SCRUB_PAGES
-+              else {
-+                      v = kmap(page);
-+                      scrub_pages(v, 1);
-+                      kunmap(page);
-+              }
-+#endif
-+      }
-+
-+      /* Ensure that ballooned highmem pages don't have kmaps. */
-+      kmap_flush_unused();
-+      flush_tlb_all();
-+
-+      balloon_lock(flags);
-+
-+      /* No more mappings: invalidate P2M and add to balloon. */
-+      for (i = 0; i < nr_pages; i++) {
-+              pfn = mfn_to_pfn(frame_list[i]);
-+              set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
-+              balloon_append(pfn_to_page(pfn));
-+      }
-+
-+      set_xen_guest_handle(reservation.extent_start, frame_list);
-+      reservation.nr_extents   = nr_pages;
-+      ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
-+      BUG_ON(ret != nr_pages);
-+
-+      bs.current_pages -= nr_pages;
-+      totalram_pages = bs.current_pages;
-+
-+      balloon_unlock(flags);
-+
-+      return need_sleep;
-+}
-+
-+/*
-+ * 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)
-+{
-+      int need_sleep = 0;
-+      long credit;
-+
-+      down(&balloon_mutex);
-+
-+      do {
-+              credit = current_target() - bs.current_pages;
-+              if (credit > 0)
-+                      need_sleep = (increase_reservation(credit) != 0);
-+              if (credit < 0)
-+                      need_sleep = (decrease_reservation(-credit) != 0);
-+
-+#ifndef CONFIG_PREEMPT
-+              if (need_resched())
-+                      schedule();
-+#endif
-+      } while ((credit != 0) && !need_sleep);
-+
-+      /* Schedule more work if there is some still to be done. */
-+      if (current_target() != bs.current_pages)
-+              mod_timer(&balloon_timer, jiffies + HZ);
-+
-+      up(&balloon_mutex);
-+}
-+
-+/* Resets the Xen limit, sets new target, and kicks off processing. */
-+void balloon_set_new_target(unsigned long target)
-+{
-+      /* No need for lock. Not read-modify-write updates. */
-+      bs.hard_limit   = ~0UL;
-+      bs.target_pages = target;
-+      schedule_work(&balloon_worker);
-+}
-+
-+static struct xenbus_watch target_watch =
-+{
-+      .node = "memory/target"
-+};
-+
-+/* React to a change in the target key */
-+static void watch_target(struct xenbus_watch *watch,
-+                       const char **vec, unsigned int len)
-+{
-+      unsigned long long new_target;
-+      int err;
-+
-+      err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target);
-+      if (err != 1) {
-+              /* This is ok (for domain0 at least) - so just return */
-+              return;
-+      }
-+
-+      /* The given memory/target value is in KiB, so it needs converting to
-+       * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10.
-+       */
-+      balloon_set_new_target(new_target >> (PAGE_SHIFT - 10));
-+}
-+
-+static int balloon_init_watcher(struct notifier_block *notifier,
-+                              unsigned long event,
-+                              void *data)
-+{
-+      int err;
-+
-+      err = register_xenbus_watch(&target_watch);
-+      if (err)
-+              printk(KERN_ERR "Failed to set balloon watcher\n");
-+
-+      return NOTIFY_DONE;
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+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);
-+      balloon_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;
-+
-+      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"
-+              "Driver pages:       %8lu kB\n"
-+              "Xen hard limit:     ",
-+              PAGES2KB(bs.current_pages), PAGES2KB(bs.target_pages), 
-+              PAGES2KB(bs.balloon_low), PAGES2KB(bs.balloon_high),
-+              PAGES2KB(bs.driver_pages));
-+
-+      if (bs.hard_limit != ~0UL)
-+              len += sprintf(page + len, "%8lu kB\n",
-+                             PAGES2KB(bs.hard_limit));
-+      else
-+              len += sprintf(page + len, "     ??? kB\n");
-+
-+      *eof = 1;
-+      return len;
-+}
-+#endif
-+
-+static struct notifier_block xenstore_notifier;
-+
-+static int __init balloon_init(void)
-+{
-+      unsigned long pfn;
-+      struct page *page;
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      IPRINTK("Initialising balloon driver.\n");
-+
-+      bs.current_pages = min(xen_start_info->nr_pages, max_pfn);
-+      totalram_pages   = bs.current_pages;
-+      bs.target_pages  = bs.current_pages;
-+      bs.balloon_low   = 0;
-+      bs.balloon_high  = 0;
-+      bs.driver_pages  = 0UL;
-+      bs.hard_limit    = ~0UL;
-+
-+      init_timer(&balloon_timer);
-+      balloon_timer.data = 0;
-+      balloon_timer.function = balloon_alarm;
-+    
-+#ifdef CONFIG_PROC_FS
-+      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;
-+#endif
-+      balloon_sysfs_init();
-+    
-+      /* Initialise the balloon with excess memory space. */
-+      for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
-+              page = pfn_to_page(pfn);
-+              if (!PageReserved(page))
-+                      balloon_append(page);
-+      }
-+
-+      target_watch.callback = watch_target;
-+      xenstore_notifier.notifier_call = balloon_init_watcher;
-+
-+      register_xenstore_notifier(&xenstore_notifier);
-+    
-+      return 0;
-+}
-+
-+subsys_initcall(balloon_init);
-+
-+void balloon_update_driver_allowance(long delta)
-+{
-+      unsigned long flags;
-+
-+      balloon_lock(flags);
-+      bs.driver_pages += delta;
-+      balloon_unlock(flags);
-+}
-+
-+static int dealloc_pte_fn(
-+      pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
-+{
-+      unsigned long mfn = pte_mfn(*pte);
-+      int ret;
-+      struct xen_memory_reservation reservation = {
-+              .nr_extents   = 1,
-+              .extent_order = 0,
-+              .domid        = DOMID_SELF
-+      };
-+      set_xen_guest_handle(reservation.extent_start, &mfn);
-+      set_pte_at(&init_mm, addr, pte, __pte_ma(0));
-+      set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
-+      ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
-+      BUG_ON(ret != 1);
-+      return 0;
-+}
-+
-+struct page **alloc_empty_pages_and_pagevec(int nr_pages)
-+{
-+      unsigned long vaddr, flags;
-+      struct page *page, **pagevec;
-+      int i, ret;
-+
-+      pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL);
-+      if (pagevec == NULL)
-+              return NULL;
-+
-+      for (i = 0; i < nr_pages; i++) {
-+              page = pagevec[i] = alloc_page(GFP_KERNEL);
-+              if (page == NULL)
-+                      goto err;
-+
-+              vaddr = (unsigned long)page_address(page);
-+
-+              scrub_pages(vaddr, 1);
-+
-+              balloon_lock(flags);
-+
-+              if (xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      unsigned long gmfn = page_to_pfn(page);
-+                      struct xen_memory_reservation reservation = {
-+                              .nr_extents   = 1,
-+                              .extent_order = 0,
-+                              .domid        = DOMID_SELF
-+                      };
-+                      set_xen_guest_handle(reservation.extent_start, &gmfn);
-+                      ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-+                                                 &reservation);
-+                      if (ret == 1)
-+                              ret = 0; /* success */
-+              } else {
-+                      ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,
-+                                                dealloc_pte_fn, NULL);
-+              }
-+
-+              if (ret != 0) {
-+                      balloon_unlock(flags);
-+                      __free_page(page);
-+                      goto err;
-+              }
-+
-+              totalram_pages = --bs.current_pages;
-+
-+              balloon_unlock(flags);
-+      }
-+
-+ out:
-+      schedule_work(&balloon_worker);
-+      flush_tlb_all();
-+      return pagevec;
-+
-+ err:
-+      balloon_lock(flags);
-+      while (--i >= 0)
-+              balloon_append(pagevec[i]);
-+      balloon_unlock(flags);
-+      kfree(pagevec);
-+      pagevec = NULL;
-+      goto out;
-+}
-+
-+void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
-+{
-+      unsigned long flags;
-+      int i;
-+
-+      if (pagevec == NULL)
-+              return;
-+
-+      balloon_lock(flags);
-+      for (i = 0; i < nr_pages; i++) {
-+              BUG_ON(page_count(pagevec[i]) != 1);
-+              balloon_append(pagevec[i]);
-+      }
-+      balloon_unlock(flags);
-+
-+      kfree(pagevec);
-+
-+      schedule_work(&balloon_worker);
-+}
-+
-+void balloon_release_driver_page(struct page *page)
-+{
-+      unsigned long flags;
-+
-+      balloon_lock(flags);
-+      balloon_append(page);
-+      bs.driver_pages--;
-+      balloon_unlock(flags);
-+
-+      schedule_work(&balloon_worker);
-+}
-+
-+EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
-+EXPORT_SYMBOL_GPL(alloc_empty_pages_and_pagevec);
-+EXPORT_SYMBOL_GPL(free_empty_pages_and_pagevec);
-+EXPORT_SYMBOL_GPL(balloon_release_driver_page);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/balloon/common.h linux-2.6.16.33/drivers/xen/balloon/common.h
---- linux-2.6.16.33-noxen/drivers/xen/balloon/common.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/balloon/common.h       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,58 @@
-+/******************************************************************************
-+ * balloon/common.h
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __XEN_BALLOON_COMMON_H__
-+#define __XEN_BALLOON_COMMON_H__
-+
-+#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
-+
-+struct balloon_stats {
-+      /* We aim for 'current allocation' == 'target allocation'. */
-+      unsigned long current_pages;
-+      unsigned long target_pages;
-+      /* We may hit the hard limit in Xen. If we do then we remember it. */
-+      unsigned long hard_limit;
-+      /*
-+       * Drivers may alter the memory reservation independently, but they
-+       * must inform the balloon driver so we avoid hitting the hard limit.
-+       */
-+      unsigned long driver_pages;
-+      /* Number of pages in high- and low-memory balloons. */
-+      unsigned long balloon_low;
-+      unsigned long balloon_high;
-+};
-+
-+extern struct balloon_stats balloon_stats;
-+#define bs balloon_stats
-+
-+int balloon_sysfs_init(void);
-+void balloon_sysfs_exit(void);
-+
-+void balloon_set_new_target(unsigned long target);
-+
-+#endif /* __XEN_BALLOON_COMMON_H__ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/balloon/sysfs.c linux-2.6.16.33/drivers/xen/balloon/sysfs.c
---- linux-2.6.16.33-noxen/drivers/xen/balloon/sysfs.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/balloon/sysfs.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,165 @@
-+/******************************************************************************
-+ * balloon/sysfs.c
-+ *
-+ * Xen balloon driver - sysfs interfaces.
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/capability.h>
-+#include <linux/stat.h>
-+#include <linux/sysdev.h>
-+#include "common.h"
-+
-+#define BALLOON_CLASS_NAME "memory"
-+
-+#define BALLOON_SHOW(name, format, args...)                   \
-+      static ssize_t show_##name(struct sys_device *dev,      \
-+                                 char *buf)                   \
-+      {                                                       \
-+              return sprintf(buf, format, ##args);            \
-+      }                                                       \
-+      static SYSDEV_ATTR(name, S_IRUGO, show_##name, NULL)
-+
-+BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(bs.current_pages));
-+BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(bs.balloon_low));
-+BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(bs.balloon_high));
-+BALLOON_SHOW(hard_limit_kb,
-+           (bs.hard_limit!=~0UL) ? "%lu\n" : "???\n",
-+           (bs.hard_limit!=~0UL) ? PAGES2KB(bs.hard_limit) : 0);
-+BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(bs.driver_pages));
-+
-+static ssize_t show_target_kb(struct sys_device *dev, char *buf)
-+{
-+      return sprintf(buf, "%lu\n", PAGES2KB(bs.target_pages));
-+}
-+
-+static ssize_t store_target_kb(struct sys_device *dev,
-+                             const char *buf,
-+                             size_t count)
-+{
-+      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 */
-+      strcpy(memstring, buf);
-+      
-+      target_bytes = memparse(memstring, &endchar);
-+      balloon_set_new_target(target_bytes >> PAGE_SHIFT);
-+      
-+      return count;
-+}
-+
-+static SYSDEV_ATTR(target_kb, S_IRUGO | S_IWUSR,
-+                 show_target_kb, store_target_kb);
-+
-+static struct sysdev_attribute *balloon_attrs[] = {
-+      &attr_target_kb,
-+};
-+
-+static struct attribute *balloon_info_attrs[] = {
-+      &attr_current_kb.attr,
-+      &attr_low_kb.attr,
-+      &attr_high_kb.attr,
-+      &attr_hard_limit_kb.attr,
-+      &attr_driver_kb.attr,
-+      NULL
-+};
-+
-+static struct attribute_group balloon_info_group = {
-+      .name = "info",
-+      .attrs = balloon_info_attrs,
-+};
-+
-+static struct sysdev_class balloon_sysdev_class = {
-+      set_kset_name(BALLOON_CLASS_NAME),
-+};
-+
-+static struct sys_device balloon_sysdev;
-+
-+static int register_balloon(struct sys_device *sysdev)
-+{
-+      int i, error;
-+
-+      error = sysdev_class_register(&balloon_sysdev_class);
-+      if (error)
-+              return error;
-+
-+      sysdev->id = 0;
-+      sysdev->cls = &balloon_sysdev_class;
-+
-+      error = sysdev_register(sysdev);
-+      if (error) {
-+              sysdev_class_unregister(&balloon_sysdev_class);
-+              return error;
-+      }
-+
-+      for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++) {
-+              error = sysdev_create_file(sysdev, balloon_attrs[i]);
-+              if (error)
-+                      goto fail;
-+      }
-+
-+      error = sysfs_create_group(&sysdev->kobj, &balloon_info_group);
-+      if (error)
-+              goto fail;
-+      
-+      return 0;
-+
-+ fail:
-+      while (--i >= 0)
-+              sysdev_remove_file(sysdev, balloon_attrs[i]);
-+      sysdev_unregister(sysdev);
-+      sysdev_class_unregister(&balloon_sysdev_class);
-+      return error;
-+}
-+
-+static void unregister_balloon(struct sys_device *sysdev)
-+{
-+      int i;
-+
-+      sysfs_remove_group(&sysdev->kobj, &balloon_info_group);
-+      for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++)
-+              sysdev_remove_file(sysdev, balloon_attrs[i]);
-+      sysdev_unregister(sysdev);
-+      sysdev_class_unregister(&balloon_sysdev_class);
-+}
-+
-+int balloon_sysfs_init(void)
-+{
-+      return register_balloon(&balloon_sysdev);
-+}
-+
-+void balloon_sysfs_exit(void)
-+{
-+      unregister_balloon(&balloon_sysdev);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkback/Makefile linux-2.6.16.33/drivers/xen/blkback/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/blkback/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkback/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,3 @@
-+obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o
-+
-+blkbk-y       := blkback.o xenbus.o interface.o vbd.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkback/blkback.c linux-2.6.16.33/drivers/xen/blkback/blkback.c
---- linux-2.6.16.33-noxen/drivers/xen/blkback/blkback.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkback/blkback.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,580 @@
-+/******************************************************************************
-+ * arch/xen/drivers/blkif/backend/main.c
-+ * 
-+ * Back-end of the driver for virtual block devices. This portion of the
-+ * driver exports a 'unified' block-device interface that can be accessed
-+ * by any operating system that implements a compatible front end. A 
-+ * reference front-end implementation can be found in:
-+ *  arch/xen/drivers/blkif/frontend
-+ * 
-+ * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
-+ * Copyright (c) 2005, Christopher Clark
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/spinlock.h>
-+#include <linux/kthread.h>
-+#include <linux/list.h>
-+#include <xen/balloon.h>
-+#include <asm/hypervisor.h>
-+#include "common.h"
-+
-+/*
-+ * These are rather arbitrary. They are fairly large because adjacent requests
-+ * pulled from a communication ring are quite likely to end up being part of
-+ * the same scatter/gather request at the disc.
-+ * 
-+ * ** TRY INCREASING 'blkif_reqs' IF WRITE SPEEDS SEEM TOO LOW **
-+ * 
-+ * This will increase the chances of being able to write whole tracks.
-+ * 64 should be enough to keep us competitive with Linux.
-+ */
-+static int blkif_reqs = 64;
-+module_param_named(reqs, blkif_reqs, int, 0);
-+MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate");
-+
-+/* Run-time switchable: /sys/module/blkback/parameters/ */
-+static unsigned int log_stats = 0;
-+static unsigned int debug_lvl = 0;
-+module_param(log_stats, int, 0644);
-+module_param(debug_lvl, int, 0644);
-+
-+/*
-+ * Each outstanding request that we've passed to the lower device layers has a 
-+ * 'pending_req' allocated to it. Each buffer_head that completes decrements 
-+ * the pendcnt towards zero. When it hits zero, the specified domain has a 
-+ * response queued for it, with the saved 'id' passed back.
-+ */
-+typedef struct {
-+      blkif_t       *blkif;
-+      unsigned long  id;
-+      int            nr_pages;
-+      atomic_t       pendcnt;
-+      unsigned short operation;
-+      int            status;
-+      struct list_head free_list;
-+} pending_req_t;
-+
-+static pending_req_t *pending_reqs;
-+static struct list_head pending_free;
-+static DEFINE_SPINLOCK(pending_free_lock);
-+static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq);
-+
-+#define BLKBACK_INVALID_HANDLE (~0)
-+
-+static struct page **pending_pages;
-+static grant_handle_t *pending_grant_handles;
-+
-+static inline int vaddr_pagenr(pending_req_t *req, int seg)
-+{
-+      return (req - pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg;
-+}
-+
-+static inline unsigned long vaddr(pending_req_t *req, int seg)
-+{
-+      unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]);
-+      return (unsigned long)pfn_to_kaddr(pfn);
-+}
-+
-+#define pending_handle(_req, _seg) \
-+      (pending_grant_handles[vaddr_pagenr(_req, _seg)])
-+
-+
-+static int do_block_io_op(blkif_t *blkif);
-+static void dispatch_rw_block_io(blkif_t *blkif,
-+                               blkif_request_t *req,
-+                               pending_req_t *pending_req);
-+static void make_response(blkif_t *blkif, unsigned long id, 
-+                        unsigned short op, int st);
-+
-+/******************************************************************
-+ * misc small helpers
-+ */
-+static pending_req_t* alloc_req(void)
-+{
-+      pending_req_t *req = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&pending_free_lock, flags);
-+      if (!list_empty(&pending_free)) {
-+              req = list_entry(pending_free.next, pending_req_t, free_list);
-+              list_del(&req->free_list);
-+      }
-+      spin_unlock_irqrestore(&pending_free_lock, flags);
-+      return req;
-+}
-+
-+static void free_req(pending_req_t *req)
-+{
-+      unsigned long flags;
-+      int was_empty;
-+
-+      spin_lock_irqsave(&pending_free_lock, flags);
-+      was_empty = list_empty(&pending_free);
-+      list_add(&req->free_list, &pending_free);
-+      spin_unlock_irqrestore(&pending_free_lock, flags);
-+      if (was_empty)
-+              wake_up(&pending_free_wq);
-+}
-+
-+static void unplug_queue(blkif_t *blkif)
-+{
-+      if (blkif->plug == NULL)
-+              return;
-+      if (blkif->plug->unplug_fn)
-+              blkif->plug->unplug_fn(blkif->plug);
-+      blk_put_queue(blkif->plug);
-+      blkif->plug = NULL;
-+}
-+
-+static void plug_queue(blkif_t *blkif, struct bio *bio)
-+{
-+      request_queue_t *q = bdev_get_queue(bio->bi_bdev);
-+
-+      if (q == blkif->plug)
-+              return;
-+      unplug_queue(blkif);
-+      blk_get_queue(q);
-+      blkif->plug = q;
-+}
-+
-+static void fast_flush_area(pending_req_t *req)
-+{
-+      struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-+      unsigned int i, invcount = 0;
-+      grant_handle_t handle;
-+      int ret;
-+
-+      for (i = 0; i < req->nr_pages; i++) {
-+              handle = pending_handle(req, i);
-+              if (handle == BLKBACK_INVALID_HANDLE)
-+                      continue;
-+              gnttab_set_unmap_op(&unmap[i], vaddr(req, i), GNTMAP_host_map,
-+                                  handle);
-+              pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
-+              invcount++;
-+      }
-+
-+      ret = HYPERVISOR_grant_table_op(
-+              GNTTABOP_unmap_grant_ref, unmap, invcount);
-+      BUG_ON(ret);
-+}
-+
-+/******************************************************************
-+ * SCHEDULER FUNCTIONS
-+ */
-+
-+static void print_stats(blkif_t *blkif)
-+{
-+      printk(KERN_DEBUG "%s: oo %3d  |  rd %4d  |  wr %4d  |  br %4d\n",
-+             current->comm, blkif->st_oo_req,
-+             blkif->st_rd_req, blkif->st_wr_req, blkif->st_br_req);
-+      blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
-+      blkif->st_rd_req = 0;
-+      blkif->st_wr_req = 0;
-+      blkif->st_oo_req = 0;
-+}
-+
-+int blkif_schedule(void *arg)
-+{
-+      blkif_t *blkif = arg;
-+
-+      blkif_get(blkif);
-+
-+      if (debug_lvl)
-+              printk(KERN_DEBUG "%s: started\n", current->comm);
-+
-+      while (!kthread_should_stop()) {
-+              wait_event_interruptible(
-+                      blkif->wq,
-+                      blkif->waiting_reqs || kthread_should_stop());
-+              wait_event_interruptible(
-+                      pending_free_wq,
-+                      !list_empty(&pending_free) || kthread_should_stop());
-+
-+              blkif->waiting_reqs = 0;
-+              smp_mb(); /* clear flag *before* checking for work */
-+
-+              if (do_block_io_op(blkif))
-+                      blkif->waiting_reqs = 1;
-+              unplug_queue(blkif);
-+
-+              if (log_stats && time_after(jiffies, blkif->st_print))
-+                      print_stats(blkif);
-+      }
-+
-+      if (log_stats)
-+              print_stats(blkif);
-+      if (debug_lvl)
-+              printk(KERN_DEBUG "%s: exiting\n", current->comm);
-+
-+      blkif->xenblkd = NULL;
-+      blkif_put(blkif);
-+
-+      return 0;
-+}
-+
-+/******************************************************************
-+ * COMPLETION CALLBACK -- Called as bh->b_end_io()
-+ */
-+
-+static void __end_block_io_op(pending_req_t *pending_req, int error)
-+{
-+      /* An error fails the entire request. */
-+      if ((pending_req->operation == BLKIF_OP_WRITE_BARRIER) &&
-+          (error == -EOPNOTSUPP)) {
-+              DPRINTK("blkback: write barrier op failed, not supported\n");
-+              blkback_barrier(XBT_NIL, pending_req->blkif->be, 0);
-+              pending_req->status = BLKIF_RSP_EOPNOTSUPP;
-+      } else if (error) {
-+              DPRINTK("Buffer not up-to-date at end of operation, "
-+                      "error=%d\n", error);
-+              pending_req->status = BLKIF_RSP_ERROR;
-+      }
-+
-+      if (atomic_dec_and_test(&pending_req->pendcnt)) {
-+              fast_flush_area(pending_req);
-+              make_response(pending_req->blkif, pending_req->id,
-+                            pending_req->operation, pending_req->status);
-+              blkif_put(pending_req->blkif);
-+              free_req(pending_req);
-+      }
-+}
-+
-+static int end_block_io_op(struct bio *bio, unsigned int done, int error)
-+{
-+      if (bio->bi_size != 0)
-+              return 1;
-+      __end_block_io_op(bio->bi_private, error);
-+      bio_put(bio);
-+      return error;
-+}
-+
-+
-+/******************************************************************************
-+ * NOTIFICATION FROM GUEST OS.
-+ */
-+
-+static void blkif_notify_work(blkif_t *blkif)
-+{
-+      blkif->waiting_reqs = 1;
-+      wake_up(&blkif->wq);
-+}
-+
-+irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      blkif_notify_work(dev_id);
-+      return IRQ_HANDLED;
-+}
-+
-+
-+
-+/******************************************************************
-+ * DOWNWARD CALLS -- These interface with the block-device layer proper.
-+ */
-+
-+static int do_block_io_op(blkif_t *blkif)
-+{
-+      blkif_back_ring_t *blk_ring = &blkif->blk_ring;
-+      blkif_request_t req;
-+      pending_req_t *pending_req;
-+      RING_IDX rc, rp;
-+      int more_to_do = 0;
-+
-+      rc = blk_ring->req_cons;
-+      rp = blk_ring->sring->req_prod;
-+      rmb(); /* Ensure we see queued requests up to 'rp'. */
-+
-+      while ((rc != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) {
-+
-+              pending_req = alloc_req();
-+              if (NULL == pending_req) {
-+                      blkif->st_oo_req++;
-+                      more_to_do = 1;
-+                      break;
-+              }
-+
-+              memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req));
-+              blk_ring->req_cons = ++rc; /* before make_response() */
-+
-+              switch (req.operation) {
-+              case BLKIF_OP_READ:
-+                      blkif->st_rd_req++;
-+                      dispatch_rw_block_io(blkif, &req, pending_req);
-+                      break;
-+              case BLKIF_OP_WRITE_BARRIER:
-+                      blkif->st_br_req++;
-+                      /* fall through */
-+              case BLKIF_OP_WRITE:
-+                      blkif->st_wr_req++;
-+                      dispatch_rw_block_io(blkif, &req, pending_req);
-+                      break;
-+              default:
-+                      DPRINTK("error: unknown block io operation [%d]\n",
-+                              req.operation);
-+                      make_response(blkif, req.id, req.operation,
-+                                    BLKIF_RSP_ERROR);
-+                      free_req(pending_req);
-+                      break;
-+              }
-+      }
-+      return more_to_do;
-+}
-+
-+static void dispatch_rw_block_io(blkif_t *blkif,
-+                               blkif_request_t *req,
-+                               pending_req_t *pending_req)
-+{
-+      extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
-+      struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-+      struct phys_req preq;
-+      struct { 
-+              unsigned long buf; unsigned int nsec;
-+      } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-+      unsigned int nseg;
-+      struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-+      int ret, i, nbio = 0;
-+      int operation;
-+
-+      switch (req->operation) {
-+      case BLKIF_OP_READ:
-+              operation = READ;
-+              break;
-+      case BLKIF_OP_WRITE:
-+              operation = WRITE;
-+              break;
-+      case BLKIF_OP_WRITE_BARRIER:
-+              operation = WRITE_BARRIER;
-+              break;
-+      default:
-+              operation = 0; /* make gcc happy */
-+              BUG();
-+      }
-+
-+      /* Check that number of segments is sane. */
-+      nseg = req->nr_segments;
-+      if (unlikely(nseg == 0) || 
-+          unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
-+              DPRINTK("Bad number of segments in request (%d)\n", nseg);
-+              goto fail_response;
-+      }
-+
-+      preq.dev           = req->handle;
-+      preq.sector_number = req->sector_number;
-+      preq.nr_sects      = 0;
-+
-+      pending_req->blkif     = blkif;
-+      pending_req->id        = req->id;
-+      pending_req->operation = req->operation;
-+      pending_req->status    = BLKIF_RSP_OKAY;
-+      pending_req->nr_pages  = nseg;
-+
-+      for (i = 0; i < nseg; i++) {
-+              uint32_t flags;
-+
-+              seg[i].nsec = req->seg[i].last_sect -
-+                      req->seg[i].first_sect + 1;
-+
-+              if ((req->seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
-+                  (req->seg[i].last_sect < req->seg[i].first_sect))
-+                      goto fail_response;
-+              preq.nr_sects += seg[i].nsec;
-+
-+              flags = GNTMAP_host_map;
-+              if (operation != READ)
-+                      flags |= GNTMAP_readonly;
-+              gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags,
-+                                req->seg[i].gref, blkif->domid);
-+      }
-+
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg);
-+      BUG_ON(ret);
-+
-+      for (i = 0; i < nseg; i++) {
-+              if (unlikely(map[i].status != 0)) {
-+                      DPRINTK("invalid buffer -- could not remap it\n");
-+                      map[i].handle = BLKBACK_INVALID_HANDLE;
-+                      ret |= 1;
-+              }
-+
-+              pending_handle(pending_req, i) = map[i].handle;
-+
-+              if (ret)
-+                      continue;
-+
-+              set_phys_to_machine(__pa(vaddr(
-+                      pending_req, i)) >> PAGE_SHIFT,
-+                      FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
-+              seg[i].buf  = map[i].dev_bus_addr | 
-+                      (req->seg[i].first_sect << 9);
-+      }
-+
-+      if (ret)
-+              goto fail_flush;
-+
-+      if (vbd_translate(&preq, blkif, operation) != 0) {
-+              DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", 
-+                      operation == READ ? "read" : "write",
-+                      preq.sector_number,
-+                      preq.sector_number + preq.nr_sects, preq.dev);
-+              goto fail_flush;
-+      }
-+
-+      for (i = 0; i < nseg; i++) {
-+              if (((int)preq.sector_number|(int)seg[i].nsec) &
-+                  ((bdev_hardsect_size(preq.bdev) >> 9) - 1)) {
-+                      DPRINTK("Misaligned I/O request from domain %d",
-+                              blkif->domid);
-+                      goto fail_put_bio;
-+              }
-+
-+              while ((bio == NULL) ||
-+                     (bio_add_page(bio,
-+                                   virt_to_page(vaddr(pending_req, i)),
-+                                   seg[i].nsec << 9,
-+                                   seg[i].buf & ~PAGE_MASK) == 0)) {
-+                      bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i);
-+                      if (unlikely(bio == NULL))
-+                              goto fail_put_bio;
-+
-+                      bio->bi_bdev    = preq.bdev;
-+                      bio->bi_private = pending_req;
-+                      bio->bi_end_io  = end_block_io_op;
-+                      bio->bi_sector  = preq.sector_number;
-+              }
-+
-+              preq.sector_number += seg[i].nsec;
-+      }
-+
-+      plug_queue(blkif, bio);
-+      atomic_set(&pending_req->pendcnt, nbio);
-+      blkif_get(blkif);
-+
-+      for (i = 0; i < nbio; i++)
-+              submit_bio(operation, biolist[i]);
-+
-+      return;
-+
-+ fail_put_bio:
-+      for (i = 0; i < (nbio-1); i++)
-+              bio_put(biolist[i]);
-+ fail_flush:
-+      fast_flush_area(pending_req);
-+ fail_response:
-+      make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
-+      free_req(pending_req);
-+} 
-+
-+
-+
-+/******************************************************************
-+ * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING
-+ */
-+
-+
-+static void make_response(blkif_t *blkif, unsigned long id, 
-+                        unsigned short op, int st)
-+{
-+      blkif_response_t *resp;
-+      unsigned long     flags;
-+      blkif_back_ring_t *blk_ring = &blkif->blk_ring;
-+      int more_to_do = 0;
-+      int notify;
-+
-+      spin_lock_irqsave(&blkif->blk_ring_lock, flags);
-+
-+      /* Place on the response ring for the relevant domain. */ 
-+      resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
-+      resp->id        = id;
-+      resp->operation = op;
-+      resp->status    = st;
-+      blk_ring->rsp_prod_pvt++;
-+      RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
-+
-+      if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) {
-+              /*
-+               * Tail check for pending requests. Allows frontend to avoid
-+               * notifications if requests are already in flight (lower
-+               * overheads and promotes batching).
-+               */
-+              RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
-+
-+      } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
-+              more_to_do = 1;
-+
-+      }
-+      spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
-+
-+      if (more_to_do)
-+              blkif_notify_work(blkif);
-+      if (notify)
-+              notify_remote_via_irq(blkif->irq);
-+}
-+
-+static int __init blkif_init(void)
-+{
-+      int i, mmap_pages;
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
-+
-+      pending_reqs          = kmalloc(sizeof(pending_reqs[0]) *
-+                                      blkif_reqs, GFP_KERNEL);
-+      pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
-+                                      mmap_pages, GFP_KERNEL);
-+      pending_pages         = alloc_empty_pages_and_pagevec(mmap_pages);
-+
-+      if (!pending_reqs || !pending_grant_handles || !pending_pages)
-+              goto out_of_memory;
-+
-+      for (i = 0; i < mmap_pages; i++)
-+              pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
-+
-+      blkif_interface_init();
-+
-+      memset(pending_reqs, 0, sizeof(pending_reqs));
-+      INIT_LIST_HEAD(&pending_free);
-+
-+      for (i = 0; i < blkif_reqs; i++)
-+              list_add_tail(&pending_reqs[i].free_list, &pending_free);
-+
-+      blkif_xenbus_init();
-+
-+      return 0;
-+
-+ out_of_memory:
-+      kfree(pending_reqs);
-+      kfree(pending_grant_handles);
-+      free_empty_pages_and_pagevec(pending_pages, mmap_pages);
-+      printk("%s: out of memory\n", __FUNCTION__);
-+      return -ENOMEM;
-+}
-+
-+module_init(blkif_init);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkback/common.h linux-2.6.16.33/drivers/xen/blkback/common.h
---- linux-2.6.16.33-noxen/drivers/xen/blkback/common.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkback/common.h       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,139 @@
-+/* 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __BLKIF__BACKEND__COMMON_H__
-+#define __BLKIF__BACKEND__COMMON_H__
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/blkdev.h>
-+#include <linux/vmalloc.h>
-+#include <linux/wait.h>
-+#include <asm/io.h>
-+#include <asm/setup.h>
-+#include <asm/pgalloc.h>
-+#include <xen/evtchn.h>
-+#include <asm/hypervisor.h>
-+#include <xen/interface/io/blkif.h>
-+#include <xen/interface/io/ring.h>
-+#include <xen/gnttab.h>
-+#include <xen/driver_util.h>
-+#include <xen/xenbus.h>
-+
-+#define DPRINTK(_f, _a...)                    \
-+      pr_debug("(file=%s, line=%d) " _f,      \
-+               __FILE__ , __LINE__ , ## _a )
-+
-+struct vbd {
-+      blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
-+      unsigned char  readonly;    /* Non-zero -> read-only */
-+      unsigned char  type;        /* VDISK_xxx */
-+      u32            pdevice;     /* phys device that this vbd maps to */
-+      struct block_device *bdev;
-+};
-+
-+struct backend_info;
-+
-+typedef struct blkif_st {
-+      /* Unique identifier for this interface. */
-+      domid_t           domid;
-+      unsigned int      handle;
-+      /* Physical parameters of the comms window. */
-+      unsigned int      evtchn;
-+      unsigned int      irq;
-+      /* Comms information. */
-+      blkif_back_ring_t blk_ring;
-+      struct vm_struct *blk_ring_area;
-+      /* The VBD attached to this interface. */
-+      struct vbd        vbd;
-+      /* Back pointer to the backend_info. */
-+      struct backend_info *be;
-+      /* Private fields. */
-+      spinlock_t       blk_ring_lock;
-+      atomic_t         refcnt;
-+
-+      wait_queue_head_t   wq;
-+      struct task_struct  *xenblkd;
-+      unsigned int        waiting_reqs;
-+      request_queue_t     *plug;
-+
-+      /* statistics */
-+      unsigned long       st_print;
-+      int                 st_rd_req;
-+      int                 st_wr_req;
-+      int                 st_oo_req;
-+      int                 st_br_req;
-+
-+      wait_queue_head_t waiting_to_free;
-+
-+      grant_handle_t shmem_handle;
-+      grant_ref_t    shmem_ref;
-+} blkif_t;
-+
-+blkif_t *blkif_alloc(domid_t domid);
-+void blkif_disconnect(blkif_t *blkif);
-+void blkif_free(blkif_t *blkif);
-+int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
-+
-+#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
-+#define blkif_put(_b)                                 \
-+      do {                                            \
-+              if (atomic_dec_and_test(&(_b)->refcnt)) \
-+                      wake_up(&(_b)->waiting_to_free);\
-+      } while (0)
-+
-+/* Create a vbd. */
-+int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, unsigned major,
-+             unsigned minor, int readonly);
-+void vbd_free(struct vbd *vbd);
-+
-+unsigned long long vbd_size(struct vbd *vbd);
-+unsigned int vbd_info(struct vbd *vbd);
-+unsigned long vbd_secsize(struct vbd *vbd);
-+
-+struct phys_req {
-+      unsigned short       dev;
-+      unsigned short       nr_sects;
-+      struct block_device *bdev;
-+      blkif_sector_t       sector_number;
-+};
-+
-+int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation);
-+
-+void blkif_interface_init(void);
-+
-+void blkif_xenbus_init(void);
-+
-+irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
-+int blkif_schedule(void *arg);
-+
-+int blkback_barrier(struct xenbus_transaction xbt,
-+                  struct backend_info *be, int state);
-+
-+#endif /* __BLKIF__BACKEND__COMMON_H__ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkback/interface.c linux-2.6.16.33/drivers/xen/blkback/interface.c
---- linux-2.6.16.33-noxen/drivers/xen/blkback/interface.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkback/interface.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,171 @@
-+/******************************************************************************
-+ * arch/xen/drivers/blkif/backend/interface.c
-+ * 
-+ * Block-device interface management.
-+ * 
-+ * Copyright (c) 2004, Keir Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include "common.h"
-+#include <xen/evtchn.h>
-+#include <linux/kthread.h>
-+
-+static kmem_cache_t *blkif_cachep;
-+
-+blkif_t *blkif_alloc(domid_t domid)
-+{
-+      blkif_t *blkif;
-+
-+      blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
-+      if (!blkif)
-+              return ERR_PTR(-ENOMEM);
-+
-+      memset(blkif, 0, sizeof(*blkif));
-+      blkif->domid = domid;
-+      spin_lock_init(&blkif->blk_ring_lock);
-+      atomic_set(&blkif->refcnt, 1);
-+      init_waitqueue_head(&blkif->wq);
-+      blkif->st_print = jiffies;
-+      init_waitqueue_head(&blkif->waiting_to_free);
-+
-+      return blkif;
-+}
-+
-+static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
-+{
-+      struct gnttab_map_grant_ref op;
-+      int ret;
-+
-+      gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
-+                        GNTMAP_host_map, shared_page, blkif->domid);
-+
-+      lock_vm_area(blkif->blk_ring_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-+      unlock_vm_area(blkif->blk_ring_area);
-+      BUG_ON(ret);
-+
-+      if (op.status) {
-+              DPRINTK(" Grant table operation failure !\n");
-+              return op.status;
-+      }
-+
-+      blkif->shmem_ref = shared_page;
-+      blkif->shmem_handle = op.handle;
-+
-+      return 0;
-+}
-+
-+static void unmap_frontend_page(blkif_t *blkif)
-+{
-+      struct gnttab_unmap_grant_ref op;
-+      int ret;
-+
-+      gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
-+                          GNTMAP_host_map, blkif->shmem_handle);
-+
-+      lock_vm_area(blkif->blk_ring_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-+      unlock_vm_area(blkif->blk_ring_area);
-+      BUG_ON(ret);
-+}
-+
-+int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
-+{
-+      blkif_sring_t *sring;
-+      int err;
-+      struct evtchn_bind_interdomain bind_interdomain;
-+
-+      /* Already connected through? */
-+      if (blkif->irq)
-+              return 0;
-+
-+      if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
-+              return -ENOMEM;
-+
-+      err = map_frontend_page(blkif, shared_page);
-+      if (err) {
-+              free_vm_area(blkif->blk_ring_area);
-+              return err;
-+      }
-+
-+      bind_interdomain.remote_dom  = blkif->domid;
-+      bind_interdomain.remote_port = evtchn;
-+
-+      err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-+                                        &bind_interdomain);
-+      if (err) {
-+              unmap_frontend_page(blkif);
-+              free_vm_area(blkif->blk_ring_area);
-+              return err;
-+      }
-+
-+      blkif->evtchn = bind_interdomain.local_port;
-+
-+      sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
-+      BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
-+
-+      blkif->irq = bind_evtchn_to_irqhandler(
-+              blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
-+
-+      return 0;
-+}
-+
-+void blkif_disconnect(blkif_t *blkif)
-+{
-+      if (blkif->xenblkd) {
-+              kthread_stop(blkif->xenblkd);
-+              blkif->xenblkd = NULL;
-+      }
-+
-+      atomic_dec(&blkif->refcnt);
-+      wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
-+      atomic_inc(&blkif->refcnt);
-+
-+      if (blkif->irq) {
-+              unbind_from_irqhandler(blkif->irq, blkif);
-+              blkif->irq = 0;
-+      }
-+
-+      if (blkif->blk_ring.sring) {
-+              unmap_frontend_page(blkif);
-+              free_vm_area(blkif->blk_ring_area);
-+              blkif->blk_ring.sring = NULL;
-+      }
-+}
-+
-+void blkif_free(blkif_t *blkif)
-+{
-+      if (!atomic_dec_and_test(&blkif->refcnt))
-+              BUG();
-+      kmem_cache_free(blkif_cachep, blkif);
-+}
-+
-+void __init blkif_interface_init(void)
-+{
-+      blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 
-+                                       0, 0, NULL, NULL);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkback/vbd.c linux-2.6.16.33/drivers/xen/blkback/vbd.c
---- linux-2.6.16.33-noxen/drivers/xen/blkback/vbd.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkback/vbd.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,118 @@
-+/******************************************************************************
-+ * blkback/vbd.c
-+ * 
-+ * Routines for managing virtual block devices (VBDs).
-+ * 
-+ * Copyright (c) 2003-2005, Keir Fraser & Steve Hand
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include "common.h"
-+
-+#define vbd_sz(_v)   ((_v)->bdev->bd_part ?                           \
-+      (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
-+
-+unsigned long long vbd_size(struct vbd *vbd)
-+{
-+      return vbd_sz(vbd);
-+}
-+
-+unsigned int vbd_info(struct vbd *vbd)
-+{
-+      return vbd->type | (vbd->readonly?VDISK_READONLY:0);
-+}
-+
-+unsigned long vbd_secsize(struct vbd *vbd)
-+{
-+      return bdev_hardsect_size(vbd->bdev);
-+}
-+
-+int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major,
-+             unsigned minor, int readonly)
-+{
-+      struct vbd *vbd;
-+      struct block_device *bdev;
-+
-+      vbd = &blkif->vbd;
-+      vbd->handle   = handle; 
-+      vbd->readonly = readonly;
-+      vbd->type     = 0;
-+
-+      vbd->pdevice  = MKDEV(major, minor);
-+
-+      bdev = open_by_devnum(vbd->pdevice,
-+                            vbd->readonly ? FMODE_READ : FMODE_WRITE);
-+
-+      if (IS_ERR(bdev)) {
-+              DPRINTK("vbd_creat: device %08x could not be opened.\n",
-+                      vbd->pdevice);
-+              return -ENOENT;
-+      }
-+
-+      vbd->bdev = bdev;
-+
-+      if (vbd->bdev->bd_disk == NULL) {
-+              DPRINTK("vbd_creat: device %08x doesn't exist.\n",
-+                      vbd->pdevice);
-+              vbd_free(vbd);
-+              return -ENOENT;
-+      }
-+
-+      if (vbd->bdev->bd_disk->flags & GENHD_FL_CD)
-+              vbd->type |= VDISK_CDROM;
-+      if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE)
-+              vbd->type |= VDISK_REMOVABLE;
-+
-+      DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
-+              handle, blkif->domid);
-+      return 0;
-+}
-+
-+void vbd_free(struct vbd *vbd)
-+{
-+      if (vbd->bdev)
-+              blkdev_put(vbd->bdev);
-+      vbd->bdev = NULL;
-+}
-+
-+int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
-+{
-+      struct vbd *vbd = &blkif->vbd;
-+      int rc = -EACCES;
-+
-+      if ((operation != READ) && vbd->readonly)
-+              goto out;
-+
-+      if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
-+              goto out;
-+
-+      req->dev  = vbd->pdevice;
-+      req->bdev = vbd->bdev;
-+      rc = 0;
-+
-+ out:
-+      return rc;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkback/xenbus.c linux-2.6.16.33/drivers/xen/blkback/xenbus.c
---- linux-2.6.16.33-noxen/drivers/xen/blkback/xenbus.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkback/xenbus.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,485 @@
-+/*  Xenbus code for blkif backend
-+    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
-+    Copyright (C) 2005 XenSource Ltd
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+*/
-+
-+#include <stdarg.h>
-+#include <linux/module.h>
-+#include <linux/kthread.h>
-+#include "common.h"
-+
-+#undef DPRINTK
-+#define DPRINTK(fmt, args...)                         \
-+      pr_debug("blkback/xenbus (%s:%d) " fmt ".\n",   \
-+               __FUNCTION__, __LINE__, ##args)
-+
-+struct backend_info
-+{
-+      struct xenbus_device *dev;
-+      blkif_t *blkif;
-+      struct xenbus_watch backend_watch;
-+      unsigned major;
-+      unsigned minor;
-+      char *mode;
-+};
-+
-+static void connect(struct backend_info *);
-+static int connect_ring(struct backend_info *);
-+static void backend_changed(struct xenbus_watch *, const char **,
-+                          unsigned int);
-+
-+static void update_blkif_status(blkif_t *blkif)
-+{ 
-+      int err;
-+
-+      /* Not ready to connect? */
-+      if (!blkif->irq || !blkif->vbd.bdev)
-+              return;
-+
-+      /* Already connected? */
-+      if (blkif->be->dev->state == XenbusStateConnected)
-+              return;
-+
-+      /* Attempt to connect: exit if we fail to. */
-+      connect(blkif->be);
-+      if (blkif->be->dev->state != XenbusStateConnected)
-+              return;
-+
-+      blkif->xenblkd = kthread_run(blkif_schedule, blkif,
-+                                   "xvd %d %02x:%02x",
-+                                   blkif->domid,
-+                                   blkif->be->major, blkif->be->minor);
-+      if (IS_ERR(blkif->xenblkd)) {
-+              err = PTR_ERR(blkif->xenblkd);
-+              blkif->xenblkd = NULL;
-+              xenbus_dev_error(blkif->be->dev, err, "start xenblkd");
-+      }
-+}
-+
-+
-+/****************************************************************
-+ *  sysfs interface for VBD I/O requests
-+ */
-+
-+#define VBD_SHOW(name, format, args...)                                       \
-+      static ssize_t show_##name(struct device *_dev,                 \
-+                                 struct device_attribute *attr,       \
-+                                 char *buf)                           \
-+      {                                                               \
-+              struct xenbus_device *dev = to_xenbus_device(_dev);     \
-+              struct backend_info *be = dev->dev.driver_data;         \
-+                                                                      \
-+              return sprintf(buf, format, ##args);                    \
-+      }                                                               \
-+      DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
-+
-+VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
-+VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
-+VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
-+VBD_SHOW(br_req, "%d\n", be->blkif->st_br_req);
-+
-+static struct attribute *vbdstat_attrs[] = {
-+      &dev_attr_oo_req.attr,
-+      &dev_attr_rd_req.attr,
-+      &dev_attr_wr_req.attr,
-+      &dev_attr_br_req.attr,
-+      NULL
-+};
-+
-+static struct attribute_group vbdstat_group = {
-+      .name = "statistics",
-+      .attrs = vbdstat_attrs,
-+};
-+
-+VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
-+VBD_SHOW(mode, "%s\n", be->mode);
-+
-+int xenvbd_sysfs_addif(struct xenbus_device *dev)
-+{
-+      int error;
-+      
-+      error = device_create_file(&dev->dev, &dev_attr_physical_device);
-+      if (error)
-+              goto fail1;
-+
-+      error = device_create_file(&dev->dev, &dev_attr_mode);
-+      if (error)
-+              goto fail2;
-+
-+      error = sysfs_create_group(&dev->dev.kobj, &vbdstat_group);
-+      if (error)
-+              goto fail3;
-+
-+      return 0;
-+
-+fail3:        sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
-+fail2:        device_remove_file(&dev->dev, &dev_attr_mode);
-+fail1:        device_remove_file(&dev->dev, &dev_attr_physical_device);
-+      return error;
-+}
-+
-+void xenvbd_sysfs_delif(struct xenbus_device *dev)
-+{
-+      sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
-+      device_remove_file(&dev->dev, &dev_attr_mode);
-+      device_remove_file(&dev->dev, &dev_attr_physical_device);
-+}
-+
-+static int blkback_remove(struct xenbus_device *dev)
-+{
-+      struct backend_info *be = dev->dev.driver_data;
-+
-+      DPRINTK("");
-+
-+      if (be->backend_watch.node) {
-+              unregister_xenbus_watch(&be->backend_watch);
-+              kfree(be->backend_watch.node);
-+              be->backend_watch.node = NULL;
-+      }
-+
-+      if (be->blkif) {
-+              blkif_disconnect(be->blkif);
-+              vbd_free(&be->blkif->vbd);
-+              blkif_free(be->blkif);
-+              be->blkif = NULL;
-+      }
-+
-+      if (be->major || be->minor)
-+              xenvbd_sysfs_delif(dev);
-+
-+      kfree(be);
-+      dev->dev.driver_data = NULL;
-+      return 0;
-+}
-+
-+int blkback_barrier(struct xenbus_transaction xbt,
-+                  struct backend_info *be, int state)
-+{
-+      struct xenbus_device *dev = be->dev;
-+      int err;
-+
-+      err = xenbus_printf(xbt, dev->nodename, "feature-barrier",
-+                          "%d", state);
-+      if (err)
-+              xenbus_dev_fatal(dev, err, "writing feature-barrier");
-+
-+      return err;
-+}
-+
-+/**
-+ * Entry point to this code when a new device is created.  Allocate the basic
-+ * structures, and watch the store waiting for the hotplug scripts to tell us
-+ * the device's physical major and minor numbers.  Switch to InitWait.
-+ */
-+static int blkback_probe(struct xenbus_device *dev,
-+                       const struct xenbus_device_id *id)
-+{
-+      int err;
-+      struct backend_info *be = kzalloc(sizeof(struct backend_info),
-+                                        GFP_KERNEL);
-+      if (!be) {
-+              xenbus_dev_fatal(dev, -ENOMEM,
-+                               "allocating backend structure");
-+              return -ENOMEM;
-+      }
-+      be->dev = dev;
-+      dev->dev.driver_data = be;
-+
-+      be->blkif = blkif_alloc(dev->otherend_id);
-+      if (IS_ERR(be->blkif)) {
-+              err = PTR_ERR(be->blkif);
-+              be->blkif = NULL;
-+              xenbus_dev_fatal(dev, err, "creating block interface");
-+              goto fail;
-+      }
-+
-+      /* setup back pointer */
-+      be->blkif->be = be;
-+
-+      err = xenbus_watch_path2(dev, dev->nodename, "physical-device",
-+                               &be->backend_watch, backend_changed);
-+      if (err)
-+              goto fail;
-+
-+      err = xenbus_switch_state(dev, XenbusStateInitWait);
-+      if (err)
-+              goto fail;
-+
-+      return 0;
-+
-+fail:
-+      DPRINTK("failed");
-+      blkback_remove(dev);
-+      return err;
-+}
-+
-+
-+/**
-+ * Callback received when the hotplug scripts have placed the physical-device
-+ * node.  Read it and the mode node, and create a vbd.  If the frontend is
-+ * ready, connect.
-+ */
-+static void backend_changed(struct xenbus_watch *watch,
-+                          const char **vec, unsigned int len)
-+{
-+      int err;
-+      unsigned major;
-+      unsigned minor;
-+      struct backend_info *be
-+              = container_of(watch, struct backend_info, backend_watch);
-+      struct xenbus_device *dev = be->dev;
-+
-+      DPRINTK("");
-+
-+      err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x",
-+                         &major, &minor);
-+      if (XENBUS_EXIST_ERR(err)) {
-+              /* Since this watch will fire once immediately after it is
-+                 registered, we expect this.  Ignore it, and wait for the
-+                 hotplug scripts. */
-+              return;
-+      }
-+      if (err != 2) {
-+              xenbus_dev_fatal(dev, err, "reading physical-device");
-+              return;
-+      }
-+
-+      if ((be->major || be->minor) &&
-+          ((be->major != major) || (be->minor != minor))) {
-+              printk(KERN_WARNING
-+                     "blkback: changing physical device (from %x:%x to "
-+                     "%x:%x) not supported.\n", be->major, be->minor,
-+                     major, minor);
-+              return;
-+      }
-+
-+      be->mode = xenbus_read(XBT_NIL, dev->nodename, "mode", NULL);
-+      if (IS_ERR(be->mode)) {
-+              err = PTR_ERR(be->mode);
-+              be->mode = NULL;
-+              xenbus_dev_fatal(dev, err, "reading mode");
-+              return;
-+      }
-+
-+      if (be->major == 0 && be->minor == 0) {
-+              /* Front end dir is a number, which is used as the handle. */
-+
-+              char *p = strrchr(dev->otherend, '/') + 1;
-+              long handle = simple_strtoul(p, NULL, 0);
-+
-+              be->major = major;
-+              be->minor = minor;
-+
-+              err = vbd_create(be->blkif, handle, major, minor,
-+                               (NULL == strchr(be->mode, 'w')));
-+              if (err) {
-+                      be->major = be->minor = 0;
-+                      xenbus_dev_fatal(dev, err, "creating vbd structure");
-+                      return;
-+              }
-+
-+              err = xenvbd_sysfs_addif(dev);
-+              if (err) {
-+                      vbd_free(&be->blkif->vbd);
-+                      be->major = be->minor = 0;
-+                      xenbus_dev_fatal(dev, err, "creating sysfs entries");
-+                      return;
-+              }
-+
-+              /* We're potentially connected now */
-+              update_blkif_status(be->blkif);
-+      }
-+}
-+
-+
-+/**
-+ * Callback received when the frontend's state changes.
-+ */
-+static void frontend_changed(struct xenbus_device *dev,
-+                           enum xenbus_state frontend_state)
-+{
-+      struct backend_info *be = dev->dev.driver_data;
-+      int err;
-+
-+      DPRINTK("%s", xenbus_strstate(frontend_state));
-+
-+      switch (frontend_state) {
-+      case XenbusStateInitialising:
-+              if (dev->state == XenbusStateClosed) {
-+                      printk("%s: %s: prepare for reconnect\n",
-+                             __FUNCTION__, dev->nodename);
-+                      xenbus_switch_state(dev, XenbusStateInitWait);
-+              }
-+              break;
-+
-+      case XenbusStateInitialised:
-+      case XenbusStateConnected:
-+              /* Ensure we connect even when two watches fire in 
-+                 close successsion and we miss the intermediate value 
-+                 of frontend_state. */
-+              if (dev->state == XenbusStateConnected)
-+                      break;
-+
-+              err = connect_ring(be);
-+              if (err)
-+                      break;
-+              update_blkif_status(be->blkif);
-+              break;
-+
-+      case XenbusStateClosing:
-+              blkif_disconnect(be->blkif);
-+              xenbus_switch_state(dev, XenbusStateClosing);
-+              break;
-+
-+      case XenbusStateClosed:
-+              xenbus_switch_state(dev, XenbusStateClosed);
-+              if (xenbus_dev_is_online(dev))
-+                      break;
-+              /* fall through if not online */
-+      case XenbusStateUnknown:
-+              device_unregister(&dev->dev);
-+              break;
-+
-+      default:
-+              xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
-+                               frontend_state);
-+              break;
-+      }
-+}
-+
-+
-+/* ** Connection ** */
-+
-+
-+/**
-+ * Write the physical details regarding the block device to the store, and
-+ * switch to Connected state.
-+ */
-+static void connect(struct backend_info *be)
-+{
-+      struct xenbus_transaction xbt;
-+      int err;
-+      struct xenbus_device *dev = be->dev;
-+
-+      DPRINTK("%s", dev->otherend);
-+
-+      /* Supply the information about the device the frontend needs */
-+again:
-+      err = xenbus_transaction_start(&xbt);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "starting transaction");
-+              return;
-+      }
-+
-+      err = blkback_barrier(xbt, be, 1);
-+      if (err)
-+              goto abort;
-+
-+      err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
-+                          vbd_size(&be->blkif->vbd));
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "writing %s/sectors",
-+                               dev->nodename);
-+              goto abort;
-+      }
-+
-+      /* FIXME: use a typename instead */
-+      err = xenbus_printf(xbt, dev->nodename, "info", "%u",
-+                          vbd_info(&be->blkif->vbd));
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "writing %s/info",
-+                               dev->nodename);
-+              goto abort;
-+      }
-+      err = xenbus_printf(xbt, dev->nodename, "sector-size", "%lu",
-+                          vbd_secsize(&be->blkif->vbd));
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "writing %s/sector-size",
-+                               dev->nodename);
-+              goto abort;
-+      }
-+
-+      err = xenbus_transaction_end(xbt, 0);
-+      if (err == -EAGAIN)
-+              goto again;
-+      if (err)
-+              xenbus_dev_fatal(dev, err, "ending transaction");
-+
-+      err = xenbus_switch_state(dev, XenbusStateConnected);
-+      if (err)
-+              xenbus_dev_fatal(dev, err, "switching to Connected state",
-+                               dev->nodename);
-+
-+      return;
-+ abort:
-+      xenbus_transaction_end(xbt, 1);
-+}
-+
-+
-+static int connect_ring(struct backend_info *be)
-+{
-+      struct xenbus_device *dev = be->dev;
-+      unsigned long ring_ref;
-+      unsigned int evtchn;
-+      int err;
-+
-+      DPRINTK("%s", dev->otherend);
-+
-+      err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", &ring_ref,
-+                          "event-channel", "%u", &evtchn, NULL);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err,
-+                               "reading %s/ring-ref and event-channel",
-+                               dev->otherend);
-+              return err;
-+      }
-+
-+      /* Map the shared frame, irq etc. */
-+      err = blkif_map(be->blkif, ring_ref, evtchn);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "mapping ring-ref %lu port %u",
-+                               ring_ref, evtchn);
-+              return err;
-+      }
-+
-+      return 0;
-+}
-+
-+
-+/* ** Driver Registration ** */
-+
-+
-+static struct xenbus_device_id blkback_ids[] = {
-+      { "vbd" },
-+      { "" }
-+};
-+
-+
-+static struct xenbus_driver blkback = {
-+      .name = "vbd",
-+      .owner = THIS_MODULE,
-+      .ids = blkback_ids,
-+      .probe = blkback_probe,
-+      .remove = blkback_remove,
-+      .otherend_changed = frontend_changed
-+};
-+
-+
-+void blkif_xenbus_init(void)
-+{
-+      xenbus_register_backend(&blkback);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkfront/Makefile linux-2.6.16.33/drivers/xen/blkfront/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/blkfront/Makefile        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkfront/Makefile      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,5 @@
-+
-+obj-$(CONFIG_XEN_BLKDEV_FRONTEND)     := xenblk.o
-+
-+xenblk-objs := blkfront.o vbd.o
-+
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkfront/blkfront.c linux-2.6.16.33/drivers/xen/blkfront/blkfront.c
---- linux-2.6.16.33-noxen/drivers/xen/blkfront/blkfront.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkfront/blkfront.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,891 @@
-+/******************************************************************************
-+ * blkfront.c
-+ * 
-+ * XenLinux virtual block-device driver.
-+ * 
-+ * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
-+ * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
-+ * Copyright (c) 2004, Christian Limpach
-+ * Copyright (c) 2004, Andrew Warfield
-+ * Copyright (c) 2005, Christopher Clark
-+ * Copyright (c) 2005, XenSource Ltd
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/version.h>
-+#include "block.h"
-+#include <linux/cdrom.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <scsi/scsi.h>
-+#include <xen/evtchn.h>
-+#include <xen/xenbus.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/gnttab.h>
-+#include <asm/hypervisor.h>
-+#include <asm/maddr.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+#define BLKIF_STATE_DISCONNECTED 0
-+#define BLKIF_STATE_CONNECTED    1
-+#define BLKIF_STATE_SUSPENDED    2
-+
-+#define MAXIMUM_OUTSTANDING_BLOCK_REQS \
-+    (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLK_RING_SIZE)
-+#define GRANT_INVALID_REF     0
-+
-+static void connect(struct blkfront_info *);
-+static void blkfront_closing(struct xenbus_device *);
-+static int blkfront_remove(struct xenbus_device *);
-+static int talk_to_backend(struct xenbus_device *, struct blkfront_info *);
-+static int setup_blkring(struct xenbus_device *, struct blkfront_info *);
-+
-+static void kick_pending_request_queues(struct blkfront_info *);
-+
-+static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs);
-+static void blkif_restart_queue(void *arg);
-+static void blkif_recover(struct blkfront_info *);
-+static void blkif_completion(struct blk_shadow *);
-+static void blkif_free(struct blkfront_info *, int);
-+
-+
-+/**
-+ * Entry point to this code when a new device is created.  Allocate the basic
-+ * structures and the ring buffer for communication with the backend, and
-+ * inform the backend of the appropriate details for those.  Switch to
-+ * Initialised state.
-+ */
-+static int blkfront_probe(struct xenbus_device *dev,
-+                        const struct xenbus_device_id *id)
-+{
-+      int err, vdevice, i;
-+      struct blkfront_info *info;
-+
-+      /* FIXME: Use dynamic device id if this is not set. */
-+      err = xenbus_scanf(XBT_NIL, dev->nodename,
-+                         "virtual-device", "%i", &vdevice);
-+      if (err != 1) {
-+              xenbus_dev_fatal(dev, err, "reading virtual-device");
-+              return err;
-+      }
-+
-+      info = kzalloc(sizeof(*info), GFP_KERNEL);
-+      if (!info) {
-+              xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
-+              return -ENOMEM;
-+      }
-+
-+      info->xbdev = dev;
-+      info->vdevice = vdevice;
-+      info->connected = BLKIF_STATE_DISCONNECTED;
-+      INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
-+
-+      for (i = 0; i < BLK_RING_SIZE; i++)
-+              info->shadow[i].req.id = i+1;
-+      info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
-+
-+      /* Front end dir is a number, which is used as the id. */
-+      info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
-+      dev->dev.driver_data = info;
-+
-+      err = talk_to_backend(dev, info);
-+      if (err) {
-+              kfree(info);
-+              dev->dev.driver_data = NULL;
-+              return err;
-+      }
-+
-+      return 0;
-+}
-+
-+
-+/**
-+ * We are reconnecting to the backend, due to a suspend/resume, or a backend
-+ * driver restart.  We tear down our blkif structure and recreate it, but
-+ * leave the device-layer structures intact so that this is transparent to the
-+ * rest of the kernel.
-+ */
-+static int blkfront_resume(struct xenbus_device *dev)
-+{
-+      struct blkfront_info *info = dev->dev.driver_data;
-+      int err;
-+
-+      DPRINTK("blkfront_resume: %s\n", dev->nodename);
-+
-+      blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
-+
-+      err = talk_to_backend(dev, info);
-+      if (info->connected == BLKIF_STATE_SUSPENDED && !err)
-+              blkif_recover(info);
-+
-+      return err;
-+}
-+
-+
-+/* Common code used when first setting up, and when resuming. */
-+static int talk_to_backend(struct xenbus_device *dev,
-+                         struct blkfront_info *info)
-+{
-+      const char *message = NULL;
-+      struct xenbus_transaction xbt;
-+      int err;
-+
-+      /* Create shared ring, alloc event channel. */
-+      err = setup_blkring(dev, info);
-+      if (err)
-+              goto out;
-+
-+again:
-+      err = xenbus_transaction_start(&xbt);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "starting transaction");
-+              goto destroy_blkring;
-+      }
-+
-+      err = xenbus_printf(xbt, dev->nodename,
-+                          "ring-ref","%u", info->ring_ref);
-+      if (err) {
-+              message = "writing ring-ref";
-+              goto abort_transaction;
-+      }
-+      err = xenbus_printf(xbt, dev->nodename,
-+                          "event-channel", "%u", info->evtchn);
-+      if (err) {
-+              message = "writing event-channel";
-+              goto abort_transaction;
-+      }
-+
-+      err = xenbus_transaction_end(xbt, 0);
-+      if (err) {
-+              if (err == -EAGAIN)
-+                      goto again;
-+              xenbus_dev_fatal(dev, err, "completing transaction");
-+              goto destroy_blkring;
-+      }
-+
-+      xenbus_switch_state(dev, XenbusStateInitialised);
-+
-+      return 0;
-+
-+ abort_transaction:
-+      xenbus_transaction_end(xbt, 1);
-+      if (message)
-+              xenbus_dev_fatal(dev, err, "%s", message);
-+ destroy_blkring:
-+      blkif_free(info, 0);
-+ out:
-+      return err;
-+}
-+
-+
-+static int setup_blkring(struct xenbus_device *dev,
-+                       struct blkfront_info *info)
-+{
-+      blkif_sring_t *sring;
-+      int err;
-+
-+      info->ring_ref = GRANT_INVALID_REF;
-+
-+      sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
-+      if (!sring) {
-+              xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
-+              return -ENOMEM;
-+      }
-+      SHARED_RING_INIT(sring);
-+      FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
-+
-+      err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
-+      if (err < 0) {
-+              free_page((unsigned long)sring);
-+              info->ring.sring = NULL;
-+              goto fail;
-+      }
-+      info->ring_ref = err;
-+
-+      err = xenbus_alloc_evtchn(dev, &info->evtchn);
-+      if (err)
-+              goto fail;
-+
-+      err = bind_evtchn_to_irqhandler(
-+              info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
-+      if (err <= 0) {
-+              xenbus_dev_fatal(dev, err,
-+                               "bind_evtchn_to_irqhandler failed");
-+              goto fail;
-+      }
-+      info->irq = err;
-+
-+      return 0;
-+fail:
-+      blkif_free(info, 0);
-+      return err;
-+}
-+
-+
-+/**
-+ * Callback received when the backend's state changes.
-+ */
-+static void backend_changed(struct xenbus_device *dev,
-+                          enum xenbus_state backend_state)
-+{
-+      struct blkfront_info *info = dev->dev.driver_data;
-+      struct block_device *bd;
-+
-+      DPRINTK("blkfront:backend_changed.\n");
-+
-+      switch (backend_state) {
-+      case XenbusStateInitialising:
-+      case XenbusStateInitWait:
-+      case XenbusStateInitialised:
-+      case XenbusStateUnknown:
-+      case XenbusStateClosed:
-+              break;
-+
-+      case XenbusStateConnected:
-+              connect(info);
-+              break;
-+
-+      case XenbusStateClosing:
-+              bd = bdget(info->dev);
-+              if (bd == NULL)
-+                      xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
-+
-+              down(&bd->bd_sem);
-+              if (info->users > 0)
-+                      xenbus_dev_error(dev, -EBUSY,
-+                                       "Device in use; refusing to close");
-+              else
-+                      blkfront_closing(dev);
-+              up(&bd->bd_sem);
-+              bdput(bd);
-+              break;
-+      }
-+}
-+
-+
-+/* ** Connection ** */
-+
-+
-+/*
-+ * Invoked when the backend is finally 'ready' (and has told produced
-+ * the details about the physical device - #sectors, size, etc).
-+ */
-+static void connect(struct blkfront_info *info)
-+{
-+      unsigned long long sectors;
-+      unsigned long sector_size;
-+      unsigned int binfo;
-+      int err;
-+
-+      if ((info->connected == BLKIF_STATE_CONNECTED) ||
-+          (info->connected == BLKIF_STATE_SUSPENDED) )
-+              return;
-+
-+      DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
-+
-+      err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-+                          "sectors", "%Lu", &sectors,
-+                          "info", "%u", &binfo,
-+                          "sector-size", "%lu", &sector_size,
-+                          NULL);
-+      if (err) {
-+              xenbus_dev_fatal(info->xbdev, err,
-+                               "reading backend fields at %s",
-+                               info->xbdev->otherend);
-+              return;
-+      }
-+
-+      err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-+                          "feature-barrier", "%lu", &info->feature_barrier,
-+                          NULL);
-+      if (err)
-+              info->feature_barrier = 0;
-+
-+      err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
-+      if (err) {
-+              xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
-+                               info->xbdev->otherend);
-+              return;
-+      }
-+
-+      (void)xenbus_switch_state(info->xbdev, XenbusStateConnected);
-+
-+      /* Kick pending requests. */
-+      spin_lock_irq(&blkif_io_lock);
-+      info->connected = BLKIF_STATE_CONNECTED;
-+      kick_pending_request_queues(info);
-+      spin_unlock_irq(&blkif_io_lock);
-+
-+      add_disk(info->gd);
-+}
-+
-+/**
-+ * Handle the change of state of the backend to Closing.  We must delete our
-+ * device-layer structures now, to ensure that writes are flushed through to
-+ * the backend.  Once is this done, we can switch to Closed in
-+ * acknowledgement.
-+ */
-+static void blkfront_closing(struct xenbus_device *dev)
-+{
-+      struct blkfront_info *info = dev->dev.driver_data;
-+      unsigned long flags;
-+
-+      DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
-+
-+      if (info->rq == NULL)
-+              goto out;
-+
-+      spin_lock_irqsave(&blkif_io_lock, flags);
-+      /* No more blkif_request(). */
-+      blk_stop_queue(info->rq);
-+      /* No more gnttab callback work. */
-+      gnttab_cancel_free_callback(&info->callback);
-+      spin_unlock_irqrestore(&blkif_io_lock, flags);
-+
-+      /* Flush gnttab callback work. Must be done with no locks held. */
-+      flush_scheduled_work();
-+
-+      xlvbd_del(info);
-+
-+ out:
-+      xenbus_frontend_closed(dev);
-+}
-+
-+
-+static int blkfront_remove(struct xenbus_device *dev)
-+{
-+      struct blkfront_info *info = dev->dev.driver_data;
-+
-+      DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
-+
-+      blkif_free(info, 0);
-+
-+      kfree(info);
-+
-+      return 0;
-+}
-+
-+
-+static inline int GET_ID_FROM_FREELIST(
-+      struct blkfront_info *info)
-+{
-+      unsigned long free = info->shadow_free;
-+      BUG_ON(free > BLK_RING_SIZE);
-+      info->shadow_free = info->shadow[free].req.id;
-+      info->shadow[free].req.id = 0x0fffffee; /* debug */
-+      return free;
-+}
-+
-+static inline void ADD_ID_TO_FREELIST(
-+      struct blkfront_info *info, unsigned long id)
-+{
-+      info->shadow[id].req.id  = info->shadow_free;
-+      info->shadow[id].request = 0;
-+      info->shadow_free = id;
-+}
-+
-+static inline void flush_requests(struct blkfront_info *info)
-+{
-+      int notify;
-+
-+      RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->ring, notify);
-+
-+      if (notify)
-+              notify_remote_via_irq(info->irq);
-+}
-+
-+static void kick_pending_request_queues(struct blkfront_info *info)
-+{
-+      if (!RING_FULL(&info->ring)) {
-+              /* Re-enable calldowns. */
-+              blk_start_queue(info->rq);
-+              /* Kick things off immediately. */
-+              do_blkif_request(info->rq);
-+      }
-+}
-+
-+static void blkif_restart_queue(void *arg)
-+{
-+      struct blkfront_info *info = (struct blkfront_info *)arg;
-+      spin_lock_irq(&blkif_io_lock);
-+      if (info->connected == BLKIF_STATE_CONNECTED)
-+              kick_pending_request_queues(info);
-+      spin_unlock_irq(&blkif_io_lock);
-+}
-+
-+static void blkif_restart_queue_callback(void *arg)
-+{
-+      struct blkfront_info *info = (struct blkfront_info *)arg;
-+      schedule_work(&info->work);
-+}
-+
-+int blkif_open(struct inode *inode, struct file *filep)
-+{
-+      struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
-+      info->users++;
-+      return 0;
-+}
-+
-+
-+int blkif_release(struct inode *inode, struct file *filep)
-+{
-+      struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
-+      info->users--;
-+      if (info->users == 0) {
-+              /* Check whether we have been instructed to close.  We will
-+                 have ignored this request initially, as the device was
-+                 still mounted. */
-+              struct xenbus_device * dev = info->xbdev;
-+              enum xenbus_state state = xenbus_read_driver_state(dev->otherend);
-+
-+              if (state == XenbusStateClosing)
-+                      blkfront_closing(dev);
-+      }
-+      return 0;
-+}
-+
-+
-+int blkif_ioctl(struct inode *inode, struct file *filep,
-+              unsigned command, unsigned long argument)
-+{
-+      int i;
-+
-+      DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
-+                    command, (long)argument, inode->i_rdev);
-+
-+      switch (command) {
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
-+      case HDIO_GETGEO: {
-+              struct block_device *bd = inode->i_bdev;
-+              struct hd_geometry geo;
-+              int ret;
-+
-+                if (!argument)
-+                        return -EINVAL;
-+
-+              geo.start = get_start_sect(bd);
-+              ret = blkif_getgeo(bd, &geo);
-+              if (ret)
-+                      return ret;
-+
-+              if (copy_to_user((struct hd_geometry __user *)argument, &geo,
-+                               sizeof(geo)))
-+                        return -EFAULT;
-+
-+                return 0;
-+      }
-+#endif
-+      case CDROMMULTISESSION:
-+              DPRINTK("FIXME: support multisession CDs later\n");
-+              for (i = 0; i < sizeof(struct cdrom_multisession); i++)
-+                      if (put_user(0, (char __user *)(argument + i)))
-+                              return -EFAULT;
-+              return 0;
-+
-+      default:
-+              /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
-+                command);*/
-+              return -EINVAL; /* same return as native Linux */
-+      }
-+
-+      return 0;
-+}
-+
-+
-+int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
-+{
-+      /* We don't have real geometry info, but let's at least return
-+         values consistent with the size of the device */
-+      sector_t nsect = get_capacity(bd->bd_disk);
-+      sector_t cylinders = nsect;
-+
-+      hg->heads = 0xff;
-+      hg->sectors = 0x3f;
-+      sector_div(cylinders, hg->heads * hg->sectors);
-+      hg->cylinders = cylinders;
-+      if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
-+              hg->cylinders = 0xffff;
-+      return 0;
-+}
-+
-+
-+/*
-+ * blkif_queue_request
-+ *
-+ * request block io
-+ *
-+ * id: for guest use only.
-+ * operation: BLKIF_OP_{READ,WRITE,PROBE}
-+ * buffer: buffer to read/write into. this should be a
-+ *   virtual address in the guest os.
-+ */
-+static int blkif_queue_request(struct request *req)
-+{
-+      struct blkfront_info *info = req->rq_disk->private_data;
-+      unsigned long buffer_mfn;
-+      blkif_request_t *ring_req;
-+      struct bio *bio;
-+      struct bio_vec *bvec;
-+      int idx;
-+      unsigned long id;
-+      unsigned int fsect, lsect;
-+      int ref;
-+      grant_ref_t gref_head;
-+
-+      if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
-+              return 1;
-+
-+      if (gnttab_alloc_grant_references(
-+              BLKIF_MAX_SEGMENTS_PER_REQUEST, &gref_head) < 0) {
-+              gnttab_request_free_callback(
-+                      &info->callback,
-+                      blkif_restart_queue_callback,
-+                      info,
-+                      BLKIF_MAX_SEGMENTS_PER_REQUEST);
-+              return 1;
-+      }
-+
-+      /* Fill out a communications ring structure. */
-+      ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
-+      id = GET_ID_FROM_FREELIST(info);
-+      info->shadow[id].request = (unsigned long)req;
-+
-+      ring_req->id = id;
-+      ring_req->sector_number = (blkif_sector_t)req->sector;
-+      ring_req->handle = info->handle;
-+
-+      ring_req->operation = rq_data_dir(req) ?
-+              BLKIF_OP_WRITE : BLKIF_OP_READ;
-+      if (blk_barrier_rq(req))
-+              ring_req->operation = BLKIF_OP_WRITE_BARRIER;
-+
-+      ring_req->nr_segments = 0;
-+      rq_for_each_bio (bio, req) {
-+              bio_for_each_segment (bvec, bio, idx) {
-+                      BUG_ON(ring_req->nr_segments
-+                             == BLKIF_MAX_SEGMENTS_PER_REQUEST);
-+                      buffer_mfn = page_to_phys(bvec->bv_page) >> PAGE_SHIFT;
-+                      fsect = bvec->bv_offset >> 9;
-+                      lsect = fsect + (bvec->bv_len >> 9) - 1;
-+                      /* install a grant reference. */
-+                      ref = gnttab_claim_grant_reference(&gref_head);
-+                      BUG_ON(ref == -ENOSPC);
-+
-+                      gnttab_grant_foreign_access_ref(
-+                              ref,
-+                              info->xbdev->otherend_id,
-+                              buffer_mfn,
-+                              rq_data_dir(req) );
-+
-+                      info->shadow[id].frame[ring_req->nr_segments] =
-+                              mfn_to_pfn(buffer_mfn);
-+
-+                      ring_req->seg[ring_req->nr_segments] =
-+                              (struct blkif_request_segment) {
-+                                      .gref       = ref,
-+                                      .first_sect = fsect,
-+                                      .last_sect  = lsect };
-+
-+                      ring_req->nr_segments++;
-+              }
-+      }
-+
-+      info->ring.req_prod_pvt++;
-+
-+      /* Keep a private copy so we can reissue requests when recovering. */
-+      info->shadow[id].req = *ring_req;
-+
-+      gnttab_free_grant_references(gref_head);
-+
-+      return 0;
-+}
-+
-+/*
-+ * do_blkif_request
-+ *  read a block; request is in a request queue
-+ */
-+void do_blkif_request(request_queue_t *rq)
-+{
-+      struct blkfront_info *info = NULL;
-+      struct request *req;
-+      int queued;
-+
-+      DPRINTK("Entered do_blkif_request\n");
-+
-+      queued = 0;
-+
-+      while ((req = elv_next_request(rq)) != NULL) {
-+              info = req->rq_disk->private_data;
-+              if (!blk_fs_request(req)) {
-+                      end_request(req, 0);
-+                      continue;
-+              }
-+
-+              if (RING_FULL(&info->ring))
-+                      goto wait;
-+
-+              DPRINTK("do_blk_req %p: cmd %p, sec %lx, "
-+                      "(%u/%li) buffer:%p [%s]\n",
-+                      req, req->cmd, req->sector, req->current_nr_sectors,
-+                      req->nr_sectors, req->buffer,
-+                      rq_data_dir(req) ? "write" : "read");
-+
-+
-+              blkdev_dequeue_request(req);
-+              if (blkif_queue_request(req)) {
-+                      blk_requeue_request(rq, req);
-+              wait:
-+                      /* Avoid pointless unplugs. */
-+                      blk_stop_queue(rq);
-+                      break;
-+              }
-+
-+              queued++;
-+      }
-+
-+      if (queued != 0)
-+              flush_requests(info);
-+}
-+
-+
-+static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
-+{
-+      struct request *req;
-+      blkif_response_t *bret;
-+      RING_IDX i, rp;
-+      unsigned long flags;
-+      struct blkfront_info *info = (struct blkfront_info *)dev_id;
-+      int uptodate;
-+
-+      spin_lock_irqsave(&blkif_io_lock, flags);
-+
-+      if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
-+              spin_unlock_irqrestore(&blkif_io_lock, flags);
-+              return IRQ_HANDLED;
-+      }
-+
-+ again:
-+      rp = info->ring.sring->rsp_prod;
-+      rmb(); /* Ensure we see queued responses up to 'rp'. */
-+
-+      for (i = info->ring.rsp_cons; i != rp; i++) {
-+              unsigned long id;
-+              int ret;
-+
-+              bret = RING_GET_RESPONSE(&info->ring, i);
-+              id   = bret->id;
-+              req  = (struct request *)info->shadow[id].request;
-+
-+              blkif_completion(&info->shadow[id]);
-+
-+              ADD_ID_TO_FREELIST(info, id);
-+
-+              uptodate = (bret->status == BLKIF_RSP_OKAY);
-+              switch (bret->operation) {
-+              case BLKIF_OP_WRITE_BARRIER:
-+                      if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
-+                              printk("blkfront: %s: write barrier op failed\n",
-+                                     info->gd->disk_name);
-+                              uptodate = -EOPNOTSUPP;
-+                              info->feature_barrier = 0;
-+                              xlvbd_barrier(info);
-+                      }
-+                      /* fall through */
-+              case BLKIF_OP_READ:
-+              case BLKIF_OP_WRITE:
-+                      if (unlikely(bret->status != BLKIF_RSP_OKAY))
-+                              DPRINTK("Bad return from blkdev data "
-+                                      "request: %x\n", bret->status);
-+
-+                      ret = end_that_request_first(req, uptodate,
-+                              req->hard_nr_sectors);
-+                      BUG_ON(ret);
-+                      end_that_request_last(req, uptodate);
-+                      break;
-+              default:
-+                      BUG();
-+              }
-+      }
-+
-+      info->ring.rsp_cons = i;
-+
-+      if (i != info->ring.req_prod_pvt) {
-+              int more_to_do;
-+              RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
-+              if (more_to_do)
-+                      goto again;
-+      } else
-+              info->ring.sring->rsp_event = i + 1;
-+
-+      kick_pending_request_queues(info);
-+
-+      spin_unlock_irqrestore(&blkif_io_lock, flags);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static void blkif_free(struct blkfront_info *info, int suspend)
-+{
-+      /* Prevent new requests being issued until we fix things up. */
-+      spin_lock_irq(&blkif_io_lock);
-+      info->connected = suspend ?
-+              BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
-+      /* No more blkif_request(). */
-+      if (info->rq)
-+              blk_stop_queue(info->rq);
-+      /* No more gnttab callback work. */
-+      gnttab_cancel_free_callback(&info->callback);
-+      spin_unlock_irq(&blkif_io_lock);
-+
-+      /* Flush gnttab callback work. Must be done with no locks held. */
-+      flush_scheduled_work();
-+
-+      /* Free resources associated with old device channel. */
-+      if (info->ring_ref != GRANT_INVALID_REF) {
-+              gnttab_end_foreign_access(info->ring_ref, 0,
-+                                        (unsigned long)info->ring.sring);
-+              info->ring_ref = GRANT_INVALID_REF;
-+              info->ring.sring = NULL;
-+      }
-+      if (info->irq)
-+              unbind_from_irqhandler(info->irq, info);
-+      info->evtchn = info->irq = 0;
-+
-+}
-+
-+static void blkif_completion(struct blk_shadow *s)
-+{
-+      int i;
-+      for (i = 0; i < s->req.nr_segments; i++)
-+              gnttab_end_foreign_access(s->req.seg[i].gref, 0, 0UL);
-+}
-+
-+static void blkif_recover(struct blkfront_info *info)
-+{
-+      int i;
-+      blkif_request_t *req;
-+      struct blk_shadow *copy;
-+      int j;
-+
-+      /* Stage 1: Make a safe copy of the shadow state. */
-+      copy = kmalloc(sizeof(info->shadow), GFP_KERNEL | __GFP_NOFAIL);
-+      memcpy(copy, info->shadow, sizeof(info->shadow));
-+
-+      /* Stage 2: Set up free list. */
-+      memset(&info->shadow, 0, sizeof(info->shadow));
-+      for (i = 0; i < BLK_RING_SIZE; i++)
-+              info->shadow[i].req.id = i+1;
-+      info->shadow_free = info->ring.req_prod_pvt;
-+      info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
-+
-+      /* Stage 3: Find pending requests and requeue them. */
-+      for (i = 0; i < BLK_RING_SIZE; i++) {
-+              /* Not in use? */
-+              if (copy[i].request == 0)
-+                      continue;
-+
-+              /* Grab a request slot and copy shadow state into it. */
-+              req = RING_GET_REQUEST(
-+                      &info->ring, info->ring.req_prod_pvt);
-+              *req = copy[i].req;
-+
-+              /* We get a new request id, and must reset the shadow state. */
-+              req->id = GET_ID_FROM_FREELIST(info);
-+              memcpy(&info->shadow[req->id], &copy[i], sizeof(copy[i]));
-+
-+              /* Rewrite any grant references invalidated by susp/resume. */
-+              for (j = 0; j < req->nr_segments; j++)
-+                      gnttab_grant_foreign_access_ref(
-+                              req->seg[j].gref,
-+                              info->xbdev->otherend_id,
-+                              pfn_to_mfn(info->shadow[req->id].frame[j]),
-+                              rq_data_dir(
-+                                      (struct request *)
-+                                      info->shadow[req->id].request));
-+              info->shadow[req->id].req = *req;
-+
-+              info->ring.req_prod_pvt++;
-+      }
-+
-+      kfree(copy);
-+
-+      (void)xenbus_switch_state(info->xbdev, XenbusStateConnected);
-+
-+      spin_lock_irq(&blkif_io_lock);
-+
-+      /* Now safe for us to use the shared ring */
-+      info->connected = BLKIF_STATE_CONNECTED;
-+
-+      /* Send off requeued requests */
-+      flush_requests(info);
-+
-+      /* Kick any other new requests queued since we resumed */
-+      kick_pending_request_queues(info);
-+
-+      spin_unlock_irq(&blkif_io_lock);
-+}
-+
-+
-+/* ** Driver Registration ** */
-+
-+
-+static struct xenbus_device_id blkfront_ids[] = {
-+      { "vbd" },
-+      { "" }
-+};
-+
-+
-+static struct xenbus_driver blkfront = {
-+      .name = "vbd",
-+      .owner = THIS_MODULE,
-+      .ids = blkfront_ids,
-+      .probe = blkfront_probe,
-+      .remove = blkfront_remove,
-+      .resume = blkfront_resume,
-+      .otherend_changed = backend_changed,
-+};
-+
-+
-+static int __init xlblk_init(void)
-+{
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      return xenbus_register_frontend(&blkfront);
-+}
-+module_init(xlblk_init);
-+
-+
-+static void xlblk_exit(void)
-+{
-+      return xenbus_unregister_driver(&blkfront);
-+}
-+module_exit(xlblk_exit);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkfront/block.h linux-2.6.16.33/drivers/xen/blkfront/block.h
---- linux-2.6.16.33-noxen/drivers/xen/blkfront/block.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkfront/block.h       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,158 @@
-+/******************************************************************************
-+ * block.h
-+ * 
-+ * Shared definitions between all levels of XenLinux Virtual block devices.
-+ * 
-+ * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
-+ * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
-+ * Copyright (c) 2004-2005, Christian Limpach
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __XEN_DRIVERS_BLOCK_H__
-+#define __XEN_DRIVERS_BLOCK_H__
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/fs.h>
-+#include <linux/hdreg.h>
-+#include <linux/blkdev.h>
-+#include <linux/major.h>
-+#include <linux/devfs_fs_kernel.h>
-+#include <asm/hypervisor.h>
-+#include <xen/xenbus.h>
-+#include <xen/gnttab.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/io/blkif.h>
-+#include <xen/interface/io/ring.h>
-+#include <asm/io.h>
-+#include <asm/atomic.h>
-+#include <asm/uaccess.h>
-+
-+#if 1
-+#define IPRINTK(fmt, args...)                         \
-+      printk(KERN_INFO "xen_blk: " fmt, ##args)
-+#else
-+#define IPRINTK(fmt, args...) ((void)0)
-+#endif
-+
-+#if 1
-+#define WPRINTK(fmt, args...)                         \
-+      printk(KERN_WARNING "xen_blk: " fmt, ##args)
-+#else
-+#define WPRINTK(fmt, args...) ((void)0)
-+#endif
-+
-+#define DPRINTK(_f, _a...) pr_debug(_f, ## _a)
-+
-+#if 0
-+#define DPRINTK_IOCTL(_f, _a...) printk(KERN_ALERT _f, ## _a)
-+#else
-+#define DPRINTK_IOCTL(_f, _a...) ((void)0)
-+#endif
-+
-+struct xlbd_type_info
-+{
-+      int partn_shift;
-+      int disks_per_major;
-+      char *devname;
-+      char *diskname;
-+};
-+
-+struct xlbd_major_info
-+{
-+      int major;
-+      int index;
-+      int usage;
-+      struct xlbd_type_info *type;
-+};
-+
-+struct blk_shadow {
-+      blkif_request_t req;
-+      unsigned long request;
-+      unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-+};
-+
-+#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
-+
-+/*
-+ * We have one of these per vbd, whether ide, scsi or 'other'.  They
-+ * hang in private_data off the gendisk structure. We may end up
-+ * putting all kinds of interesting stuff here :-)
-+ */
-+struct blkfront_info
-+{
-+      struct xenbus_device *xbdev;
-+      dev_t dev;
-+      struct gendisk *gd;
-+      int vdevice;
-+      blkif_vdev_t handle;
-+      int connected;
-+      int ring_ref;
-+      blkif_front_ring_t ring;
-+      unsigned int evtchn, irq;
-+      struct xlbd_major_info *mi;
-+      request_queue_t *rq;
-+      struct work_struct work;
-+      struct gnttab_free_callback callback;
-+      struct blk_shadow shadow[BLK_RING_SIZE];
-+      unsigned long shadow_free;
-+      int feature_barrier;
-+
-+      /**
-+       * The number of people holding this device open.  We won't allow a
-+       * hot-unplug unless this is 0.
-+       */
-+      int users;
-+};
-+
-+extern spinlock_t blkif_io_lock;
-+
-+extern int blkif_open(struct inode *inode, struct file *filep);
-+extern int blkif_release(struct inode *inode, struct file *filep);
-+extern int blkif_ioctl(struct inode *inode, struct file *filep,
-+                     unsigned command, unsigned long argument);
-+extern int blkif_getgeo(struct block_device *, struct hd_geometry *);
-+extern int blkif_check(dev_t dev);
-+extern int blkif_revalidate(dev_t dev);
-+extern void do_blkif_request (request_queue_t *rq);
-+
-+/* Virtual block-device subsystem. */
-+/* Note that xlvbd_add doesn't call add_disk for you: you're expected
-+   to call add_disk on info->gd once the disk is properly connected
-+   up. */
-+int xlvbd_add(blkif_sector_t capacity, int device,
-+            u16 vdisk_info, u16 sector_size, struct blkfront_info *info);
-+void xlvbd_del(struct blkfront_info *info);
-+int xlvbd_barrier(struct blkfront_info *info);
-+
-+#endif /* __XEN_DRIVERS_BLOCK_H__ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blkfront/vbd.c linux-2.6.16.33/drivers/xen/blkfront/vbd.c
---- linux-2.6.16.33-noxen/drivers/xen/blkfront/vbd.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blkfront/vbd.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,375 @@
-+/******************************************************************************
-+ * vbd.c
-+ * 
-+ * XenLinux virtual block-device driver (xvd).
-+ * 
-+ * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
-+ * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
-+ * Copyright (c) 2004-2005, Christian Limpach
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include "block.h"
-+#include <linux/blkdev.h>
-+#include <linux/list.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+#define BLKIF_MAJOR(dev) ((dev)>>8)
-+#define BLKIF_MINOR(dev) ((dev) & 0xff)
-+
-+/*
-+ * For convenience we distinguish between ide, scsi and 'other' (i.e.,
-+ * potentially combinations of the two) in the naming scheme and in a few other
-+ * places.
-+ */
-+
-+#define NUM_IDE_MAJORS 10
-+#define NUM_SCSI_MAJORS 17
-+#define NUM_VBD_MAJORS 1
-+
-+static struct xlbd_type_info xlbd_ide_type = {
-+      .partn_shift = 6,
-+      .disks_per_major = 2,
-+      .devname = "ide",
-+      .diskname = "hd",
-+};
-+
-+static struct xlbd_type_info xlbd_scsi_type = {
-+      .partn_shift = 4,
-+      .disks_per_major = 16,
-+      .devname = "sd",
-+      .diskname = "sd",
-+};
-+
-+static struct xlbd_type_info xlbd_vbd_type = {
-+      .partn_shift = 4,
-+      .disks_per_major = 16,
-+      .devname = "xvd",
-+      .diskname = "xvd",
-+};
-+
-+static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS +
-+                                       NUM_VBD_MAJORS];
-+
-+#define XLBD_MAJOR_IDE_START  0
-+#define XLBD_MAJOR_SCSI_START (NUM_IDE_MAJORS)
-+#define XLBD_MAJOR_VBD_START  (NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
-+
-+#define XLBD_MAJOR_IDE_RANGE  XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1
-+#define XLBD_MAJOR_SCSI_RANGE XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1
-+#define XLBD_MAJOR_VBD_RANGE  XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1
-+
-+/* Information about our VBDs. */
-+#define MAX_VBDS 64
-+static LIST_HEAD(vbds_list);
-+
-+static struct block_device_operations xlvbd_block_fops =
-+{
-+      .owner = THIS_MODULE,
-+      .open = blkif_open,
-+      .release = blkif_release,
-+      .ioctl  = blkif_ioctl,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+      .getgeo = blkif_getgeo
-+#endif
-+};
-+
-+DEFINE_SPINLOCK(blkif_io_lock);
-+
-+static struct xlbd_major_info *
-+xlbd_alloc_major_info(int major, int minor, int index)
-+{
-+      struct xlbd_major_info *ptr;
-+
-+      ptr = kzalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
-+      if (ptr == NULL)
-+              return NULL;
-+
-+      ptr->major = major;
-+
-+      switch (index) {
-+      case XLBD_MAJOR_IDE_RANGE:
-+              ptr->type = &xlbd_ide_type;
-+              ptr->index = index - XLBD_MAJOR_IDE_START;
-+              break;
-+      case XLBD_MAJOR_SCSI_RANGE:
-+              ptr->type = &xlbd_scsi_type;
-+              ptr->index = index - XLBD_MAJOR_SCSI_START;
-+              break;
-+      case XLBD_MAJOR_VBD_RANGE:
-+              ptr->type = &xlbd_vbd_type;
-+              ptr->index = index - XLBD_MAJOR_VBD_START;
-+              break;
-+      }
-+
-+      printk("Registering block device major %i\n", ptr->major);
-+      if (register_blkdev(ptr->major, ptr->type->devname)) {
-+              WPRINTK("can't get major %d with name %s\n",
-+                      ptr->major, ptr->type->devname);
-+              kfree(ptr);
-+              return NULL;
-+      }
-+
-+      devfs_mk_dir(ptr->type->devname);
-+      major_info[index] = ptr;
-+      return ptr;
-+}
-+
-+static struct xlbd_major_info *
-+xlbd_get_major_info(int vdevice)
-+{
-+      struct xlbd_major_info *mi;
-+      int major, minor, index;
-+
-+      major = BLKIF_MAJOR(vdevice);
-+      minor = BLKIF_MINOR(vdevice);
-+
-+      switch (major) {
-+      case IDE0_MAJOR: index = 0; break;
-+      case IDE1_MAJOR: index = 1; break;
-+      case IDE2_MAJOR: index = 2; break;
-+      case IDE3_MAJOR: index = 3; break;
-+      case IDE4_MAJOR: index = 4; break;
-+      case IDE5_MAJOR: index = 5; break;
-+      case IDE6_MAJOR: index = 6; break;
-+      case IDE7_MAJOR: index = 7; break;
-+      case IDE8_MAJOR: index = 8; break;
-+      case IDE9_MAJOR: index = 9; break;
-+      case SCSI_DISK0_MAJOR: index = 10; break;
-+      case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
-+              index = 11 + major - SCSI_DISK1_MAJOR;
-+              break;
-+        case SCSI_DISK8_MAJOR ... SCSI_DISK15_MAJOR:
-+                index = 18 + major - SCSI_DISK8_MAJOR;
-+                break;
-+        case SCSI_CDROM_MAJOR: index = 26; break;
-+        default: index = 27; break;
-+      }
-+
-+      mi = ((major_info[index] != NULL) ? major_info[index] :
-+            xlbd_alloc_major_info(major, minor, index));
-+      if (mi)
-+              mi->usage++;
-+      return mi;
-+}
-+
-+static void
-+xlbd_put_major_info(struct xlbd_major_info *mi)
-+{
-+      mi->usage--;
-+      /* XXX: release major if 0 */
-+}
-+
-+static int
-+xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
-+{
-+      request_queue_t *rq;
-+
-+      rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
-+      if (rq == NULL)
-+              return -1;
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-+      elevator_init(rq, "noop");
-+#else
-+      elevator_init(rq, &elevator_noop);
-+#endif
-+
-+      /* Hard sector size and max sectors impersonate the equiv. hardware. */
-+      blk_queue_hardsect_size(rq, sector_size);
-+      blk_queue_max_sectors(rq, 512);
-+
-+      /* Each segment in a request is up to an aligned page in size. */
-+      blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
-+      blk_queue_max_segment_size(rq, PAGE_SIZE);
-+
-+      /* Ensure a merged request will fit in a single I/O ring slot. */
-+      blk_queue_max_phys_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-+      blk_queue_max_hw_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-+
-+      /* Make sure buffer addresses are sector-aligned. */
-+      blk_queue_dma_alignment(rq, 511);
-+
-+      gd->queue = rq;
-+
-+      return 0;
-+}
-+
-+static int
-+xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, int vdevice,
-+                  u16 vdisk_info, u16 sector_size,
-+                  struct blkfront_info *info)
-+{
-+      struct gendisk *gd;
-+      struct xlbd_major_info *mi;
-+      int nr_minors = 1;
-+      int err = -ENODEV;
-+      unsigned int offset;
-+
-+      BUG_ON(info->gd != NULL);
-+      BUG_ON(info->mi != NULL);
-+      BUG_ON(info->rq != NULL);
-+
-+      mi = xlbd_get_major_info(vdevice);
-+      if (mi == NULL)
-+              goto out;
-+      info->mi = mi;
-+
-+      if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
-+              nr_minors = 1 << mi->type->partn_shift;
-+
-+      gd = alloc_disk(nr_minors);
-+      if (gd == NULL)
-+              goto out;
-+
-+      offset =  mi->index * mi->type->disks_per_major +
-+                      (minor >> mi->type->partn_shift);
-+      if (nr_minors > 1) {
-+              if (offset < 26) {
-+                      sprintf(gd->disk_name, "%s%c",
-+                               mi->type->diskname, 'a' + offset );
-+              }
-+              else {
-+                      sprintf(gd->disk_name, "%s%c%c",
-+                              mi->type->diskname,
-+                              'a' + ((offset/26)-1), 'a' + (offset%26) );
-+              }
-+      }
-+      else {
-+              if (offset < 26) {
-+                      sprintf(gd->disk_name, "%s%c%d",
-+                              mi->type->diskname,
-+                              'a' + offset,
-+                              minor & ((1 << mi->type->partn_shift) - 1));
-+              }
-+              else {
-+                      sprintf(gd->disk_name, "%s%c%c%d",
-+                              mi->type->diskname,
-+                              'a' + ((offset/26)-1), 'a' + (offset%26),
-+                              minor & ((1 << mi->type->partn_shift) - 1));
-+              }
-+      }
-+
-+      gd->major = mi->major;
-+      gd->first_minor = minor;
-+      gd->fops = &xlvbd_block_fops;
-+      gd->private_data = info;
-+      gd->driverfs_dev = &(info->xbdev->dev);
-+      set_capacity(gd, capacity);
-+
-+      if (xlvbd_init_blk_queue(gd, sector_size)) {
-+              del_gendisk(gd);
-+              goto out;
-+      }
-+
-+      info->rq = gd->queue;
-+      info->gd = gd;
-+
-+      if (info->feature_barrier)
-+              xlvbd_barrier(info);
-+
-+      if (vdisk_info & VDISK_READONLY)
-+              set_disk_ro(gd, 1);
-+
-+      if (vdisk_info & VDISK_REMOVABLE)
-+              gd->flags |= GENHD_FL_REMOVABLE;
-+
-+      if (vdisk_info & VDISK_CDROM)
-+              gd->flags |= GENHD_FL_CD;
-+
-+      return 0;
-+
-+ out:
-+      if (mi)
-+              xlbd_put_major_info(mi);
-+      info->mi = NULL;
-+      return err;
-+}
-+
-+int
-+xlvbd_add(blkif_sector_t capacity, int vdevice, u16 vdisk_info,
-+        u16 sector_size, struct blkfront_info *info)
-+{
-+      struct block_device *bd;
-+      int err = 0;
-+
-+      info->dev = MKDEV(BLKIF_MAJOR(vdevice), BLKIF_MINOR(vdevice));
-+
-+      bd = bdget(info->dev);
-+      if (bd == NULL)
-+              return -ENODEV;
-+
-+      err = xlvbd_alloc_gendisk(BLKIF_MINOR(vdevice), capacity, vdevice,
-+                                vdisk_info, sector_size, info);
-+
-+      bdput(bd);
-+      return err;
-+}
-+
-+void
-+xlvbd_del(struct blkfront_info *info)
-+{
-+      if (info->mi == NULL)
-+              return;
-+
-+      BUG_ON(info->gd == NULL);
-+      del_gendisk(info->gd);
-+      put_disk(info->gd);
-+      info->gd = NULL;
-+
-+      xlbd_put_major_info(info->mi);
-+      info->mi = NULL;
-+
-+      BUG_ON(info->rq == NULL);
-+      blk_cleanup_queue(info->rq);
-+      info->rq = NULL;
-+}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+int
-+xlvbd_barrier(struct blkfront_info *info)
-+{
-+      int err;
-+
-+      err = blk_queue_ordered(info->rq,
-+              info->feature_barrier ? QUEUE_ORDERED_DRAIN : QUEUE_ORDERED_NONE, NULL);
-+      if (err)
-+              return err;
-+      printk("blkfront: %s: barriers %s\n",
-+             info->gd->disk_name, info->feature_barrier ? "enabled" : "disabled");
-+      return 0;
-+}
-+#else
-+int
-+xlvbd_barrier(struct blkfront_info *info)
-+{
-+      printk("blkfront: %s: barriers disabled\n", info->gd->disk_name);
-+      return -ENOSYS;
-+}
-+#endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blktap/Makefile linux-2.6.16.33/drivers/xen/blktap/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/blktap/Makefile  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blktap/Makefile        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,3 @@
-+LINUXINCLUDE += -I../xen/include/public/io
-+obj-y := xenbus.o interface.o blktap.o 
-+
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blktap/blktap.c linux-2.6.16.33/drivers/xen/blktap/blktap.c
---- linux-2.6.16.33-noxen/drivers/xen/blktap/blktap.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blktap/blktap.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1517 @@
-+/******************************************************************************
-+ * drivers/xen/blktap/blktap.c
-+ * 
-+ * Back-end driver for user level virtual block devices. This portion of the
-+ * driver exports a 'unified' block-device interface that can be accessed
-+ * by any operating system that implements a compatible front end. Requests
-+ * are remapped to a user-space memory region.
-+ *
-+ * Based on the blkback driver code.
-+ * 
-+ * Copyright (c) 2004-2005, Andrew Warfield and Julian Chesterfield
-+ *
-+ * Clean ups and fix ups:
-+ *    Copyright (c) 2006, Steven Rostedt - Red Hat, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/spinlock.h>
-+#include <linux/kthread.h>
-+#include <linux/list.h>
-+#include <asm/hypervisor.h>
-+#include "common.h"
-+#include <xen/balloon.h>
-+#include <linux/kernel.h>
-+#include <linux/fs.h>
-+#include <linux/mm.h>
-+#include <linux/errno.h>
-+#include <linux/major.h>
-+#include <linux/gfp.h>
-+#include <linux/poll.h>
-+#include <asm/tlbflush.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+#define MAX_TAP_DEV 256     /*the maximum number of tapdisk ring devices    */
-+#define MAX_DEV_NAME 100    /*the max tapdisk ring device name e.g. blktap0 */
-+
-+
-+struct class *xen_class;
-+EXPORT_SYMBOL_GPL(xen_class);
-+
-+/*
-+ * Setup the xen class.  This should probably go in another file, but
-+ * since blktap is the only user of it so far, it gets to keep it.
-+ */
-+int setup_xen_class(void)
-+{
-+      int ret;
-+
-+      if (xen_class)
-+              return 0;
-+
-+      xen_class = class_create(THIS_MODULE, "xen");
-+      if ((ret = IS_ERR(xen_class))) {
-+              xen_class = NULL;
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-+ * The maximum number of requests that can be outstanding at any time
-+ * is determined by 
-+ *
-+ *   [mmap_alloc * MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST] 
-+ *
-+ * where mmap_alloc < MAX_DYNAMIC_MEM.
-+ *
-+ * TODO:
-+ * mmap_alloc is initialised to 2 and should be adjustable on the fly via
-+ * sysfs.
-+ */
-+#define BLK_RING_SIZE         __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
-+#define MAX_DYNAMIC_MEM               BLK_RING_SIZE
-+#define MAX_PENDING_REQS      BLK_RING_SIZE
-+#define MMAP_PAGES (MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
-+#define MMAP_VADDR(_start, _req,_seg)                                   \
-+        (_start +                                                       \
-+         ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) +        \
-+         ((_seg) * PAGE_SIZE))
-+static int blkif_reqs = MAX_PENDING_REQS;
-+static int mmap_pages = MMAP_PAGES;
-+
-+#define RING_PAGES 1 /* BLKTAP - immediately before the mmap area, we
-+                    * have a bunch of pages reserved for shared
-+                    * memory rings.
-+                    */
-+
-+/*Data struct handed back to userspace for tapdisk device to VBD mapping*/
-+typedef struct domid_translate {
-+      unsigned short domid;
-+      unsigned short busid;
-+} domid_translate_t ;
-+
-+/*Data struct associated with each of the tapdisk devices*/
-+typedef struct tap_blkif {
-+      struct vm_area_struct *vma;   /*Shared memory area                   */
-+      unsigned long rings_vstart;   /*Kernel memory mapping                */
-+      unsigned long user_vstart;    /*User memory mapping                  */
-+      unsigned long dev_inuse;      /*One process opens device at a time.  */
-+      unsigned long dev_pending;    /*In process of being opened           */
-+      unsigned long ring_ok;        /*make this ring->state                */
-+      blkif_front_ring_t ufe_ring;  /*Rings up to user space.              */
-+      wait_queue_head_t wait;       /*for poll                             */
-+      unsigned long mode;           /*current switching mode               */
-+      int minor;                    /*Minor number for tapdisk device      */
-+      pid_t pid;                    /*tapdisk process id                   */
-+      enum { RUNNING, CLEANSHUTDOWN } status; /*Detect a clean userspace 
-+                                                shutdown                   */
-+      unsigned long *idx_map;       /*Record the user ring id to kern 
-+                                      [req id, idx] tuple                  */
-+      blkif_t *blkif;               /*Associate blkif with tapdev          */
-+      struct domid_translate trans; /*Translation from domid to bus.       */
-+} tap_blkif_t;
-+
-+static struct tap_blkif *tapfds[MAX_TAP_DEV];
-+static int blktap_next_minor;
-+
-+static int __init set_blkif_reqs(char *str)
-+{
-+      get_option(&str, &blkif_reqs);
-+      return 1;
-+}
-+__setup("blkif_reqs=", set_blkif_reqs);
-+
-+/* Run-time switchable: /sys/module/blktap/parameters/ */
-+static unsigned int log_stats = 0;
-+static unsigned int debug_lvl = 0;
-+module_param(log_stats, int, 0644);
-+module_param(debug_lvl, int, 0644);
-+
-+/*
-+ * Each outstanding request that we've passed to the lower device layers has a 
-+ * 'pending_req' allocated to it. Each buffer_head that completes decrements 
-+ * the pendcnt towards zero. When it hits zero, the specified domain has a 
-+ * response queued for it, with the saved 'id' passed back.
-+ */
-+typedef struct {
-+      blkif_t       *blkif;
-+      unsigned long  id;
-+      unsigned short mem_idx;
-+      int            nr_pages;
-+      atomic_t       pendcnt;
-+      unsigned short operation;
-+      int            status;
-+      struct list_head free_list;
-+      int            inuse;
-+} pending_req_t;
-+
-+static pending_req_t *pending_reqs[MAX_PENDING_REQS];
-+static struct list_head pending_free;
-+static DEFINE_SPINLOCK(pending_free_lock);
-+static DECLARE_WAIT_QUEUE_HEAD (pending_free_wq);
-+static int alloc_pending_reqs;
-+
-+typedef unsigned int PEND_RING_IDX;
-+
-+static inline int MASK_PEND_IDX(int i) { 
-+      return (i & (MAX_PENDING_REQS-1));
-+}
-+
-+static inline unsigned int RTN_PEND_IDX(pending_req_t *req, int idx) {
-+      return (req - pending_reqs[idx]);
-+}
-+
-+#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
-+
-+#define BLKBACK_INVALID_HANDLE (~0)
-+
-+static struct page **foreign_pages[MAX_DYNAMIC_MEM];
-+static inline unsigned long idx_to_kaddr(
-+      unsigned int mmap_idx, unsigned int req_idx, unsigned int sg_idx)
-+{
-+      unsigned int arr_idx = req_idx*BLKIF_MAX_SEGMENTS_PER_REQUEST + sg_idx;
-+      unsigned long pfn = page_to_pfn(foreign_pages[mmap_idx][arr_idx]);
-+      return (unsigned long)pfn_to_kaddr(pfn);
-+}
-+
-+static unsigned short mmap_alloc = 0;
-+static unsigned short mmap_lock = 0;
-+static unsigned short mmap_inuse = 0;
-+
-+/******************************************************************
-+ * GRANT HANDLES
-+ */
-+
-+/* When using grant tables to map a frame for device access then the
-+ * handle returned must be used to unmap the frame. This is needed to
-+ * drop the ref count on the frame.
-+ */
-+struct grant_handle_pair
-+{
-+        grant_handle_t kernel;
-+        grant_handle_t user;
-+};
-+#define INVALID_GRANT_HANDLE  0xFFFF
-+
-+static struct grant_handle_pair 
-+    pending_grant_handles[MAX_DYNAMIC_MEM][MMAP_PAGES];
-+#define pending_handle(_id, _idx, _i) \
-+    (pending_grant_handles[_id][((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) \
-+    + (_i)])
-+
-+
-+static int blktap_read_ufe_ring(tap_blkif_t *info); /*local prototypes*/
-+
-+#define BLKTAP_MINOR 0  /*/dev/xen/blktap has a dynamic major */
-+#define BLKTAP_DEV_DIR  "/dev/xen"
-+
-+static int blktap_major;
-+
-+/* blktap IOCTLs: */
-+#define BLKTAP_IOCTL_KICK_FE         1
-+#define BLKTAP_IOCTL_KICK_BE         2 /* currently unused */
-+#define BLKTAP_IOCTL_SETMODE         3
-+#define BLKTAP_IOCTL_SENDPID       4
-+#define BLKTAP_IOCTL_NEWINTF       5
-+#define BLKTAP_IOCTL_MINOR         6
-+#define BLKTAP_IOCTL_MAJOR         7
-+#define BLKTAP_QUERY_ALLOC_REQS      8
-+#define BLKTAP_IOCTL_FREEINTF        9
-+#define BLKTAP_IOCTL_PRINT_IDXS      100  
-+
-+/* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE)             */
-+#define BLKTAP_MODE_PASSTHROUGH      0x00000000  /* default            */
-+#define BLKTAP_MODE_INTERCEPT_FE     0x00000001
-+#define BLKTAP_MODE_INTERCEPT_BE     0x00000002  /* unimp.             */
-+
-+#define BLKTAP_MODE_INTERPOSE \
-+           (BLKTAP_MODE_INTERCEPT_FE | BLKTAP_MODE_INTERCEPT_BE)
-+
-+
-+static inline int BLKTAP_MODE_VALID(unsigned long arg)
-+{
-+      return ((arg == BLKTAP_MODE_PASSTHROUGH ) ||
-+              (arg == BLKTAP_MODE_INTERCEPT_FE) ||
-+                (arg == BLKTAP_MODE_INTERPOSE   ));
-+}
-+
-+/* Requests passing through the tap to userspace are re-assigned an ID.
-+ * We must record a mapping between the BE [IDX,ID] tuple and the userspace
-+ * ring ID. 
-+ */
-+
-+static inline unsigned long MAKE_ID(domid_t fe_dom, PEND_RING_IDX idx)
-+{
-+        return ((fe_dom << 16) | MASK_PEND_IDX(idx));
-+}
-+
-+extern inline PEND_RING_IDX ID_TO_IDX(unsigned long id)
-+{
-+        return (PEND_RING_IDX)(id & 0x0000ffff);
-+}
-+
-+extern inline int ID_TO_MIDX(unsigned long id)
-+{
-+        return (int)(id >> 16);
-+}
-+
-+#define INVALID_REQ 0xdead0000
-+
-+/*TODO: Convert to a free list*/
-+static inline int GET_NEXT_REQ(unsigned long *idx_map)
-+{
-+      int i;
-+      for (i = 0; i < MAX_PENDING_REQS; i++)
-+              if (idx_map[i] == INVALID_REQ)
-+                      return i;
-+
-+      return INVALID_REQ;
-+}
-+
-+
-+#define BLKTAP_INVALID_HANDLE(_g) \
-+    (((_g->kernel) == INVALID_GRANT_HANDLE) &&  \
-+     ((_g->user) == INVALID_GRANT_HANDLE))
-+
-+#define BLKTAP_INVALIDATE_HANDLE(_g) do {       \
-+    (_g)->kernel = INVALID_GRANT_HANDLE; (_g)->user = INVALID_GRANT_HANDLE; \
-+    } while(0)
-+
-+
-+/******************************************************************
-+ * BLKTAP VM OPS
-+ */
-+
-+static struct page *blktap_nopage(struct vm_area_struct *vma,
-+                                unsigned long address,
-+                                int *type)
-+{
-+      /*
-+       * if the page has not been mapped in by the driver then return
-+       * NOPAGE_SIGBUS to the domain.
-+       */
-+
-+      return NOPAGE_SIGBUS;
-+}
-+
-+struct vm_operations_struct blktap_vm_ops = {
-+      nopage:   blktap_nopage,
-+};
-+
-+/******************************************************************
-+ * BLKTAP FILE OPS
-+ */
-+ 
-+/*Function Declarations*/
-+static tap_blkif_t *get_next_free_dev(void);
-+static int blktap_open(struct inode *inode, struct file *filp);
-+static int blktap_release(struct inode *inode, struct file *filp);
-+static int blktap_mmap(struct file *filp, struct vm_area_struct *vma);
-+static int blktap_ioctl(struct inode *inode, struct file *filp,
-+                        unsigned int cmd, unsigned long arg);
-+static unsigned int blktap_poll(struct file *file, poll_table *wait);
-+
-+static struct file_operations blktap_fops = {
-+      .owner   = THIS_MODULE,
-+      .poll    = blktap_poll,
-+      .ioctl   = blktap_ioctl,
-+      .open    = blktap_open,
-+      .release = blktap_release,
-+      .mmap    = blktap_mmap,
-+};
-+
-+
-+static tap_blkif_t *get_next_free_dev(void)
-+{
-+      tap_blkif_t *info;
-+      int minor;
-+
-+      /*
-+       * This is called only from the ioctl, which
-+       * means we should always have interrupts enabled.
-+       */
-+      BUG_ON(irqs_disabled());
-+
-+      spin_lock_irq(&pending_free_lock);
-+
-+      /* tapfds[0] is always NULL */
-+
-+      for (minor = 1; minor < blktap_next_minor; minor++) {
-+              info = tapfds[minor];
-+              /* we could have failed a previous attempt. */
-+              if (!info ||
-+                  ((info->dev_inuse == 0) &&
-+                   (info->dev_pending == 0)) ) {
-+                      info->dev_pending = 1;
-+                      goto found;
-+              }
-+      }
-+      info = NULL;
-+      minor = -1;
-+
-+      /*
-+       * We didn't find free device. If we can still allocate
-+       * more, then we grab the next device minor that is
-+       * available.  This is done while we are still under
-+       * the protection of the pending_free_lock.
-+       */
-+      if (blktap_next_minor < MAX_TAP_DEV)
-+              minor = blktap_next_minor++;
-+found:
-+      spin_unlock_irq(&pending_free_lock);
-+
-+      if (!info && minor > 0) {
-+              info = kzalloc(sizeof(*info), GFP_KERNEL);
-+              if (unlikely(!info)) {
-+                      /*
-+                       * If we failed here, try to put back
-+                       * the next minor number. But if one
-+                       * was just taken, then we just lose this
-+                       * minor.  We can try to allocate this
-+                       * minor again later.
-+                       */
-+                      spin_lock_irq(&pending_free_lock);
-+                      if (blktap_next_minor == minor+1)
-+                              blktap_next_minor--;
-+                      spin_unlock_irq(&pending_free_lock);
-+                      goto out;
-+              }
-+
-+              info->minor = minor;
-+              /*
-+               * Make sure that we have a minor before others can
-+               * see us.
-+               */
-+              wmb();
-+              tapfds[minor] = info;
-+
-+              class_device_create(xen_class, NULL,
-+                                  MKDEV(blktap_major, minor), NULL,
-+                                  "blktap%d", minor);
-+              devfs_mk_cdev(MKDEV(blktap_major, minor),
-+                      S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", minor);
-+      }
-+
-+out:
-+      return info;
-+}
-+
-+int dom_to_devid(domid_t domid, int xenbus_id, blkif_t *blkif) 
-+{
-+      tap_blkif_t *info;
-+      int i;
-+
-+      for (i = 1; i < blktap_next_minor; i++) {
-+              info = tapfds[i];
-+              if ( info &&
-+                   (info->trans.domid == domid) &&
-+                   (info->trans.busid == xenbus_id) ) {
-+                      info->blkif = blkif;
-+                      info->status = RUNNING;
-+                      return i;
-+              }
-+      }
-+      return -1;
-+}
-+
-+void signal_tapdisk(int idx) 
-+{
-+      tap_blkif_t *info;
-+      struct task_struct *ptask;
-+
-+      info = tapfds[idx];
-+      if ((idx < 0) || (idx > MAX_TAP_DEV) || !info)
-+              return;
-+
-+      if (info->pid > 0) {
-+              ptask = find_task_by_pid(info->pid);
-+              if (ptask)
-+                      info->status = CLEANSHUTDOWN;
-+      }
-+      info->blkif = NULL;
-+
-+      return;
-+}
-+
-+static int blktap_open(struct inode *inode, struct file *filp)
-+{
-+      blkif_sring_t *sring;
-+      int idx = iminor(inode) - BLKTAP_MINOR;
-+      tap_blkif_t *info;
-+      int i;
-+      
-+      /* ctrl device, treat differently */
-+      if (!idx)
-+              return 0;
-+
-+      info = tapfds[idx];
-+
-+      if ((idx < 0) || (idx > MAX_TAP_DEV) || !info) {
-+              WPRINTK("Unable to open device /dev/xen/blktap%d\n",
-+                      idx);
-+              return -ENODEV;
-+      }
-+
-+      DPRINTK("Opening device /dev/xen/blktap%d\n",idx);
-+      
-+      /*Only one process can access device at a time*/
-+      if (test_and_set_bit(0, &info->dev_inuse))
-+              return -EBUSY;
-+
-+      info->dev_pending = 0;
-+          
-+      /* Allocate the fe ring. */
-+      sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
-+      if (sring == NULL)
-+              goto fail_nomem;
-+
-+      SetPageReserved(virt_to_page(sring));
-+    
-+      SHARED_RING_INIT(sring);
-+      FRONT_RING_INIT(&info->ufe_ring, sring, PAGE_SIZE);
-+      
-+      filp->private_data = info;
-+      info->vma = NULL;
-+
-+      info->idx_map = kmalloc(sizeof(unsigned long) * MAX_PENDING_REQS, 
-+                              GFP_KERNEL);
-+      
-+      if (idx > 0) {
-+              init_waitqueue_head(&info->wait);
-+              for (i = 0; i < MAX_PENDING_REQS; i++) 
-+                      info->idx_map[i] = INVALID_REQ;
-+      }
-+
-+      DPRINTK("Tap open: device /dev/xen/blktap%d\n",idx);
-+      return 0;
-+
-+ fail_nomem:
-+      return -ENOMEM;
-+}
-+
-+static int blktap_release(struct inode *inode, struct file *filp)
-+{
-+      tap_blkif_t *info = filp->private_data;
-+      
-+      /* check for control device */
-+      if (!info)
-+              return 0;
-+
-+      info->dev_inuse = 0;
-+      DPRINTK("Freeing device [/dev/xen/blktap%d]\n",info->minor);
-+
-+      /* Free the ring page. */
-+      ClearPageReserved(virt_to_page(info->ufe_ring.sring));
-+      free_page((unsigned long) info->ufe_ring.sring);
-+
-+      /* Clear any active mappings and free foreign map table */
-+      if (info->vma) {
-+              zap_page_range(
-+                      info->vma, info->vma->vm_start, 
-+                      info->vma->vm_end - info->vma->vm_start, NULL);
-+              info->vma = NULL;
-+      }
-+      
-+      if ( (info->status != CLEANSHUTDOWN) && (info->blkif != NULL) ) {
-+              if (info->blkif->xenblkd != NULL) {
-+                      kthread_stop(info->blkif->xenblkd);
-+                      info->blkif->xenblkd = NULL;
-+              }
-+              info->status = CLEANSHUTDOWN;
-+      }       
-+      return 0;
-+}
-+
-+
-+/* Note on mmap:
-+ * We need to map pages to user space in a way that will allow the block
-+ * subsystem set up direct IO to them.  This couldn't be done before, because
-+ * there isn't really a sane way to translate a user virtual address down to a 
-+ * physical address when the page belongs to another domain.
-+ *
-+ * My first approach was to map the page in to kernel memory, add an entry
-+ * for it in the physical frame list (using alloc_lomem_region as in blkback)
-+ * and then attempt to map that page up to user space.  This is disallowed
-+ * by xen though, which realizes that we don't really own the machine frame
-+ * underlying the physical page.
-+ *
-+ * The new approach is to provide explicit support for this in xen linux.
-+ * The VMA now has a flag, VM_FOREIGN, to indicate that it contains pages
-+ * mapped from other vms.  vma->vm_private_data is set up as a mapping 
-+ * from pages to actual page structs.  There is a new clause in get_user_pages
-+ * that does the right thing for this sort of mapping.
-+ */
-+static int blktap_mmap(struct file *filp, struct vm_area_struct *vma)
-+{
-+      int size;
-+      struct page **map;
-+      int i;
-+      tap_blkif_t *info = filp->private_data;
-+
-+      if (info == NULL) {
-+              WPRINTK("blktap: mmap, retrieving idx failed\n");
-+              return -ENOMEM;
-+      }
-+      
-+      vma->vm_flags |= VM_RESERVED;
-+      vma->vm_ops = &blktap_vm_ops;
-+
-+      size = vma->vm_end - vma->vm_start;
-+      if (size != ((mmap_pages + RING_PAGES) << PAGE_SHIFT)) {
-+              WPRINTK("you _must_ map exactly %d pages!\n",
-+                     mmap_pages + RING_PAGES);
-+              return -EAGAIN;
-+      }
-+
-+      size >>= PAGE_SHIFT;
-+      info->rings_vstart = vma->vm_start;
-+      info->user_vstart  = info->rings_vstart + (RING_PAGES << PAGE_SHIFT);
-+    
-+      /* Map the ring pages to the start of the region and reserve it. */
-+      if (remap_pfn_range(vma, vma->vm_start, 
-+                          __pa(info->ufe_ring.sring) >> PAGE_SHIFT, 
-+                          PAGE_SIZE, vma->vm_page_prot)) {
-+              WPRINTK("Mapping user ring failed!\n");
-+              goto fail;
-+      }
-+
-+      /* Mark this VM as containing foreign pages, and set up mappings. */
-+      map = kzalloc(((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)
-+                    * sizeof(struct page_struct*),
-+                    GFP_KERNEL);
-+      if (map == NULL) {
-+              WPRINTK("Couldn't alloc VM_FOREIGN map.\n");
-+              goto fail;
-+      }
-+
-+      for (i = 0; i < ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT); i++)
-+              map[i] = NULL;
-+    
-+      vma->vm_private_data = map;
-+      vma->vm_flags |= VM_FOREIGN;
-+
-+      info->vma = vma;
-+      info->ring_ok = 1;
-+      return 0;
-+ fail:
-+      /* Clear any active mappings. */
-+      zap_page_range(vma, vma->vm_start, 
-+                     vma->vm_end - vma->vm_start, NULL);
-+
-+      return -ENOMEM;
-+}
-+
-+
-+static int blktap_ioctl(struct inode *inode, struct file *filp,
-+                        unsigned int cmd, unsigned long arg)
-+{
-+      tap_blkif_t *info = filp->private_data;
-+
-+      switch(cmd) {
-+      case BLKTAP_IOCTL_KICK_FE: 
-+      {
-+              /* There are fe messages to process. */
-+              return blktap_read_ufe_ring(info);
-+      }
-+      case BLKTAP_IOCTL_SETMODE:
-+      {
-+              if (info) {
-+                      if (BLKTAP_MODE_VALID(arg)) {
-+                              info->mode = arg;
-+                              /* XXX: may need to flush rings here. */
-+                              DPRINTK("blktap: set mode to %lx\n", 
-+                                     arg);
-+                              return 0;
-+                      }
-+              }
-+              return 0;
-+      }
-+      case BLKTAP_IOCTL_PRINT_IDXS:
-+        {
-+              if (info) {
-+                      printk("User Rings: \n-----------\n");
-+                      printk("UF: rsp_cons: %2d, req_prod_prv: %2d "
-+                              "| req_prod: %2d, rsp_prod: %2d\n",
-+                              info->ufe_ring.rsp_cons,
-+                              info->ufe_ring.req_prod_pvt,
-+                              info->ufe_ring.sring->req_prod,
-+                              info->ufe_ring.sring->rsp_prod);
-+              }
-+              return 0;
-+        }
-+      case BLKTAP_IOCTL_SENDPID:
-+      {
-+              if (info) {
-+                      info->pid = (pid_t)arg;
-+                      DPRINTK("blktap: pid received %d\n", 
-+                             info->pid);
-+              }
-+              return 0;
-+      }
-+      case BLKTAP_IOCTL_NEWINTF:
-+      {               
-+              uint64_t val = (uint64_t)arg;
-+              domid_translate_t *tr = (domid_translate_t *)&val;
-+
-+              DPRINTK("NEWINTF Req for domid %d and bus id %d\n", 
-+                     tr->domid, tr->busid);
-+              info = get_next_free_dev();
-+              if (!info) {
-+                      WPRINTK("Error initialising /dev/xen/blktap - "
-+                              "No more devices\n");
-+                      return -1;
-+              }
-+              info->trans.domid = tr->domid;
-+              info->trans.busid = tr->busid;
-+              return info->minor;
-+      }
-+      case BLKTAP_IOCTL_FREEINTF:
-+      {
-+              unsigned long dev = arg;
-+              unsigned long flags;
-+
-+              info = tapfds[dev];
-+
-+              if ((dev > MAX_TAP_DEV) || !info)
-+                      return 0; /* should this be an error? */
-+
-+              spin_lock_irqsave(&pending_free_lock, flags);
-+              if (info->dev_pending)
-+                      info->dev_pending = 0;
-+              spin_unlock_irqrestore(&pending_free_lock, flags);
-+
-+              return 0;
-+      }
-+      case BLKTAP_IOCTL_MINOR:
-+      {
-+              unsigned long dev = arg;
-+
-+              info = tapfds[dev];
-+
-+              if ((dev > MAX_TAP_DEV) || !info)
-+                      return -EINVAL;
-+
-+              return info->minor;
-+      }
-+      case BLKTAP_IOCTL_MAJOR:
-+              return blktap_major;
-+
-+      case BLKTAP_QUERY_ALLOC_REQS:
-+      {
-+              WPRINTK("BLKTAP_QUERY_ALLOC_REQS ioctl: %d/%d\n",
-+                     alloc_pending_reqs, blkif_reqs);
-+              return (alloc_pending_reqs/blkif_reqs) * 100;
-+      }
-+      }
-+      return -ENOIOCTLCMD;
-+}
-+
-+static unsigned int blktap_poll(struct file *filp, poll_table *wait)
-+{
-+      tap_blkif_t *info = filp->private_data;
-+      
-+      /* do not work on the control device */
-+      if (!info)
-+              return 0;
-+
-+      poll_wait(filp, &info->wait, wait);
-+      if (info->ufe_ring.req_prod_pvt != info->ufe_ring.sring->req_prod) {
-+              RING_PUSH_REQUESTS(&info->ufe_ring);
-+              return POLLIN | POLLRDNORM;
-+      }
-+      return 0;
-+}
-+
-+void blktap_kick_user(int idx)
-+{
-+      tap_blkif_t *info;
-+
-+      info = tapfds[idx];
-+
-+      if ((idx < 0) || (idx > MAX_TAP_DEV) || !info)
-+              return;
-+
-+      wake_up_interruptible(&info->wait);
-+
-+      return;
-+}
-+
-+static int do_block_io_op(blkif_t *blkif);
-+static void dispatch_rw_block_io(blkif_t *blkif,
-+                               blkif_request_t *req,
-+                               pending_req_t *pending_req);
-+static void make_response(blkif_t *blkif, unsigned long id, 
-+                          unsigned short op, int st);
-+
-+/******************************************************************
-+ * misc small helpers
-+ */
-+static int req_increase(void)
-+{
-+      int i, j;
-+
-+      if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) 
-+              return -EINVAL;
-+
-+      pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t)
-+                                          * blkif_reqs, GFP_KERNEL);
-+      foreign_pages[mmap_alloc] = alloc_empty_pages_and_pagevec(mmap_pages);
-+
-+      if (!pending_reqs[mmap_alloc] || !foreign_pages[mmap_alloc])
-+              goto out_of_memory;
-+
-+      DPRINTK("%s: reqs=%d, pages=%d\n",
-+              __FUNCTION__, blkif_reqs, mmap_pages);
-+
-+      for (i = 0; i < MAX_PENDING_REQS; i++) {
-+              list_add_tail(&pending_reqs[mmap_alloc][i].free_list, 
-+                            &pending_free);
-+              pending_reqs[mmap_alloc][i].mem_idx = mmap_alloc;
-+              for (j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++)
-+                      BLKTAP_INVALIDATE_HANDLE(&pending_handle(mmap_alloc, 
-+                                                               i, j));
-+      }
-+
-+      mmap_alloc++;
-+      DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
-+      return 0;
-+
-+ out_of_memory:
-+      free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
-+      kfree(pending_reqs[mmap_alloc]);
-+      WPRINTK("%s: out of memory\n", __FUNCTION__);
-+      return -ENOMEM;
-+}
-+
-+static void mmap_req_del(int mmap)
-+{
-+      BUG_ON(!spin_is_locked(&pending_free_lock));
-+
-+      kfree(pending_reqs[mmap]);
-+      pending_reqs[mmap] = NULL;
-+
-+      free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
-+      foreign_pages[mmap] = NULL;
-+
-+      mmap_lock = 0;
-+      DPRINTK("# MMAPs decreased to %d\n",mmap_alloc);
-+      mmap_alloc--;
-+}
-+
-+static pending_req_t* alloc_req(void)
-+{
-+      pending_req_t *req = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&pending_free_lock, flags);
-+
-+      if (!list_empty(&pending_free)) {
-+              req = list_entry(pending_free.next, pending_req_t, free_list);
-+              list_del(&req->free_list);
-+      }
-+
-+      if (req) {
-+              req->inuse = 1;
-+              alloc_pending_reqs++;
-+      }
-+      spin_unlock_irqrestore(&pending_free_lock, flags);
-+
-+      return req;
-+}
-+
-+static void free_req(pending_req_t *req)
-+{
-+      unsigned long flags;
-+      int was_empty;
-+
-+      spin_lock_irqsave(&pending_free_lock, flags);
-+
-+      alloc_pending_reqs--;
-+      req->inuse = 0;
-+      if (mmap_lock && (req->mem_idx == mmap_alloc-1)) {
-+              mmap_inuse--;
-+              if (mmap_inuse == 0) mmap_req_del(mmap_alloc-1);
-+              spin_unlock_irqrestore(&pending_free_lock, flags);
-+              return;
-+      }
-+      was_empty = list_empty(&pending_free);
-+      list_add(&req->free_list, &pending_free);
-+
-+      spin_unlock_irqrestore(&pending_free_lock, flags);
-+
-+      if (was_empty)
-+              wake_up(&pending_free_wq);
-+}
-+
-+static void fast_flush_area(pending_req_t *req, int k_idx, int u_idx,
-+                          int tapidx)
-+{
-+      struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
-+      unsigned int i, invcount = 0;
-+      struct grant_handle_pair *khandle;
-+      uint64_t ptep;
-+      int ret, mmap_idx;
-+      unsigned long kvaddr, uvaddr;
-+      tap_blkif_t *info;
-+      
-+
-+      info = tapfds[tapidx];
-+
-+      if ((tapidx < 0) || (tapidx > MAX_TAP_DEV) || !info) {
-+              WPRINTK("fast_flush: Couldn't get info!\n");
-+              return;
-+      }
-+
-+      if (info->vma != NULL &&
-+          xen_feature(XENFEAT_auto_translated_physmap)) {
-+              down_write(&info->vma->vm_mm->mmap_sem);
-+              zap_page_range(info->vma, 
-+                             MMAP_VADDR(info->user_vstart, u_idx, 0), 
-+                             req->nr_pages << PAGE_SHIFT, NULL);
-+              up_write(&info->vma->vm_mm->mmap_sem);
-+      }
-+
-+      mmap_idx = req->mem_idx;
-+
-+      for (i = 0; i < req->nr_pages; i++) {
-+              kvaddr = idx_to_kaddr(mmap_idx, k_idx, i);
-+              uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i);
-+
-+              khandle = &pending_handle(mmap_idx, k_idx, i);
-+
-+              if (khandle->kernel != INVALID_GRANT_HANDLE) {
-+                      gnttab_set_unmap_op(&unmap[invcount],
-+                                          idx_to_kaddr(mmap_idx, k_idx, i),
-+                                          GNTMAP_host_map, khandle->kernel);
-+                      invcount++;
-+              }
-+
-+              if (khandle->user != INVALID_GRANT_HANDLE) {
-+                      BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
-+                      if (create_lookup_pte_addr(
-+                              info->vma->vm_mm,
-+                              MMAP_VADDR(info->user_vstart, u_idx, i),
-+                              &ptep) !=0) {
-+                              WPRINTK("Couldn't get a pte addr!\n");
-+                              return;
-+                      }
-+
-+                      gnttab_set_unmap_op(&unmap[invcount], ptep,
-+                                          GNTMAP_host_map
-+                                          | GNTMAP_application_map
-+                                          | GNTMAP_contains_pte,
-+                                          khandle->user);
-+                      invcount++;
-+              }
-+
-+              BLKTAP_INVALIDATE_HANDLE(khandle);
-+      }
-+      ret = HYPERVISOR_grant_table_op(
-+              GNTTABOP_unmap_grant_ref, unmap, invcount);
-+      BUG_ON(ret);
-+      
-+      if (info->vma != NULL && !xen_feature(XENFEAT_auto_translated_physmap))
-+              zap_page_range(info->vma, 
-+                             MMAP_VADDR(info->user_vstart, u_idx, 0), 
-+                             req->nr_pages << PAGE_SHIFT, NULL);
-+}
-+
-+/******************************************************************
-+ * SCHEDULER FUNCTIONS
-+ */
-+
-+static void print_stats(blkif_t *blkif)
-+{
-+      printk(KERN_DEBUG "%s: oo %3d  |  rd %4d  |  wr %4d\n",
-+             current->comm, blkif->st_oo_req,
-+             blkif->st_rd_req, blkif->st_wr_req);
-+      blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
-+      blkif->st_rd_req = 0;
-+      blkif->st_wr_req = 0;
-+      blkif->st_oo_req = 0;
-+}
-+
-+int tap_blkif_schedule(void *arg)
-+{
-+      blkif_t *blkif = arg;
-+
-+      blkif_get(blkif);
-+
-+      if (debug_lvl)
-+              printk(KERN_DEBUG "%s: started\n", current->comm);
-+
-+      while (!kthread_should_stop()) {
-+              wait_event_interruptible(
-+                      blkif->wq,
-+                      blkif->waiting_reqs || kthread_should_stop());
-+              wait_event_interruptible(
-+                      pending_free_wq,
-+                      !list_empty(&pending_free) || kthread_should_stop());
-+
-+              blkif->waiting_reqs = 0;
-+              smp_mb(); /* clear flag *before* checking for work */
-+
-+              if (do_block_io_op(blkif))
-+                      blkif->waiting_reqs = 1;
-+
-+              if (log_stats && time_after(jiffies, blkif->st_print))
-+                      print_stats(blkif);
-+      }
-+
-+      if (log_stats)
-+              print_stats(blkif);
-+      if (debug_lvl)
-+              printk(KERN_DEBUG "%s: exiting\n", current->comm);
-+
-+      blkif->xenblkd = NULL;
-+      blkif_put(blkif);
-+
-+      return 0;
-+}
-+
-+/******************************************************************
-+ * COMPLETION CALLBACK -- Called by user level ioctl()
-+ */
-+
-+static int blktap_read_ufe_ring(tap_blkif_t *info)
-+{
-+      /* This is called to read responses from the UFE ring. */
-+      RING_IDX i, j, rp;
-+      blkif_response_t *resp;
-+      blkif_t *blkif=NULL;
-+      int pending_idx, usr_idx, mmap_idx;
-+      pending_req_t *pending_req;
-+      
-+      if (!info)
-+              return 0;
-+
-+      /* We currently only forward packets in INTERCEPT_FE mode. */
-+      if (!(info->mode & BLKTAP_MODE_INTERCEPT_FE))
-+              return 0;
-+
-+      /* for each outstanding message on the UFEring  */
-+      rp = info->ufe_ring.sring->rsp_prod;
-+      rmb();
-+        
-+      for (i = info->ufe_ring.rsp_cons; i != rp; i++) {
-+              blkif_response_t res;
-+              resp = RING_GET_RESPONSE(&info->ufe_ring, i);
-+              memcpy(&res, resp, sizeof(res));
-+              mb(); /* rsp_cons read by RING_FULL() in do_block_io_op(). */
-+              ++info->ufe_ring.rsp_cons;
-+
-+              /*retrieve [usr_idx] to [mmap_idx,pending_idx] mapping*/
-+              usr_idx = (int)res.id;
-+              pending_idx = MASK_PEND_IDX(ID_TO_IDX(info->idx_map[usr_idx]));
-+              mmap_idx = ID_TO_MIDX(info->idx_map[usr_idx]);
-+
-+              if ( (mmap_idx >= mmap_alloc) || 
-+                 (ID_TO_IDX(info->idx_map[usr_idx]) >= MAX_PENDING_REQS) )
-+                      WPRINTK("Incorrect req map"
-+                             "[%d], internal map [%d,%d (%d)]\n", 
-+                             usr_idx, mmap_idx, 
-+                             ID_TO_IDX(info->idx_map[usr_idx]),
-+                             MASK_PEND_IDX(
-+                                     ID_TO_IDX(info->idx_map[usr_idx])));
-+
-+              pending_req = &pending_reqs[mmap_idx][pending_idx];
-+              blkif = pending_req->blkif;
-+
-+              for (j = 0; j < pending_req->nr_pages; j++) {
-+
-+                      unsigned long kvaddr, uvaddr;
-+                      struct page **map = info->vma->vm_private_data;
-+                      struct page *pg;
-+                      int offset;
-+
-+                      uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, j);
-+                      kvaddr = idx_to_kaddr(mmap_idx, pending_idx, j);
-+
-+                      pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
-+                      ClearPageReserved(pg);
-+                      offset = (uvaddr - info->vma->vm_start) 
-+                              >> PAGE_SHIFT;
-+                      map[offset] = NULL;
-+              }
-+              fast_flush_area(pending_req, pending_idx, usr_idx, info->minor);
-+              info->idx_map[usr_idx] = INVALID_REQ;
-+              make_response(blkif, pending_req->id, res.operation,
-+                            res.status);
-+              blkif_put(pending_req->blkif);
-+              free_req(pending_req);
-+      }
-+              
-+      return 0;
-+}
-+
-+
-+/******************************************************************************
-+ * NOTIFICATION FROM GUEST OS.
-+ */
-+
-+static void blkif_notify_work(blkif_t *blkif)
-+{
-+      blkif->waiting_reqs = 1;
-+      wake_up(&blkif->wq);
-+}
-+
-+irqreturn_t tap_blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      blkif_notify_work(dev_id);
-+      return IRQ_HANDLED;
-+}
-+
-+
-+
-+/******************************************************************
-+ * DOWNWARD CALLS -- These interface with the block-device layer proper.
-+ */
-+static int print_dbug = 1;
-+static int do_block_io_op(blkif_t *blkif)
-+{
-+      blkif_back_ring_t *blk_ring = &blkif->blk_ring;
-+      blkif_request_t req;
-+      pending_req_t *pending_req;
-+      RING_IDX rc, rp;
-+      int more_to_do = 0;
-+      tap_blkif_t *info;
-+
-+      rc = blk_ring->req_cons;
-+      rp = blk_ring->sring->req_prod;
-+      rmb(); /* Ensure we see queued requests up to 'rp'. */
-+
-+      /*Check blkif has corresponding UE ring*/
-+      if (blkif->dev_num < 0) {
-+              /*oops*/
-+              if (print_dbug) {
-+                      WPRINTK("Corresponding UE " 
-+                             "ring does not exist!\n");
-+                      print_dbug = 0; /*We only print this message once*/
-+              }
-+              return 0;
-+      }
-+
-+      info = tapfds[blkif->dev_num];
-+
-+      if (blkif->dev_num > MAX_TAP_DEV || !info || !info->dev_inuse) {
-+              if (print_dbug) {
-+                      WPRINTK("Can't get UE info!\n");
-+                      print_dbug = 0;
-+              }
-+              return 0;
-+      }
-+
-+      while (rc != rp) {
-+              
-+              if (RING_FULL(&info->ufe_ring)) {
-+                      WPRINTK("RING_FULL! More to do\n");
-+                      more_to_do = 1;
-+                      break;
-+              }
-+              
-+              if (RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) {
-+                      WPRINTK("RING_REQUEST_CONS_OVERFLOW!"
-+                             " More to do\n");
-+                      more_to_do = 1;
-+                      break;          
-+              }
-+
-+              pending_req = alloc_req();
-+              if (NULL == pending_req) {
-+                      blkif->st_oo_req++;
-+                      more_to_do = 1;
-+                      break;
-+              }
-+
-+              memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req));
-+              blk_ring->req_cons = ++rc; /* before make_response() */ 
-+
-+              switch (req.operation) {
-+              case BLKIF_OP_READ:
-+                      blkif->st_rd_req++;
-+                      dispatch_rw_block_io(blkif, &req, pending_req);
-+                      break;
-+
-+              case BLKIF_OP_WRITE:
-+                      blkif->st_wr_req++;
-+                      dispatch_rw_block_io(blkif, &req, pending_req);
-+                      break;
-+
-+              default:
-+                      WPRINTK("unknown operation [%d]\n",
-+                              req.operation);
-+                      make_response(blkif, req.id, req.operation,
-+                                    BLKIF_RSP_ERROR);
-+                      free_req(pending_req);
-+                      break;
-+              }
-+      }
-+              
-+      blktap_kick_user(blkif->dev_num);
-+
-+      return more_to_do;
-+}
-+
-+static void dispatch_rw_block_io(blkif_t *blkif,
-+                               blkif_request_t *req,
-+                               pending_req_t *pending_req)
-+{
-+      extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
-+      int op, operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
-+      struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
-+      unsigned int nseg;
-+      int ret, i;
-+      tap_blkif_t *info;
-+      uint64_t sector;
-+      blkif_request_t *target;
-+      int pending_idx = RTN_PEND_IDX(pending_req,pending_req->mem_idx);
-+      int usr_idx;
-+      uint16_t mmap_idx = pending_req->mem_idx;
-+
-+      if (blkif->dev_num < 0 || blkif->dev_num > MAX_TAP_DEV)
-+              goto fail_response;
-+
-+      info = tapfds[blkif->dev_num];
-+      if (info == NULL)
-+              goto fail_response;
-+
-+      /* Check we have space on user ring - should never fail. */
-+      usr_idx = GET_NEXT_REQ(info->idx_map);
-+      if (usr_idx == INVALID_REQ) {
-+              BUG();
-+              goto fail_response;
-+      }
-+
-+      /* Check that number of segments is sane. */
-+      nseg = req->nr_segments;
-+      if ( unlikely(nseg == 0) || 
-+          unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) ) {
-+              WPRINTK("Bad number of segments in request (%d)\n", nseg);
-+              goto fail_response;
-+      }
-+      
-+      /* Make sure userspace is ready. */
-+      if (!info->ring_ok) {
-+              WPRINTK("blktap: ring not ready for requests!\n");
-+              goto fail_response;
-+      }
-+
-+      if (RING_FULL(&info->ufe_ring)) {
-+              WPRINTK("blktap: fe_ring is full, can't add "
-+                      "IO Request will be dropped. %d %d\n",
-+                      RING_SIZE(&info->ufe_ring),
-+                      RING_SIZE(&blkif->blk_ring));
-+              goto fail_response;
-+      }
-+
-+      pending_req->blkif     = blkif;
-+      pending_req->id        = req->id;
-+      pending_req->operation = operation;
-+      pending_req->status    = BLKIF_RSP_OKAY;
-+      pending_req->nr_pages  = nseg;
-+      op = 0;
-+      for (i = 0; i < nseg; i++) {
-+              unsigned long uvaddr;
-+              unsigned long kvaddr;
-+              uint64_t ptep;
-+              uint32_t flags;
-+
-+              uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
-+              kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
-+
-+              sector = req->sector_number + ((PAGE_SIZE / 512) * i);
-+              if( (blkif->sectors > 0) && (sector >= blkif->sectors) ) {
-+                      WPRINTK("BLKTAP: Sector request greater" 
-+                             "than size\n");
-+                      WPRINTK("BLKTAP: %s request sector" 
-+                             "[%llu,%llu], Total [%llu]\n",
-+                             (req->operation == 
-+                              BLKIF_OP_WRITE ? "WRITE" : "READ"),
-+                              (long long unsigned) sector,
-+                              (long long unsigned) sector>>9,
-+                              (long long unsigned) blkif->sectors);
-+              }
-+
-+              flags = GNTMAP_host_map;
-+              if (operation == WRITE)
-+                      flags |= GNTMAP_readonly;
-+              gnttab_set_map_op(&map[op], kvaddr, flags,
-+                                req->seg[i].gref, blkif->domid);
-+              op++;
-+
-+              if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      /* Now map it to user. */
-+                      ret = create_lookup_pte_addr(info->vma->vm_mm, 
-+                                                   uvaddr, &ptep);
-+                      if (ret) {
-+                              WPRINTK("Couldn't get a pte addr!\n");
-+                              goto fail_flush;
-+                      }
-+
-+                      flags = GNTMAP_host_map | GNTMAP_application_map
-+                              | GNTMAP_contains_pte;
-+                      if (operation == WRITE)
-+                              flags |= GNTMAP_readonly;
-+                      gnttab_set_map_op(&map[op], ptep, flags,
-+                                        req->seg[i].gref, blkif->domid);
-+                      op++;
-+              }
-+      }
-+
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
-+      BUG_ON(ret);
-+
-+      if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+              for (i = 0; i < (nseg*2); i+=2) {
-+                      unsigned long uvaddr;
-+                      unsigned long kvaddr;
-+                      unsigned long offset;
-+                      struct page *pg;
-+
-+                      uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i/2);
-+                      kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i/2);
-+
-+                      if (unlikely(map[i].status != 0)) {
-+                              WPRINTK("invalid kernel buffer -- "
-+                                      "could not remap it\n");
-+                              ret |= 1;
-+                              map[i].handle = INVALID_GRANT_HANDLE;
-+                      }
-+
-+                      if (unlikely(map[i+1].status != 0)) {
-+                              WPRINTK("invalid user buffer -- "
-+                                      "could not remap it\n");
-+                              ret |= 1;
-+                              map[i+1].handle = INVALID_GRANT_HANDLE;
-+                      }
-+
-+                      pending_handle(mmap_idx, pending_idx, i/2).kernel 
-+                              = map[i].handle;
-+                      pending_handle(mmap_idx, pending_idx, i/2).user   
-+                              = map[i+1].handle;
-+
-+                      if (ret)
-+                              continue;
-+
-+                      set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
-+                                          FOREIGN_FRAME(map[i].dev_bus_addr
-+                                                        >> PAGE_SHIFT));
-+                      offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
-+                      pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
-+                      ((struct page **)info->vma->vm_private_data)[offset] =
-+                              pg;
-+              }
-+      } else {
-+              for (i = 0; i < nseg; i++) {
-+                      unsigned long uvaddr;
-+                      unsigned long kvaddr;
-+                      unsigned long offset;
-+                      struct page *pg;
-+
-+                      uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
-+                      kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
-+
-+                      if (unlikely(map[i].status != 0)) {
-+                              WPRINTK("invalid kernel buffer -- "
-+                                      "could not remap it\n");
-+                              ret |= 1;
-+                              map[i].handle = INVALID_GRANT_HANDLE;
-+                      }
-+
-+                      pending_handle(mmap_idx, pending_idx, i).kernel 
-+                              = map[i].handle;
-+
-+                      if (ret)
-+                              continue;
-+
-+                      offset = (uvaddr - info->vma->vm_start) >> PAGE_SHIFT;
-+                      pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
-+                      ((struct page **)info->vma->vm_private_data)[offset] =
-+                              pg;
-+              }
-+      }
-+
-+      if (ret)
-+              goto fail_flush;
-+
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              down_write(&info->vma->vm_mm->mmap_sem);
-+      /* Mark mapped pages as reserved: */
-+      for (i = 0; i < req->nr_segments; i++) {
-+              unsigned long kvaddr;
-+              struct page *pg;
-+
-+              kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
-+              pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
-+              SetPageReserved(pg);
-+              if (xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      ret = vm_insert_page(info->vma,
-+                                           MMAP_VADDR(info->user_vstart,
-+                                                      usr_idx, i), pg);
-+                      if (ret) {
-+                              up_write(&info->vma->vm_mm->mmap_sem);
-+                              goto fail_flush;
-+                      }
-+              }
-+      }
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              up_write(&info->vma->vm_mm->mmap_sem);
-+      
-+      /*record [mmap_idx,pending_idx] to [usr_idx] mapping*/
-+      info->idx_map[usr_idx] = MAKE_ID(mmap_idx, pending_idx);
-+
-+      blkif_get(blkif);
-+      /* Finally, write the request message to the user ring. */
-+      target = RING_GET_REQUEST(&info->ufe_ring,
-+                                info->ufe_ring.req_prod_pvt);
-+      memcpy(target, req, sizeof(*req));
-+      target->id = usr_idx;
-+      wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
-+      info->ufe_ring.req_prod_pvt++;
-+      return;
-+
-+ fail_flush:
-+      WPRINTK("Reached Fail_flush\n");
-+      fast_flush_area(pending_req, pending_idx, usr_idx, blkif->dev_num);
-+ fail_response:
-+      make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
-+      free_req(pending_req);
-+} 
-+
-+
-+
-+/******************************************************************
-+ * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING
-+ */
-+
-+
-+static void make_response(blkif_t *blkif, unsigned long id, 
-+                          unsigned short op, int st)
-+{
-+      blkif_response_t *resp;
-+      unsigned long     flags;
-+      blkif_back_ring_t *blk_ring = &blkif->blk_ring;
-+      int more_to_do = 0;
-+      int notify;
-+
-+      spin_lock_irqsave(&blkif->blk_ring_lock, flags);
-+      /* Place on the response ring for the relevant domain. */ 
-+      resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
-+      resp->id        = id;
-+      resp->operation = op;
-+      resp->status    = st;
-+      blk_ring->rsp_prod_pvt++;
-+      RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
-+
-+      if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) {
-+              /*
-+               * Tail check for pending requests. Allows frontend to avoid
-+               * notifications if requests are already in flight (lower
-+               * overheads and promotes batching).
-+               */
-+              RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
-+      } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
-+              more_to_do = 1;
-+
-+      }       
-+      spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
-+      if (more_to_do)
-+              blkif_notify_work(blkif);
-+      if (notify)
-+              notify_remote_via_irq(blkif->irq);
-+}
-+
-+static int __init blkif_init(void)
-+{
-+      int i,ret,blktap_dir;
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      INIT_LIST_HEAD(&pending_free);
-+        for(i = 0; i < 2; i++) {
-+              ret = req_increase();
-+              if (ret)
-+                      break;
-+      }
-+      if (i == 0)
-+              return ret;
-+
-+      tap_blkif_interface_init();
-+
-+      alloc_pending_reqs = 0;
-+
-+      tap_blkif_xenbus_init();
-+
-+      /* Dynamically allocate a major for this device */
-+      ret = register_chrdev(0, "blktap", &blktap_fops);
-+      blktap_dir = devfs_mk_dir(NULL, "xen", 0, NULL);
-+
-+      if ( (ret < 0)||(blktap_dir < 0) ) {
-+              WPRINTK("Couldn't register /dev/xen/blktap\n");
-+              return -ENOMEM;
-+      }       
-+      
-+      blktap_major = ret;
-+
-+      /* tapfds[0] is always NULL */
-+      blktap_next_minor++;
-+
-+      ret = devfs_mk_cdev(MKDEV(blktap_major, i),
-+                          S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", i);
-+
-+      if(ret != 0)
-+              return -ENOMEM;
-+
-+      DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i);
-+
-+      /* Make sure the xen class exists */
-+      if (!setup_xen_class()) {
-+              /*
-+               * This will allow udev to create the blktap ctrl device.
-+               * We only want to create blktap0 first.  We don't want
-+               * to flood the sysfs system with needless blktap devices.
-+               * We only create the device when a request of a new device is
-+               * made.
-+               */
-+              class_device_create(xen_class, NULL,
-+                                  MKDEV(blktap_major, 0), NULL,
-+                                  "blktap0");
-+      } else {
-+              /* this is bad, but not fatal */
-+              WPRINTK("blktap: sysfs xen_class not created\n");
-+      }
-+
-+      DPRINTK("Blktap device successfully created\n");
-+
-+      return 0;
-+}
-+
-+module_init(blkif_init);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blktap/common.h linux-2.6.16.33/drivers/xen/blktap/common.h
---- linux-2.6.16.33-noxen/drivers/xen/blktap/common.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blktap/common.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,121 @@
-+/* 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __BLKIF__BACKEND__COMMON_H__
-+#define __BLKIF__BACKEND__COMMON_H__
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/blkdev.h>
-+#include <linux/vmalloc.h>
-+#include <asm/io.h>
-+#include <asm/setup.h>
-+#include <asm/pgalloc.h>
-+#include <xen/evtchn.h>
-+#include <asm/hypervisor.h>
-+#include <xen/interface/io/blkif.h>
-+#include <xen/interface/io/ring.h>
-+#include <xen/gnttab.h>
-+#include <xen/driver_util.h>
-+
-+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
-+                                    __FILE__ , __LINE__ , ## _a )
-+
-+#define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
-+
-+struct backend_info;
-+
-+typedef struct blkif_st {
-+      /* Unique identifier for this interface. */
-+      domid_t           domid;
-+      unsigned int      handle;
-+      /* Physical parameters of the comms window. */
-+      unsigned int      evtchn;
-+      unsigned int      irq;
-+      /* Comms information. */
-+      blkif_back_ring_t blk_ring;
-+      struct vm_struct *blk_ring_area;
-+      /* Back pointer to the backend_info. */
-+      struct backend_info *be;
-+      /* Private fields. */
-+      spinlock_t       blk_ring_lock;
-+      atomic_t         refcnt;
-+
-+      wait_queue_head_t   wq;
-+      struct task_struct  *xenblkd;
-+      unsigned int        waiting_reqs;
-+      request_queue_t     *plug;
-+
-+      /* statistics */
-+      unsigned long       st_print;
-+      int                 st_rd_req;
-+      int                 st_wr_req;
-+      int                 st_oo_req;
-+
-+      wait_queue_head_t waiting_to_free;
-+
-+      grant_handle_t shmem_handle;
-+      grant_ref_t    shmem_ref;
-+      
-+      int             dev_num;
-+      uint64_t        sectors;
-+} blkif_t;
-+
-+blkif_t *tap_alloc_blkif(domid_t domid);
-+void tap_blkif_free(blkif_t *blkif);
-+int tap_blkif_map(blkif_t *blkif, unsigned long shared_page, 
-+                unsigned int evtchn);
-+void tap_blkif_unmap(blkif_t *blkif);
-+
-+#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
-+#define blkif_put(_b)                                 \
-+      do {                                            \
-+              if (atomic_dec_and_test(&(_b)->refcnt)) \
-+                      wake_up(&(_b)->waiting_to_free);\
-+      } while (0)
-+
-+
-+struct phys_req {
-+      unsigned short       dev;
-+      unsigned short       nr_sects;
-+      struct block_device *bdev;
-+      blkif_sector_t       sector_number;
-+};
-+
-+void tap_blkif_interface_init(void);
-+
-+void tap_blkif_xenbus_init(void);
-+
-+irqreturn_t tap_blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
-+int tap_blkif_schedule(void *arg);
-+
-+int dom_to_devid(domid_t domid, int xenbus_id, blkif_t *blkif);
-+void signal_tapdisk(int idx);
-+
-+#endif /* __BLKIF__BACKEND__COMMON_H__ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blktap/interface.c linux-2.6.16.33/drivers/xen/blktap/interface.c
---- linux-2.6.16.33-noxen/drivers/xen/blktap/interface.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blktap/interface.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,164 @@
-+/******************************************************************************
-+ * drivers/xen/blktap/interface.c
-+ * 
-+ * Block-device interface management.
-+ * 
-+ * Copyright (c) 2004, Keir Fraser
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+
-+ */
-+
-+#include "common.h"
-+#include <xen/evtchn.h>
-+
-+static kmem_cache_t *blkif_cachep;
-+
-+blkif_t *tap_alloc_blkif(domid_t domid)
-+{
-+      blkif_t *blkif;
-+
-+      blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
-+      if (!blkif)
-+              return ERR_PTR(-ENOMEM);
-+
-+      memset(blkif, 0, sizeof(*blkif));
-+      blkif->domid = domid;
-+      spin_lock_init(&blkif->blk_ring_lock);
-+      atomic_set(&blkif->refcnt, 1);
-+      init_waitqueue_head(&blkif->wq);
-+      blkif->st_print = jiffies;
-+      init_waitqueue_head(&blkif->waiting_to_free);
-+
-+      return blkif;
-+}
-+
-+static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
-+{
-+      struct gnttab_map_grant_ref op;
-+      int ret;
-+
-+      gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
-+                        GNTMAP_host_map, shared_page, blkif->domid);
-+
-+      lock_vm_area(blkif->blk_ring_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-+      unlock_vm_area(blkif->blk_ring_area);
-+      BUG_ON(ret);
-+
-+      if (op.status) {
-+              DPRINTK(" Grant table operation failure !\n");
-+              return op.status;
-+      }
-+
-+      blkif->shmem_ref = shared_page;
-+      blkif->shmem_handle = op.handle;
-+
-+      return 0;
-+}
-+
-+static void unmap_frontend_page(blkif_t *blkif)
-+{
-+      struct gnttab_unmap_grant_ref op;
-+      int ret;
-+
-+      gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
-+                          GNTMAP_host_map, blkif->shmem_handle);
-+
-+      lock_vm_area(blkif->blk_ring_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-+      unlock_vm_area(blkif->blk_ring_area);
-+      BUG_ON(ret);
-+}
-+
-+int tap_blkif_map(blkif_t *blkif, unsigned long shared_page, 
-+                unsigned int evtchn)
-+{
-+      blkif_sring_t *sring;
-+      int err;
-+      struct evtchn_bind_interdomain bind_interdomain;
-+
-+      /* Already connected through? */
-+      if (blkif->irq)
-+              return 0;
-+
-+      if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
-+              return -ENOMEM;
-+
-+      err = map_frontend_page(blkif, shared_page);
-+      if (err) {
-+              free_vm_area(blkif->blk_ring_area);
-+              return err;
-+      }
-+
-+      bind_interdomain.remote_dom  = blkif->domid;
-+      bind_interdomain.remote_port = evtchn;
-+
-+      err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-+                                        &bind_interdomain);
-+      if (err) {
-+              unmap_frontend_page(blkif);
-+              free_vm_area(blkif->blk_ring_area);
-+              return err;
-+      }
-+
-+      blkif->evtchn = bind_interdomain.local_port;
-+
-+      sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
-+      BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
-+
-+      blkif->irq = bind_evtchn_to_irqhandler(
-+              blkif->evtchn, tap_blkif_be_int, 0, "blkif-backend", blkif);
-+
-+      return 0;
-+}
-+
-+void tap_blkif_unmap(blkif_t *blkif)
-+{
-+      if (blkif->irq) {
-+              unbind_from_irqhandler(blkif->irq, blkif);
-+              blkif->irq = 0;
-+      }
-+      if (blkif->blk_ring.sring) {
-+              unmap_frontend_page(blkif);
-+              free_vm_area(blkif->blk_ring_area);
-+              blkif->blk_ring.sring = NULL;
-+      }
-+}
-+
-+void tap_blkif_free(blkif_t *blkif)
-+{
-+      atomic_dec(&blkif->refcnt);
-+      wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
-+
-+      tap_blkif_unmap(blkif);
-+      kmem_cache_free(blkif_cachep, blkif);
-+}
-+
-+void __init tap_blkif_interface_init(void)
-+{
-+      blkif_cachep = kmem_cache_create("blktapif_cache", sizeof(blkif_t), 
-+                                       0, 0, NULL, NULL);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/blktap/xenbus.c linux-2.6.16.33/drivers/xen/blktap/xenbus.c
---- linux-2.6.16.33-noxen/drivers/xen/blktap/xenbus.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/blktap/xenbus.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,366 @@
-+/* drivers/xen/blktap/xenbus.c
-+ *
-+ * Xenbus code for blktap
-+ *
-+ * Copyright (c) 2004-2005, Andrew Warfield and Julian Chesterfield
-+ *
-+ * Based on the blkback xenbus code:
-+ *
-+ * Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
-+ * Copyright (C) 2005 XenSource Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <stdarg.h>
-+#include <linux/module.h>
-+#include <linux/kthread.h>
-+#include <xen/xenbus.h>
-+#include "common.h"
-+
-+
-+struct backend_info
-+{
-+      struct xenbus_device *dev;
-+      blkif_t *blkif;
-+      struct xenbus_watch backend_watch;
-+      int xenbus_id;
-+};
-+
-+
-+static void connect(struct backend_info *);
-+static int connect_ring(struct backend_info *);
-+static int blktap_remove(struct xenbus_device *dev);
-+static int blktap_probe(struct xenbus_device *dev,
-+                       const struct xenbus_device_id *id);
-+static void tap_backend_changed(struct xenbus_watch *, const char **,
-+                          unsigned int);
-+static void tap_frontend_changed(struct xenbus_device *dev,
-+                           enum xenbus_state frontend_state);
-+
-+static int strsep_len(const char *str, char c, unsigned int len)
-+{
-+        unsigned int i;
-+
-+        for (i = 0; str[i]; i++)
-+                if (str[i] == c) {
-+                        if (len == 0)
-+                                return i;
-+                        len--;
-+                }
-+        return (len == 0) ? i : -ERANGE;
-+}
-+
-+static long get_id(const char *str)
-+{
-+        int len,end;
-+        const char *ptr;
-+        char *tptr, num[10];
-+      
-+        len = strsep_len(str, '/', 2);
-+        end = strlen(str);
-+        if ( (len < 0) || (end < 0) ) return -1;
-+      
-+        ptr = str + len + 1;
-+        strncpy(num,ptr,end - len);
-+        tptr = num + (end - (len + 1));
-+        *tptr = '\0';
-+      DPRINTK("Get_id called for %s (%s)\n",str,num);
-+      
-+        return simple_strtol(num, NULL, 10);
-+}                             
-+
-+static void tap_update_blkif_status(blkif_t *blkif)
-+{ 
-+      int err;
-+
-+      /* Not ready to connect? */
-+      if(!blkif->irq || !blkif->sectors) {
-+              return;
-+      } 
-+
-+      /* Already connected? */
-+      if (blkif->be->dev->state == XenbusStateConnected)
-+              return;
-+
-+      /* Attempt to connect: exit if we fail to. */
-+      connect(blkif->be);
-+      if (blkif->be->dev->state != XenbusStateConnected)
-+              return;
-+
-+      blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif,
-+                                   "xvd %d",
-+                                   blkif->domid);
-+
-+      if (IS_ERR(blkif->xenblkd)) {
-+              err = PTR_ERR(blkif->xenblkd);
-+              blkif->xenblkd = NULL;
-+              xenbus_dev_fatal(blkif->be->dev, err, "start xenblkd");
-+              WPRINTK("Error starting thread\n");
-+      }
-+}
-+
-+static int blktap_remove(struct xenbus_device *dev)
-+{
-+      struct backend_info *be = dev->dev.driver_data;
-+
-+      if (be->backend_watch.node) {
-+              unregister_xenbus_watch(&be->backend_watch);
-+              kfree(be->backend_watch.node);
-+              be->backend_watch.node = NULL;
-+      }
-+      if (be->blkif) {
-+              if (be->blkif->xenblkd)
-+                      kthread_stop(be->blkif->xenblkd);
-+              signal_tapdisk(be->blkif->dev_num);
-+              tap_blkif_free(be->blkif);
-+              be->blkif = NULL;
-+      }
-+      kfree(be);
-+      dev->dev.driver_data = NULL;
-+      return 0;
-+}
-+
-+/**
-+ * Entry point to this code when a new device is created.  Allocate
-+ * the basic structures, and watch the store waiting for the
-+ * user-space program to tell us the physical device info.  Switch to
-+ * InitWait.
-+ */
-+static int blktap_probe(struct xenbus_device *dev,
-+                       const struct xenbus_device_id *id)
-+{
-+      int err;
-+      struct backend_info *be = kzalloc(sizeof(struct backend_info),
-+                                        GFP_KERNEL);
-+      if (!be) {
-+              xenbus_dev_fatal(dev, -ENOMEM,
-+                               "allocating backend structure");
-+              return -ENOMEM;
-+      }
-+
-+      be->dev = dev;
-+      dev->dev.driver_data = be;
-+      be->xenbus_id = get_id(dev->nodename);
-+
-+      be->blkif = tap_alloc_blkif(dev->otherend_id);
-+      if (IS_ERR(be->blkif)) {
-+              err = PTR_ERR(be->blkif);
-+              be->blkif = NULL;
-+              xenbus_dev_fatal(dev, err, "creating block interface");
-+              goto fail;
-+      }
-+
-+      /* setup back pointer */
-+      be->blkif->be = be;
-+      be->blkif->sectors = 0;
-+
-+      /* set a watch on disk info, waiting for userspace to update details*/
-+      err = xenbus_watch_path2(dev, dev->nodename, "info",
-+                               &be->backend_watch, tap_backend_changed);
-+      if (err)
-+              goto fail;
-+      
-+      err = xenbus_switch_state(dev, XenbusStateInitWait);
-+      if (err)
-+              goto fail;
-+      return 0;
-+
-+fail:
-+      DPRINTK("blktap probe failed\n");
-+      blktap_remove(dev);
-+      return err;
-+}
-+
-+
-+/**
-+ * Callback received when the user space code has placed the device
-+ * information in xenstore. 
-+ */
-+static void tap_backend_changed(struct xenbus_watch *watch,
-+                          const char **vec, unsigned int len)
-+{
-+      int err;
-+      unsigned long info;
-+      struct backend_info *be
-+              = container_of(watch, struct backend_info, backend_watch);
-+      struct xenbus_device *dev = be->dev;
-+      
-+      /** 
-+       * Check to see whether userspace code has opened the image 
-+       * and written sector
-+       * and disk info to xenstore
-+       */
-+      err = xenbus_gather(XBT_NIL, dev->nodename, "info", "%lu", &info, 
-+                          NULL);      
-+      if (err) {
-+              xenbus_dev_error(dev, err, "getting info");
-+              return;
-+      }
-+
-+      DPRINTK("Userspace update on disk info, %lu\n",info);
-+
-+      err = xenbus_gather(XBT_NIL, dev->nodename, "sectors", "%llu", 
-+                          &be->blkif->sectors, NULL);
-+
-+      /* Associate tap dev with domid*/
-+      be->blkif->dev_num = dom_to_devid(be->blkif->domid, be->xenbus_id, 
-+                                        be->blkif);
-+      DPRINTK("Thread started for domid [%d], connecting disk\n", 
-+              be->blkif->dev_num);
-+
-+      tap_update_blkif_status(be->blkif);
-+}
-+
-+/**
-+ * Callback received when the frontend's state changes.
-+ */
-+static void tap_frontend_changed(struct xenbus_device *dev,
-+                           enum xenbus_state frontend_state)
-+{
-+      struct backend_info *be = dev->dev.driver_data;
-+      int err;
-+
-+      DPRINTK("\n");
-+
-+      switch (frontend_state) {
-+      case XenbusStateInitialising:
-+              if (dev->state == XenbusStateClosed) {
-+                      printk("%s: %s: prepare for reconnect\n",
-+                             __FUNCTION__, dev->nodename);
-+                      xenbus_switch_state(dev, XenbusStateInitWait);
-+              }
-+              break;
-+
-+      case XenbusStateInitialised:
-+      case XenbusStateConnected:
-+              /* Ensure we connect even when two watches fire in 
-+                 close successsion and we miss the intermediate value 
-+                 of frontend_state. */
-+              if (dev->state == XenbusStateConnected)
-+                      break;
-+
-+              err = connect_ring(be);
-+              if (err)
-+                      break;
-+              tap_update_blkif_status(be->blkif);
-+              break;
-+
-+      case XenbusStateClosing:
-+              if (be->blkif->xenblkd) {
-+                      kthread_stop(be->blkif->xenblkd);
-+                      be->blkif->xenblkd = NULL;
-+              }
-+              xenbus_switch_state(dev, XenbusStateClosing);
-+              break;
-+
-+      case XenbusStateClosed:
-+              xenbus_switch_state(dev, XenbusStateClosed);
-+              if (xenbus_dev_is_online(dev))
-+                      break;
-+              /* fall through if not online */
-+      case XenbusStateUnknown:
-+              device_unregister(&dev->dev);
-+              break;
-+
-+      default:
-+              xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
-+                               frontend_state);
-+              break;
-+      }
-+}
-+
-+
-+/**
-+ * Switch to Connected state.
-+ */
-+static void connect(struct backend_info *be)
-+{
-+      int err;
-+
-+      struct xenbus_device *dev = be->dev;
-+
-+      err = xenbus_switch_state(dev, XenbusStateConnected);
-+      if (err)
-+              xenbus_dev_fatal(dev, err, "switching to Connected state",
-+                               dev->nodename);
-+
-+      return;
-+}
-+
-+
-+static int connect_ring(struct backend_info *be)
-+{
-+      struct xenbus_device *dev = be->dev;
-+      unsigned long ring_ref;
-+      unsigned int evtchn;
-+      int err;
-+
-+      DPRINTK("%s\n", dev->otherend);
-+
-+      err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", 
-+                          &ring_ref, "event-channel", "%u", &evtchn, NULL);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err,
-+                               "reading %s/ring-ref and event-channel",
-+                               dev->otherend);
-+              return err;
-+      }
-+
-+      /* Map the shared frame, irq etc. */
-+      err = tap_blkif_map(be->blkif, ring_ref, evtchn);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "mapping ring-ref %lu port %u",
-+                               ring_ref, evtchn);
-+              return err;
-+      } 
-+
-+      return 0;
-+}
-+
-+
-+/* ** Driver Registration ** */
-+
-+
-+static struct xenbus_device_id blktap_ids[] = {
-+      { "tap" },
-+      { "" }
-+};
-+
-+
-+static struct xenbus_driver blktap = {
-+      .name = "tap",
-+      .owner = THIS_MODULE,
-+      .ids = blktap_ids,
-+      .probe = blktap_probe,
-+      .remove = blktap_remove,
-+      .otherend_changed = tap_frontend_changed
-+};
-+
-+
-+void tap_blkif_xenbus_init(void)
-+{
-+      xenbus_register_backend(&blktap);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/char/Makefile linux-2.6.16.33/drivers/xen/char/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/char/Makefile    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/char/Makefile  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2 @@
-+
-+obj-y := mem.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/char/mem.c linux-2.6.16.33/drivers/xen/char/mem.c
---- linux-2.6.16.33-noxen/drivers/xen/char/mem.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/char/mem.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,205 @@
-+/*
-+ *  Originally from linux/drivers/char/mem.c
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ *
-+ *  Added devfs support. 
-+ *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
-+ *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/mm.h>
-+#include <linux/miscdevice.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/mman.h>
-+#include <linux/random.h>
-+#include <linux/init.h>
-+#include <linux/raw.h>
-+#include <linux/tty.h>
-+#include <linux/capability.h>
-+#include <linux/smp_lock.h>
-+#include <linux/devfs_fs_kernel.h>
-+#include <linux/ptrace.h>
-+#include <linux/device.h>
-+#include <asm/pgalloc.h>
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <asm/hypervisor.h>
-+
-+#ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
-+static inline int valid_phys_addr_range(unsigned long addr, size_t *count)
-+{
-+      return 1;
-+}
-+#endif
-+
-+/*
-+ * This funcion reads the *physical* memory. The f_pos points directly to the 
-+ * memory location. 
-+ */
-+static ssize_t read_mem(struct file * file, char __user * buf,
-+                      size_t count, loff_t *ppos)
-+{
-+      unsigned long p = *ppos, ignored;
-+      ssize_t read = 0, sz;
-+      void __iomem *v;
-+
-+      if (!valid_phys_addr_range(p, &count))
-+              return -EFAULT;
-+
-+      while (count > 0) {
-+              /*
-+               * Handle first page in case it's not aligned
-+               */
-+              if (-p & (PAGE_SIZE - 1))
-+                      sz = -p & (PAGE_SIZE - 1);
-+              else
-+                      sz = PAGE_SIZE;
-+
-+              sz = min_t(unsigned long, sz, count);
-+
-+              v = xlate_dev_mem_ptr(p, sz);
-+              if (IS_ERR(v) || v == NULL) {
-+                      /*
-+                       * Some programs (e.g., dmidecode) groove off into
-+                       * weird RAM areas where no tables can possibly exist
-+                       * (because Xen will have stomped on them!). These
-+                       * programs get rather upset if we let them know that
-+                       * Xen failed their access, so we fake out a read of
-+                       * all zeroes.
-+                       */
-+                      if (clear_user(buf, count))
-+                              return -EFAULT;
-+                      read += count;
-+                      break;
-+              }
-+
-+              ignored = copy_to_user(buf, v, sz);
-+              xlate_dev_mem_ptr_unmap(v);
-+              if (ignored)
-+                      return -EFAULT;
-+              buf += sz;
-+              p += sz;
-+              count -= sz;
-+              read += sz;
-+      }
-+
-+      *ppos += read;
-+      return read;
-+}
-+
-+static ssize_t write_mem(struct file * file, const char __user * buf, 
-+                       size_t count, loff_t *ppos)
-+{
-+      unsigned long p = *ppos, ignored;
-+      ssize_t written = 0, sz;
-+      void __iomem *v;
-+
-+      if (!valid_phys_addr_range(p, &count))
-+              return -EFAULT;
-+
-+      while (count > 0) {
-+              /*
-+               * Handle first page in case it's not aligned
-+               */
-+              if (-p & (PAGE_SIZE - 1))
-+                      sz = -p & (PAGE_SIZE - 1);
-+              else
-+                      sz = PAGE_SIZE;
-+
-+              sz = min_t(unsigned long, sz, count);
-+
-+              v = xlate_dev_mem_ptr(p, sz);
-+              if (v == NULL)
-+                      break;
-+              if (IS_ERR(v)) {
-+                      if (written == 0)
-+                              return PTR_ERR(v);
-+                      break;
-+              }
-+
-+              ignored = copy_from_user(v, buf, sz);
-+              xlate_dev_mem_ptr_unmap(v);
-+              if (ignored) {
-+                      written += sz - ignored;
-+                      if (written)
-+                              break;
-+                      return -EFAULT;
-+              }
-+              buf += sz;
-+              p += sz;
-+              count -= sz;
-+              written += sz;
-+      }
-+
-+      *ppos += written;
-+      return written;
-+}
-+
-+#ifndef ARCH_HAS_DEV_MEM_MMAP_MEM
-+static inline int uncached_access(struct file *file)
-+{
-+      if (file->f_flags & O_SYNC)
-+              return 1;
-+      /* Xen sets correct MTRR type on non-RAM for us. */
-+      return 0;
-+}
-+
-+static int xen_mmap_mem(struct file * file, struct vm_area_struct * vma)
-+{
-+      size_t size = vma->vm_end - vma->vm_start;
-+
-+      if (uncached_access(file))
-+              vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+
-+      /* We want to return the real error code, not EAGAIN. */
-+      return direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-+                                    size, vma->vm_page_prot, DOMID_IO);
-+}
-+#endif
-+
-+/*
-+ * The memory devices use the full 32/64 bits of the offset, and so we cannot
-+ * check against negative addresses: they are ok. The return value is weird,
-+ * though, in that case (0).
-+ *
-+ * also note that seeking relative to the "end of file" isn't supported:
-+ * it has no meaning, so it returns -EINVAL.
-+ */
-+static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
-+{
-+      loff_t ret;
-+
-+      mutex_lock(&file->f_dentry->d_inode->i_mutex);
-+      switch (orig) {
-+              case 0:
-+                      file->f_pos = offset;
-+                      ret = file->f_pos;
-+                      force_successful_syscall_return();
-+                      break;
-+              case 1:
-+                      file->f_pos += offset;
-+                      ret = file->f_pos;
-+                      force_successful_syscall_return();
-+                      break;
-+              default:
-+                      ret = -EINVAL;
-+      }
-+      mutex_unlock(&file->f_dentry->d_inode->i_mutex);
-+      return ret;
-+}
-+
-+static int open_mem(struct inode * inode, struct file * filp)
-+{
-+      return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
-+}
-+
-+struct file_operations mem_fops = {
-+      .llseek         = memory_lseek,
-+      .read           = read_mem,
-+      .write          = write_mem,
-+      .mmap           = xen_mmap_mem,
-+      .open           = open_mem,
-+};
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/console/Makefile linux-2.6.16.33/drivers/xen/console/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/console/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/console/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2 @@
-+
-+obj-y := console.o xencons_ring.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/console/console.c linux-2.6.16.33/drivers/xen/console/console.c
---- linux-2.6.16.33-noxen/drivers/xen/console/console.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/console/console.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,718 @@
-+/******************************************************************************
-+ * console.c
-+ * 
-+ * Virtual console driver.
-+ * 
-+ * Copyright (c) 2002-2004, K A Fraser.
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/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 <linux/bootmem.h>
-+#include <linux/sysrq.h>
-+#include <linux/screen_info.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/event_channel.h>
-+#include <asm/hypervisor.h>
-+#include <xen/evtchn.h>
-+#include <xen/xenbus.h>
-+#include <xen/xencons.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]+'.
-+ *  'xencons=xvc'  [XC_XVC]:     Console attached to '/dev/xvc0'.
-+ *  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_TTY, XC_SERIAL, XC_XVC
-+} xc_mode;
-+static int xc_num = -1;
-+
-+/* /dev/xvc0 device number allocated by lanana.org. */
-+#define XEN_XVC_MAJOR 204
-+#define XEN_XVC_MINOR 191
-+
-+#ifdef CONFIG_MAGIC_SYSRQ
-+static unsigned long sysrq_requested;
-+extern int sysrq_enabled;
-+#endif
-+
-+void xencons_early_setup(void)
-+{
-+      extern int console_use_vt;
-+
-+      if (is_initial_xendomain()) {
-+              xc_mode = XC_SERIAL;
-+      } else {
-+              xc_mode = XC_TTY;
-+              console_use_vt = 0;
-+      }
-+}
-+
-+static int __init xencons_setup(char *str)
-+{
-+      char *q;
-+      int n;
-+      extern int console_use_vt;
-+
-+      console_use_vt = 1;
-+      if (!strncmp(str, "ttyS", 4)) {
-+              xc_mode = XC_SERIAL;
-+              str += 4;
-+      } else if (!strncmp(str, "tty", 3)) {
-+              xc_mode = XC_TTY;
-+              str += 3;
-+              console_use_vt = 0;
-+      } else if (!strncmp(str, "xvc", 3)) {
-+              xc_mode = XC_XVC;
-+              str += 3;
-+      } else if (!strncmp(str, "off", 3)) {
-+              xc_mode = XC_OFF;
-+              str += 3;
-+      }
-+
-+      n = simple_strtol(str, &q, 10);
-+      if (q != str)
-+              xc_num = n;
-+
-+      return 1;
-+}
-+__setup("xencons=", xencons_setup);
-+
-+/* The kernel and user-land drivers share a common transmit buffer. */
-+static unsigned int wbuf_size = 4096;
-+#define WBUF_MASK(_i) ((_i)&(wbuf_size-1))
-+static char *wbuf;
-+static unsigned int wc, wp; /* write_cons, write_prod */
-+
-+static int __init xencons_bufsz_setup(char *str)
-+{
-+      unsigned int goal;
-+      goal = simple_strtoul(str, NULL, 0);
-+      if (goal) {
-+              goal = roundup_pow_of_two(goal);
-+              if (wbuf_size < goal)
-+                      wbuf_size = goal;
-+      }
-+      return 1;
-+}
-+__setup("xencons_bufsz=", xencons_bufsz_setup);
-+
-+/* This lock protects accesses to the common transmit buffer. */
-+static DEFINE_SPINLOCK(xencons_lock);
-+
-+/* Common transmit-kick routine. */
-+static void __xencons_tx_flush(void);
-+
-+static struct tty_driver *xencons_driver;
-+
-+/******************** Kernel console driver ********************************/
-+
-+static void kcons_write(struct console *c, const char *s, unsigned int count)
-+{
-+      int           i = 0;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&xencons_lock, flags);
-+
-+      while (i < count) {
-+              for (; 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)
-+{
-+
-+      while (count > 0) {
-+              int rc;
-+              rc = HYPERVISOR_console_io( CONSOLEIO_write, count, (char *)s);
-+              if (rc <= 0)
-+                      break;
-+              count -= rc;
-+              s += rc;
-+      }
-+}
-+
-+static struct tty_driver *kcons_device(struct console *c, int *index)
-+{
-+      *index = 0;
-+      return xencons_driver;
-+}
-+
-+static struct console kcons_info = {
-+      .device = kcons_device,
-+      .flags  = CON_PRINTBUFFER | CON_ENABLED,
-+      .index  = -1,
-+};
-+
-+static int __init xen_console_init(void)
-+{
-+      if (!is_running_on_xen())
-+              goto out;
-+
-+      if (is_initial_xendomain()) {
-+              kcons_info.write = kcons_write_dom0;
-+      } else {
-+              if (!xen_start_info->console.domU.evtchn)
-+                      goto out;
-+              kcons_info.write = kcons_write;
-+      }
-+
-+      switch (xc_mode) {
-+      case XC_XVC:
-+              strcpy(kcons_info.name, "xvc");
-+              if (xc_num == -1)
-+                      xc_num = 0;
-+              break;
-+
-+      case XC_SERIAL:
-+              strcpy(kcons_info.name, "ttyS");
-+              if (xc_num == -1)
-+                      xc_num = 0;
-+              break;
-+
-+      case XC_TTY:
-+              strcpy(kcons_info.name, "tty");
-+              if (xc_num == -1)
-+                      xc_num = 1;
-+              break;
-+
-+      default:
-+              goto out;
-+      }
-+
-+      wbuf = alloc_bootmem(wbuf_size);
-+
-+      register_console(&kcons_info);
-+
-+ out:
-+      return 0;
-+}
-+console_initcall(xen_console_init);
-+
-+/*** 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)
-+{
-+      int sz;
-+
-+      /* Emergency console is synchronous, so there's nothing to flush. */
-+      if (!is_running_on_xen() ||
-+          is_initial_xendomain() ||
-+          !xen_start_info->console.domU.evtchn)
-+              return;
-+
-+      /* Spin until console data is flushed through to the daemon. */
-+      while (wc != wp) {
-+              int sent = 0;
-+              if ((sz = wp - wc) == 0)
-+                      continue;
-+              sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
-+              if (sent > 0)
-+                      wc += sent;
-+      }
-+}
-+
-+
-+void dom0_init_screen_info(const struct dom0_vga_console_info *info)
-+{
-+      switch (info->video_type) {
-+      case XEN_VGATYPE_TEXT_MODE_3:
-+              screen_info.orig_video_mode = 3;
-+              screen_info.orig_video_ega_bx = 3;
-+              screen_info.orig_video_isVGA = 1;
-+              screen_info.orig_video_lines = info->u.text_mode_3.rows;
-+              screen_info.orig_video_cols = info->u.text_mode_3.columns;
-+              screen_info.orig_x = info->u.text_mode_3.cursor_x;
-+              screen_info.orig_y = info->u.text_mode_3.cursor_y;
-+              screen_info.orig_video_points =
-+                      info->u.text_mode_3.font_height;
-+              break;
-+      case XEN_VGATYPE_VESA_LFB:
-+              screen_info.orig_video_isVGA = VIDEO_TYPE_VLFB;
-+              screen_info.lfb_width = info->u.vesa_lfb.width;
-+              screen_info.lfb_height = info->u.vesa_lfb.height;
-+              screen_info.lfb_depth = info->u.vesa_lfb.bits_per_pixel;
-+              screen_info.lfb_base = info->u.vesa_lfb.lfb_base;
-+              screen_info.lfb_size = info->u.vesa_lfb.lfb_size;
-+              screen_info.lfb_linelength = info->u.vesa_lfb.bytes_per_line;
-+              screen_info.red_size = info->u.vesa_lfb.red_size;
-+              screen_info.red_pos = info->u.vesa_lfb.red_pos;
-+              screen_info.green_size = info->u.vesa_lfb.green_size;
-+              screen_info.green_pos = info->u.vesa_lfb.green_pos;
-+              screen_info.blue_size = info->u.vesa_lfb.blue_size;
-+              screen_info.blue_pos = info->u.vesa_lfb.blue_pos;
-+              screen_info.rsvd_size = info->u.vesa_lfb.rsvd_size;
-+              screen_info.rsvd_pos = info->u.vesa_lfb.rsvd_pos;
-+              break;
-+      }
-+}
-+
-+
-+/******************** User-space console driver (/dev/console) ************/
-+
-+#define DRV(_d)         (_d)
-+#define DUMMY_TTY(_tty) ((xc_mode == XC_TTY) &&               \
-+                       ((_tty)->index != (xc_num - 1)))
-+
-+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;
-+
-+void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
-+{
-+      int           i;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&xencons_lock, flags);
-+      if (xencons_tty == NULL)
-+              goto out;
-+
-+      for (i = 0; i < len; i++) {
-+#ifdef CONFIG_MAGIC_SYSRQ
-+              if (sysrq_enabled) {
-+                      if (buf[i] == '\x0f') { /* ^O */
-+                              sysrq_requested = jiffies;
-+                              continue; /* don't print the sysrq key */
-+                      } else if (sysrq_requested) {
-+                              unsigned long sysrq_timeout =
-+                                      sysrq_requested + HZ*2;
-+                              sysrq_requested = 0;
-+                              if (time_before(jiffies, sysrq_timeout)) {
-+                                      spin_unlock_irqrestore(
-+                                              &xencons_lock, flags);
-+                                      handle_sysrq(
-+                                              buf[i], regs, xencons_tty);
-+                                      spin_lock_irqsave(
-+                                              &xencons_lock, flags);
-+                                      continue;
-+                              }
-+                      }
-+              }
-+#endif
-+              tty_insert_flip_char(xencons_tty, buf[i], 0);
-+      }
-+      tty_flip_buffer_push(xencons_tty);
-+
-+ out:
-+      spin_unlock_irqrestore(&xencons_lock, flags);
-+}
-+
-+static void __xencons_tx_flush(void)
-+{
-+      int sent, sz, work_done = 0;
-+
-+      if (x_char) {
-+              if (is_initial_xendomain())
-+                      kcons_write_dom0(NULL, &x_char, 1);
-+              else
-+                      while (x_char)
-+                              if (xencons_ring_send(&x_char, 1) == 1)
-+                                      break;
-+              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);
-+              if (is_initial_xendomain()) {
-+                      kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz);
-+                      wc += sz;
-+              } else {
-+                      sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
-+                      if (sent == 0)
-+                              break;
-+                      wc += sent;
-+              }
-+              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);
-+      }
-+}
-+
-+void xencons_tx(void)
-+{
-+      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         l;
-+
-+      while ((l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0)
-+              xencons_rx(rbuf, l, regs);
-+
-+      xencons_tx();
-+
-+      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 (DUMMY_TTY(tty))
-+              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 (DUMMY_TTY(tty))
-+              return;
-+
-+      if (I_IXOFF(tty))
-+              xencons_send_xchar(tty, STOP_CHAR(tty));
-+}
-+
-+static void xencons_unthrottle(struct tty_struct *tty)
-+{
-+      if (DUMMY_TTY(tty))
-+              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 (DUMMY_TTY(tty))
-+              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;
-+}
-+
-+static int xencons_write(
-+      struct tty_struct *tty,
-+      const unsigned char *buf,
-+      int count)
-+{
-+      int i;
-+      unsigned long flags;
-+
-+      if (DUMMY_TTY(tty))
-+              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;
-+}
-+
-+static void xencons_put_char(struct tty_struct *tty, u_char ch)
-+{
-+      unsigned long flags;
-+
-+      if (DUMMY_TTY(tty))
-+              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 (DUMMY_TTY(tty))
-+              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 (DUMMY_TTY(tty))
-+              return;
-+
-+      while (DRV(tty->driver)->chars_in_buffer(tty)) {
-+              set_current_state(TASK_INTERRUPTIBLE);
-+              schedule_timeout(1);
-+              if (signal_pending(current))
-+                      break;
-+              if (timeout && 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 (DUMMY_TTY(tty))
-+              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 (DUMMY_TTY(tty))
-+              return;
-+
-+      down(&tty_sem);
-+
-+      if (tty->count != 1) {
-+              up(&tty_sem);
-+              return;
-+      }
-+
-+      /* Prevent other threads from re-opening this tty. */
-+      set_bit(TTY_CLOSING, &tty->flags);
-+      up(&tty_sem);
-+
-+      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);
-+}
-+
-+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,
-+};
-+
-+static int __init xencons_init(void)
-+{
-+      int rc;
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      if (xc_mode == XC_OFF)
-+              return 0;
-+
-+      if (!is_initial_xendomain()) {
-+              rc = xencons_ring_init();
-+              if (rc)
-+                      return rc;
-+      }
-+
-+      xencons_driver = alloc_tty_driver((xc_mode == XC_TTY) ?
-+                                        MAX_NR_CONSOLES : 1);
-+      if (xencons_driver == NULL)
-+              return -ENOMEM;
-+
-+      DRV(xencons_driver)->name            = "xencons";
-+      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;
-+      DRV(xencons_driver)->termios         = xencons_termios;
-+      DRV(xencons_driver)->termios_locked  = xencons_termios_locked;
-+
-+      switch (xc_mode) {
-+      case XC_XVC:
-+              DRV(xencons_driver)->name        = "xvc";
-+              DRV(xencons_driver)->major       = XEN_XVC_MAJOR;
-+              DRV(xencons_driver)->minor_start = XEN_XVC_MINOR;
-+              DRV(xencons_driver)->name_base   = xc_num;
-+              break;
-+      case XC_SERIAL:
-+              DRV(xencons_driver)->name        = "ttyS";
-+              DRV(xencons_driver)->minor_start = 64 + xc_num;
-+              DRV(xencons_driver)->name_base   = xc_num;
-+              break;
-+      default:
-+              DRV(xencons_driver)->name        = "tty";
-+              DRV(xencons_driver)->minor_start = 1;
-+              DRV(xencons_driver)->name_base   = 1;
-+              break;
-+      }
-+
-+      tty_set_operations(xencons_driver, &xencons_ops);
-+
-+      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);
-+              put_tty_driver(xencons_driver);
-+              xencons_driver = NULL;
-+              return rc;
-+      }
-+
-+      if (is_initial_xendomain()) {
-+              xencons_priv_irq = bind_virq_to_irqhandler(
-+                      VIRQ_CONSOLE,
-+                      0,
-+                      xencons_priv_interrupt,
-+                      0,
-+                      "console",
-+                      NULL);
-+              BUG_ON(xencons_priv_irq < 0);
-+      }
-+
-+      printk("Xen virtual console successfully installed as %s%d\n",
-+             DRV(xencons_driver)->name, xc_num);
-+
-+      return 0;
-+}
-+
-+module_init(xencons_init);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/console/xencons_ring.c linux-2.6.16.33/drivers/xen/console/xencons_ring.c
---- linux-2.6.16.33-noxen/drivers/xen/console/xencons_ring.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/console/xencons_ring.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,143 @@
-+/* 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/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 <asm/hypervisor.h>
-+#include <xen/evtchn.h>
-+#include <xen/xencons.h>
-+#include <linux/wait.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/err.h>
-+#include <xen/interface/io/console.h>
-+
-+static int xencons_irq;
-+
-+static inline struct xencons_interface *xencons_interface(void)
-+{
-+      return mfn_to_virt(xen_start_info->console.domU.mfn);
-+}
-+
-+static inline void notify_daemon(void)
-+{
-+      /* Use evtchn: this is called early, before irq is set up. */
-+      notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
-+}
-+
-+int xencons_ring_send(const char *data, unsigned len)
-+{
-+      int sent = 0;
-+      struct xencons_interface *intf = xencons_interface();
-+      XENCONS_RING_IDX cons, prod;
-+
-+      cons = intf->out_cons;
-+      prod = intf->out_prod;
-+      mb();
-+      BUG_ON((prod - cons) > sizeof(intf->out));
-+
-+      while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
-+              intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
-+
-+      wmb();
-+      intf->out_prod = prod;
-+
-+      notify_daemon();
-+
-+      return sent;
-+}
-+
-+static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs)
-+{
-+      struct xencons_interface *intf = xencons_interface();
-+      XENCONS_RING_IDX cons, prod;
-+
-+      cons = intf->in_cons;
-+      prod = intf->in_prod;
-+      mb();
-+      BUG_ON((prod - cons) > sizeof(intf->in));
-+
-+      while (cons != prod) {
-+              xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs);
-+              cons++;
-+      }
-+
-+      mb();
-+      intf->in_cons = cons;
-+
-+      notify_daemon();
-+
-+      xencons_tx();
-+
-+      return IRQ_HANDLED;
-+}
-+
-+int xencons_ring_init(void)
-+{
-+      int irq;
-+
-+      if (xencons_irq)
-+              unbind_from_irqhandler(xencons_irq, NULL);
-+      xencons_irq = 0;
-+
-+      if (!is_running_on_xen() ||
-+          is_initial_xendomain() ||
-+          !xen_start_info->console.domU.evtchn)
-+              return -ENODEV;
-+
-+      irq = bind_evtchn_to_irqhandler(
-+              xen_start_info->console.domU.evtchn,
-+              handle_input, 0, "xencons", NULL);
-+      if (irq < 0) {
-+              printk(KERN_ERR "XEN console request irq failed %i\n", irq);
-+              return irq;
-+      }
-+
-+      xencons_irq = irq;
-+
-+      /* In case we have in-flight data after save/restore... */
-+      notify_daemon();
-+
-+      return 0;
-+}
-+
-+void xencons_resume(void)
-+{
-+      (void)xencons_ring_init();
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/Makefile linux-2.6.16.33/drivers/xen/core/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/core/Makefile    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/Makefile  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,14 @@
-+#
-+# Makefile for the linux kernel.
-+#
-+
-+obj-y := evtchn.o gnttab.o features.o
-+
-+obj-$(CONFIG_PROC_FS)         += xen_proc.o
-+obj-$(CONFIG_SYSFS)           += hypervisor_sysfs.o
-+obj-$(CONFIG_HOTPLUG_CPU)     += cpu_hotplug.o
-+obj-$(CONFIG_XEN_SYSFS)               += xen_sysfs.o
-+obj-$(CONFIG_XEN_SKBUFF)      += skbuff.o
-+obj-$(CONFIG_XEN_REBOOT)      += reboot.o machine_reboot.o
-+obj-$(CONFIG_XEN_SMPBOOT)     += smpboot.o
-+obj-$(CONFIG_KEXEC)           += machine_kexec.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/cpu_hotplug.c linux-2.6.16.33/drivers/xen/core/cpu_hotplug.c
---- linux-2.6.16.33-noxen/drivers/xen/core/cpu_hotplug.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/cpu_hotplug.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,188 @@
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/notifier.h>
-+#include <linux/cpu.h>
-+#include <xen/cpu_hotplug.h>
-+#include <xen/xenbus.h>
-+
-+/*
-+ * Set of CPUs that remote admin software will allow us to bring online.
-+ * Notified to us via xenbus.
-+ */
-+static cpumask_t xenbus_allowed_cpumask;
-+
-+/* Set of CPUs that local admin will allow us to bring online. */
-+static cpumask_t local_allowed_cpumask = CPU_MASK_ALL;
-+
-+static int local_cpu_hotplug_request(void)
-+{
-+      /*
-+       * We assume a CPU hotplug request comes from local admin if it is made
-+       * via a userspace process (i.e., one with a real mm_struct).
-+       */
-+      return (current->mm != NULL);
-+}
-+
-+static void vcpu_hotplug(unsigned int cpu)
-+{
-+      int err;
-+      char dir[32], state[32];
-+
-+      if ((cpu >= NR_CPUS) || !cpu_possible(cpu))
-+              return;
-+
-+      sprintf(dir, "cpu/%d", cpu);
-+      err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
-+      if (err != 1) {
-+              printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
-+              return;
-+      }
-+
-+      if (strcmp(state, "online") == 0) {
-+              cpu_set(cpu, xenbus_allowed_cpumask);
-+              (void)cpu_up(cpu);
-+      } else if (strcmp(state, "offline") == 0) {
-+              cpu_clear(cpu, xenbus_allowed_cpumask);
-+              (void)cpu_down(cpu);
-+      } else {
-+              printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
-+                     state, cpu);
-+      }
-+}
-+
-+static void handle_vcpu_hotplug_event(
-+      struct xenbus_watch *watch, const char **vec, unsigned int len)
-+{
-+      int cpu;
-+      char *cpustr;
-+      const char *node = vec[XS_WATCH_PATH];
-+
-+      if ((cpustr = strstr(node, "cpu/")) != NULL) {
-+              sscanf(cpustr, "cpu/%d", &cpu);
-+              vcpu_hotplug(cpu);
-+      }
-+}
-+
-+static int smpboot_cpu_notify(struct notifier_block *notifier,
-+                            unsigned long action, void *hcpu)
-+{
-+      int cpu = (long)hcpu;
-+
-+      /*
-+       * We do this in a callback notifier rather than __cpu_disable()
-+       * because local_cpu_hotplug_request() does not work in the latter
-+       * as it's always executed from within a stopmachine kthread.
-+       */
-+      if ((action == CPU_DOWN_PREPARE) && local_cpu_hotplug_request())
-+              cpu_clear(cpu, local_allowed_cpumask);
-+
-+      return NOTIFY_OK;
-+}
-+
-+static int setup_cpu_watcher(struct notifier_block *notifier,
-+                            unsigned long event, void *data)
-+{
-+      int i;
-+
-+      static struct xenbus_watch cpu_watch = {
-+              .node = "cpu",
-+              .callback = handle_vcpu_hotplug_event,
-+              .flags = XBWF_new_thread };
-+      (void)register_xenbus_watch(&cpu_watch);
-+
-+      if (!is_initial_xendomain()) {
-+              for_each_cpu(i)
-+                      vcpu_hotplug(i);
-+              printk(KERN_INFO "Brought up %ld CPUs\n",
-+                     (long)num_online_cpus());
-+      }
-+
-+      return NOTIFY_DONE;
-+}
-+
-+static int __init setup_vcpu_hotplug_event(void)
-+{
-+      static struct notifier_block hotplug_cpu = {
-+              .notifier_call = smpboot_cpu_notify };
-+      static struct notifier_block xsn_cpu = {
-+              .notifier_call = setup_cpu_watcher };
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      register_cpu_notifier(&hotplug_cpu);
-+      register_xenstore_notifier(&xsn_cpu);
-+
-+      return 0;
-+}
-+
-+arch_initcall(setup_vcpu_hotplug_event);
-+
-+int smp_suspend(void)
-+{
-+      int i, err;
-+
-+      lock_cpu_hotplug();
-+
-+      /*
-+       * Take all other CPUs offline. We hold the hotplug mutex to
-+       * avoid other processes bringing up CPUs under our feet.
-+       */
-+      while (num_online_cpus() > 1) {
-+              unlock_cpu_hotplug();
-+              for_each_online_cpu(i) {
-+                      if (i == 0)
-+                              continue;
-+                      err = cpu_down(i);
-+                      if (err) {
-+                              printk(KERN_CRIT "Failed to take all CPUs "
-+                                     "down: %d.\n", err);
-+                              for_each_cpu(i)
-+                                      vcpu_hotplug(i);
-+                              return err;
-+                      }
-+              }
-+              lock_cpu_hotplug();
-+      }
-+
-+      return 0;
-+}
-+
-+void smp_resume(void)
-+{
-+      int cpu;
-+
-+      for_each_cpu(cpu)
-+              cpu_initialize_context(cpu);
-+
-+      unlock_cpu_hotplug();
-+
-+      for_each_cpu(cpu)
-+              vcpu_hotplug(cpu);
-+}
-+
-+int cpu_up_check(unsigned int cpu)
-+{
-+      int rc = 0;
-+
-+      if (local_cpu_hotplug_request()) {
-+              cpu_set(cpu, local_allowed_cpumask);
-+              if (!cpu_isset(cpu, xenbus_allowed_cpumask)) {
-+                      printk("%s: attempt to bring up CPU %u disallowed by "
-+                             "remote admin.\n", __FUNCTION__, cpu);
-+                      rc = -EBUSY;
-+              }
-+      } else if (!cpu_isset(cpu, local_allowed_cpumask) ||
-+                 !cpu_isset(cpu, xenbus_allowed_cpumask)) {
-+              rc = -EBUSY;
-+      }
-+
-+      return rc;
-+}
-+
-+void init_xenbus_allowed_cpumask(void)
-+{
-+      xenbus_allowed_cpumask = cpu_present_map;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/evtchn.c linux-2.6.16.33/drivers/xen/core/evtchn.c
---- linux-2.6.16.33-noxen/drivers/xen/core/evtchn.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/evtchn.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,872 @@
-+/******************************************************************************
-+ * evtchn.c
-+ * 
-+ * Communication via Xen event channels.
-+ * 
-+ * Copyright (c) 2002-2005, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/irq.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/version.h>
-+#include <asm/atomic.h>
-+#include <asm/system.h>
-+#include <asm/ptrace.h>
-+#include <asm/synch_bitops.h>
-+#include <xen/evtchn.h>
-+#include <xen/interface/event_channel.h>
-+#include <xen/interface/physdev.h>
-+#include <asm/hypervisor.h>
-+#include <linux/mc146818rtc.h> /* RTC_IRQ */
-+
-+/*
-+ * This lock protects updates to the following mapping and reference-count
-+ * arrays. The lock does not need to be acquired to read the mapping tables.
-+ */
-+static DEFINE_SPINLOCK(irq_mapping_update_lock);
-+
-+/* IRQ <-> event-channel mappings. */
-+static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
-+      [0 ...  NR_EVENT_CHANNELS-1] = -1 };
-+
-+/* Packed IRQ information: binding type, sub-type index, and event channel. */
-+static u32 irq_info[NR_IRQS];
-+
-+/* Binding types. */
-+enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
-+
-+/* Constructor for packed IRQ information. */
-+static inline u32 mk_irq_info(u32 type, u32 index, u32 evtchn)
-+{
-+      return ((type << 24) | (index << 16) | evtchn);
-+}
-+
-+/* Convenient shorthand for packed representation of an unbound IRQ. */
-+#define IRQ_UNBOUND   mk_irq_info(IRQT_UNBOUND, 0, 0)
-+
-+/*
-+ * Accessors for packed IRQ information.
-+ */
-+
-+static inline unsigned int evtchn_from_irq(int irq)
-+{
-+      return (u16)(irq_info[irq]);
-+}
-+
-+static inline unsigned int index_from_irq(int irq)
-+{
-+      return (u8)(irq_info[irq] >> 16);
-+}
-+
-+static inline unsigned int type_from_irq(int irq)
-+{
-+      return (u8)(irq_info[irq] >> 24);
-+}
-+
-+/* IRQ <-> VIRQ mapping. */
-+DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
-+
-+/* IRQ <-> IPI mapping. */
-+#ifndef NR_IPIS
-+#define NR_IPIS 1
-+#endif
-+DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]) = {[0 ... NR_IPIS-1] = -1};
-+
-+/* Reference counts for bindings to IRQs. */
-+static int irq_bindcount[NR_IRQS];
-+
-+/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
-+static unsigned long pirq_needs_eoi[NR_PIRQS/sizeof(unsigned long)];
-+
-+#ifdef CONFIG_SMP
-+
-+static u8 cpu_evtchn[NR_EVENT_CHANNELS];
-+static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG];
-+
-+static inline unsigned long active_evtchns(unsigned int cpu, shared_info_t *sh,
-+                                         unsigned int idx)
-+{
-+      return (sh->evtchn_pending[idx] &
-+              cpu_evtchn_mask[cpu][idx] &
-+              ~sh->evtchn_mask[idx]);
-+}
-+
-+static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
-+{
-+      int irq = evtchn_to_irq[chn];
-+
-+      BUG_ON(irq == -1);
-+      set_native_irq_info(irq, cpumask_of_cpu(cpu));
-+
-+      clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
-+      set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
-+      cpu_evtchn[chn] = cpu;
-+}
-+
-+static void init_evtchn_cpu_bindings(void)
-+{
-+      int i;
-+
-+      /* By default all event channels notify CPU#0. */
-+      for (i = 0; i < NR_IRQS; i++)
-+              set_native_irq_info(i, cpumask_of_cpu(0));
-+
-+      memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
-+      memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
-+}
-+
-+static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
-+{
-+      return cpu_evtchn[evtchn];
-+}
-+
-+#else
-+
-+static inline unsigned long active_evtchns(unsigned int cpu, shared_info_t *sh,
-+                                         unsigned int idx)
-+{
-+      return (sh->evtchn_pending[idx] & ~sh->evtchn_mask[idx]);
-+}
-+
-+static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
-+{
-+}
-+
-+static void init_evtchn_cpu_bindings(void)
-+{
-+}
-+
-+static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
-+{
-+      return 0;
-+}
-+
-+#endif
-+
-+/* Upcall to generic IRQ layer. */
-+#ifdef CONFIG_X86
-+extern fastcall unsigned int do_IRQ(struct pt_regs *regs);
-+void __init xen_init_IRQ(void);
-+void __init init_IRQ(void)
-+{
-+      irq_ctx_init(0);
-+      xen_init_IRQ();
-+}
-+#if defined (__i386__)
-+static inline void exit_idle(void) {}
-+#define IRQ_REG orig_eax
-+#elif defined (__x86_64__)
-+#include <asm/idle.h>
-+#define IRQ_REG orig_rax
-+#endif
-+#define do_IRQ(irq, regs) do {                \
-+      (regs)->IRQ_REG = ~(irq);       \
-+      do_IRQ((regs));                 \
-+} while (0)
-+#endif
-+
-+/* Xen will never allocate port zero for any purpose. */
-+#define VALID_EVTCHN(chn)     ((chn) != 0)
-+
-+/*
-+ * Force a proper event-channel callback from Xen after clearing the
-+ * callback mask. We do this in a very simple manner, by making a call
-+ * down into Xen. The pending flag will be checked by Xen on return.
-+ */
-+void force_evtchn_callback(void)
-+{
-+      (void)HYPERVISOR_xen_version(0, NULL);
-+}
-+/* Not a GPL symbol: used in ubiquitous macros, so too restrictive. */
-+EXPORT_SYMBOL(force_evtchn_callback);
-+
-+/* NB. Interrupts are disabled on entry. */
-+asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
-+{
-+      unsigned long  l1, l2;
-+      unsigned int   l1i, l2i, port;
-+      int            irq, cpu = smp_processor_id();
-+      shared_info_t *s = HYPERVISOR_shared_info;
-+      vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
-+
-+      vcpu_info->evtchn_upcall_pending = 0;
-+
-+#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
-+      /* Clear master pending flag /before/ clearing selector flag. */
-+      rmb();
-+#endif
-+      l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
-+      while (l1 != 0) {
-+              l1i = __ffs(l1);
-+              l1 &= ~(1UL << l1i);
-+
-+              while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
-+                      l2i = __ffs(l2);
-+
-+                      port = (l1i * BITS_PER_LONG) + l2i;
-+                      if ((irq = evtchn_to_irq[port]) != -1)
-+                              do_IRQ(irq, regs);
-+                      else {
-+                              exit_idle();
-+                              evtchn_device_upcall(port);
-+                      }
-+              }
-+      }
-+}
-+
-+static int find_unbound_irq(void)
-+{
-+      static int warned;
-+      int dynirq, irq;
-+
-+      for (dynirq = 0; dynirq < NR_DYNIRQS; dynirq++) {
-+              irq = dynirq_to_irq(dynirq);
-+              if (irq_bindcount[irq] == 0)
-+                      return irq;
-+      }
-+
-+      if (!warned) {
-+              warned = 1;
-+              printk(KERN_WARNING "No available IRQ to bind to: "
-+                     "increase NR_DYNIRQS.\n");
-+      }
-+
-+      return -ENOSPC;
-+}
-+
-+static int bind_evtchn_to_irq(unsigned int evtchn)
-+{
-+      int irq;
-+
-+      spin_lock(&irq_mapping_update_lock);
-+
-+      if ((irq = evtchn_to_irq[evtchn]) == -1) {
-+              if ((irq = find_unbound_irq()) < 0)
-+                      goto out;
-+
-+              evtchn_to_irq[evtchn] = irq;
-+              irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
-+      }
-+
-+      irq_bindcount[irq]++;
-+
-+ out:
-+      spin_unlock(&irq_mapping_update_lock);
-+      return irq;
-+}
-+
-+static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
-+{
-+      struct evtchn_bind_virq bind_virq;
-+      int evtchn, irq;
-+
-+      spin_lock(&irq_mapping_update_lock);
-+
-+      if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
-+              if ((irq = find_unbound_irq()) < 0)
-+                      goto out;
-+
-+              bind_virq.virq = virq;
-+              bind_virq.vcpu = cpu;
-+              if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
-+                                              &bind_virq) != 0)
-+                      BUG();
-+              evtchn = bind_virq.port;
-+
-+              evtchn_to_irq[evtchn] = irq;
-+              irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
-+
-+              per_cpu(virq_to_irq, cpu)[virq] = irq;
-+
-+              bind_evtchn_to_cpu(evtchn, cpu);
-+      }
-+
-+      irq_bindcount[irq]++;
-+
-+ out:
-+      spin_unlock(&irq_mapping_update_lock);
-+      return irq;
-+}
-+
-+static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
-+{
-+      struct evtchn_bind_ipi bind_ipi;
-+      int evtchn, irq;
-+
-+      spin_lock(&irq_mapping_update_lock);
-+
-+      if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
-+              if ((irq = find_unbound_irq()) < 0)
-+                      goto out;
-+
-+              bind_ipi.vcpu = cpu;
-+              if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
-+                                              &bind_ipi) != 0)
-+                      BUG();
-+              evtchn = bind_ipi.port;
-+
-+              evtchn_to_irq[evtchn] = irq;
-+              irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
-+
-+              per_cpu(ipi_to_irq, cpu)[ipi] = irq;
-+
-+              bind_evtchn_to_cpu(evtchn, cpu);
-+      }
-+
-+      irq_bindcount[irq]++;
-+
-+ out:
-+      spin_unlock(&irq_mapping_update_lock);
-+      return irq;
-+}
-+
-+static void unbind_from_irq(unsigned int irq)
-+{
-+      struct evtchn_close close;
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      spin_lock(&irq_mapping_update_lock);
-+
-+      if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
-+              close.port = evtchn;
-+              if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
-+                      BUG();
-+
-+              switch (type_from_irq(irq)) {
-+              case IRQT_VIRQ:
-+                      per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
-+                              [index_from_irq(irq)] = -1;
-+                      break;
-+              case IRQT_IPI:
-+                      per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))
-+                              [index_from_irq(irq)] = -1;
-+                      break;
-+              default:
-+                      break;
-+              }
-+
-+              /* Closed ports are implicitly re-bound to VCPU0. */
-+              bind_evtchn_to_cpu(evtchn, 0);
-+
-+              evtchn_to_irq[evtchn] = -1;
-+              irq_info[irq] = IRQ_UNBOUND;
-+      }
-+
-+      spin_unlock(&irq_mapping_update_lock);
-+}
-+
-+int bind_evtchn_to_irqhandler(
-+      unsigned int evtchn,
-+      irqreturn_t (*handler)(int, void *, struct pt_regs *),
-+      unsigned long irqflags,
-+      const char *devname,
-+      void *dev_id)
-+{
-+      unsigned int irq;
-+      int retval;
-+
-+      irq = bind_evtchn_to_irq(evtchn);
-+      if (irq < 0)
-+              return irq;
-+
-+      retval = request_irq(irq, handler, irqflags, devname, dev_id);
-+      if (retval != 0) {
-+              unbind_from_irq(irq);
-+              return retval;
-+      }
-+
-+      return irq;
-+}
-+EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler);
-+
-+int bind_virq_to_irqhandler(
-+      unsigned int virq,
-+      unsigned int cpu,
-+      irqreturn_t (*handler)(int, void *, struct pt_regs *),
-+      unsigned long irqflags,
-+      const char *devname,
-+      void *dev_id)
-+{
-+      unsigned int irq;
-+      int retval;
-+
-+      irq = bind_virq_to_irq(virq, cpu);
-+      if (irq < 0)
-+              return irq;
-+
-+      retval = request_irq(irq, handler, irqflags, devname, dev_id);
-+      if (retval != 0) {
-+              unbind_from_irq(irq);
-+              return retval;
-+      }
-+
-+      return irq;
-+}
-+EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
-+
-+int bind_ipi_to_irqhandler(
-+      unsigned int ipi,
-+      unsigned int cpu,
-+      irqreturn_t (*handler)(int, void *, struct pt_regs *),
-+      unsigned long irqflags,
-+      const char *devname,
-+      void *dev_id)
-+{
-+      unsigned int irq;
-+      int retval;
-+
-+      irq = bind_ipi_to_irq(ipi, cpu);
-+      if (irq < 0)
-+              return irq;
-+
-+      retval = request_irq(irq, handler, irqflags, devname, dev_id);
-+      if (retval != 0) {
-+              unbind_from_irq(irq);
-+              return retval;
-+      }
-+
-+      return irq;
-+}
-+EXPORT_SYMBOL_GPL(bind_ipi_to_irqhandler);
-+
-+void unbind_from_irqhandler(unsigned int irq, void *dev_id)
-+{
-+      free_irq(irq, dev_id);
-+      unbind_from_irq(irq);
-+}
-+EXPORT_SYMBOL_GPL(unbind_from_irqhandler);
-+
-+/* Rebind an evtchn so that it gets delivered to a specific cpu */
-+static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
-+{
-+      struct evtchn_bind_vcpu bind_vcpu;
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (!VALID_EVTCHN(evtchn))
-+              return;
-+
-+      /* Send future instances of this interrupt to other vcpu. */
-+      bind_vcpu.port = evtchn;
-+      bind_vcpu.vcpu = tcpu;
-+
-+      /*
-+       * If this fails, it usually just indicates that we're dealing with a 
-+       * virq or IPI channel, which don't actually need to be rebound. Ignore
-+       * it, but don't do the xenlinux-level rebind in that case.
-+       */
-+      if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
-+              bind_evtchn_to_cpu(evtchn, tcpu);
-+}
-+
-+
-+static void set_affinity_irq(unsigned irq, cpumask_t dest)
-+{
-+      unsigned tcpu = first_cpu(dest);
-+      rebind_irq_to_cpu(irq, tcpu);
-+}
-+
-+/*
-+ * Interface to generic handling in irq.c
-+ */
-+
-+static unsigned int startup_dynirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn))
-+              unmask_evtchn(evtchn);
-+      return 0;
-+}
-+
-+static void shutdown_dynirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn))
-+              mask_evtchn(evtchn);
-+}
-+
-+static void enable_dynirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn))
-+              unmask_evtchn(evtchn);
-+}
-+
-+static void disable_dynirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn))
-+              mask_evtchn(evtchn);
-+}
-+
-+static void ack_dynirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      move_native_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn)) {
-+              mask_evtchn(evtchn);
-+              clear_evtchn(evtchn);
-+      }
-+}
-+
-+static void end_dynirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED))
-+              unmask_evtchn(evtchn);
-+}
-+
-+static struct hw_interrupt_type dynirq_type = {
-+      "Dynamic-irq",
-+      startup_dynirq,
-+      shutdown_dynirq,
-+      enable_dynirq,
-+      disable_dynirq,
-+      ack_dynirq,
-+      end_dynirq,
-+      set_affinity_irq
-+};
-+
-+static inline void pirq_unmask_notify(int pirq)
-+{
-+      struct physdev_eoi eoi = { .irq = pirq };
-+      if (unlikely(test_bit(pirq, &pirq_needs_eoi[0])))
-+              (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
-+}
-+
-+static inline void pirq_query_unmask(int pirq)
-+{
-+      struct physdev_irq_status_query irq_status;
-+      irq_status.irq = pirq;
-+      (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
-+      clear_bit(pirq, &pirq_needs_eoi[0]);
-+      if (irq_status.flags & XENIRQSTAT_needs_eoi)
-+              set_bit(pirq, &pirq_needs_eoi[0]);
-+}
-+
-+/*
-+ * On startup, if there is no action associated with the IRQ then we are
-+ * probing. In this case we should not share with others as it will confuse us.
-+ */
-+#define probing_irq(_irq) (irq_desc[(_irq)].action == NULL)
-+
-+static unsigned int startup_pirq(unsigned int irq)
-+{
-+      struct evtchn_bind_pirq bind_pirq;
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn))
-+              goto out;
-+
-+      bind_pirq.pirq  = irq;
-+      /* NB. We are happy to share unless we are probing. */
-+      bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
-+      if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) {
-+              if (!probing_irq(irq))
-+                      printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
-+                             irq);
-+              return 0;
-+      }
-+      evtchn = bind_pirq.port;
-+
-+      pirq_query_unmask(irq_to_pirq(irq));
-+
-+      evtchn_to_irq[evtchn] = irq;
-+      bind_evtchn_to_cpu(evtchn, 0);
-+      irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, evtchn);
-+
-+ out:
-+      unmask_evtchn(evtchn);
-+      pirq_unmask_notify(irq_to_pirq(irq));
-+
-+      return 0;
-+}
-+
-+static void shutdown_pirq(unsigned int irq)
-+{
-+      struct evtchn_close close;
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (!VALID_EVTCHN(evtchn))
-+              return;
-+
-+      mask_evtchn(evtchn);
-+
-+      close.port = evtchn;
-+      if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
-+              BUG();
-+
-+      bind_evtchn_to_cpu(evtchn, 0);
-+      evtchn_to_irq[evtchn] = -1;
-+      irq_info[irq] = IRQ_UNBOUND;
-+}
-+
-+static void enable_pirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn)) {
-+              unmask_evtchn(evtchn);
-+              pirq_unmask_notify(irq_to_pirq(irq));
-+      }
-+}
-+
-+static void disable_pirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn))
-+              mask_evtchn(evtchn);
-+}
-+
-+static void ack_pirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      move_native_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn)) {
-+              mask_evtchn(evtchn);
-+              clear_evtchn(evtchn);
-+      }
-+}
-+
-+static void end_pirq(unsigned int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
-+              unmask_evtchn(evtchn);
-+              pirq_unmask_notify(irq_to_pirq(irq));
-+      }
-+}
-+
-+static struct hw_interrupt_type pirq_type = {
-+      "Phys-irq",
-+      startup_pirq,
-+      shutdown_pirq,
-+      enable_pirq,
-+      disable_pirq,
-+      ack_pirq,
-+      end_pirq,
-+      set_affinity_irq
-+};
-+
-+int irq_ignore_unhandled(unsigned int irq)
-+{
-+      struct physdev_irq_status_query irq_status = { .irq = irq };
-+
-+      if (!is_running_on_xen())
-+              return 0;
-+
-+      (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
-+      return !!(irq_status.flags & XENIRQSTAT_shared);
-+}
-+
-+void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i)
-+{
-+      int evtchn = evtchn_from_irq(i);
-+      shared_info_t *s = HYPERVISOR_shared_info;
-+      if (!VALID_EVTCHN(evtchn))
-+              return;
-+      BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0]));
-+      synch_set_bit(evtchn, &s->evtchn_pending[0]);
-+}
-+
-+void notify_remote_via_irq(int irq)
-+{
-+      int evtchn = evtchn_from_irq(irq);
-+
-+      if (VALID_EVTCHN(evtchn))
-+              notify_remote_via_evtchn(evtchn);
-+}
-+EXPORT_SYMBOL_GPL(notify_remote_via_irq);
-+
-+void mask_evtchn(int port)
-+{
-+      shared_info_t *s = HYPERVISOR_shared_info;
-+      synch_set_bit(port, &s->evtchn_mask[0]);
-+}
-+EXPORT_SYMBOL_GPL(mask_evtchn);
-+
-+void unmask_evtchn(int port)
-+{
-+      shared_info_t *s = HYPERVISOR_shared_info;
-+      unsigned int cpu = smp_processor_id();
-+      vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
-+
-+      BUG_ON(!irqs_disabled());
-+
-+      /* Slow path (hypercall) if this is a non-local port. */
-+      if (unlikely(cpu != cpu_from_evtchn(port))) {
-+              struct evtchn_unmask unmask = { .port = port };
-+              (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
-+              return;
-+      }
-+
-+      synch_clear_bit(port, &s->evtchn_mask[0]);
-+
-+      /*
-+       * The following is basically the equivalent of 'hw_resend_irq'. Just
-+       * like a real IO-APIC we 'lose the interrupt edge' if the channel is
-+       * masked.
-+       */
-+      if (synch_test_bit(port, &s->evtchn_pending[0]) &&
-+          !synch_test_and_set_bit(port / BITS_PER_LONG,
-+                                  &vcpu_info->evtchn_pending_sel))
-+              vcpu_info->evtchn_upcall_pending = 1;
-+}
-+EXPORT_SYMBOL_GPL(unmask_evtchn);
-+
-+void irq_resume(void)
-+{
-+      struct evtchn_bind_virq bind_virq;
-+      struct evtchn_bind_ipi  bind_ipi;
-+      int cpu, pirq, virq, ipi, irq, evtchn;
-+
-+      init_evtchn_cpu_bindings();
-+
-+      /* New event-channel space is not 'live' yet. */
-+      for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
-+              mask_evtchn(evtchn);
-+
-+      /* Check that no PIRQs are still bound. */
-+      for (pirq = 0; pirq < NR_PIRQS; pirq++)
-+              BUG_ON(irq_info[pirq_to_irq(pirq)] != IRQ_UNBOUND);
-+
-+      /* Secondary CPUs must have no VIRQ or IPI bindings. */
-+      for_each_possible_cpu(cpu) {
-+              if (cpu == 0)
-+                      continue;
-+              for (virq = 0; virq < NR_VIRQS; virq++)
-+                      BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1);
-+              for (ipi = 0; ipi < NR_IPIS; ipi++)
-+                      BUG_ON(per_cpu(ipi_to_irq, cpu)[ipi] != -1);
-+      }
-+
-+      /* No IRQ <-> event-channel mappings. */
-+      for (irq = 0; irq < NR_IRQS; irq++)
-+              irq_info[irq] &= ~0xFFFF; /* zap event-channel binding */
-+      for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
-+              evtchn_to_irq[evtchn] = -1;
-+
-+      /* Primary CPU: rebind VIRQs automatically. */
-+      for (virq = 0; virq < NR_VIRQS; virq++) {
-+              if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
-+                      continue;
-+
-+              BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
-+
-+              /* Get a new binding from Xen. */
-+              bind_virq.virq = virq;
-+              bind_virq.vcpu = 0;
-+              if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
-+                                              &bind_virq) != 0)
-+                      BUG();
-+              evtchn = bind_virq.port;
-+
-+              /* Record the new mapping. */
-+              evtchn_to_irq[evtchn] = irq;
-+              irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
-+
-+              /* Ready for use. */
-+              unmask_evtchn(evtchn);
-+      }
-+
-+      /* Primary CPU: rebind IPIs automatically. */
-+      for (ipi = 0; ipi < NR_IPIS; ipi++) {
-+              if ((irq = per_cpu(ipi_to_irq, 0)[ipi]) == -1)
-+                      continue;
-+
-+              BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
-+
-+              /* Get a new binding from Xen. */
-+              bind_ipi.vcpu = 0;
-+              if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
-+                                              &bind_ipi) != 0)
-+                      BUG();
-+              evtchn = bind_ipi.port;
-+
-+              /* Record the new mapping. */
-+              evtchn_to_irq[evtchn] = irq;
-+              irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
-+
-+              /* Ready for use. */
-+              unmask_evtchn(evtchn);
-+      }
-+}
-+
-+void __init xen_init_IRQ(void)
-+{
-+      int i;
-+
-+      init_evtchn_cpu_bindings();
-+
-+      /* No event channels are 'live' right now. */
-+      for (i = 0; i < NR_EVENT_CHANNELS; i++)
-+              mask_evtchn(i);
-+
-+      /* No IRQ -> event-channel mappings. */
-+      for (i = 0; i < NR_IRQS; i++)
-+              irq_info[i] = IRQ_UNBOUND;
-+
-+      /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
-+      for (i = 0; i < NR_DYNIRQS; i++) {
-+              irq_bindcount[dynirq_to_irq(i)] = 0;
-+
-+              irq_desc[dynirq_to_irq(i)].status  = IRQ_DISABLED;
-+              irq_desc[dynirq_to_irq(i)].action  = NULL;
-+              irq_desc[dynirq_to_irq(i)].depth   = 1;
-+              irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
-+      }
-+
-+      /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
-+      for (i = 0; i < NR_PIRQS; i++) {
-+              irq_bindcount[pirq_to_irq(i)] = 1;
-+
-+#ifdef RTC_IRQ
-+              /* If not domain 0, force our RTC driver to fail its probe. */
-+              if ((i == RTC_IRQ) && !is_initial_xendomain())
-+                      continue;
-+#endif
-+
-+              irq_desc[pirq_to_irq(i)].status  = IRQ_DISABLED;
-+              irq_desc[pirq_to_irq(i)].action  = NULL;
-+              irq_desc[pirq_to_irq(i)].depth   = 1;
-+              irq_desc[pirq_to_irq(i)].handler = &pirq_type;
-+      }
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/features.c linux-2.6.16.33/drivers/xen/core/features.c
---- linux-2.6.16.33-noxen/drivers/xen/core/features.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/features.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,34 @@
-+/******************************************************************************
-+ * features.c
-+ *
-+ * Xen feature flags.
-+ *
-+ * Copyright (c) 2006, Ian Campbell, XenSource Inc.
-+ */
-+#include <linux/types.h>
-+#include <linux/cache.h>
-+#include <linux/module.h>
-+#include <asm/hypervisor.h>
-+#include <xen/features.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+u8 xen_features[XENFEAT_NR_SUBMAPS * 32] __read_mostly;
-+/* Not a GPL symbol: used in ubiquitous macros, so too restrictive. */
-+EXPORT_SYMBOL(xen_features);
-+
-+void setup_xen_features(void)
-+{
-+      xen_feature_info_t fi;
-+      int i, j;
-+
-+      for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) {
-+              fi.submap_idx = i;
-+              if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
-+                      break;
-+              for (j=0; j<32; j++)
-+                      xen_features[i*32+j] = !!(fi.submap & 1<<j);
-+      }
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/gnttab.c linux-2.6.16.33/drivers/xen/core/gnttab.c
---- linux-2.6.16.33-noxen/drivers/xen/core/gnttab.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/gnttab.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,488 @@
-+/******************************************************************************
-+ * gnttab.c
-+ *
-+ * Granting foreign access to our memory reservation.
-+ *
-+ * Copyright (c) 2005, Christopher Clark
-+ * Copyright (c) 2004-2005, K A Fraser
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/vmalloc.h>
-+#include <xen/interface/xen.h>
-+#include <xen/gnttab.h>
-+#include <asm/pgtable.h>
-+#include <asm/uaccess.h>
-+#include <asm/synch_bitops.h>
-+#include <asm/io.h>
-+#include <xen/interface/memory.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+/* External tools reserve first few grant table entries. */
-+#define NR_RESERVED_ENTRIES 8
-+
-+#define NR_GRANT_ENTRIES \
-+      (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(struct grant_entry))
-+#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
-+
-+static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
-+static int gnttab_free_count;
-+static grant_ref_t gnttab_free_head;
-+static DEFINE_SPINLOCK(gnttab_list_lock);
-+
-+static struct grant_entry *shared;
-+
-+static struct gnttab_free_callback *gnttab_free_callback_list;
-+
-+static int get_free_entries(int count)
-+{
-+      unsigned long flags;
-+      int ref;
-+      grant_ref_t head;
-+      spin_lock_irqsave(&gnttab_list_lock, flags);
-+      if (gnttab_free_count < count) {
-+              spin_unlock_irqrestore(&gnttab_list_lock, flags);
-+              return -1;
-+      }
-+      ref = head = gnttab_free_head;
-+      gnttab_free_count -= count;
-+      while (count-- > 1)
-+              head = gnttab_list[head];
-+      gnttab_free_head = gnttab_list[head];
-+      gnttab_list[head] = GNTTAB_LIST_END;
-+      spin_unlock_irqrestore(&gnttab_list_lock, flags);
-+      return ref;
-+}
-+
-+#define get_free_entry() get_free_entries(1)
-+
-+static void do_free_callbacks(void)
-+{
-+      struct gnttab_free_callback *callback, *next;
-+
-+      callback = gnttab_free_callback_list;
-+      gnttab_free_callback_list = NULL;
-+
-+      while (callback != NULL) {
-+              next = callback->next;
-+              if (gnttab_free_count >= callback->count) {
-+                      callback->next = NULL;
-+                      callback->fn(callback->arg);
-+              } else {
-+                      callback->next = gnttab_free_callback_list;
-+                      gnttab_free_callback_list = callback;
-+              }
-+              callback = next;
-+      }
-+}
-+
-+static inline void check_free_callbacks(void)
-+{
-+      if (unlikely(gnttab_free_callback_list))
-+              do_free_callbacks();
-+}
-+
-+static void put_free_entry(grant_ref_t ref)
-+{
-+      unsigned long flags;
-+      spin_lock_irqsave(&gnttab_list_lock, flags);
-+      gnttab_list[ref] = gnttab_free_head;
-+      gnttab_free_head = ref;
-+      gnttab_free_count++;
-+      check_free_callbacks();
-+      spin_unlock_irqrestore(&gnttab_list_lock, flags);
-+}
-+
-+/*
-+ * Public grant-issuing interface functions
-+ */
-+
-+int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
-+                              int readonly)
-+{
-+      int ref;
-+
-+      if (unlikely((ref = get_free_entry()) == -1))
-+              return -ENOSPC;
-+
-+      shared[ref].frame = frame;
-+      shared[ref].domid = domid;
-+      wmb();
-+      shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
-+
-+      return ref;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
-+
-+void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
-+                                   unsigned long frame, int readonly)
-+{
-+      shared[ref].frame = frame;
-+      shared[ref].domid = domid;
-+      wmb();
-+      shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
-+}
-+EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref);
-+
-+
-+int gnttab_query_foreign_access(grant_ref_t ref)
-+{
-+      u16 nflags;
-+
-+      nflags = shared[ref].flags;
-+
-+      return (nflags & (GTF_reading|GTF_writing));
-+}
-+EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
-+
-+int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
-+{
-+      u16 flags, nflags;
-+
-+      nflags = shared[ref].flags;
-+      do {
-+              if ((flags = nflags) & (GTF_reading|GTF_writing)) {
-+                      printk(KERN_ALERT "WARNING: g.e. still in use!\n");
-+                      return 0;
-+              }
-+      } while ((nflags = synch_cmpxchg_subword(&shared[ref].flags, flags, 0)) !=
-+               flags);
-+
-+      return 1;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
-+
-+void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
-+                             unsigned long page)
-+{
-+      if (gnttab_end_foreign_access_ref(ref, readonly)) {
-+              put_free_entry(ref);
-+              if (page != 0)
-+                      free_page(page);
-+      } else {
-+              /* XXX This needs to be fixed so that the ref and page are
-+                 placed on a list to be freed up later. */
-+              printk(KERN_WARNING
-+                     "WARNING: leaking g.e. and page still in use!\n");
-+      }
-+}
-+EXPORT_SYMBOL_GPL(gnttab_end_foreign_access);
-+
-+int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
-+{
-+      int ref;
-+
-+      if (unlikely((ref = get_free_entry()) == -1))
-+              return -ENOSPC;
-+      gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
-+
-+      return ref;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer);
-+
-+void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
-+                                     unsigned long pfn)
-+{
-+      shared[ref].frame = pfn;
-+      shared[ref].domid = domid;
-+      wmb();
-+      shared[ref].flags = GTF_accept_transfer;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref);
-+
-+unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref)
-+{
-+      unsigned long frame;
-+      u16           flags;
-+
-+      /*
-+       * If a transfer is not even yet started, try to reclaim the grant
-+       * reference and return failure (== 0).
-+       */
-+      while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
-+              if (synch_cmpxchg_subword(&shared[ref].flags, flags, 0) == flags)
-+                      return 0;
-+              cpu_relax();
-+      }
-+
-+      /* If a transfer is in progress then wait until it is completed. */
-+      while (!(flags & GTF_transfer_completed)) {
-+              flags = shared[ref].flags;
-+              cpu_relax();
-+      }
-+
-+      /* Read the frame number /after/ reading completion status. */
-+      rmb();
-+      frame = shared[ref].frame;
-+      BUG_ON(frame == 0);
-+
-+      return frame;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref);
-+
-+unsigned long gnttab_end_foreign_transfer(grant_ref_t ref)
-+{
-+      unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
-+      put_free_entry(ref);
-+      return frame;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer);
-+
-+void gnttab_free_grant_reference(grant_ref_t ref)
-+{
-+      put_free_entry(ref);
-+}
-+EXPORT_SYMBOL_GPL(gnttab_free_grant_reference);
-+
-+void gnttab_free_grant_references(grant_ref_t head)
-+{
-+      grant_ref_t ref;
-+      unsigned long flags;
-+      int count = 1;
-+      if (head == GNTTAB_LIST_END)
-+              return;
-+      spin_lock_irqsave(&gnttab_list_lock, flags);
-+      ref = head;
-+      while (gnttab_list[ref] != GNTTAB_LIST_END) {
-+              ref = gnttab_list[ref];
-+              count++;
-+      }
-+      gnttab_list[ref] = gnttab_free_head;
-+      gnttab_free_head = head;
-+      gnttab_free_count += count;
-+      check_free_callbacks();
-+      spin_unlock_irqrestore(&gnttab_list_lock, flags);
-+}
-+EXPORT_SYMBOL_GPL(gnttab_free_grant_references);
-+
-+int gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
-+{
-+      int h = get_free_entries(count);
-+
-+      if (h == -1)
-+              return -ENOSPC;
-+
-+      *head = h;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references);
-+
-+int gnttab_empty_grant_references(const grant_ref_t *private_head)
-+{
-+      return (*private_head == GNTTAB_LIST_END);
-+}
-+EXPORT_SYMBOL_GPL(gnttab_empty_grant_references);
-+
-+int gnttab_claim_grant_reference(grant_ref_t *private_head)
-+{
-+      grant_ref_t g = *private_head;
-+      if (unlikely(g == GNTTAB_LIST_END))
-+              return -ENOSPC;
-+      *private_head = gnttab_list[g];
-+      return g;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference);
-+
-+void gnttab_release_grant_reference(grant_ref_t *private_head,
-+                                  grant_ref_t release)
-+{
-+      gnttab_list[release] = *private_head;
-+      *private_head = release;
-+}
-+EXPORT_SYMBOL_GPL(gnttab_release_grant_reference);
-+
-+void gnttab_request_free_callback(struct gnttab_free_callback *callback,
-+                                void (*fn)(void *), void *arg, u16 count)
-+{
-+      unsigned long flags;
-+      spin_lock_irqsave(&gnttab_list_lock, flags);
-+      if (callback->next)
-+              goto out;
-+      callback->fn = fn;
-+      callback->arg = arg;
-+      callback->count = count;
-+      callback->next = gnttab_free_callback_list;
-+      gnttab_free_callback_list = callback;
-+      check_free_callbacks();
-+out:
-+      spin_unlock_irqrestore(&gnttab_list_lock, flags);
-+}
-+EXPORT_SYMBOL_GPL(gnttab_request_free_callback);
-+
-+void gnttab_cancel_free_callback(struct gnttab_free_callback *callback)
-+{
-+      struct gnttab_free_callback **pcb;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&gnttab_list_lock, flags);
-+      for (pcb = &gnttab_free_callback_list; *pcb; pcb = &(*pcb)->next) {
-+              if (*pcb == callback) {
-+                      *pcb = callback->next;
-+                      break;
-+              }
-+      }
-+      spin_unlock_irqrestore(&gnttab_list_lock, flags);
-+}
-+EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback);
-+
-+#ifdef CONFIG_XEN
-+
-+#ifndef __ia64__
-+static int map_pte_fn(pte_t *pte, struct page *pmd_page,
-+                    unsigned long addr, void *data)
-+{
-+      unsigned long **frames = (unsigned long **)data;
-+
-+      set_pte_at(&init_mm, addr, pte, pfn_pte_ma((*frames)[0], PAGE_KERNEL));
-+      (*frames)++;
-+      return 0;
-+}
-+
-+static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
-+                      unsigned long addr, void *data)
-+{
-+
-+      set_pte_at(&init_mm, addr, pte, __pte(0));
-+      return 0;
-+}
-+#endif
-+
-+int gnttab_resume(void)
-+{
-+      struct gnttab_setup_table setup;
-+      unsigned long frames[NR_GRANT_FRAMES];
-+      int rc;
-+#ifndef __ia64__
-+      void *pframes = frames;
-+      struct vm_struct *area;
-+#endif
-+
-+      setup.dom        = DOMID_SELF;
-+      setup.nr_frames  = NR_GRANT_FRAMES;
-+      set_xen_guest_handle(setup.frame_list, frames);
-+
-+      rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
-+      if (rc == -ENOSYS)
-+              return -ENOSYS;
-+
-+      BUG_ON(rc || setup.status);
-+
-+#ifndef __ia64__
-+      if (shared == NULL) {
-+              area = get_vm_area(PAGE_SIZE * NR_GRANT_FRAMES, VM_IOREMAP);
-+              BUG_ON(area == NULL);
-+              shared = area->addr;
-+      }
-+      rc = apply_to_page_range(&init_mm, (unsigned long)shared,
-+                               PAGE_SIZE * NR_GRANT_FRAMES,
-+                               map_pte_fn, &pframes);
-+      BUG_ON(rc);
-+#else
-+      shared = __va(frames[0] << PAGE_SHIFT);
-+      printk("grant table at %p\n", shared);
-+#endif
-+
-+      return 0;
-+}
-+
-+int gnttab_suspend(void)
-+{
-+#ifndef __ia64__
-+      apply_to_page_range(&init_mm, (unsigned long)shared,
-+                          PAGE_SIZE * NR_GRANT_FRAMES,
-+                          unmap_pte_fn, NULL);
-+#endif
-+      return 0;
-+}
-+
-+#else /* !CONFIG_XEN */
-+
-+#include <platform-pci.h>
-+
-+int gnttab_resume(void)
-+{
-+      unsigned long frames;
-+      struct xen_add_to_physmap xatp;
-+      unsigned int i;
-+
-+      frames = alloc_xen_mmio(PAGE_SIZE * NR_GRANT_FRAMES);
-+
-+      for (i = 0; i < NR_GRANT_FRAMES; i++) {
-+              xatp.domid = DOMID_SELF;
-+              xatp.idx = i;
-+              xatp.space = XENMAPSPACE_grant_table;
-+              xatp.gpfn = (frames >> PAGE_SHIFT) + i;
-+              if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
-+                      BUG();
-+      }
-+
-+      shared = ioremap(frames, PAGE_SIZE * NR_GRANT_FRAMES);
-+      if (shared == NULL) {
-+              printk("error to ioremap gnttab share frames\n");
-+              return -1;
-+      }
-+
-+      return 0;
-+}
-+
-+int gnttab_suspend(void)
-+{
-+      iounmap(shared);
-+      return 0;
-+}
-+
-+#endif /* !CONFIG_XEN */
-+
-+int __init gnttab_init(void)
-+{
-+      int i;
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      if (gnttab_resume() < 0)
-+              return -ENODEV;
-+
-+      for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
-+              gnttab_list[i] = i + 1;
-+      gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
-+      gnttab_free_head  = NR_RESERVED_ENTRIES;
-+
-+      printk("Grant table initialized\n");
-+      return 0;
-+}
-+
-+#ifdef CONFIG_XEN
-+core_initcall(gnttab_init);
-+#endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/hypervisor_sysfs.c linux-2.6.16.33/drivers/xen/core/hypervisor_sysfs.c
---- linux-2.6.16.33-noxen/drivers/xen/core/hypervisor_sysfs.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/hypervisor_sysfs.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,60 @@
-+/*
-+ *  copyright (c) 2006 IBM Corporation
-+ *  Authored by: Mike D. Day <ncmike@us.ibm.com>
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License version 2 as
-+ *  published by the Free Software Foundation.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/kobject.h>
-+#include <xen/hypervisor_sysfs.h>
-+
-+decl_subsys(hypervisor, NULL, NULL);
-+
-+static ssize_t hyp_sysfs_show(struct kobject *kobj,
-+                            struct attribute *attr,
-+                            char *buffer)
-+{
-+      struct hyp_sysfs_attr *hyp_attr;
-+      hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr);
-+      if (hyp_attr->show)
-+              return hyp_attr->show(hyp_attr, buffer);
-+      return 0;
-+}
-+
-+static ssize_t hyp_sysfs_store(struct kobject *kobj,
-+                             struct attribute *attr,
-+                             const char *buffer,
-+                             size_t len)
-+{
-+      struct hyp_sysfs_attr *hyp_attr;
-+      hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr);
-+      if (hyp_attr->store)
-+              return hyp_attr->store(hyp_attr, buffer, len);
-+      return 0;
-+}
-+
-+struct sysfs_ops hyp_sysfs_ops = {
-+      .show = hyp_sysfs_show,
-+      .store = hyp_sysfs_store,
-+};
-+
-+static struct kobj_type hyp_sysfs_kobj_type = {
-+      .sysfs_ops = &hyp_sysfs_ops,
-+};
-+
-+static int __init hypervisor_subsys_init(void)
-+{
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      hypervisor_subsys.kset.kobj.ktype = &hyp_sysfs_kobj_type;
-+      return subsystem_register(&hypervisor_subsys);
-+}
-+
-+device_initcall(hypervisor_subsys_init);
-+EXPORT_SYMBOL_GPL(hypervisor_subsys);
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/machine_kexec.c linux-2.6.16.33/drivers/xen/core/machine_kexec.c
---- linux-2.6.16.33-noxen/drivers/xen/core/machine_kexec.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/machine_kexec.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,190 @@
-+/*
-+ * drivers/xen/core/machine_kexec.c 
-+ * handle transition of Linux booting another kernel
-+ */
-+
-+#include <linux/kexec.h>
-+#include <xen/interface/kexec.h>
-+#include <linux/mm.h>
-+#include <linux/bootmem.h>
-+#include <asm/hypercall.h>
-+
-+extern void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, 
-+                                       struct kimage *image);
-+
-+int xen_max_nr_phys_cpus;
-+struct resource xen_hypervisor_res;
-+struct resource *xen_phys_cpus;
-+
-+void xen_machine_kexec_setup_resources(void)
-+{
-+      xen_kexec_range_t range;
-+      struct resource *res;
-+      int k = 0;
-+
-+      if (!is_initial_xendomain())
-+              return;
-+
-+      /* determine maximum number of physical cpus */
-+
-+      while (1) {
-+              memset(&range, 0, sizeof(range));
-+              range.range = KEXEC_RANGE_MA_CPU;
-+              range.nr = k;
-+
-+              if(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
-+                      break;
-+
-+              k++;
-+      }
-+
-+      if (k == 0)
-+              return;
-+
-+      xen_max_nr_phys_cpus = k;
-+
-+      /* allocate xen_phys_cpus */
-+
-+      xen_phys_cpus = alloc_bootmem_low(k * sizeof(struct resource));
-+      BUG_ON(xen_phys_cpus == NULL);
-+
-+      /* fill in xen_phys_cpus with per-cpu crash note information */
-+
-+      for (k = 0; k < xen_max_nr_phys_cpus; k++) {
-+              memset(&range, 0, sizeof(range));
-+              range.range = KEXEC_RANGE_MA_CPU;
-+              range.nr = k;
-+
-+              if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
-+                      goto err;
-+
-+              res = xen_phys_cpus + k;
-+
-+              memset(res, 0, sizeof(*res));
-+              res->name = "Crash note";
-+              res->start = range.start;
-+              res->end = range.start + range.size - 1;
-+              res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
-+      }
-+
-+      /* fill in xen_hypervisor_res with hypervisor machine address range */
-+
-+      memset(&range, 0, sizeof(range));
-+      range.range = KEXEC_RANGE_MA_XEN;
-+
-+      if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
-+              goto err;
-+
-+      xen_hypervisor_res.name = "Hypervisor code and data";
-+      xen_hypervisor_res.start = range.start;
-+      xen_hypervisor_res.end = range.start + range.size - 1;
-+      xen_hypervisor_res.flags = IORESOURCE_BUSY | IORESOURCE_MEM;
-+
-+      /* fill in crashk_res if range is reserved by hypervisor */
-+
-+      memset(&range, 0, sizeof(range));
-+      range.range = KEXEC_RANGE_MA_CRASH;
-+
-+      if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
-+              return;
-+
-+      if (range.size) {
-+              crashk_res.start = range.start;
-+              crashk_res.end = range.start + range.size - 1;
-+      }
-+
-+      return;
-+
-+ err:
-+      /*
-+       * It isn't possible to free xen_phys_cpus this early in the
-+       * boot. Since failure at this stage is unexpected and the
-+       * amount is small we leak the memory.
-+         */
-+      xen_max_nr_phys_cpus = 0;
-+      return;
-+}
-+
-+void xen_machine_kexec_register_resources(struct resource *res)
-+{
-+      int k;
-+
-+      request_resource(res, &xen_hypervisor_res);
-+
-+      for (k = 0; k < xen_max_nr_phys_cpus; k++)
-+              request_resource(&xen_hypervisor_res, xen_phys_cpus + k);
-+
-+}
-+
-+static void setup_load_arg(xen_kexec_image_t *xki, struct kimage *image)
-+{
-+      machine_kexec_setup_load_arg(xki, image);
-+
-+      xki->indirection_page = image->head;
-+      xki->start_address = image->start;
-+}
-+
-+/*
-+ * Load the image into xen so xen can kdump itself
-+ * This might have been done in prepare, but prepare
-+ * is currently called too early. It might make sense
-+ * to move prepare, but for now, just add an extra hook.
-+ */
-+int xen_machine_kexec_load(struct kimage *image)
-+{
-+      xen_kexec_load_t xkl;
-+
-+      memset(&xkl, 0, sizeof(xkl));
-+      xkl.type = image->type;
-+      setup_load_arg(&xkl.image, image);
-+      return HYPERVISOR_kexec_op(KEXEC_CMD_kexec_load, &xkl);
-+}
-+
-+/*
-+ * Unload the image that was stored by machine_kexec_load()
-+ * This might have been done in machine_kexec_cleanup() but it
-+ * is called too late, and its possible xen could try and kdump
-+ * using resources that have been freed.
-+ */
-+void xen_machine_kexec_unload(struct kimage *image)
-+{
-+      xen_kexec_load_t xkl;
-+
-+      memset(&xkl, 0, sizeof(xkl));
-+      xkl.type = image->type;
-+      HYPERVISOR_kexec_op(KEXEC_CMD_kexec_unload, &xkl);
-+}
-+
-+/*
-+ * Do not allocate memory (or fail in any way) in machine_kexec().
-+ * We are past the point of no return, committed to rebooting now.
-+ *
-+ * This has the hypervisor move to the prefered reboot CPU, 
-+ * stop all CPUs and kexec. That is it combines machine_shutdown()
-+ * and machine_kexec() in Linux kexec terms.
-+ */
-+NORET_TYPE void machine_kexec(struct kimage *image)
-+{
-+      xen_kexec_exec_t xke;
-+
-+      memset(&xke, 0, sizeof(xke));
-+      xke.type = image->type;
-+      HYPERVISOR_kexec_op(KEXEC_CMD_kexec, &xke);
-+      panic("KEXEC_CMD_kexec hypercall should not return\n");
-+}
-+
-+void machine_shutdown(void)
-+{
-+      /* do nothing */
-+}
-+
-+
-+/*
-+ * Local variables:
-+ *  c-file-style: "linux"
-+ *  indent-tabs-mode: t
-+ *  c-indent-level: 8
-+ *  c-basic-offset: 8
-+ *  tab-width: 8
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/machine_reboot.c linux-2.6.16.33/drivers/xen/core/machine_reboot.c
---- linux-2.6.16.33-noxen/drivers/xen/core/machine_reboot.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/machine_reboot.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,185 @@
-+#define __KERNEL_SYSCALLS__
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/unistd.h>
-+#include <linux/module.h>
-+#include <linux/reboot.h>
-+#include <linux/sysrq.h>
-+#include <linux/stringify.h>
-+#include <asm/irq.h>
-+#include <asm/mmu_context.h>
-+#include <xen/evtchn.h>
-+#include <asm/hypervisor.h>
-+#include <xen/interface/dom0_ops.h>
-+#include <xen/xenbus.h>
-+#include <linux/cpu.h>
-+#include <linux/kthread.h>
-+#include <xen/gnttab.h>
-+#include <xen/xencons.h>
-+#include <xen/cpu_hotplug.h>
-+
-+#if defined(__i386__) || defined(__x86_64__)
-+
-+/*
-+ * Power off function, if any
-+ */
-+void (*pm_power_off)(void);
-+EXPORT_SYMBOL(pm_power_off);
-+
-+void machine_emergency_restart(void)
-+{
-+      /* We really want to get pending console data out before we die. */
-+      xencons_force_flush();
-+      HYPERVISOR_shutdown(SHUTDOWN_reboot);
-+}
-+
-+void machine_restart(char * __unused)
-+{
-+      machine_emergency_restart();
-+}
-+
-+void machine_halt(void)
-+{
-+      machine_power_off();
-+}
-+
-+void machine_power_off(void)
-+{
-+      /* We really want to get pending console data out before we die. */
-+      xencons_force_flush();
-+      if (pm_power_off)
-+              pm_power_off();
-+      HYPERVISOR_shutdown(SHUTDOWN_poweroff);
-+}
-+
-+int reboot_thru_bios = 0;     /* for dmi_scan.c */
-+EXPORT_SYMBOL(machine_restart);
-+EXPORT_SYMBOL(machine_halt);
-+EXPORT_SYMBOL(machine_power_off);
-+
-+/* Ensure we run on the idle task page tables so that we will
-+   switch page tables before running user space. This is needed
-+   on architectures with separate kernel and user page tables
-+   because the user page table pointer is not saved/restored. */
-+static void switch_idle_mm(void)
-+{
-+      struct mm_struct *mm = current->active_mm;
-+
-+      if (mm == &init_mm)
-+              return;
-+
-+      atomic_inc(&init_mm.mm_count);
-+      switch_mm(mm, &init_mm, current);
-+      current->active_mm = &init_mm;
-+      mmdrop(mm);
-+}
-+
-+static void pre_suspend(void)
-+{
-+      HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
-+      clear_fixmap(FIX_SHARED_INFO);
-+
-+      xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
-+      xen_start_info->console.domU.mfn =
-+              mfn_to_pfn(xen_start_info->console.domU.mfn);
-+}
-+
-+static void post_suspend(void)
-+{
-+      int i, j, k, fpp;
-+      extern unsigned long max_pfn;
-+      extern unsigned long *pfn_to_mfn_frame_list_list;
-+      extern unsigned long *pfn_to_mfn_frame_list[];
-+
-+      set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-+
-+      HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-+
-+      memset(empty_zero_page, 0, PAGE_SIZE);
-+
-+      HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
-+              virt_to_mfn(pfn_to_mfn_frame_list_list);
-+
-+      fpp = PAGE_SIZE/sizeof(unsigned long);
-+      for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
-+              if ((j % fpp) == 0) {
-+                      k++;
-+                      pfn_to_mfn_frame_list_list[k] =
-+                              virt_to_mfn(pfn_to_mfn_frame_list[k]);
-+                      j = 0;
-+              }
-+              pfn_to_mfn_frame_list[k][j] =
-+                      virt_to_mfn(&phys_to_machine_mapping[i]);
-+      }
-+      HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-+}
-+
-+#else /* !(defined(__i386__) || defined(__x86_64__)) */
-+
-+#define switch_idle_mm()      ((void)0)
-+#define mm_pin_all()          ((void)0)
-+#define pre_suspend()         ((void)0)
-+#define post_suspend()                ((void)0)
-+
-+#endif
-+
-+int __xen_suspend(void)
-+{
-+      int err;
-+
-+      extern void time_resume(void);
-+
-+      BUG_ON(smp_processor_id() != 0);
-+      BUG_ON(in_interrupt());
-+
-+#if defined(__i386__) || defined(__x86_64__)
-+      if (xen_feature(XENFEAT_auto_translated_physmap)) {
-+              printk(KERN_WARNING "Cannot suspend in "
-+                     "auto_translated_physmap mode.\n");
-+              return -EOPNOTSUPP;
-+      }
-+#endif
-+
-+      err = smp_suspend();
-+      if (err)
-+              return err;
-+
-+      xenbus_suspend();
-+
-+      preempt_disable();
-+
-+      mm_pin_all();
-+      local_irq_disable();
-+      preempt_enable();
-+
-+      gnttab_suspend();
-+
-+      pre_suspend();
-+
-+      /*
-+       * We'll stop somewhere inside this hypercall. When it returns,
-+       * we'll start resuming after the restore.
-+       */
-+      HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
-+
-+      post_suspend();
-+
-+      gnttab_resume();
-+
-+      irq_resume();
-+
-+      time_resume();
-+
-+      switch_idle_mm();
-+
-+      local_irq_enable();
-+
-+      xencons_resume();
-+
-+      xenbus_resume();
-+
-+      smp_resume();
-+
-+      return err;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/reboot.c linux-2.6.16.33/drivers/xen/core/reboot.c
---- linux-2.6.16.33-noxen/drivers/xen/core/reboot.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/reboot.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,220 @@
-+#define __KERNEL_SYSCALLS__
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/unistd.h>
-+#include <linux/module.h>
-+#include <linux/reboot.h>
-+#include <linux/sysrq.h>
-+#include <asm/hypervisor.h>
-+#include <xen/xenbus.h>
-+#include <linux/kthread.h>
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-+
-+#define SHUTDOWN_INVALID  -1
-+#define SHUTDOWN_POWEROFF  0
-+#define SHUTDOWN_SUSPEND   2
-+/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
-+ * report a crash, not be instructed to crash!
-+ * HALT is the same as POWEROFF, as far as we're concerned.  The tools use
-+ * the distinction when we return the reason code to them.
-+ */
-+#define SHUTDOWN_HALT      4
-+
-+/* Ignore multiple shutdown requests. */
-+static int shutting_down = SHUTDOWN_INVALID;
-+
-+static void __shutdown_handler(void *unused);
-+static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
-+
-+#ifdef CONFIG_XEN
-+int __xen_suspend(void);
-+#else
-+#define __xen_suspend() (void)0
-+#endif
-+
-+static int shutdown_process(void *__unused)
-+{
-+      static char *envp[] = { "HOME=/", "TERM=linux",
-+                              "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
-+      static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
-+
-+      extern asmlinkage long sys_reboot(int magic1, int magic2,
-+                                        unsigned int cmd, void *arg);
-+
-+      if ((shutting_down == SHUTDOWN_POWEROFF) ||
-+          (shutting_down == SHUTDOWN_HALT)) {
-+              if (call_usermodehelper("/sbin/poweroff", poweroff_argv, envp, 0) < 0) {
-+#ifdef CONFIG_XEN
-+                      sys_reboot(LINUX_REBOOT_MAGIC1,
-+                                 LINUX_REBOOT_MAGIC2,
-+                                 LINUX_REBOOT_CMD_POWER_OFF,
-+                                 NULL);
-+#endif /* CONFIG_XEN */
-+              }
-+      }
-+
-+      shutting_down = SHUTDOWN_INVALID; /* could try again */
-+
-+      return 0;
-+}
-+
-+static int xen_suspend(void *__unused)
-+{
-+      __xen_suspend();
-+      shutting_down = SHUTDOWN_INVALID;
-+      return 0;
-+}
-+
-+static int kthread_create_on_cpu(int (*f)(void *arg),
-+                               void *arg,
-+                               const char *name,
-+                               int cpu)
-+{
-+      struct task_struct *p;
-+      p = kthread_create(f, arg, name);
-+      if (IS_ERR(p))
-+              return PTR_ERR(p);
-+      kthread_bind(p, cpu);
-+      wake_up_process(p);
-+      return 0;
-+}
-+
-+static void __shutdown_handler(void *unused)
-+{
-+      int err;
-+
-+      if (shutting_down != SHUTDOWN_SUSPEND)
-+              err = kernel_thread(shutdown_process, NULL,
-+                                  CLONE_FS | CLONE_FILES);
-+      else
-+              err = kthread_create_on_cpu(xen_suspend, NULL, "suspend", 0);
-+
-+      if (err < 0) {
-+              printk(KERN_WARNING "Error creating shutdown process (%d): "
-+                     "retrying...\n", -err);
-+              schedule_delayed_work(&shutdown_work, HZ/2);
-+      }
-+}
-+
-+static void shutdown_handler(struct xenbus_watch *watch,
-+                           const char **vec, unsigned int len)
-+{
-+      char *str;
-+      struct xenbus_transaction xbt;
-+      int err;
-+
-+      if (shutting_down != SHUTDOWN_INVALID)
-+              return;
-+
-+ again:
-+      err = xenbus_transaction_start(&xbt);
-+      if (err)
-+              return;
-+      str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
-+      /* Ignore read errors and empty reads. */
-+      if (XENBUS_IS_ERR_READ(str)) {
-+              xenbus_transaction_end(xbt, 1);
-+              return;
-+      }
-+
-+      xenbus_write(xbt, "control", "shutdown", "");
-+
-+      err = xenbus_transaction_end(xbt, 0);
-+      if (err == -EAGAIN) {
-+              kfree(str);
-+              goto again;
-+      }
-+
-+      if (strcmp(str, "poweroff") == 0)
-+              shutting_down = SHUTDOWN_POWEROFF;
-+      else if (strcmp(str, "reboot") == 0)
-+              kill_proc(1, SIGINT, 1); /* interrupt init */
-+      else if (strcmp(str, "suspend") == 0)
-+              shutting_down = SHUTDOWN_SUSPEND;
-+      else if (strcmp(str, "halt") == 0)
-+              shutting_down = SHUTDOWN_HALT;
-+      else {
-+              printk("Ignoring shutdown request: %s\n", str);
-+              shutting_down = SHUTDOWN_INVALID;
-+      }
-+
-+      if (shutting_down != SHUTDOWN_INVALID)
-+              schedule_work(&shutdown_work);
-+
-+      kfree(str);
-+}
-+
-+static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
-+                        unsigned int len)
-+{
-+      char sysrq_key = '\0';
-+      struct xenbus_transaction xbt;
-+      int err;
-+
-+ again:
-+      err = xenbus_transaction_start(&xbt);
-+      if (err)
-+              return;
-+      if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
-+              printk(KERN_ERR "Unable to read sysrq code in "
-+                     "control/sysrq\n");
-+              xenbus_transaction_end(xbt, 1);
-+              return;
-+      }
-+
-+      if (sysrq_key != '\0')
-+              xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
-+
-+      err = xenbus_transaction_end(xbt, 0);
-+      if (err == -EAGAIN)
-+              goto again;
-+
-+#ifdef CONFIG_MAGIC_SYSRQ
-+      if (sysrq_key != '\0')
-+              handle_sysrq(sysrq_key, NULL, NULL);
-+#endif
-+}
-+
-+static struct xenbus_watch shutdown_watch = {
-+      .node = "control/shutdown",
-+      .callback = shutdown_handler
-+};
-+
-+static struct xenbus_watch sysrq_watch = {
-+      .node ="control/sysrq",
-+      .callback = sysrq_handler
-+};
-+
-+static int setup_shutdown_watcher(struct notifier_block *notifier,
-+                                unsigned long event,
-+                                void *data)
-+{
-+      int err;
-+
-+      err = register_xenbus_watch(&shutdown_watch);
-+      if (err)
-+              printk(KERN_ERR "Failed to set shutdown watcher\n");
-+      else
-+              xenbus_write(XBT_NIL, "control", "feature-reboot", "1");
-+
-+      err = register_xenbus_watch(&sysrq_watch);
-+      if (err)
-+              printk(KERN_ERR "Failed to set sysrq watcher\n");
-+      else
-+              xenbus_write(XBT_NIL, "control", "feature-sysrq", "1");
-+
-+      return NOTIFY_DONE;
-+}
-+
-+static int __init setup_shutdown_event(void)
-+{
-+      static struct notifier_block xenstore_notifier = {
-+              .notifier_call = setup_shutdown_watcher
-+      };
-+      register_xenstore_notifier(&xenstore_notifier);
-+
-+      return 0;
-+}
-+
-+subsys_initcall(setup_shutdown_event);
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/skbuff.c linux-2.6.16.33/drivers/xen/core/skbuff.c
---- linux-2.6.16.33-noxen/drivers/xen/core/skbuff.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/skbuff.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,145 @@
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/netdevice.h>
-+#include <linux/inetdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/init.h>
-+#include <asm/io.h>
-+#include <asm/page.h>
-+#include <asm/hypervisor.h>
-+
-+/* Referenced in netback.c. */
-+/*static*/ kmem_cache_t *skbuff_cachep;
-+EXPORT_SYMBOL(skbuff_cachep);
-+
-+/* Allow up to 64kB or page-sized packets (whichever is greater). */
-+#if PAGE_SHIFT < 16
-+#define MAX_SKBUFF_ORDER (16 - PAGE_SHIFT)
-+#else
-+#define MAX_SKBUFF_ORDER 0
-+#endif
-+static kmem_cache_t *skbuff_order_cachep[MAX_SKBUFF_ORDER + 1];
-+
-+static struct {
-+      int size;
-+      kmem_cache_t *cachep;
-+} skbuff_small[] = { { 512, NULL }, { 2048, NULL } };
-+
-+struct sk_buff *__alloc_skb(unsigned int length, gfp_t gfp_mask,
-+                          int fclone)
-+{
-+      int order, i;
-+      kmem_cache_t *cachep;
-+
-+      length = SKB_DATA_ALIGN(length) + sizeof(struct skb_shared_info);
-+
-+      if (length <= skbuff_small[ARRAY_SIZE(skbuff_small)-1].size) {
-+              for (i = 0; skbuff_small[i].size < length; i++)
-+                      continue;
-+              cachep = skbuff_small[i].cachep;
-+      } else {
-+              order = get_order(length);
-+              if (order > MAX_SKBUFF_ORDER) {
-+                      printk(KERN_ALERT "Attempt to allocate order %d "
-+                             "skbuff. Increase MAX_SKBUFF_ORDER.\n", order);
-+                      return NULL;
-+              }
-+              cachep = skbuff_order_cachep[order];
-+      }
-+
-+      length -= sizeof(struct skb_shared_info);
-+
-+      return alloc_skb_from_cache(cachep, length, gfp_mask, fclone);
-+}
-+
-+struct sk_buff *__dev_alloc_skb(unsigned int length, gfp_t gfp_mask)
-+{
-+      struct sk_buff *skb;
-+      int order;
-+
-+      length = SKB_DATA_ALIGN(length + 16);
-+      order = get_order(length + sizeof(struct skb_shared_info));
-+      if (order > MAX_SKBUFF_ORDER) {
-+              printk(KERN_ALERT "Attempt to allocate order %d skbuff. "
-+                     "Increase MAX_SKBUFF_ORDER.\n", order);
-+              return NULL;
-+      }
-+
-+      skb = alloc_skb_from_cache(
-+              skbuff_order_cachep[order], length, gfp_mask, 0);
-+      if (skb != NULL)
-+              skb_reserve(skb, 16);
-+
-+      return skb;
-+}
-+
-+static void skbuff_ctor(void *buf, kmem_cache_t *cachep, unsigned long unused)
-+{
-+      int order = 0;
-+
-+      while (skbuff_order_cachep[order] != cachep)
-+              order++;
-+
-+      /* Do our best to allocate contiguous memory but fall back to IOMMU. */
-+      if (order != 0)
-+              (void)xen_create_contiguous_region(
-+                      (unsigned long)buf, order, 0);
-+
-+      scrub_pages(buf, 1 << order);
-+}
-+
-+static void skbuff_dtor(void *buf, kmem_cache_t *cachep, unsigned long unused)
-+{
-+      int order = 0;
-+
-+      while (skbuff_order_cachep[order] != cachep)
-+              order++;
-+
-+      if (order != 0)
-+              xen_destroy_contiguous_region((unsigned long)buf, order);
-+}
-+
-+static int __init skbuff_init(void)
-+{
-+      static char name[MAX_SKBUFF_ORDER + 1][20];
-+      static char small_name[ARRAY_SIZE(skbuff_small)][20];
-+      unsigned long size;
-+      int i, order;
-+
-+      for (i = 0; i < ARRAY_SIZE(skbuff_small); i++) {
-+              size = skbuff_small[i].size;
-+              sprintf(small_name[i], "xen-skb-%lu", size);
-+              /*
-+               * No ctor/dtor: objects do not span page boundaries, and they
-+               * are only used on transmit path so no need for scrubbing.
-+               */
-+              skbuff_small[i].cachep = kmem_cache_create(
-+                      small_name[i], size, size, 0, NULL, NULL);
-+      }
-+
-+      for (order = 0; order <= MAX_SKBUFF_ORDER; order++) {
-+              size = PAGE_SIZE << order;
-+              sprintf(name[order], "xen-skb-%lu", size);
-+              if (is_running_on_xen() && is_initial_xendomain())
-+                      skbuff_order_cachep[order] = kmem_cache_create(
-+                              name[order], size, size, 0,
-+                              skbuff_ctor, skbuff_dtor);
-+              else
-+                      skbuff_order_cachep[order] = kmem_cache_create(
-+                              name[order], size, size, 0, NULL, NULL);
-+                      
-+      }
-+
-+      skbuff_cachep = skbuff_order_cachep[0];
-+
-+      return 0;
-+}
-+core_initcall(skbuff_init);
-+
-+EXPORT_SYMBOL(__dev_alloc_skb);
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/smpboot.c linux-2.6.16.33/drivers/xen/core/smpboot.c
---- linux-2.6.16.33-noxen/drivers/xen/core/smpboot.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/smpboot.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,459 @@
-+/*
-+ *    Xen SMP booting functions
-+ *
-+ *    See arch/i386/kernel/smpboot.c for copyright and credits for derived
-+ *    portions of this file.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/sched.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/smp_lock.h>
-+#include <linux/irq.h>
-+#include <linux/bootmem.h>
-+#include <linux/notifier.h>
-+#include <linux/cpu.h>
-+#include <linux/percpu.h>
-+#include <asm/desc.h>
-+#include <asm/arch_hooks.h>
-+#include <asm/pgalloc.h>
-+#include <xen/evtchn.h>
-+#include <xen/interface/vcpu.h>
-+#include <xen/cpu_hotplug.h>
-+#include <xen/xenbus.h>
-+
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+#include <asm/smp_alt.h>
-+#endif
-+
-+extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *);
-+extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *);
-+
-+extern int local_setup_timer(unsigned int cpu);
-+extern void local_teardown_timer(unsigned int cpu);
-+
-+extern void hypervisor_callback(void);
-+extern void failsafe_callback(void);
-+extern void system_call(void);
-+extern void smp_trap_init(trap_info_t *);
-+
-+/* Number of siblings per CPU package */
-+int smp_num_siblings = 1;
-+int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
-+EXPORT_SYMBOL(phys_proc_id);
-+int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
-+EXPORT_SYMBOL(cpu_core_id);
-+
-+cpumask_t cpu_online_map;
-+EXPORT_SYMBOL(cpu_online_map);
-+cpumask_t cpu_possible_map;
-+EXPORT_SYMBOL(cpu_possible_map);
-+
-+struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-+EXPORT_SYMBOL(cpu_data);
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+DEFINE_PER_CPU(int, cpu_state) = { 0 };
-+#endif
-+
-+static DEFINE_PER_CPU(int, resched_irq);
-+static DEFINE_PER_CPU(int, callfunc_irq);
-+static char resched_name[NR_CPUS][15];
-+static char callfunc_name[NR_CPUS][15];
-+
-+u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
-+
-+void *xquad_portio;
-+
-+cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
-+cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
-+EXPORT_SYMBOL(cpu_core_map);
-+
-+#if defined(__i386__)
-+u8 x86_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = 0xff };
-+EXPORT_SYMBOL(x86_cpu_to_apicid);
-+#elif !defined(CONFIG_X86_IO_APIC)
-+unsigned int maxcpus = NR_CPUS;
-+#endif
-+
-+void __init prefill_possible_map(void)
-+{
-+      int i, rc;
-+
-+      if (!cpus_empty(cpu_possible_map))
-+              return;
-+
-+      for (i = 0; i < NR_CPUS; i++) {
-+              rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
-+              if (rc >= 0)
-+                      cpu_set(i, cpu_possible_map);
-+      }
-+}
-+
-+void __init smp_alloc_memory(void)
-+{
-+}
-+
-+static inline void
-+set_cpu_sibling_map(int cpu)
-+{
-+      phys_proc_id[cpu] = cpu;
-+      cpu_core_id[cpu]  = 0;
-+
-+      cpu_sibling_map[cpu] = cpumask_of_cpu(cpu);
-+      cpu_core_map[cpu]    = cpumask_of_cpu(cpu);
-+
-+      cpu_data[cpu].booted_cores = 1;
-+}
-+
-+static void
-+remove_siblinginfo(int cpu)
-+{
-+      phys_proc_id[cpu] = BAD_APICID;
-+      cpu_core_id[cpu]  = BAD_APICID;
-+
-+      cpus_clear(cpu_sibling_map[cpu]);
-+      cpus_clear(cpu_core_map[cpu]);
-+
-+      cpu_data[cpu].booted_cores = 0;
-+}
-+
-+static int xen_smp_intr_init(unsigned int cpu)
-+{
-+      int rc;
-+
-+      per_cpu(resched_irq, cpu) = per_cpu(callfunc_irq, cpu) = -1;
-+
-+      sprintf(resched_name[cpu], "resched%d", cpu);
-+      rc = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR,
-+                                  cpu,
-+                                  smp_reschedule_interrupt,
-+                                  SA_INTERRUPT,
-+                                  resched_name[cpu],
-+                                  NULL);
-+      if (rc < 0)
-+              goto fail;
-+      per_cpu(resched_irq, cpu) = rc;
-+
-+      sprintf(callfunc_name[cpu], "callfunc%d", cpu);
-+      rc = bind_ipi_to_irqhandler(CALL_FUNCTION_VECTOR,
-+                                  cpu,
-+                                  smp_call_function_interrupt,
-+                                  SA_INTERRUPT,
-+                                  callfunc_name[cpu],
-+                                  NULL);
-+      if (rc < 0)
-+              goto fail;
-+      per_cpu(callfunc_irq, cpu) = rc;
-+
-+      if ((cpu != 0) && ((rc = local_setup_timer(cpu)) != 0))
-+              goto fail;
-+
-+      return 0;
-+
-+ fail:
-+      if (per_cpu(resched_irq, cpu) >= 0)
-+              unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
-+      if (per_cpu(callfunc_irq, cpu) >= 0)
-+              unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
-+      return rc;
-+}
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+static void xen_smp_intr_exit(unsigned int cpu)
-+{
-+      if (cpu != 0)
-+              local_teardown_timer(cpu);
-+
-+      unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
-+      unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
-+}
-+#endif
-+
-+void cpu_bringup(void)
-+{
-+      cpu_init();
-+      touch_softlockup_watchdog();
-+      preempt_disable();
-+      local_irq_enable();
-+}
-+
-+static void cpu_bringup_and_idle(void)
-+{
-+      cpu_bringup();
-+      cpu_idle();
-+}
-+
-+void cpu_initialize_context(unsigned int cpu)
-+{
-+      vcpu_guest_context_t ctxt;
-+      struct task_struct *idle = idle_task(cpu);
-+#ifdef __x86_64__
-+      struct desc_ptr *gdt_descr = &cpu_gdt_descr[cpu];
-+#else
-+      struct Xgt_desc_struct *gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
-+#endif
-+
-+      if (cpu == 0)
-+              return;
-+
-+      memset(&ctxt, 0, sizeof(ctxt));
-+
-+      ctxt.flags = VGCF_IN_KERNEL;
-+      ctxt.user_regs.ds = __USER_DS;
-+      ctxt.user_regs.es = __USER_DS;
-+      ctxt.user_regs.fs = 0;
-+      ctxt.user_regs.gs = 0;
-+      ctxt.user_regs.ss = __KERNEL_DS;
-+      ctxt.user_regs.eip = (unsigned long)cpu_bringup_and_idle;
-+      ctxt.user_regs.eflags = X86_EFLAGS_IF | 0x1000; /* IOPL_RING1 */
-+
-+      memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
-+
-+      smp_trap_init(ctxt.trap_ctxt);
-+
-+      ctxt.ldt_ents = 0;
-+
-+      ctxt.gdt_frames[0] = virt_to_mfn(gdt_descr->address);
-+      ctxt.gdt_ents      = gdt_descr->size / 8;
-+
-+#ifdef __i386__
-+      ctxt.user_regs.cs = __KERNEL_CS;
-+      ctxt.user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
-+
-+      ctxt.kernel_ss = __KERNEL_DS;
-+      ctxt.kernel_sp = idle->thread.esp0;
-+
-+      ctxt.event_callback_cs     = __KERNEL_CS;
-+      ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
-+      ctxt.failsafe_callback_cs  = __KERNEL_CS;
-+      ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
-+
-+      ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
-+#else /* __x86_64__ */
-+      ctxt.user_regs.cs = __KERNEL_CS;
-+      ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs);
-+
-+      ctxt.kernel_ss = __KERNEL_DS;
-+      ctxt.kernel_sp = idle->thread.rsp0;
-+
-+      ctxt.event_callback_eip    = (unsigned long)hypervisor_callback;
-+      ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
-+      ctxt.syscall_callback_eip  = (unsigned long)system_call;
-+
-+      ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt));
-+
-+      ctxt.gs_base_kernel = (unsigned long)(cpu_pda(cpu));
-+#endif
-+
-+      BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, &ctxt));
-+}
-+
-+void __init smp_prepare_cpus(unsigned int max_cpus)
-+{
-+      int cpu;
-+      struct task_struct *idle;
-+#ifdef __x86_64__
-+      struct desc_ptr *gdt_descr;
-+#else
-+      struct Xgt_desc_struct *gdt_descr;
-+#endif
-+
-+      boot_cpu_data.apicid = 0;
-+      cpu_data[0] = boot_cpu_data;
-+
-+      cpu_2_logical_apicid[0] = 0;
-+      x86_cpu_to_apicid[0] = 0;
-+
-+      current_thread_info()->cpu = 0;
-+
-+      for (cpu = 0; cpu < NR_CPUS; cpu++) {
-+              cpus_clear(cpu_sibling_map[cpu]);
-+              cpus_clear(cpu_core_map[cpu]);
-+      }
-+
-+      set_cpu_sibling_map(0);
-+
-+      if (xen_smp_intr_init(0))
-+              BUG();
-+
-+      /* Restrict the possible_map according to max_cpus. */
-+      while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) {
-+              for (cpu = NR_CPUS-1; !cpu_isset(cpu, cpu_possible_map); cpu--)
-+                      continue;
-+              cpu_clear(cpu, cpu_possible_map);
-+      }
-+
-+      for_each_cpu (cpu) {
-+              if (cpu == 0)
-+                      continue;
-+
-+#ifdef __x86_64__
-+              gdt_descr = &cpu_gdt_descr[cpu];
-+#else
-+              gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
-+#endif
-+              gdt_descr->address = get_zeroed_page(GFP_KERNEL);
-+              if (unlikely(!gdt_descr->address)) {
-+                      printk(KERN_CRIT "CPU%d failed to allocate GDT\n",
-+                             cpu);
-+                      continue;
-+              }
-+              gdt_descr->size = GDT_SIZE;
-+              memcpy((void *)gdt_descr->address, cpu_gdt_table, GDT_SIZE);
-+              make_page_readonly(
-+                      (void *)gdt_descr->address,
-+                      XENFEAT_writable_descriptor_tables);
-+
-+              cpu_data[cpu] = boot_cpu_data;
-+              cpu_data[cpu].apicid = cpu;
-+
-+              cpu_2_logical_apicid[cpu] = cpu;
-+              x86_cpu_to_apicid[cpu] = cpu;
-+
-+              idle = fork_idle(cpu);
-+              if (IS_ERR(idle))
-+                      panic("failed fork for CPU %d", cpu);
-+
-+#ifdef __x86_64__
-+              cpu_pda(cpu)->pcurrent = idle;
-+              cpu_pda(cpu)->cpunumber = cpu;
-+              clear_ti_thread_flag(idle->thread_info, TIF_FORK);
-+#endif
-+
-+              irq_ctx_init(cpu);
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+              if (is_initial_xendomain())
-+                      cpu_set(cpu, cpu_present_map);
-+#else
-+              cpu_set(cpu, cpu_present_map);
-+#endif
-+
-+              cpu_initialize_context(cpu);
-+      }
-+
-+      init_xenbus_allowed_cpumask();
-+
-+#ifdef CONFIG_X86_IO_APIC
-+      /*
-+       * Here we can be sure that there is an IO-APIC in the system. Let's
-+       * go and set it up:
-+       */
-+      if (!skip_ioapic_setup && nr_ioapics)
-+              setup_IO_APIC();
-+#endif
-+}
-+
-+void __devinit smp_prepare_boot_cpu(void)
-+{
-+      prefill_possible_map();
-+      cpu_present_map  = cpumask_of_cpu(0);
-+      cpu_online_map   = cpumask_of_cpu(0);
-+}
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+
-+/*
-+ * Initialize cpu_present_map late to skip SMP boot code in init/main.c.
-+ * But do it early enough to catch critical for_each_present_cpu() loops
-+ * in i386-specific code.
-+ */
-+static int __init initialize_cpu_present_map(void)
-+{
-+      cpu_present_map = cpu_possible_map;
-+      return 0;
-+}
-+core_initcall(initialize_cpu_present_map);
-+
-+int __cpu_disable(void)
-+{
-+      cpumask_t map = cpu_online_map;
-+      int cpu = smp_processor_id();
-+
-+      if (cpu == 0)
-+              return -EBUSY;
-+
-+      remove_siblinginfo(cpu);
-+
-+      cpu_clear(cpu, map);
-+      fixup_irqs(map);
-+      cpu_clear(cpu, cpu_online_map);
-+
-+      return 0;
-+}
-+
-+void __cpu_die(unsigned int cpu)
-+{
-+      while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) {
-+              current->state = TASK_UNINTERRUPTIBLE;
-+              schedule_timeout(HZ/10);
-+      }
-+
-+      xen_smp_intr_exit(cpu);
-+
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+      if (num_online_cpus() == 1)
-+              unprepare_for_smp();
-+#endif
-+}
-+
-+#else /* !CONFIG_HOTPLUG_CPU */
-+
-+int __cpu_disable(void)
-+{
-+      return -ENOSYS;
-+}
-+
-+void __cpu_die(unsigned int cpu)
-+{
-+      BUG();
-+}
-+
-+#endif /* CONFIG_HOTPLUG_CPU */
-+
-+int __devinit __cpu_up(unsigned int cpu)
-+{
-+      int rc;
-+
-+      rc = cpu_up_check(cpu);
-+      if (rc)
-+              return rc;
-+
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+      if (num_online_cpus() == 1)
-+              prepare_for_smp();
-+#endif
-+
-+      /* This must be done before setting cpu_online_map */
-+      set_cpu_sibling_map(cpu);
-+      wmb();
-+
-+      rc = xen_smp_intr_init(cpu);
-+      if (rc) {
-+              remove_siblinginfo(cpu);
-+              return rc;
-+      }
-+
-+      cpu_set(cpu, cpu_online_map);
-+
-+      rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
-+      BUG_ON(rc);
-+
-+      return 0;
-+}
-+
-+void __init smp_cpus_done(unsigned int max_cpus)
-+{
-+}
-+
-+#ifndef CONFIG_X86_LOCAL_APIC
-+int setup_profiling_timer(unsigned int multiplier)
-+{
-+      return -EINVAL;
-+}
-+#endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/xen_proc.c linux-2.6.16.33/drivers/xen/core/xen_proc.c
---- linux-2.6.16.33-noxen/drivers/xen/core/xen_proc.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/xen_proc.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,19 @@
-+
-+#include <linux/config.h>
-+#include <linux/proc_fs.h>
-+#include <xen/xen_proc.h>
-+
-+static struct proc_dir_entry *xen_base;
-+
-+struct proc_dir_entry *create_xen_proc_entry(const char *name, mode_t mode)
-+{
-+      if ( xen_base == NULL )
-+              if ( (xen_base = proc_mkdir("xen", &proc_root)) == NULL )
-+                      panic("Couldn't create /proc/xen");
-+      return create_proc_entry(name, mode, xen_base);
-+}
-+
-+void remove_xen_proc_entry(const char *name)
-+{
-+      remove_proc_entry(name, xen_base);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/core/xen_sysfs.c linux-2.6.16.33/drivers/xen/core/xen_sysfs.c
---- linux-2.6.16.33-noxen/drivers/xen/core/xen_sysfs.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/core/xen_sysfs.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,379 @@
-+/*
-+ *  copyright (c) 2006 IBM Corporation
-+ *  Authored by: Mike D. Day <ncmike@us.ibm.com>
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License version 2 as
-+ *  published by the Free Software Foundation.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/err.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <asm/hypervisor.h>
-+#include <xen/features.h>
-+#include <xen/hypervisor_sysfs.h>
-+#include <xen/xenbus.h>
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Mike D. Day <ncmike@us.ibm.com>");
-+
-+static ssize_t type_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      return sprintf(buffer, "xen\n");
-+}
-+
-+HYPERVISOR_ATTR_RO(type);
-+
-+static int __init xen_sysfs_type_init(void)
-+{
-+      return sysfs_create_file(&hypervisor_subsys.kset.kobj, &type_attr.attr);
-+}
-+
-+static void xen_sysfs_type_destroy(void)
-+{
-+      sysfs_remove_file(&hypervisor_subsys.kset.kobj, &type_attr.attr);
-+}
-+
-+/* xen version attributes */
-+static ssize_t major_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int version = HYPERVISOR_xen_version(XENVER_version, NULL);
-+      if (version)
-+              return sprintf(buffer, "%d\n", version >> 16);
-+      return -ENODEV;
-+}
-+
-+HYPERVISOR_ATTR_RO(major);
-+
-+static ssize_t minor_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int version = HYPERVISOR_xen_version(XENVER_version, NULL);
-+      if (version)
-+              return sprintf(buffer, "%d\n", version & 0xff);
-+      return -ENODEV;
-+}
-+
-+HYPERVISOR_ATTR_RO(minor);
-+
-+static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int ret = -ENOMEM;
-+      char *extra;
-+
-+      extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
-+      if (extra) {
-+              ret = HYPERVISOR_xen_version(XENVER_extraversion, extra);
-+              if (!ret)
-+                      ret = sprintf(buffer, "%s\n", extra);
-+              kfree(extra);
-+      }
-+
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(extra);
-+
-+static struct attribute *version_attrs[] = {
-+      &major_attr.attr,
-+      &minor_attr.attr,
-+      &extra_attr.attr,
-+      NULL
-+};
-+
-+static struct attribute_group version_group = {
-+      .name = "version",
-+      .attrs = version_attrs,
-+};
-+
-+static int __init xen_sysfs_version_init(void)
-+{
-+      return sysfs_create_group(&hypervisor_subsys.kset.kobj,
-+                                &version_group);
-+}
-+
-+static void xen_sysfs_version_destroy(void)
-+{
-+      sysfs_remove_group(&hypervisor_subsys.kset.kobj, &version_group);
-+}
-+
-+/* UUID */
-+
-+static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      char *vm, *val;
-+      int ret;
-+
-+      vm = xenbus_read(XBT_NIL, "vm", "", NULL);
-+      if (IS_ERR(vm))
-+              return PTR_ERR(vm);
-+      val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
-+      kfree(vm);
-+      if (IS_ERR(val))
-+              return PTR_ERR(val);
-+      ret = sprintf(buffer, "%s\n", val);
-+      kfree(val);
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(uuid);
-+
-+static int __init xen_sysfs_uuid_init(void)
-+{
-+      return sysfs_create_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
-+}
-+
-+static void xen_sysfs_uuid_destroy(void)
-+{
-+      sysfs_remove_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
-+}
-+
-+/* xen compilation attributes */
-+
-+static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int ret = -ENOMEM;
-+      struct xen_compile_info *info;
-+
-+      info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
-+      if (info) {
-+              ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
-+              if (!ret)
-+                      ret = sprintf(buffer, "%s\n", info->compiler);
-+              kfree(info);
-+      }
-+
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(compiler);
-+
-+static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int ret = -ENOMEM;
-+      struct xen_compile_info *info;
-+
-+      info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
-+      if (info) {
-+              ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
-+              if (!ret)
-+                      ret = sprintf(buffer, "%s\n", info->compile_by);
-+              kfree(info);
-+      }
-+
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(compiled_by);
-+
-+static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int ret = -ENOMEM;
-+      struct xen_compile_info *info;
-+
-+      info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
-+      if (info) {
-+              ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
-+              if (!ret)
-+                      ret = sprintf(buffer, "%s\n", info->compile_date);
-+              kfree(info);
-+      }
-+
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(compile_date);
-+
-+static struct attribute *xen_compile_attrs[] = {
-+      &compiler_attr.attr,
-+      &compiled_by_attr.attr,
-+      &compile_date_attr.attr,
-+      NULL
-+};
-+
-+static struct attribute_group xen_compilation_group = {
-+      .name = "compilation",
-+      .attrs = xen_compile_attrs,
-+};
-+
-+int __init static xen_compilation_init(void)
-+{
-+      return sysfs_create_group(&hypervisor_subsys.kset.kobj,
-+                                &xen_compilation_group);
-+}
-+
-+static void xen_compilation_destroy(void)
-+{
-+      sysfs_remove_group(&hypervisor_subsys.kset.kobj,
-+                         &xen_compilation_group);
-+}
-+
-+/* xen properties info */
-+
-+static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int ret = -ENOMEM;
-+      char *caps;
-+
-+      caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
-+      if (caps) {
-+              ret = HYPERVISOR_xen_version(XENVER_capabilities, caps);
-+              if (!ret)
-+                      ret = sprintf(buffer, "%s\n", caps);
-+              kfree(caps);
-+      }
-+
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(capabilities);
-+
-+static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int ret = -ENOMEM;
-+      char *cset;
-+
-+      cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
-+      if (cset) {
-+              ret = HYPERVISOR_xen_version(XENVER_changeset, cset);
-+              if (!ret)
-+                      ret = sprintf(buffer, "%s\n", cset);
-+              kfree(cset);
-+      }
-+
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(changeset);
-+
-+static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int ret = -ENOMEM;
-+      struct xen_platform_parameters *parms;
-+
-+      parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
-+      if (parms) {
-+              ret = HYPERVISOR_xen_version(XENVER_platform_parameters,
-+                                           parms);
-+              if (!ret)
-+                      ret = sprintf(buffer, "%lx\n", parms->virt_start);
-+              kfree(parms);
-+      }
-+
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(virtual_start);
-+
-+static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      int ret;
-+
-+      ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL);
-+      if (ret > 0)
-+              ret = sprintf(buffer, "%x\n", ret);
-+
-+      return ret;
-+}
-+
-+HYPERVISOR_ATTR_RO(pagesize);
-+
-+/* eventually there will be several more features to export */
-+static ssize_t xen_feature_show(int index, char *buffer)
-+{
-+      int ret = -ENOMEM;
-+      struct xen_feature_info *info;
-+
-+      info = kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
-+      if (info) {
-+              info->submap_idx = index;
-+              ret = HYPERVISOR_xen_version(XENVER_get_features, info);
-+              if (!ret)
-+                      ret = sprintf(buffer, "%d\n", info->submap);
-+              kfree(info);
-+      }
-+
-+      return ret;
-+}
-+
-+static ssize_t writable_pt_show(struct hyp_sysfs_attr *attr, char *buffer)
-+{
-+      return xen_feature_show(XENFEAT_writable_page_tables, buffer);
-+}
-+
-+HYPERVISOR_ATTR_RO(writable_pt);
-+
-+static struct attribute *xen_properties_attrs[] = {
-+      &capabilities_attr.attr,
-+      &changeset_attr.attr,
-+      &virtual_start_attr.attr,
-+      &pagesize_attr.attr,
-+      &writable_pt_attr.attr,
-+      NULL
-+};
-+
-+static struct attribute_group xen_properties_group = {
-+      .name = "properties",
-+      .attrs = xen_properties_attrs,
-+};
-+
-+static int __init xen_properties_init(void)
-+{
-+      return sysfs_create_group(&hypervisor_subsys.kset.kobj,
-+                                &xen_properties_group);
-+}
-+
-+static void xen_properties_destroy(void)
-+{
-+      sysfs_remove_group(&hypervisor_subsys.kset.kobj,
-+                         &xen_properties_group);
-+}
-+
-+static int __init hyper_sysfs_init(void)
-+{
-+      int ret;
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      ret = xen_sysfs_type_init();
-+      if (ret)
-+              goto out;
-+      ret = xen_sysfs_version_init();
-+      if (ret)
-+              goto version_out;
-+      ret = xen_compilation_init();
-+      if (ret)
-+              goto comp_out;
-+      ret = xen_sysfs_uuid_init();
-+      if (ret)
-+              goto uuid_out;
-+      ret = xen_properties_init();
-+      if (!ret)
-+              goto out;
-+
-+      xen_sysfs_uuid_destroy();
-+uuid_out:
-+      xen_compilation_destroy();
-+comp_out:
-+      xen_sysfs_version_destroy();
-+version_out:
-+      xen_sysfs_type_destroy();
-+out:
-+      return ret;
-+}
-+
-+static void hyper_sysfs_exit(void)
-+{
-+      xen_properties_destroy();
-+      xen_compilation_destroy();
-+      xen_sysfs_uuid_destroy();
-+      xen_sysfs_version_destroy();
-+      xen_sysfs_type_destroy();
-+
-+}
-+
-+module_init(hyper_sysfs_init);
-+module_exit(hyper_sysfs_exit);
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/evtchn/Makefile linux-2.6.16.33/drivers/xen/evtchn/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/evtchn/Makefile  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/evtchn/Makefile        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2 @@
-+
-+obj-y := evtchn.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/evtchn/evtchn.c linux-2.6.16.33/drivers/xen/evtchn/evtchn.c
---- linux-2.6.16.33-noxen/drivers/xen/evtchn/evtchn.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/evtchn/evtchn.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,457 @@
-+/******************************************************************************
-+ * evtchn.c
-+ * 
-+ * Driver for receiving and demuxing event-channel signals.
-+ * 
-+ * Copyright (c) 2004-2005, K A Fraser
-+ * Multi-process extensions Copyright (c) 2004, Steven Smith
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/fs.h>
-+#include <linux/errno.h>
-+#include <linux/miscdevice.h>
-+#include <linux/major.h>
-+#include <linux/proc_fs.h>
-+#include <linux/stat.h>
-+#include <linux/poll.h>
-+#include <linux/irq.h>
-+#include <linux/init.h>
-+#include <linux/gfp.h>
-+#include <xen/evtchn.h>
-+#include <xen/public/evtchn.h>
-+
-+struct per_user_data {
-+      /* Notification ring, accessed via /dev/xen/evtchn. */
-+#define EVTCHN_RING_SIZE     (PAGE_SIZE / sizeof(evtchn_port_t))
-+#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
-+      evtchn_port_t *ring;
-+      unsigned int ring_cons, ring_prod, ring_overflow;
-+
-+      /* Processes wait on this queue when ring is empty. */
-+      wait_queue_head_t evtchn_wait;
-+      struct fasync_struct *evtchn_async_queue;
-+};
-+
-+/* Who's bound to each port? */
-+static struct per_user_data *port_user[NR_EVENT_CHANNELS];
-+static spinlock_t port_user_lock;
-+
-+void evtchn_device_upcall(int port)
-+{
-+      struct per_user_data *u;
-+
-+      spin_lock(&port_user_lock);
-+
-+      mask_evtchn(port);
-+      clear_evtchn(port);
-+
-+      if ((u = port_user[port]) != NULL) {
-+              if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
-+                      u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
-+                      if (u->ring_cons == u->ring_prod++) {
-+                              wake_up_interruptible(&u->evtchn_wait);
-+                              kill_fasync(&u->evtchn_async_queue,
-+                                          SIGIO, POLL_IN);
-+                      }
-+              } else {
-+                      u->ring_overflow = 1;
-+              }
-+      }
-+
-+      spin_unlock(&port_user_lock);
-+}
-+
-+static ssize_t evtchn_read(struct file *file, char __user *buf,
-+                         size_t count, loff_t *ppos)
-+{
-+      int rc;
-+      unsigned int c, p, bytes1 = 0, bytes2 = 0;
-+      struct per_user_data *u = file->private_data;
-+
-+      /* Whole number of ports. */
-+      count &= ~(sizeof(evtchn_port_t)-1);
-+
-+      if (count == 0)
-+              return 0;
-+
-+      if (count > PAGE_SIZE)
-+              count = PAGE_SIZE;
-+
-+      for (;;) {
-+              if (u->ring_overflow)
-+                      return -EFBIG;
-+
-+              if ((c = u->ring_cons) != (p = u->ring_prod))
-+                      break;
-+
-+              if (file->f_flags & O_NONBLOCK)
-+                      return -EAGAIN;
-+
-+              rc = wait_event_interruptible(
-+                      u->evtchn_wait, u->ring_cons != u->ring_prod);
-+              if (rc)
-+                      return rc;
-+      }
-+
-+      /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
-+      if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
-+              bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
-+                      sizeof(evtchn_port_t);
-+              bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
-+      } else {
-+              bytes1 = (p - c) * sizeof(evtchn_port_t);
-+              bytes2 = 0;
-+      }
-+
-+      /* Truncate chunks according to caller's maximum byte count. */
-+      if (bytes1 > count) {
-+              bytes1 = count;
-+              bytes2 = 0;
-+      } else if ((bytes1 + bytes2) > count) {
-+              bytes2 = count - bytes1;
-+      }
-+
-+      if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
-+          ((bytes2 != 0) &&
-+           copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
-+              return -EFAULT;
-+
-+      u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
-+
-+      return bytes1 + bytes2;
-+}
-+
-+static ssize_t evtchn_write(struct file *file, const char __user *buf,
-+                          size_t count, loff_t *ppos)
-+{
-+      int  rc, i;
-+      evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
-+      struct per_user_data *u = file->private_data;
-+
-+      if (kbuf == NULL)
-+              return -ENOMEM;
-+
-+      /* Whole number of ports. */
-+      count &= ~(sizeof(evtchn_port_t)-1);
-+
-+      if (count == 0) {
-+              rc = 0;
-+              goto out;
-+      }
-+
-+      if (count > PAGE_SIZE)
-+              count = PAGE_SIZE;
-+
-+      if (copy_from_user(kbuf, buf, count) != 0) {
-+              rc = -EFAULT;
-+              goto out;
-+      }
-+
-+      spin_lock_irq(&port_user_lock);
-+      for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
-+              if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
-+                      unmask_evtchn(kbuf[i]);
-+      spin_unlock_irq(&port_user_lock);
-+
-+      rc = count;
-+
-+ out:
-+      free_page((unsigned long)kbuf);
-+      return rc;
-+}
-+
-+static void evtchn_bind_to_user(struct per_user_data *u, int port)
-+{
-+      spin_lock_irq(&port_user_lock);
-+      BUG_ON(port_user[port] != NULL);
-+      port_user[port] = u;
-+      unmask_evtchn(port);
-+      spin_unlock_irq(&port_user_lock);
-+}
-+
-+static int evtchn_ioctl(struct inode *inode, struct file *file,
-+                      unsigned int cmd, unsigned long arg)
-+{
-+      int rc;
-+      struct per_user_data *u = file->private_data;
-+      void __user *uarg = (void __user *) arg;
-+
-+      switch (cmd) {
-+      case IOCTL_EVTCHN_BIND_VIRQ: {
-+              struct ioctl_evtchn_bind_virq bind;
-+              struct evtchn_bind_virq bind_virq;
-+
-+              rc = -EFAULT;
-+              if (copy_from_user(&bind, uarg, sizeof(bind)))
-+                      break;
-+
-+              bind_virq.virq = bind.virq;
-+              bind_virq.vcpu = 0;
-+              rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
-+                                               &bind_virq);
-+              if (rc != 0)
-+                      break;
-+
-+              rc = bind_virq.port;
-+              evtchn_bind_to_user(u, rc);
-+              break;
-+      }
-+
-+      case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
-+              struct ioctl_evtchn_bind_interdomain bind;
-+              struct evtchn_bind_interdomain bind_interdomain;
-+
-+              rc = -EFAULT;
-+              if (copy_from_user(&bind, uarg, sizeof(bind)))
-+                      break;
-+
-+              bind_interdomain.remote_dom  = bind.remote_domain;
-+              bind_interdomain.remote_port = bind.remote_port;
-+              rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-+                                               &bind_interdomain);
-+              if (rc != 0)
-+                      break;
-+
-+              rc = bind_interdomain.local_port;
-+              evtchn_bind_to_user(u, rc);
-+              break;
-+      }
-+
-+      case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
-+              struct ioctl_evtchn_bind_unbound_port bind;
-+              struct evtchn_alloc_unbound alloc_unbound;
-+
-+              rc = -EFAULT;
-+              if (copy_from_user(&bind, uarg, sizeof(bind)))
-+                      break;
-+
-+              alloc_unbound.dom        = DOMID_SELF;
-+              alloc_unbound.remote_dom = bind.remote_domain;
-+              rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
-+                                               &alloc_unbound);
-+              if (rc != 0)
-+                      break;
-+
-+              rc = alloc_unbound.port;
-+              evtchn_bind_to_user(u, rc);
-+              break;
-+      }
-+
-+      case IOCTL_EVTCHN_UNBIND: {
-+              struct ioctl_evtchn_unbind unbind;
-+              struct evtchn_close close;
-+              int ret;
-+
-+              rc = -EFAULT;
-+              if (copy_from_user(&unbind, uarg, sizeof(unbind)))
-+                      break;
-+
-+              rc = -EINVAL;
-+              if (unbind.port >= NR_EVENT_CHANNELS)
-+                      break;
-+
-+              spin_lock_irq(&port_user_lock);
-+    
-+              rc = -ENOTCONN;
-+              if (port_user[unbind.port] != u) {
-+                      spin_unlock_irq(&port_user_lock);
-+                      break;
-+              }
-+
-+              port_user[unbind.port] = NULL;
-+              mask_evtchn(unbind.port);
-+
-+              spin_unlock_irq(&port_user_lock);
-+
-+              close.port = unbind.port;
-+              ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
-+              BUG_ON(ret);
-+
-+              rc = 0;
-+              break;
-+      }
-+
-+      case IOCTL_EVTCHN_NOTIFY: {
-+              struct ioctl_evtchn_notify notify;
-+
-+              rc = -EFAULT;
-+              if (copy_from_user(&notify, uarg, sizeof(notify)))
-+                      break;
-+
-+              if (notify.port >= NR_EVENT_CHANNELS) {
-+                      rc = -EINVAL;
-+              } else if (port_user[notify.port] != u) {
-+                      rc = -ENOTCONN;
-+              } else {
-+                      notify_remote_via_evtchn(notify.port);
-+                      rc = 0;
-+              }
-+              break;
-+      }
-+
-+      case IOCTL_EVTCHN_RESET: {
-+              /* Initialise the ring to empty. Clear errors. */
-+              spin_lock_irq(&port_user_lock);
-+              u->ring_cons = u->ring_prod = u->ring_overflow = 0;
-+              spin_unlock_irq(&port_user_lock);
-+              rc = 0;
-+              break;
-+      }
-+
-+      default:
-+              rc = -ENOSYS;
-+              break;
-+      }
-+
-+      return rc;
-+}
-+
-+static unsigned int evtchn_poll(struct file *file, poll_table *wait)
-+{
-+      unsigned int mask = POLLOUT | POLLWRNORM;
-+      struct per_user_data *u = file->private_data;
-+
-+      poll_wait(file, &u->evtchn_wait, wait);
-+      if (u->ring_cons != u->ring_prod)
-+              mask |= POLLIN | POLLRDNORM;
-+      if (u->ring_overflow)
-+              mask = POLLERR;
-+      return mask;
-+}
-+
-+static int evtchn_fasync(int fd, struct file *filp, int on)
-+{
-+      struct per_user_data *u = filp->private_data;
-+      return fasync_helper(fd, filp, on, &u->evtchn_async_queue);
-+}
-+
-+static int evtchn_open(struct inode *inode, struct file *filp)
-+{
-+      struct per_user_data *u;
-+
-+      if ((u = kmalloc(sizeof(*u), GFP_KERNEL)) == NULL)
-+              return -ENOMEM;
-+
-+      memset(u, 0, sizeof(*u));
-+      init_waitqueue_head(&u->evtchn_wait);
-+
-+      u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
-+      if (u->ring == NULL) {
-+              kfree(u);
-+              return -ENOMEM;
-+      }
-+
-+      filp->private_data = u;
-+
-+      return 0;
-+}
-+
-+static int evtchn_release(struct inode *inode, struct file *filp)
-+{
-+      int i;
-+      struct per_user_data *u = filp->private_data;
-+      struct evtchn_close close;
-+
-+      spin_lock_irq(&port_user_lock);
-+
-+      free_page((unsigned long)u->ring);
-+
-+      for (i = 0; i < NR_EVENT_CHANNELS; i++) {
-+              int ret;
-+              if (port_user[i] != u)
-+                      continue;
-+
-+              port_user[i] = NULL;
-+              mask_evtchn(i);
-+
-+              close.port = i;
-+              ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
-+              BUG_ON(ret);
-+      }
-+
-+      spin_unlock_irq(&port_user_lock);
-+
-+      kfree(u);
-+
-+      return 0;
-+}
-+
-+static struct file_operations evtchn_fops = {
-+      .owner   = THIS_MODULE,
-+      .read    = evtchn_read,
-+      .write   = evtchn_write,
-+      .ioctl   = evtchn_ioctl,
-+      .poll    = evtchn_poll,
-+      .fasync  = evtchn_fasync,
-+      .open    = evtchn_open,
-+      .release = evtchn_release,
-+};
-+
-+static struct miscdevice evtchn_miscdev = {
-+      .minor        = MISC_DYNAMIC_MINOR,
-+      .name         = "evtchn",
-+      .fops         = &evtchn_fops,
-+};
-+
-+static int __init evtchn_init(void)
-+{
-+      int err;
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      spin_lock_init(&port_user_lock);
-+      memset(port_user, 0, sizeof(port_user));
-+
-+      /* Create '/dev/misc/evtchn'. */
-+      err = misc_register(&evtchn_miscdev);
-+      if (err != 0) {
-+              printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
-+              return err;
-+      }
-+
-+      printk("Event-channel device installed.\n");
-+
-+      return 0;
-+}
-+
-+static void evtchn_cleanup(void)
-+{
-+      misc_deregister(&evtchn_miscdev);
-+}
-+
-+module_init(evtchn_init);
-+module_exit(evtchn_cleanup);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/fbfront/Makefile linux-2.6.16.33/drivers/xen/fbfront/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/fbfront/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/fbfront/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_XEN_FRAMEBUFFER) := xenfb.o
-+obj-$(CONFIG_XEN_KEYBOARD)    += xenkbd.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/fbfront/xenfb.c linux-2.6.16.33/drivers/xen/fbfront/xenfb.c
---- linux-2.6.16.33-noxen/drivers/xen/fbfront/xenfb.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/fbfront/xenfb.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,750 @@
-+/*
-+ * linux/drivers/video/xenfb.c -- Xen para-virtual frame buffer device
-+ *
-+ * Copyright (C) 2005-2006 Anthony Liguori <aliguori@us.ibm.com>
-+ * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
-+ *
-+ *  Based on linux/drivers/video/q40fb.c
-+ *
-+ *  This file is subject to the terms and conditions of the GNU General Public
-+ *  License. See the file COPYING in the main directory of this archive for
-+ *  more details.
-+ */
-+
-+/*
-+ * TODO:
-+ *
-+ * Switch to grant tables when they become capable of dealing with the
-+ * frame buffer.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/fb.h>
-+#include <linux/module.h>
-+#include <linux/vmalloc.h>
-+#include <linux/mm.h>
-+#include <asm/hypervisor.h>
-+#include <xen/evtchn.h>
-+#include <xen/interface/io/fbif.h>
-+#include <xen/xenbus.h>
-+#include <linux/kthread.h>
-+
-+struct xenfb_mapping
-+{
-+      struct list_head        link;
-+      struct vm_area_struct   *vma;
-+      atomic_t                map_refs;
-+      int                     faults;
-+      struct xenfb_info       *info;
-+};
-+
-+struct xenfb_info
-+{
-+      struct task_struct      *kthread;
-+      wait_queue_head_t       wq;
-+
-+      unsigned char           *fb;
-+      struct fb_info          *fb_info;
-+      struct timer_list       refresh;
-+      int                     dirty;
-+      int                     x1, y1, x2, y2; /* dirty rectangle,
-+                                                 protected by dirty_lock */
-+      spinlock_t              dirty_lock;
-+      struct mutex            mm_lock;
-+      int                     nr_pages;
-+      struct page             **pages;
-+      struct list_head        mappings; /* protected by mm_lock */
-+
-+      unsigned                evtchn;
-+      int                     irq;
-+      struct xenfb_page       *page;
-+      unsigned long           *mfns;
-+      int                     update_wanted; /* XENFB_TYPE_UPDATE wanted */
-+
-+      struct xenbus_device    *xbdev;
-+};
-+
-+/*
-+ * How the locks work together
-+ *
-+ * There are two locks: spinlock dirty_lock protecting the dirty
-+ * rectangle, and mutex mm_lock protecting mappings.
-+ *
-+ * The problem is that dirty rectangle and mappings aren't
-+ * independent: the dirty rectangle must cover all faulted pages in
-+ * mappings.  We need to prove that our locking maintains this
-+ * invariant.
-+ *
-+ * There are several kinds of critical regions:
-+ *
-+ * 1. Holding only dirty_lock: xenfb_refresh().  May run in
-+ *    interrupts.  Extends the dirty rectangle.  Trivially preserves
-+ *    invariant.
-+ *
-+ * 2. Holding only mm_lock: xenfb_mmap() and xenfb_vm_close().  Touch
-+ *    only mappings.  The former creates unfaulted pages.  Preserves
-+ *    invariant.  The latter removes pages.  Preserves invariant.
-+ *
-+ * 3. Holding both locks: xenfb_vm_nopage().  Extends the dirty
-+ *    rectangle and updates mappings consistently.  Preserves
-+ *    invariant.
-+ *
-+ * 4. The ugliest one: xenfb_update_screen().  Clear the dirty
-+ *    rectangle and update mappings consistently.
-+ *
-+ *    We can't simply hold both locks, because zap_page_range() cannot
-+ *    be called with a spinlock held.
-+ *
-+ *    Therefore, we first clear the dirty rectangle with both locks
-+ *    held.  Then we unlock dirty_lock and update the mappings.
-+ *    Critical regions that hold only dirty_lock may interfere with
-+ *    that.  This can only be region 1: xenfb_refresh().  But that
-+ *    just extends the dirty rectangle, which can't harm the
-+ *    invariant.
-+ *
-+ * But FIXME: the invariant is too weak.  It misses that the fault
-+ * record in mappings must be consistent with the mapping of pages in
-+ * the associated address space!  do_no_page() updates the PTE after
-+ * xenfb_vm_nopage() returns, i.e. outside the critical region.  This
-+ * allows the following race:
-+ *
-+ * X writes to some address in the Xen frame buffer
-+ * Fault - call do_no_page()
-+ *     call xenfb_vm_nopage()
-+ *         grab mm_lock
-+ *         map->faults++;
-+ *         release mm_lock
-+ *     return back to do_no_page()
-+ * (preempted, or SMP)
-+ * Xen worker thread runs.
-+ *      grab mm_lock
-+ *      look at mappings
-+ *          find this mapping, zaps its pages (but page not in pte yet)
-+ *          clear map->faults
-+ *      releases mm_lock
-+ * (back to X process)
-+ *     put page in X's pte
-+ *
-+ * Oh well, we wont be updating the writes to this page anytime soon.
-+ */
-+
-+static int xenfb_fps = 20;
-+static unsigned long xenfb_mem_len = XENFB_WIDTH * XENFB_HEIGHT * XENFB_DEPTH / 8;
-+
-+static int xenfb_remove(struct xenbus_device *);
-+static void xenfb_init_shared_page(struct xenfb_info *);
-+static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *);
-+static void xenfb_disconnect_backend(struct xenfb_info *);
-+
-+static void xenfb_do_update(struct xenfb_info *info,
-+                          int x, int y, int w, int h)
-+{
-+      union xenfb_out_event event;
-+      __u32 prod;
-+
-+      event.type = XENFB_TYPE_UPDATE;
-+      event.update.x = x;
-+      event.update.y = y;
-+      event.update.width = w;
-+      event.update.height = h;
-+
-+      prod = info->page->out_prod;
-+      /* caller ensures !xenfb_queue_full() */
-+      mb();                   /* ensure ring space available */
-+      XENFB_OUT_RING_REF(info->page, prod) = event;
-+      wmb();                  /* ensure ring contents visible */
-+      info->page->out_prod = prod + 1;
-+
-+      notify_remote_via_evtchn(info->evtchn);
-+}
-+
-+static int xenfb_queue_full(struct xenfb_info *info)
-+{
-+      __u32 cons, prod;
-+
-+      prod = info->page->out_prod;
-+      cons = info->page->out_cons;
-+      return prod - cons == XENFB_OUT_RING_LEN;
-+}
-+
-+static void xenfb_update_screen(struct xenfb_info *info)
-+{
-+      unsigned long flags;
-+      int y1, y2, x1, x2;
-+      struct xenfb_mapping *map;
-+
-+      if (!info->update_wanted)
-+              return;
-+      if (xenfb_queue_full(info))
-+              return;
-+
-+      mutex_lock(&info->mm_lock);
-+
-+      spin_lock_irqsave(&info->dirty_lock, flags);
-+      y1 = info->y1;
-+      y2 = info->y2;
-+      x1 = info->x1;
-+      x2 = info->x2;
-+      info->x1 = info->y1 = INT_MAX;
-+      info->x2 = info->y2 = 0;
-+      spin_unlock_irqrestore(&info->dirty_lock, flags);
-+
-+      list_for_each_entry(map, &info->mappings, link) {
-+              if (!map->faults)
-+                      continue;
-+              zap_page_range(map->vma, map->vma->vm_start,
-+                             map->vma->vm_end - map->vma->vm_start, NULL);
-+              map->faults = 0;
-+      }
-+
-+      mutex_unlock(&info->mm_lock);
-+
-+      xenfb_do_update(info, x1, y1, x2 - x1, y2 - y1);
-+}
-+
-+static int xenfb_thread(void *data)
-+{
-+      struct xenfb_info *info = data;
-+
-+      while (!kthread_should_stop()) {
-+              if (info->dirty) {
-+                      info->dirty = 0;
-+                      xenfb_update_screen(info);
-+              }
-+              wait_event_interruptible(info->wq,
-+                      kthread_should_stop() || info->dirty);
-+              try_to_freeze();
-+      }
-+      return 0;
-+}
-+
-+static int xenfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-+                         unsigned blue, unsigned transp,
-+                         struct fb_info *info)
-+{
-+      u32 v;
-+
-+      if (regno > info->cmap.len)
-+              return 1;
-+
-+      red   >>= (16 - info->var.red.length);
-+      green >>= (16 - info->var.green.length);
-+      blue  >>= (16 - info->var.blue.length);
-+
-+      v = (red << info->var.red.offset) |
-+          (green << info->var.green.offset) |
-+          (blue << info->var.blue.offset);
-+
-+      /* FIXME is this sane?  check against xxxfb_setcolreg()!  */
-+      switch (info->var.bits_per_pixel) {
-+      case 16:
-+      case 24:
-+      case 32:
-+              ((u32 *)info->pseudo_palette)[regno] = v;
-+              break;
-+      }
-+      
-+      return 0;
-+}
-+
-+static void xenfb_timer(unsigned long data)
-+{
-+      struct xenfb_info *info = (struct xenfb_info *)data;
-+      info->dirty = 1;
-+      wake_up(&info->wq);
-+}
-+
-+static void __xenfb_refresh(struct xenfb_info *info,
-+                          int x1, int y1, int w, int h)
-+{
-+      int y2, x2;
-+
-+      y2 = y1 + h;
-+      x2 = x1 + w;
-+
-+      if (info->y1 > y1)
-+              info->y1 = y1;
-+      if (info->y2 < y2)
-+              info->y2 = y2;
-+      if (info->x1 > x1)
-+              info->x1 = x1;
-+      if (info->x2 < x2)
-+              info->x2 = x2;
-+
-+      if (timer_pending(&info->refresh))
-+              return;
-+
-+      mod_timer(&info->refresh, jiffies + HZ/xenfb_fps);
-+}
-+
-+static void xenfb_refresh(struct xenfb_info *info,
-+                        int x1, int y1, int w, int h)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&info->dirty_lock, flags);
-+      __xenfb_refresh(info, x1, y1, w, h);
-+      spin_unlock_irqrestore(&info->dirty_lock, flags);
-+}
-+
-+static void xenfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
-+{
-+      struct xenfb_info *info = p->par;
-+
-+      cfb_fillrect(p, rect);
-+      xenfb_refresh(info, rect->dx, rect->dy, rect->width, rect->height);
-+}
-+
-+static void xenfb_imageblit(struct fb_info *p, const struct fb_image *image)
-+{
-+      struct xenfb_info *info = p->par;
-+
-+      cfb_imageblit(p, image);
-+      xenfb_refresh(info, image->dx, image->dy, image->width, image->height);
-+}
-+
-+static void xenfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
-+{
-+      struct xenfb_info *info = p->par;
-+
-+      cfb_copyarea(p, area);
-+      xenfb_refresh(info, area->dx, area->dy, area->width, area->height);
-+}
-+
-+static void xenfb_vm_open(struct vm_area_struct *vma)
-+{
-+      struct xenfb_mapping *map = vma->vm_private_data;
-+      atomic_inc(&map->map_refs);
-+}
-+
-+static void xenfb_vm_close(struct vm_area_struct *vma)
-+{
-+      struct xenfb_mapping *map = vma->vm_private_data;
-+      struct xenfb_info *info = map->info;
-+
-+      mutex_lock(&info->mm_lock);
-+      if (atomic_dec_and_test(&map->map_refs)) {
-+              list_del(&map->link);
-+              kfree(map);
-+      }
-+      mutex_unlock(&info->mm_lock);
-+}
-+
-+static struct page *xenfb_vm_nopage(struct vm_area_struct *vma,
-+                                  unsigned long vaddr, int *type)
-+{
-+      struct xenfb_mapping *map = vma->vm_private_data;
-+      struct xenfb_info *info = map->info;
-+      int pgnr = (vaddr - vma->vm_start) >> PAGE_SHIFT;
-+      unsigned long flags;
-+      struct page *page;
-+      int y1, y2;
-+
-+      if (pgnr >= info->nr_pages)
-+              return NOPAGE_SIGBUS;
-+
-+      mutex_lock(&info->mm_lock);
-+      spin_lock_irqsave(&info->dirty_lock, flags);
-+      page = info->pages[pgnr];
-+      get_page(page);
-+      map->faults++;
-+
-+      y1 = pgnr * PAGE_SIZE / info->fb_info->fix.line_length;
-+      y2 = (pgnr * PAGE_SIZE + PAGE_SIZE - 1) / info->fb_info->fix.line_length;
-+      if (y2 > info->fb_info->var.yres)
-+              y2 = info->fb_info->var.yres;
-+      __xenfb_refresh(info, 0, y1, info->fb_info->var.xres, y2 - y1);
-+      spin_unlock_irqrestore(&info->dirty_lock, flags);
-+      mutex_unlock(&info->mm_lock);
-+
-+      if (type)
-+              *type = VM_FAULT_MINOR;
-+
-+      return page;
-+}
-+
-+static struct vm_operations_struct xenfb_vm_ops = {
-+      .open   = xenfb_vm_open,
-+      .close  = xenfb_vm_close,
-+      .nopage = xenfb_vm_nopage,
-+};
-+
-+static int xenfb_mmap(struct fb_info *fb_info, struct vm_area_struct *vma)
-+{
-+      struct xenfb_info *info = fb_info->par;
-+      struct xenfb_mapping *map;
-+      int map_pages;
-+
-+      if (!(vma->vm_flags & VM_WRITE))
-+              return -EINVAL;
-+      if (!(vma->vm_flags & VM_SHARED))
-+              return -EINVAL;
-+      if (vma->vm_pgoff != 0)
-+              return -EINVAL;
-+
-+      map_pages = (vma->vm_end - vma->vm_start + PAGE_SIZE-1) >> PAGE_SHIFT;
-+      if (map_pages > info->nr_pages)
-+              return -EINVAL;
-+
-+      map = kzalloc(sizeof(*map), GFP_KERNEL);
-+      if (map == NULL)
-+              return -ENOMEM;
-+
-+      map->vma = vma;
-+      map->faults = 0;
-+      map->info = info;
-+      atomic_set(&map->map_refs, 1);
-+
-+      mutex_lock(&info->mm_lock);
-+      list_add(&map->link, &info->mappings);
-+      mutex_unlock(&info->mm_lock);
-+
-+      vma->vm_ops = &xenfb_vm_ops;
-+      vma->vm_flags |= (VM_DONTEXPAND | VM_RESERVED);
-+      vma->vm_private_data = map;
-+
-+      return 0;
-+}
-+
-+static struct fb_ops xenfb_fb_ops = {
-+      .owner          = THIS_MODULE,
-+      .fb_setcolreg   = xenfb_setcolreg,
-+      .fb_fillrect    = xenfb_fillrect,
-+      .fb_copyarea    = xenfb_copyarea,
-+      .fb_imageblit   = xenfb_imageblit,
-+      .fb_mmap        = xenfb_mmap,
-+};
-+
-+static irqreturn_t xenfb_event_handler(int rq, void *dev_id,
-+                                     struct pt_regs *regs)
-+{
-+      /*
-+       * No in events recognized, simply ignore them all.
-+       * If you need to recognize some, see xenbkd's input_handler()
-+       * for how to do that.
-+       */
-+      struct xenfb_info *info = dev_id;
-+      struct xenfb_page *page = info->page;
-+
-+      if (page->in_cons != page->in_prod) {
-+              info->page->in_cons = info->page->in_prod;
-+              notify_remote_via_evtchn(info->evtchn);
-+      }
-+      return IRQ_HANDLED;
-+}
-+
-+static unsigned long vmalloc_to_mfn(void *address)
-+{
-+      return pfn_to_mfn(vmalloc_to_pfn(address));
-+}
-+
-+static int __devinit xenfb_probe(struct xenbus_device *dev,
-+                               const struct xenbus_device_id *id)
-+{
-+      struct xenfb_info *info;
-+      struct fb_info *fb_info;
-+      int ret;
-+
-+      info = kzalloc(sizeof(*info), GFP_KERNEL);
-+      if (info == NULL) {
-+              xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
-+              return -ENOMEM;
-+      }
-+      dev->dev.driver_data = info;
-+      info->xbdev = dev;
-+      info->irq = -1;
-+      info->x1 = info->y1 = INT_MAX;
-+      spin_lock_init(&info->dirty_lock);
-+      mutex_init(&info->mm_lock);
-+      init_waitqueue_head(&info->wq);
-+      init_timer(&info->refresh);
-+      info->refresh.function = xenfb_timer;
-+      info->refresh.data = (unsigned long)info;
-+      INIT_LIST_HEAD(&info->mappings);
-+
-+      info->fb = vmalloc(xenfb_mem_len);
-+      if (info->fb == NULL)
-+              goto error_nomem;
-+      memset(info->fb, 0, xenfb_mem_len);
-+
-+      info->nr_pages = (xenfb_mem_len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+
-+      info->pages = kmalloc(sizeof(struct page *) * info->nr_pages,
-+                            GFP_KERNEL);
-+      if (info->pages == NULL)
-+              goto error_nomem;
-+
-+      info->mfns = vmalloc(sizeof(unsigned long) * info->nr_pages);
-+      if (!info->mfns)
-+              goto error_nomem;
-+
-+      /* set up shared page */
-+      info->page = (void *)__get_free_page(GFP_KERNEL);
-+      if (!info->page)
-+              goto error_nomem;
-+
-+      xenfb_init_shared_page(info);
-+
-+      fb_info = framebuffer_alloc(sizeof(u32) * 256, NULL);
-+                              /* see fishy hackery below */
-+      if (fb_info == NULL)
-+              goto error_nomem;
-+
-+      /* FIXME fishy hackery */
-+      fb_info->pseudo_palette = fb_info->par;
-+      fb_info->par = info;
-+      /* /FIXME */
-+      fb_info->screen_base = info->fb;
-+
-+      fb_info->fbops = &xenfb_fb_ops;
-+      fb_info->var.xres_virtual = fb_info->var.xres = info->page->width;
-+      fb_info->var.yres_virtual = fb_info->var.yres = info->page->height;
-+      fb_info->var.bits_per_pixel = info->page->depth;
-+
-+      fb_info->var.red = (struct fb_bitfield){16, 8, 0};
-+      fb_info->var.green = (struct fb_bitfield){8, 8, 0};
-+      fb_info->var.blue = (struct fb_bitfield){0, 8, 0};
-+
-+      fb_info->var.activate = FB_ACTIVATE_NOW;
-+      fb_info->var.height = -1;
-+      fb_info->var.width = -1;
-+      fb_info->var.vmode = FB_VMODE_NONINTERLACED;
-+
-+      fb_info->fix.visual = FB_VISUAL_TRUECOLOR;
-+      fb_info->fix.line_length = info->page->line_length;
-+      fb_info->fix.smem_start = 0;
-+      fb_info->fix.smem_len = xenfb_mem_len;
-+      strcpy(fb_info->fix.id, "xen");
-+      fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
-+      fb_info->fix.accel = FB_ACCEL_NONE;
-+
-+      fb_info->flags = FBINFO_FLAG_DEFAULT;
-+
-+      ret = fb_alloc_cmap(&fb_info->cmap, 256, 0);
-+      if (ret < 0) {
-+              framebuffer_release(fb_info);
-+              xenbus_dev_fatal(dev, ret, "fb_alloc_cmap");
-+              goto error;
-+      }
-+
-+      ret = register_framebuffer(fb_info);
-+      if (ret) {
-+              fb_dealloc_cmap(&info->fb_info->cmap);
-+              framebuffer_release(fb_info);
-+              xenbus_dev_fatal(dev, ret, "register_framebuffer");
-+              goto error;
-+      }
-+      info->fb_info = fb_info;
-+
-+      /* FIXME should this be delayed until backend XenbusStateConnected? */
-+      info->kthread = kthread_run(xenfb_thread, info, "xenfb thread");
-+      if (IS_ERR(info->kthread)) {
-+              ret = PTR_ERR(info->kthread);
-+              info->kthread = NULL;
-+              xenbus_dev_fatal(dev, ret, "register_framebuffer");
-+              goto error;
-+      }
-+
-+      ret = xenfb_connect_backend(dev, info);
-+      if (ret < 0)
-+              goto error;
-+
-+      return 0;
-+
-+ error_nomem:
-+      ret = -ENOMEM;
-+      xenbus_dev_fatal(dev, ret, "allocating device memory");
-+ error:
-+      xenfb_remove(dev);
-+      return ret;
-+}
-+
-+static int xenfb_resume(struct xenbus_device *dev)
-+{
-+      struct xenfb_info *info = dev->dev.driver_data;
-+
-+      xenfb_disconnect_backend(info);
-+      xenfb_init_shared_page(info);
-+      return xenfb_connect_backend(dev, info);
-+}
-+
-+static int xenfb_remove(struct xenbus_device *dev)
-+{
-+      struct xenfb_info *info = dev->dev.driver_data;
-+
-+      del_timer(&info->refresh);
-+      if (info->kthread)
-+              kthread_stop(info->kthread);
-+      xenfb_disconnect_backend(info);
-+      if (info->fb_info) {
-+              unregister_framebuffer(info->fb_info);
-+              fb_dealloc_cmap(&info->fb_info->cmap);
-+              framebuffer_release(info->fb_info);
-+      }
-+      free_page((unsigned long)info->page);
-+      vfree(info->mfns);
-+      kfree(info->pages);
-+      vfree(info->fb);
-+      kfree(info);
-+
-+      return 0;
-+}
-+
-+static void xenfb_init_shared_page(struct xenfb_info *info)
-+{
-+      int i;
-+
-+      for (i = 0; i < info->nr_pages; i++)
-+              info->pages[i] = vmalloc_to_page(info->fb + i * PAGE_SIZE);
-+
-+      for (i = 0; i < info->nr_pages; i++)
-+              info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE);
-+
-+      info->page->pd[0] = vmalloc_to_mfn(info->mfns);
-+      info->page->pd[1] = 0;
-+      info->page->width = XENFB_WIDTH;
-+      info->page->height = XENFB_HEIGHT;
-+      info->page->depth = XENFB_DEPTH;
-+      info->page->line_length = (info->page->depth / 8) * info->page->width;
-+      info->page->mem_length = xenfb_mem_len;
-+      info->page->in_cons = info->page->in_prod = 0;
-+      info->page->out_cons = info->page->out_prod = 0;
-+}
-+
-+static int xenfb_connect_backend(struct xenbus_device *dev,
-+                               struct xenfb_info *info)
-+{
-+      int ret;
-+      struct xenbus_transaction xbt;
-+
-+      ret = xenbus_alloc_evtchn(dev, &info->evtchn);
-+      if (ret)
-+              return ret;
-+      ret = bind_evtchn_to_irqhandler(info->evtchn, xenfb_event_handler,
-+                                      0, "xenfb", info);
-+      if (ret < 0) {
-+              xenbus_free_evtchn(dev, info->evtchn);
-+              xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
-+              return ret;
-+      }
-+      info->irq = ret;
-+
-+ again:
-+      ret = xenbus_transaction_start(&xbt);
-+      if (ret) {
-+              xenbus_dev_fatal(dev, ret, "starting transaction");
-+              return ret;
-+      }
-+      ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
-+                          virt_to_mfn(info->page));
-+      if (ret)
-+              goto error_xenbus;
-+      ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
-+                          info->evtchn);
-+      if (ret)
-+              goto error_xenbus;
-+      ret = xenbus_printf(xbt, dev->nodename, "feature-update", "1");
-+      if (ret)
-+              goto error_xenbus;
-+      ret = xenbus_transaction_end(xbt, 0);
-+      if (ret) {
-+              if (ret == -EAGAIN)
-+                      goto again;
-+              xenbus_dev_fatal(dev, ret, "completing transaction");
-+              return ret;
-+      }
-+
-+      xenbus_switch_state(dev, XenbusStateInitialised);
-+      return 0;
-+
-+ error_xenbus:
-+      xenbus_transaction_end(xbt, 1);
-+      xenbus_dev_fatal(dev, ret, "writing xenstore");
-+      return ret;
-+}
-+
-+static void xenfb_disconnect_backend(struct xenfb_info *info)
-+{
-+      if (info->irq >= 0)
-+              unbind_from_irqhandler(info->irq, info);
-+      info->irq = -1;
-+}
-+
-+static void xenfb_backend_changed(struct xenbus_device *dev,
-+                                enum xenbus_state backend_state)
-+{
-+      struct xenfb_info *info = dev->dev.driver_data;
-+      int val;
-+
-+      switch (backend_state) {
-+      case XenbusStateInitialising:
-+      case XenbusStateInitialised:
-+      case XenbusStateUnknown:
-+      case XenbusStateClosed:
-+              break;
-+
-+      case XenbusStateInitWait:
-+      InitWait:
-+              xenbus_switch_state(dev, XenbusStateConnected);
-+              break;
-+
-+      case XenbusStateConnected:
-+              /*
-+               * Work around xenbus race condition: If backend goes
-+               * through InitWait to Connected fast enough, we can
-+               * get Connected twice here.
-+               */
-+              if (dev->state != XenbusStateConnected)
-+                      goto InitWait; /* no InitWait seen yet, fudge it */
-+
-+              if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
-+                               "request-update", "%d", &val) < 0)
-+                      val = 0;
-+              if (val)
-+                      info->update_wanted = 1;
-+              break;
-+
-+      case XenbusStateClosing:
-+              // FIXME is this safe in any dev->state?
-+              xenbus_frontend_closed(dev);
-+              break;
-+      }
-+}
-+
-+static struct xenbus_device_id xenfb_ids[] = {
-+      { "vfb" },
-+      { "" }
-+};
-+
-+static struct xenbus_driver xenfb = {
-+      .name = "vfb",
-+      .owner = THIS_MODULE,
-+      .ids = xenfb_ids,
-+      .probe = xenfb_probe,
-+      .remove = xenfb_remove,
-+      .resume = xenfb_resume,
-+      .otherend_changed = xenfb_backend_changed,
-+};
-+
-+static int __init xenfb_init(void)
-+{
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      /* Nothing to do if running in dom0. */
-+      if (is_initial_xendomain())
-+              return -ENODEV;
-+
-+      return xenbus_register_frontend(&xenfb);
-+}
-+
-+static void __exit xenfb_cleanup(void)
-+{
-+      return xenbus_unregister_driver(&xenfb);
-+}
-+
-+module_init(xenfb_init);
-+module_exit(xenfb_cleanup);
-+
-+MODULE_LICENSE("GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/fbfront/xenkbd.c linux-2.6.16.33/drivers/xen/fbfront/xenkbd.c
---- linux-2.6.16.33-noxen/drivers/xen/fbfront/xenkbd.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/fbfront/xenkbd.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,300 @@
-+/*
-+ * linux/drivers/input/keyboard/xenkbd.c -- Xen para-virtual input device
-+ *
-+ * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
-+ * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
-+ *
-+ *  Based on linux/drivers/input/mouse/sermouse.c
-+ *
-+ *  This file is subject to the terms and conditions of the GNU General Public
-+ *  License. See the file COPYING in the main directory of this archive for
-+ *  more details.
-+ */
-+
-+/*
-+ * TODO:
-+ *
-+ * Switch to grant tables together with xenfb.c.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/module.h>
-+#include <linux/input.h>
-+#include <asm/hypervisor.h>
-+#include <xen/evtchn.h>
-+#include <xen/interface/io/fbif.h>
-+#include <xen/interface/io/kbdif.h>
-+#include <xen/xenbus.h>
-+
-+struct xenkbd_info
-+{
-+      struct input_dev *dev;
-+      struct xenkbd_page *page;
-+      unsigned evtchn;
-+      int irq;
-+      struct xenbus_device *xbdev;
-+};
-+
-+static int xenkbd_remove(struct xenbus_device *);
-+static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *);
-+static void xenkbd_disconnect_backend(struct xenkbd_info *);
-+
-+/*
-+ * Note: if you need to send out events, see xenfb_do_update() for how
-+ * to do that.
-+ */
-+
-+static irqreturn_t input_handler(int rq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct xenkbd_info *info = dev_id;
-+      struct xenkbd_page *page = info->page;
-+      __u32 cons, prod;
-+
-+      prod = page->in_prod;
-+      if (prod == page->out_cons)
-+              return IRQ_HANDLED;
-+      rmb();                  /* ensure we see ring contents up to prod */
-+      for (cons = page->in_cons; cons != prod; cons++) {
-+              union xenkbd_in_event *event;
-+              event = &XENKBD_IN_RING_REF(page, cons);
-+
-+              switch (event->type) {
-+              case XENKBD_TYPE_MOTION:
-+                      input_report_rel(info->dev, REL_X, event->motion.rel_x);
-+                      input_report_rel(info->dev, REL_Y, event->motion.rel_y);
-+                      break;
-+              case XENKBD_TYPE_KEY:
-+                      input_report_key(info->dev, event->key.keycode, event->key.pressed);
-+                      break;
-+              case XENKBD_TYPE_POS:
-+                      input_report_abs(info->dev, ABS_X, event->pos.abs_x);
-+                      input_report_abs(info->dev, ABS_Y, event->pos.abs_y);
-+                      break;
-+              }
-+      }
-+      input_sync(info->dev);
-+      mb();                   /* ensure we got ring contents */
-+      page->in_cons = cons;
-+      notify_remote_via_evtchn(info->evtchn);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+int __devinit xenkbd_probe(struct xenbus_device *dev,
-+                         const struct xenbus_device_id *id)
-+{
-+      int ret, i;
-+      struct xenkbd_info *info;
-+      struct input_dev *input_dev;
-+
-+      info = kzalloc(sizeof(*info), GFP_KERNEL);
-+      if (!info) {
-+              xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
-+              return -ENOMEM;
-+      }
-+      dev->dev.driver_data = info;
-+      info->xbdev = dev;
-+
-+      info->page = (void *)__get_free_page(GFP_KERNEL);
-+      if (!info->page)
-+              goto error_nomem;
-+      info->page->in_cons = info->page->in_prod = 0;
-+      info->page->out_cons = info->page->out_prod = 0;
-+
-+      input_dev = input_allocate_device();
-+      if (!input_dev)
-+              goto error_nomem;
-+
-+      input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
-+      input_dev->keybit[LONG(BTN_MOUSE)]
-+              = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-+      /* TODO additional buttons */
-+      input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-+
-+      /* FIXME not sure this is quite right */
-+      for (i = 0; i < 256; i++)
-+              set_bit(i, input_dev->keybit);
-+
-+      input_dev->name = "Xen Virtual Keyboard/Mouse";
-+
-+      input_set_abs_params(input_dev, ABS_X, 0, XENFB_WIDTH, 0, 0);
-+      input_set_abs_params(input_dev, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
-+
-+      ret = input_register_device(input_dev);
-+      if (ret) {
-+              input_free_device(input_dev);
-+              xenbus_dev_fatal(dev, ret, "input_register_device");
-+              goto error;
-+      }
-+      info->dev = input_dev;
-+
-+      ret = xenkbd_connect_backend(dev, info);
-+      if (ret < 0)
-+              goto error;
-+
-+      return 0;
-+
-+ error_nomem:
-+      ret = -ENOMEM;
-+      xenbus_dev_fatal(dev, ret, "allocating device memory");
-+ error:
-+      xenkbd_remove(dev);
-+      return ret;
-+}
-+
-+static int xenkbd_resume(struct xenbus_device *dev)
-+{
-+      struct xenkbd_info *info = dev->dev.driver_data;
-+
-+      xenkbd_disconnect_backend(info);
-+      return xenkbd_connect_backend(dev, info);
-+}
-+
-+static int xenkbd_remove(struct xenbus_device *dev)
-+{
-+      struct xenkbd_info *info = dev->dev.driver_data;
-+
-+      xenkbd_disconnect_backend(info);
-+      input_unregister_device(info->dev);
-+      free_page((unsigned long)info->page);
-+      kfree(info);
-+      return 0;
-+}
-+
-+static int xenkbd_connect_backend(struct xenbus_device *dev,
-+                                struct xenkbd_info *info)
-+{
-+      int ret;
-+      struct xenbus_transaction xbt;
-+
-+      ret = xenbus_alloc_evtchn(dev, &info->evtchn);
-+      if (ret)
-+              return ret;
-+      ret = bind_evtchn_to_irqhandler(info->evtchn, input_handler, 0,
-+                                      "xenkbd", info);
-+      if (ret < 0) {
-+              xenbus_free_evtchn(dev, info->evtchn);
-+              xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
-+              return ret;
-+      }
-+      info->irq = ret;
-+
-+ again:
-+      ret = xenbus_transaction_start(&xbt);
-+      if (ret) {
-+              xenbus_dev_fatal(dev, ret, "starting transaction");
-+              return ret;
-+      }
-+      ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
-+                          virt_to_mfn(info->page));
-+      if (ret)
-+              goto error_xenbus;
-+      ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
-+                          info->evtchn);
-+      if (ret)
-+              goto error_xenbus;
-+      ret = xenbus_transaction_end(xbt, 0);
-+      if (ret) {
-+              if (ret == -EAGAIN)
-+                      goto again;
-+              xenbus_dev_fatal(dev, ret, "completing transaction");
-+              return ret;
-+      }
-+
-+      xenbus_switch_state(dev, XenbusStateInitialised);
-+      return 0;
-+
-+ error_xenbus:
-+      xenbus_transaction_end(xbt, 1);
-+      xenbus_dev_fatal(dev, ret, "writing xenstore");
-+      return ret;
-+}
-+
-+static void xenkbd_disconnect_backend(struct xenkbd_info *info)
-+{
-+      if (info->irq >= 0)
-+              unbind_from_irqhandler(info->irq, info);
-+      info->irq = -1;
-+}
-+
-+static void xenkbd_backend_changed(struct xenbus_device *dev,
-+                                 enum xenbus_state backend_state)
-+{
-+      struct xenkbd_info *info = dev->dev.driver_data;
-+      int ret, val;
-+
-+      switch (backend_state) {
-+      case XenbusStateInitialising:
-+      case XenbusStateInitialised:
-+      case XenbusStateUnknown:
-+      case XenbusStateClosed:
-+              break;
-+
-+      case XenbusStateInitWait:
-+      InitWait:
-+              ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
-+                                 "feature-abs-pointer", "%d", &val);
-+              if (ret < 0)
-+                      val = 0;
-+              if (val) {
-+                      ret = xenbus_printf(XBT_NIL, info->xbdev->nodename,
-+                                          "request-abs-pointer", "1");
-+                      if (ret)
-+                              ; /* FIXME */
-+              }
-+              xenbus_switch_state(dev, XenbusStateConnected);
-+              break;
-+
-+      case XenbusStateConnected:
-+              /*
-+               * Work around xenbus race condition: If backend goes
-+               * through InitWait to Connected fast enough, we can
-+               * get Connected twice here.
-+               */
-+              if (dev->state != XenbusStateConnected)
-+                      goto InitWait; /* no InitWait seen yet, fudge it */
-+              break;
-+
-+      case XenbusStateClosing:
-+              xenbus_frontend_closed(dev);
-+              break;
-+      }
-+}
-+
-+static struct xenbus_device_id xenkbd_ids[] = {
-+      { "vkbd" },
-+      { "" }
-+};
-+
-+static struct xenbus_driver xenkbd = {
-+      .name = "vkbd",
-+      .owner = THIS_MODULE,
-+      .ids = xenkbd_ids,
-+      .probe = xenkbd_probe,
-+      .remove = xenkbd_remove,
-+      .resume = xenkbd_resume,
-+      .otherend_changed = xenkbd_backend_changed,
-+};
-+
-+static int __init xenkbd_init(void)
-+{
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      /* Nothing to do if running in dom0. */
-+      if (is_initial_xendomain())
-+              return -ENODEV;
-+
-+      return xenbus_register_frontend(&xenkbd);
-+}
-+
-+static void __exit xenkbd_cleanup(void)
-+{
-+      return xenbus_unregister_driver(&xenkbd);
-+}
-+
-+module_init(xenkbd_init);
-+module_exit(xenkbd_cleanup);
-+
-+MODULE_LICENSE("GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/netback/Makefile linux-2.6.16.33/drivers/xen/netback/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/netback/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/netback/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,5 @@
-+obj-$(CONFIG_XEN_NETDEV_BACKEND) := netbk.o
-+obj-$(CONFIG_XEN_NETDEV_LOOPBACK) += netloop.o
-+
-+netbk-y   := netback.o xenbus.o interface.o
-+netloop-y := loopback.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/netback/common.h linux-2.6.16.33/drivers/xen/netback/common.h
---- linux-2.6.16.33-noxen/drivers/xen/netback/common.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/netback/common.h       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,146 @@
-+/******************************************************************************
-+ * arch/xen/drivers/netif/backend/common.h
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __NETIF__BACKEND__COMMON_H__
-+#define __NETIF__BACKEND__COMMON_H__
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/ip.h>
-+#include <linux/in.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/wait.h>
-+#include <xen/evtchn.h>
-+#include <xen/interface/io/netif.h>
-+#include <asm/io.h>
-+#include <asm/pgalloc.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/gnttab.h>
-+#include <xen/driver_util.h>
-+
-+#define DPRINTK(_f, _a...)                    \
-+      pr_debug("(file=%s, line=%d) " _f,      \
-+               __FILE__ , __LINE__ , ## _a )
-+#define IPRINTK(fmt, args...)                         \
-+      printk(KERN_INFO "xen_net: " fmt, ##args)
-+#define WPRINTK(fmt, args...)                         \
-+      printk(KERN_WARNING "xen_net: " fmt, ##args)
-+
-+typedef struct netif_st {
-+      /* Unique identifier for this interface. */
-+      domid_t          domid;
-+      unsigned int     handle;
-+
-+      u8               fe_dev_addr[6];
-+
-+      /* Physical parameters of the comms window. */
-+      grant_handle_t   tx_shmem_handle;
-+      grant_ref_t      tx_shmem_ref;
-+      grant_handle_t   rx_shmem_handle;
-+      grant_ref_t      rx_shmem_ref;
-+      unsigned int     evtchn;
-+      unsigned int     irq;
-+
-+      /* The shared rings and indexes. */
-+      netif_tx_back_ring_t tx;
-+      netif_rx_back_ring_t rx;
-+      struct vm_struct *tx_comms_area;
-+      struct vm_struct *rx_comms_area;
-+
-+      /* Set of features that can be turned on in dev->features. */
-+      int features;
-+
-+      /* Internal feature information. */
-+      int can_queue:1;        /* can queue packets for receiver? */
-+      int copying_receiver:1; /* copy packets to receiver?       */
-+
-+      /* Allow netif_be_start_xmit() to peek ahead in the rx request ring. */
-+      RING_IDX rx_req_cons_peek;
-+
-+      /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */
-+      unsigned long   credit_bytes;
-+      unsigned long   credit_usec;
-+      unsigned long   remaining_credit;
-+      struct timer_list credit_timeout;
-+
-+      /* Enforce draining of the transmit queue. */
-+      struct timer_list tx_queue_timeout;
-+
-+      /* Miscellaneous private stuff. */
-+      struct list_head list;  /* scheduling list */
-+      atomic_t         refcnt;
-+      struct net_device *dev;
-+      struct net_device_stats stats;
-+
-+      wait_queue_head_t waiting_to_free;
-+} netif_t;
-+
-+#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
-+#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
-+
-+void netif_disconnect(netif_t *netif);
-+
-+netif_t *netif_alloc(domid_t domid, unsigned int handle);
-+int netif_map(netif_t *netif, unsigned long tx_ring_ref,
-+            unsigned long rx_ring_ref, unsigned int evtchn);
-+
-+#define netif_get(_b) (atomic_inc(&(_b)->refcnt))
-+#define netif_put(_b)                                         \
-+      do {                                                    \
-+              if ( atomic_dec_and_test(&(_b)->refcnt) )       \
-+                      wake_up(&(_b)->waiting_to_free);        \
-+      } while (0)
-+
-+void netif_xenbus_init(void);
-+
-+#define netif_schedulable(dev) (netif_running(dev) && netif_carrier_ok(dev))
-+
-+void netif_schedule_work(netif_t *netif);
-+void netif_deschedule_work(netif_t *netif);
-+
-+int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev);
-+struct net_device_stats *netif_be_get_stats(struct net_device *dev);
-+irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs);
-+
-+static inline int netbk_can_queue(struct net_device *dev)
-+{
-+      netif_t *netif = netdev_priv(dev);
-+      return netif->can_queue;
-+}
-+
-+static inline int netbk_can_sg(struct net_device *dev)
-+{
-+      netif_t *netif = netdev_priv(dev);
-+      return netif->features & NETIF_F_SG;
-+}
-+
-+#endif /* __NETIF__BACKEND__COMMON_H__ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/netback/interface.c linux-2.6.16.33/drivers/xen/netback/interface.c
---- linux-2.6.16.33-noxen/drivers/xen/netback/interface.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/netback/interface.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,349 @@
-+/******************************************************************************
-+ * arch/xen/drivers/netif/backend/interface.c
-+ * 
-+ * Network-device interface management.
-+ * 
-+ * Copyright (c) 2004-2005, Keir Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include "common.h"
-+#include <linux/ethtool.h>
-+#include <linux/rtnetlink.h>
-+
-+/*
-+ * Module parameter 'queue_length':
-+ * 
-+ * Enables queuing in the network stack when a client has run out of receive
-+ * descriptors. Although this feature can improve receive bandwidth by avoiding
-+ * packet loss, it can also result in packets sitting in the 'tx_queue' for
-+ * unbounded time. This is bad if those packets hold onto foreign resources.
-+ * For example, consider a packet that holds onto resources belonging to the
-+ * guest for which it is queued (e.g., packet received on vif1.0, destined for
-+ * vif1.1 which is not activated in the guest): in this situation the guest
-+ * will never be destroyed, unless vif1.1 is taken down. To avoid this, we
-+ * run a timer (tx_queue_timeout) to drain the queue when the interface is
-+ * blocked.
-+ */
-+static unsigned long netbk_queue_length = 32;
-+module_param_named(queue_length, netbk_queue_length, ulong, 0);
-+
-+static void __netif_up(netif_t *netif)
-+{
-+      enable_irq(netif->irq);
-+      netif_schedule_work(netif);
-+}
-+
-+static void __netif_down(netif_t *netif)
-+{
-+      disable_irq(netif->irq);
-+      netif_deschedule_work(netif);
-+}
-+
-+static int net_open(struct net_device *dev)
-+{
-+      netif_t *netif = netdev_priv(dev);
-+      if (netif_carrier_ok(dev))
-+              __netif_up(netif);
-+      return 0;
-+}
-+
-+static int net_close(struct net_device *dev)
-+{
-+      netif_t *netif = netdev_priv(dev);
-+      if (netif_carrier_ok(dev))
-+              __netif_down(netif);
-+      return 0;
-+}
-+
-+static int netbk_change_mtu(struct net_device *dev, int mtu)
-+{
-+      int max = netbk_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
-+
-+      if (mtu > max)
-+              return -EINVAL;
-+      dev->mtu = mtu;
-+      return 0;
-+}
-+
-+static int netbk_set_sg(struct net_device *dev, u32 data)
-+{
-+      if (data) {
-+              netif_t *netif = netdev_priv(dev);
-+
-+              if (!(netif->features & NETIF_F_SG))
-+                      return -ENOSYS;
-+      }
-+
-+      return ethtool_op_set_sg(dev, data);
-+}
-+
-+static int netbk_set_tso(struct net_device *dev, u32 data)
-+{
-+      if (data) {
-+              netif_t *netif = netdev_priv(dev);
-+
-+              if (!(netif->features & NETIF_F_TSO))
-+                      return -ENOSYS;
-+      }
-+
-+      return ethtool_op_set_tso(dev, data);
-+}
-+
-+static struct ethtool_ops network_ethtool_ops =
-+{
-+      .get_tx_csum = ethtool_op_get_tx_csum,
-+      .set_tx_csum = ethtool_op_set_tx_csum,
-+      .get_sg = ethtool_op_get_sg,
-+      .set_sg = netbk_set_sg,
-+      .get_tso = ethtool_op_get_tso,
-+      .set_tso = netbk_set_tso,
-+      .get_link = ethtool_op_get_link,
-+};
-+
-+netif_t *netif_alloc(domid_t domid, unsigned int handle)
-+{
-+      int err = 0;
-+      struct net_device *dev;
-+      netif_t *netif;
-+      char name[IFNAMSIZ] = {};
-+
-+      snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
-+      dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
-+      if (dev == NULL) {
-+              DPRINTK("Could not create netif: out of memory\n");
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      netif_carrier_off(dev);
-+
-+      netif = netdev_priv(dev);
-+      memset(netif, 0, sizeof(*netif));
-+      netif->domid  = domid;
-+      netif->handle = handle;
-+      atomic_set(&netif->refcnt, 1);
-+      init_waitqueue_head(&netif->waiting_to_free);
-+      netif->dev = dev;
-+
-+      netif->credit_bytes = netif->remaining_credit = ~0UL;
-+      netif->credit_usec  = 0UL;
-+      init_timer(&netif->credit_timeout);
-+      /* Initialize 'expires' now: it's used to track the credit window. */
-+      netif->credit_timeout.expires = jiffies;
-+
-+      init_timer(&netif->tx_queue_timeout);
-+
-+      dev->hard_start_xmit = netif_be_start_xmit;
-+      dev->get_stats       = netif_be_get_stats;
-+      dev->open            = net_open;
-+      dev->stop            = net_close;
-+      dev->change_mtu      = netbk_change_mtu;
-+      dev->features        = NETIF_F_IP_CSUM;
-+
-+      SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
-+
-+      dev->tx_queue_len = netbk_queue_length;
-+
-+      /*
-+       * Initialise a dummy MAC address. We choose the numerically
-+       * largest non-broadcast address to prevent the address getting
-+       * stolen by an Ethernet bridge for STP purposes.
-+       * (FE:FF:FF:FF:FF:FF)
-+       */ 
-+      memset(dev->dev_addr, 0xFF, ETH_ALEN);
-+      dev->dev_addr[0] &= ~0x01;
-+
-+      rtnl_lock();
-+      err = register_netdevice(dev);
-+      rtnl_unlock();
-+      if (err) {
-+              DPRINTK("Could not register new net device %s: err=%d\n",
-+                      dev->name, err);
-+              free_netdev(dev);
-+              return ERR_PTR(err);
-+      }
-+
-+      DPRINTK("Successfully created netif\n");
-+      return netif;
-+}
-+
-+static int map_frontend_pages(
-+      netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref)
-+{
-+      struct gnttab_map_grant_ref op;
-+      int ret;
-+
-+      gnttab_set_map_op(&op, (unsigned long)netif->tx_comms_area->addr,
-+                        GNTMAP_host_map, tx_ring_ref, netif->domid);
-+    
-+      lock_vm_area(netif->tx_comms_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-+      unlock_vm_area(netif->tx_comms_area);
-+      BUG_ON(ret);
-+
-+      if (op.status) { 
-+              DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
-+              return op.status;
-+      }
-+
-+      netif->tx_shmem_ref    = tx_ring_ref;
-+      netif->tx_shmem_handle = op.handle;
-+
-+      gnttab_set_map_op(&op, (unsigned long)netif->rx_comms_area->addr,
-+                        GNTMAP_host_map, rx_ring_ref, netif->domid);
-+
-+      lock_vm_area(netif->rx_comms_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-+      unlock_vm_area(netif->rx_comms_area);
-+      BUG_ON(ret);
-+
-+      if (op.status) {
-+              DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
-+              return op.status;
-+      }
-+
-+      netif->rx_shmem_ref    = rx_ring_ref;
-+      netif->rx_shmem_handle = op.handle;
-+
-+      return 0;
-+}
-+
-+static void unmap_frontend_pages(netif_t *netif)
-+{
-+      struct gnttab_unmap_grant_ref op;
-+      int ret;
-+
-+      gnttab_set_unmap_op(&op, (unsigned long)netif->tx_comms_area->addr,
-+                          GNTMAP_host_map, netif->tx_shmem_handle);
-+
-+      lock_vm_area(netif->tx_comms_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-+      unlock_vm_area(netif->tx_comms_area);
-+      BUG_ON(ret);
-+
-+      gnttab_set_unmap_op(&op, (unsigned long)netif->rx_comms_area->addr,
-+                          GNTMAP_host_map, netif->rx_shmem_handle);
-+
-+      lock_vm_area(netif->rx_comms_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-+      unlock_vm_area(netif->rx_comms_area);
-+      BUG_ON(ret);
-+}
-+
-+int netif_map(netif_t *netif, unsigned long tx_ring_ref,
-+            unsigned long rx_ring_ref, unsigned int evtchn)
-+{
-+      int err = -ENOMEM;
-+      netif_tx_sring_t *txs;
-+      netif_rx_sring_t *rxs;
-+      struct evtchn_bind_interdomain bind_interdomain;
-+
-+      /* Already connected through? */
-+      if (netif->irq)
-+              return 0;
-+
-+      netif->tx_comms_area = alloc_vm_area(PAGE_SIZE);
-+      if (netif->tx_comms_area == NULL)
-+              return -ENOMEM;
-+      netif->rx_comms_area = alloc_vm_area(PAGE_SIZE);
-+      if (netif->rx_comms_area == NULL)
-+              goto err_rx;
-+
-+      err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref);
-+      if (err)
-+              goto err_map;
-+
-+      bind_interdomain.remote_dom = netif->domid;
-+      bind_interdomain.remote_port = evtchn;
-+
-+      err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-+                                        &bind_interdomain);
-+      if (err)
-+              goto err_hypervisor;
-+
-+      netif->evtchn = bind_interdomain.local_port;
-+
-+      netif->irq = bind_evtchn_to_irqhandler(
-+              netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
-+      disable_irq(netif->irq);
-+
-+      txs = (netif_tx_sring_t *)netif->tx_comms_area->addr;
-+      BACK_RING_INIT(&netif->tx, txs, PAGE_SIZE);
-+
-+      rxs = (netif_rx_sring_t *)
-+              ((char *)netif->rx_comms_area->addr);
-+      BACK_RING_INIT(&netif->rx, rxs, PAGE_SIZE);
-+
-+      netif->rx_req_cons_peek = 0;
-+
-+      netif_get(netif);
-+
-+      rtnl_lock();
-+      netif_carrier_on(netif->dev);
-+      if (netif_running(netif->dev))
-+              __netif_up(netif);
-+      rtnl_unlock();
-+
-+      return 0;
-+err_hypervisor:
-+      unmap_frontend_pages(netif);
-+err_map:
-+      free_vm_area(netif->rx_comms_area);
-+err_rx:
-+      free_vm_area(netif->tx_comms_area);
-+      return err;
-+}
-+
-+void netif_disconnect(netif_t *netif)
-+{
-+      if (netif_carrier_ok(netif->dev)) {
-+              rtnl_lock();
-+              netif_carrier_off(netif->dev);
-+              if (netif_running(netif->dev))
-+                      __netif_down(netif);
-+              rtnl_unlock();
-+              netif_put(netif);
-+      }
-+
-+      atomic_dec(&netif->refcnt);
-+      wait_event(netif->waiting_to_free, atomic_read(&netif->refcnt) == 0);
-+
-+      del_timer_sync(&netif->credit_timeout);
-+      del_timer_sync(&netif->tx_queue_timeout);
-+
-+      if (netif->irq)
-+              unbind_from_irqhandler(netif->irq, netif);
-+      
-+      unregister_netdev(netif->dev);
-+
-+      if (netif->tx.sring) {
-+              unmap_frontend_pages(netif);
-+              free_vm_area(netif->tx_comms_area);
-+              free_vm_area(netif->rx_comms_area);
-+      }
-+
-+      free_netdev(netif->dev);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/netback/loopback.c linux-2.6.16.33/drivers/xen/netback/loopback.c
---- linux-2.6.16.33-noxen/drivers/xen/netback/loopback.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/netback/loopback.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,321 @@
-+/******************************************************************************
-+ * netback/loopback.c
-+ * 
-+ * A two-interface loopback device to emulate a local netfront-netback
-+ * connection. This ensures that local packet delivery looks identical
-+ * to inter-domain delivery. Most importantly, packets delivered locally
-+ * originating from other domains will get *copied* when they traverse this
-+ * driver. This prevents unbounded delays in socket-buffer queues from
-+ * causing the netback driver to "seize up".
-+ * 
-+ * This driver creates a symmetric pair of loopback interfaces with names
-+ * vif0.0 and veth0. The intention is that 'vif0.0' is bound to an Ethernet
-+ * bridge, just like a proper netback interface, while a local IP interface
-+ * is configured on 'veth0'.
-+ * 
-+ * As with a real netback interface, vif0.0 is configured with a suitable
-+ * dummy MAC address. No default is provided for veth0: a reasonable strategy
-+ * is to transfer eth0's MAC address to veth0, and give eth0 a dummy address
-+ * (to avoid confusing the Etherbridge).
-+ * 
-+ * Copyright (c) 2005 K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/netdevice.h>
-+#include <linux/inetdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/ethtool.h>
-+#include <net/dst.h>
-+#include <net/xfrm.h>         /* secpath_reset() */
-+#include <asm/hypervisor.h>   /* is_initial_xendomain() */
-+
-+static int nloopbacks = -1;
-+module_param(nloopbacks, int, 0);
-+MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create");
-+
-+struct net_private {
-+      struct net_device *loopback_dev;
-+      struct net_device_stats stats;
-+};
-+
-+static int loopback_open(struct net_device *dev)
-+{
-+      struct net_private *np = netdev_priv(dev);
-+      memset(&np->stats, 0, sizeof(np->stats));
-+      netif_start_queue(dev);
-+      return 0;
-+}
-+
-+static int loopback_close(struct net_device *dev)
-+{
-+      netif_stop_queue(dev);
-+      return 0;
-+}
-+
-+#ifdef CONFIG_X86
-+static int is_foreign(unsigned long pfn)
-+{
-+      /* NB. Play it safe for auto-translation mode. */
-+      return (xen_feature(XENFEAT_auto_translated_physmap) ||
-+              (phys_to_machine_mapping[pfn] & FOREIGN_FRAME_BIT));
-+}
-+#else
-+/* How to detect a foreign mapping? Play it safe. */
-+#define is_foreign(pfn)       (1)
-+#endif
-+
-+static int skb_remove_foreign_references(struct sk_buff *skb)
-+{
-+      struct page *page;
-+      unsigned long pfn;
-+      int i, off;
-+      char *vaddr;
-+
-+      BUG_ON(skb_shinfo(skb)->frag_list);
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              pfn = page_to_pfn(skb_shinfo(skb)->frags[i].page);
-+              if (!is_foreign(pfn))
-+                      continue;
-+              
-+              page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
-+              if (unlikely(!page))
-+                      return 0;
-+
-+              vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
-+              off = skb_shinfo(skb)->frags[i].page_offset;
-+              memcpy(page_address(page) + off,
-+                     vaddr + off,
-+                     skb_shinfo(skb)->frags[i].size);
-+              kunmap_skb_frag(vaddr);
-+
-+              put_page(skb_shinfo(skb)->frags[i].page);
-+              skb_shinfo(skb)->frags[i].page = page;
-+      }
-+
-+      return 1;
-+}
-+
-+static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      struct net_private *np = netdev_priv(dev);
-+
-+      if (!skb_remove_foreign_references(skb)) {
-+              np->stats.tx_dropped++;
-+              dev_kfree_skb(skb);
-+              return 0;
-+      }
-+
-+      dst_release(skb->dst);
-+      skb->dst = NULL;
-+
-+      skb_orphan(skb);
-+
-+      np->stats.tx_bytes += skb->len;
-+      np->stats.tx_packets++;
-+
-+      /* Switch to loopback context. */
-+      dev = np->loopback_dev;
-+      np  = netdev_priv(dev);
-+
-+      np->stats.rx_bytes += skb->len;
-+      np->stats.rx_packets++;
-+
-+      if (skb->ip_summed == CHECKSUM_HW) {
-+              /* Defer checksum calculation. */
-+              skb->proto_csum_blank = 1;
-+              /* Must be a local packet: assert its integrity. */
-+              skb->proto_data_valid = 1;
-+      }
-+
-+      skb->ip_summed = skb->proto_data_valid ?
-+              CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
-+
-+      skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
-+      skb->protocol = eth_type_trans(skb, dev);
-+      skb->dev      = dev;
-+      dev->last_rx  = jiffies;
-+
-+      /* Flush netfilter context: rx'ed skbuffs not expected to have any. */
-+      nf_reset(skb);
-+      secpath_reset(skb);
-+
-+      netif_rx(skb);
-+
-+      return 0;
-+}
-+
-+static struct net_device_stats *loopback_get_stats(struct net_device *dev)
-+{
-+      struct net_private *np = netdev_priv(dev);
-+      return &np->stats;
-+}
-+
-+static struct ethtool_ops network_ethtool_ops =
-+{
-+      .get_tx_csum = ethtool_op_get_tx_csum,
-+      .set_tx_csum = ethtool_op_set_tx_csum,
-+      .get_sg = ethtool_op_get_sg,
-+      .set_sg = ethtool_op_set_sg,
-+      .get_tso = ethtool_op_get_tso,
-+      .set_tso = ethtool_op_set_tso,
-+      .get_link = ethtool_op_get_link,
-+};
-+
-+/*
-+ * Nothing to do here. Virtual interface is point-to-point and the
-+ * physical interface is probably promiscuous anyway.
-+ */
-+static void loopback_set_multicast_list(struct net_device *dev)
-+{
-+}
-+
-+static void loopback_construct(struct net_device *dev, struct net_device *lo)
-+{
-+      struct net_private *np = netdev_priv(dev);
-+
-+      np->loopback_dev     = lo;
-+
-+      dev->open            = loopback_open;
-+      dev->stop            = loopback_close;
-+      dev->hard_start_xmit = loopback_start_xmit;
-+      dev->get_stats       = loopback_get_stats;
-+      dev->set_multicast_list = loopback_set_multicast_list;
-+      dev->change_mtu      = NULL; /* allow arbitrary mtu */
-+
-+      dev->tx_queue_len    = 0;
-+
-+      dev->features        = (NETIF_F_HIGHDMA |
-+                              NETIF_F_LLTX |
-+                              NETIF_F_TSO |
-+                              NETIF_F_SG |
-+                              NETIF_F_IP_CSUM);
-+
-+      SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
-+
-+      /*
-+       * We do not set a jumbo MTU on the interface. Otherwise the network
-+       * stack will try to send large packets that will get dropped by the
-+       * Ethernet bridge (unless the physical Ethernet interface is
-+       * configured to transfer jumbo packets). If a larger MTU is desired
-+       * then the system administrator can specify it using the 'ifconfig'
-+       * command.
-+       */
-+      /*dev->mtu             = 16*1024;*/
-+}
-+
-+static int __init make_loopback(int i)
-+{
-+      struct net_device *dev1, *dev2;
-+      char dev_name[IFNAMSIZ];
-+      int err = -ENOMEM;
-+
-+      sprintf(dev_name, "vif0.%d", i);
-+      dev1 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
-+      if (!dev1)
-+              return err;
-+
-+      sprintf(dev_name, "veth%d", i);
-+      dev2 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
-+      if (!dev2)
-+              goto fail_netdev2;
-+
-+      loopback_construct(dev1, dev2);
-+      loopback_construct(dev2, dev1);
-+
-+      /*
-+       * Initialise a dummy MAC address for the 'dummy backend' interface. We
-+       * choose the numerically largest non-broadcast address to prevent the
-+       * address getting stolen by an Ethernet bridge for STP purposes.
-+       */
-+      memset(dev1->dev_addr, 0xFF, ETH_ALEN);
-+      dev1->dev_addr[0] &= ~0x01;
-+
-+      if ((err = register_netdev(dev1)) != 0)
-+              goto fail;
-+
-+      if ((err = register_netdev(dev2)) != 0) {
-+              unregister_netdev(dev1);
-+              goto fail;
-+      }
-+
-+      return 0;
-+
-+ fail:
-+      free_netdev(dev2);
-+ fail_netdev2:
-+      free_netdev(dev1);
-+      return err;
-+}
-+
-+static void __exit clean_loopback(int i)
-+{
-+      struct net_device *dev1, *dev2;
-+      char dev_name[IFNAMSIZ];
-+
-+      sprintf(dev_name, "vif0.%d", i);
-+      dev1 = dev_get_by_name(dev_name);
-+      sprintf(dev_name, "veth%d", i);
-+      dev2 = dev_get_by_name(dev_name);
-+      if (dev1 && dev2) {
-+              unregister_netdev(dev2);
-+              unregister_netdev(dev1);
-+              free_netdev(dev2);
-+              free_netdev(dev1);
-+      }
-+}
-+
-+static int __init loopback_init(void)
-+{
-+      int i, err = 0;
-+
-+      if (nloopbacks == -1)
-+              nloopbacks = is_initial_xendomain() ? 4 : 0;
-+
-+      for (i = 0; i < nloopbacks; i++)
-+              if ((err = make_loopback(i)) != 0)
-+                      break;
-+
-+      return err;
-+}
-+
-+module_init(loopback_init);
-+
-+static void __exit loopback_exit(void)
-+{
-+      int i;
-+
-+      for (i = nloopbacks; i-- > 0; )
-+              clean_loopback(i);
-+}
-+
-+module_exit(loopback_exit);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/netback/netback.c linux-2.6.16.33/drivers/xen/netback/netback.c
---- linux-2.6.16.33-noxen/drivers/xen/netback/netback.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/netback/netback.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1523 @@
-+/******************************************************************************
-+ * drivers/xen/netback/netback.c
-+ * 
-+ * Back-end of the driver for virtual network devices. This portion of the
-+ * driver exports a 'unified' network-device interface that can be accessed
-+ * by any operating system that implements a compatible front end. A 
-+ * reference front-end implementation can be found in:
-+ *  drivers/xen/netfront/netfront.c
-+ * 
-+ * Copyright (c) 2002-2005, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include "common.h"
-+#include <xen/balloon.h>
-+#include <xen/interface/memory.h>
-+
-+/*#define NETBE_DEBUG_INTERRUPT*/
-+
-+struct netbk_rx_meta {
-+      skb_frag_t frag;
-+      int id;
-+      int copy:1;
-+};
-+
-+static void netif_idx_release(u16 pending_idx);
-+static void netif_page_release(struct page *page);
-+static void make_tx_response(netif_t *netif, 
-+                           netif_tx_request_t *txp,
-+                           s8       st);
-+static netif_rx_response_t *make_rx_response(netif_t *netif, 
-+                                           u16      id, 
-+                                           s8       st,
-+                                           u16      offset,
-+                                           u16      size,
-+                                           u16      flags);
-+
-+static void net_tx_action(unsigned long unused);
-+static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0);
-+
-+static void net_rx_action(unsigned long unused);
-+static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0);
-+
-+static struct timer_list net_timer;
-+
-+#define MAX_PENDING_REQS 256
-+
-+static struct sk_buff_head rx_queue;
-+
-+static struct page **mmap_pages;
-+static inline unsigned long idx_to_kaddr(unsigned int idx)
-+{
-+      return (unsigned long)pfn_to_kaddr(page_to_pfn(mmap_pages[idx]));
-+}
-+
-+#define PKT_PROT_LEN 64
-+
-+static struct pending_tx_info {
-+      netif_tx_request_t req;
-+      netif_t *netif;
-+} pending_tx_info[MAX_PENDING_REQS];
-+static u16 pending_ring[MAX_PENDING_REQS];
-+typedef unsigned int PEND_RING_IDX;
-+#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
-+static PEND_RING_IDX pending_prod, pending_cons;
-+#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
-+
-+/* Freed TX SKBs get batched on this ring before return to pending_ring. */
-+static u16 dealloc_ring[MAX_PENDING_REQS];
-+static PEND_RING_IDX dealloc_prod, dealloc_cons;
-+
-+static struct sk_buff_head tx_queue;
-+
-+static grant_handle_t grant_tx_handle[MAX_PENDING_REQS];
-+static gnttab_unmap_grant_ref_t tx_unmap_ops[MAX_PENDING_REQS];
-+static gnttab_map_grant_ref_t tx_map_ops[MAX_PENDING_REQS];
-+
-+static struct list_head net_schedule_list;
-+static spinlock_t net_schedule_list_lock;
-+
-+#define MAX_MFN_ALLOC 64
-+static unsigned long mfn_list[MAX_MFN_ALLOC];
-+static unsigned int alloc_index = 0;
-+
-+static inline unsigned long alloc_mfn(void)
-+{
-+      return mfn_list[--alloc_index];
-+}
-+
-+static int check_mfn(int nr)
-+{
-+      struct xen_memory_reservation reservation = {
-+              .extent_order = 0,
-+              .domid        = DOMID_SELF
-+      };
-+
-+      if (likely(alloc_index >= nr))
-+              return 0;
-+
-+      set_xen_guest_handle(reservation.extent_start, mfn_list + alloc_index);
-+      reservation.nr_extents = MAX_MFN_ALLOC - alloc_index;
-+      alloc_index += HYPERVISOR_memory_op(XENMEM_increase_reservation,
-+                                          &reservation);
-+
-+      return alloc_index >= nr ? 0 : -ENOMEM;
-+}
-+
-+static inline void maybe_schedule_tx_action(void)
-+{
-+      smp_mb();
-+      if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
-+          !list_empty(&net_schedule_list))
-+              tasklet_schedule(&net_tx_tasklet);
-+}
-+
-+/*
-+ * A gross way of confirming the origin of an skb data page. The slab
-+ * allocator abuses a field in the page struct to cache the kmem_cache_t ptr.
-+ */
-+static inline int is_xen_skb(struct sk_buff *skb)
-+{
-+      extern kmem_cache_t *skbuff_cachep;
-+      kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next;
-+      return (cp == skbuff_cachep);
-+}
-+
-+/*
-+ * We can flip without copying the packet unless:
-+ *  1. The data is not allocated from our special cache; or
-+ *  2. The main data area is shared; or
-+ *  3. One or more fragments are shared; or
-+ *  4. There are chained fragments.
-+ */
-+static inline int is_flippable_skb(struct sk_buff *skb)
-+{
-+      int frag;
-+
-+      if (!is_xen_skb(skb) || skb_cloned(skb))
-+              return 0;
-+
-+      for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
-+              if (page_count(skb_shinfo(skb)->frags[frag].page) > 1)
-+                      return 0;
-+      }
-+
-+      if (skb_shinfo(skb)->frag_list != NULL)
-+              return 0;
-+
-+      return 1;
-+}
-+
-+static struct sk_buff *netbk_copy_skb(struct sk_buff *skb)
-+{
-+      struct skb_shared_info *ninfo;
-+      struct sk_buff *nskb;
-+      unsigned long offset;
-+      int ret;
-+      int len;
-+      int headlen;
-+
-+      BUG_ON(skb_shinfo(skb)->frag_list != NULL);
-+
-+      nskb = alloc_skb(SKB_MAX_HEAD(0), GFP_ATOMIC | __GFP_NOWARN);
-+      if (unlikely(!nskb))
-+              goto err;
-+
-+      skb_reserve(nskb, 16 + NET_IP_ALIGN);
-+      headlen = nskb->end - nskb->data;
-+      if (headlen > skb_headlen(skb))
-+              headlen = skb_headlen(skb);
-+      ret = skb_copy_bits(skb, 0, __skb_put(nskb, headlen), headlen);
-+      BUG_ON(ret);
-+
-+      ninfo = skb_shinfo(nskb);
-+      ninfo->gso_size = skb_shinfo(skb)->gso_size;
-+      ninfo->gso_type = skb_shinfo(skb)->gso_type;
-+
-+      offset = headlen;
-+      len = skb->len - headlen;
-+
-+      nskb->len = skb->len;
-+      nskb->data_len = len;
-+      nskb->truesize += len;
-+
-+      while (len) {
-+              struct page *page;
-+              int copy;
-+              int zero;
-+
-+              if (unlikely(ninfo->nr_frags >= MAX_SKB_FRAGS)) {
-+                      dump_stack();
-+                      goto err_free;
-+              }
-+
-+              copy = len >= PAGE_SIZE ? PAGE_SIZE : len;
-+              zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO;
-+
-+              page = alloc_page(GFP_ATOMIC | __GFP_NOWARN | zero);
-+              if (unlikely(!page))
-+                      goto err_free;
-+
-+              ret = skb_copy_bits(skb, offset, page_address(page), copy);
-+              BUG_ON(ret);
-+
-+              ninfo->frags[ninfo->nr_frags].page = page;
-+              ninfo->frags[ninfo->nr_frags].page_offset = 0;
-+              ninfo->frags[ninfo->nr_frags].size = copy;
-+              ninfo->nr_frags++;
-+
-+              offset += copy;
-+              len -= copy;
-+      }
-+
-+      offset = nskb->data - skb->data;
-+
-+      nskb->h.raw = skb->h.raw + offset;
-+      nskb->nh.raw = skb->nh.raw + offset;
-+      nskb->mac.raw = skb->mac.raw + offset;
-+
-+      return nskb;
-+
-+ err_free:
-+      kfree_skb(nskb);
-+ err:
-+      return NULL;
-+}
-+
-+static inline int netbk_max_required_rx_slots(netif_t *netif)
-+{
-+      if (netif->features & (NETIF_F_SG|NETIF_F_TSO))
-+              return MAX_SKB_FRAGS + 2; /* header + extra_info + frags */
-+      return 1; /* all in one */
-+}
-+
-+static inline int netbk_queue_full(netif_t *netif)
-+{
-+      RING_IDX peek   = netif->rx_req_cons_peek;
-+      RING_IDX needed = netbk_max_required_rx_slots(netif);
-+
-+      return ((netif->rx.sring->req_prod - peek) < needed) ||
-+             ((netif->rx.rsp_prod_pvt + NET_RX_RING_SIZE - peek) < needed);
-+}
-+
-+static void tx_queue_callback(unsigned long data)
-+{
-+      netif_t *netif = (netif_t *)data;
-+      if (netif_schedulable(netif->dev))
-+              netif_wake_queue(netif->dev);
-+}
-+
-+int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      netif_t *netif = netdev_priv(dev);
-+
-+      BUG_ON(skb->dev != dev);
-+
-+      /* Drop the packet if the target domain has no receive buffers. */
-+      if (unlikely(!netif_schedulable(dev) || netbk_queue_full(netif)))
-+              goto drop;
-+
-+      /*
-+       * Copy the packet here if it's destined for a flipping interface
-+       * but isn't flippable (e.g. extra references to data).
-+       */
-+      if (!netif->copying_receiver && !is_flippable_skb(skb)) {
-+              struct sk_buff *nskb = netbk_copy_skb(skb);
-+              if ( unlikely(nskb == NULL) )
-+                      goto drop;
-+              /* Copy only the header fields we use in this driver. */
-+              nskb->dev = skb->dev;
-+              nskb->ip_summed = skb->ip_summed;
-+              nskb->proto_data_valid = skb->proto_data_valid;
-+              dev_kfree_skb(skb);
-+              skb = nskb;
-+      }
-+
-+      netif->rx_req_cons_peek += skb_shinfo(skb)->nr_frags + 1 +
-+                                 !!skb_shinfo(skb)->gso_size;
-+      netif_get(netif);
-+
-+      if (netbk_can_queue(dev) && netbk_queue_full(netif)) {
-+              netif->rx.sring->req_event = netif->rx_req_cons_peek +
-+                      netbk_max_required_rx_slots(netif);
-+              mb(); /* request notification /then/ check & stop the queue */
-+              if (netbk_queue_full(netif)) {
-+                      netif_stop_queue(dev);
-+                      /*
-+                       * Schedule 500ms timeout to restart the queue, thus
-+                       * ensuring that an inactive queue will be drained.
-+                       * Packets will be immediately be dropped until more
-+                       * receive buffers become available (see
-+                       * netbk_queue_full() check above).
-+                       */
-+                      netif->tx_queue_timeout.data = (unsigned long)netif;
-+                      netif->tx_queue_timeout.function = tx_queue_callback;
-+                      __mod_timer(&netif->tx_queue_timeout, jiffies + HZ/2);
-+              }
-+      }
-+
-+      skb_queue_tail(&rx_queue, skb);
-+      tasklet_schedule(&net_rx_tasklet);
-+
-+      return 0;
-+
-+ drop:
-+      netif->stats.tx_dropped++;
-+      dev_kfree_skb(skb);
-+      return 0;
-+}
-+
-+#if 0
-+static void xen_network_done_notify(void)
-+{
-+      static struct net_device *eth0_dev = NULL;
-+      if (unlikely(eth0_dev == NULL))
-+              eth0_dev = __dev_get_by_name("eth0");
-+      netif_rx_schedule(eth0_dev);
-+}
-+/* 
-+ * Add following to poll() function in NAPI driver (Tigon3 is example):
-+ *  if ( xen_network_done() )
-+ *      tg3_enable_ints(tp);
-+ */
-+int xen_network_done(void)
-+{
-+      return skb_queue_empty(&rx_queue);
-+}
-+#endif
-+
-+struct netrx_pending_operations {
-+      unsigned trans_prod, trans_cons;
-+      unsigned mmu_prod, mmu_cons;
-+      unsigned mcl_prod, mcl_cons;
-+      unsigned copy_prod, copy_cons;
-+      unsigned meta_prod, meta_cons;
-+      mmu_update_t *mmu;
-+      gnttab_transfer_t *trans;
-+      gnttab_copy_t *copy;
-+      multicall_entry_t *mcl;
-+      struct netbk_rx_meta *meta;
-+};
-+
-+/* Set up the grant operations for this fragment.  If it's a flipping
-+   interface, we also set up the unmap request from here. */
-+static u16 netbk_gop_frag(netif_t *netif, struct netbk_rx_meta *meta,
-+                        int i, struct netrx_pending_operations *npo,
-+                        struct page *page, unsigned long size,
-+                        unsigned long offset)
-+{
-+      mmu_update_t *mmu;
-+      gnttab_transfer_t *gop;
-+      gnttab_copy_t *copy_gop;
-+      multicall_entry_t *mcl;
-+      netif_rx_request_t *req;
-+      unsigned long old_mfn, new_mfn;
-+
-+      old_mfn = virt_to_mfn(page_address(page));
-+
-+      req = RING_GET_REQUEST(&netif->rx, netif->rx.req_cons + i);
-+      if (netif->copying_receiver) {
-+              /* The fragment needs to be copied rather than
-+                 flipped. */
-+              meta->copy = 1;
-+              copy_gop = npo->copy + npo->copy_prod++;
-+              copy_gop->flags = GNTCOPY_dest_gref;
-+              if (PageForeign(page)) {
-+                      struct pending_tx_info *src_pend =
-+                              &pending_tx_info[page->index];
-+                      copy_gop->source.domid = src_pend->netif->domid;
-+                      copy_gop->source.u.ref = src_pend->req.gref;
-+                      copy_gop->flags |= GNTCOPY_source_gref;
-+              } else {
-+                      copy_gop->source.domid = DOMID_SELF;
-+                      copy_gop->source.u.gmfn = old_mfn;
-+              }
-+              copy_gop->source.offset = offset;
-+              copy_gop->dest.domid = netif->domid;
-+              copy_gop->dest.offset = 0;
-+              copy_gop->dest.u.ref = req->gref;
-+              copy_gop->len = size;
-+      } else {
-+              meta->copy = 0;
-+              if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      new_mfn = alloc_mfn();
-+
-+                      /*
-+                       * Set the new P2M table entry before
-+                       * reassigning the old data page. Heed the
-+                       * comment in pgtable-2level.h:pte_page(). :-)
-+                       */
-+                      set_phys_to_machine(page_to_pfn(page), new_mfn);
-+
-+                      mcl = npo->mcl + npo->mcl_prod++;
-+                      MULTI_update_va_mapping(mcl,
-+                                           (unsigned long)page_address(page),
-+                                           pfn_pte_ma(new_mfn, PAGE_KERNEL),
-+                                           0);
-+
-+                      mmu = npo->mmu + npo->mmu_prod++;
-+                      mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
-+                              MMU_MACHPHYS_UPDATE;
-+                      mmu->val = page_to_pfn(page);
-+              }
-+
-+              gop = npo->trans + npo->trans_prod++;
-+              gop->mfn = old_mfn;
-+              gop->domid = netif->domid;
-+              gop->ref = req->gref;
-+      }
-+      return req->id;
-+}
-+
-+static void netbk_gop_skb(struct sk_buff *skb,
-+                        struct netrx_pending_operations *npo)
-+{
-+      netif_t *netif = netdev_priv(skb->dev);
-+      int nr_frags = skb_shinfo(skb)->nr_frags;
-+      int i;
-+      int extra;
-+      struct netbk_rx_meta *head_meta, *meta;
-+
-+      head_meta = npo->meta + npo->meta_prod++;
-+      head_meta->frag.page_offset = skb_shinfo(skb)->gso_type;
-+      head_meta->frag.size = skb_shinfo(skb)->gso_size;
-+      extra = !!head_meta->frag.size + 1;
-+
-+      for (i = 0; i < nr_frags; i++) {
-+              meta = npo->meta + npo->meta_prod++;
-+              meta->frag = skb_shinfo(skb)->frags[i];
-+              meta->id = netbk_gop_frag(netif, meta, i + extra, npo,
-+                                        meta->frag.page,
-+                                        meta->frag.size,
-+                                        meta->frag.page_offset);
-+      }
-+
-+      /*
-+       * This must occur at the end to ensure that we don't trash
-+       * skb_shinfo until we're done.
-+       */
-+      head_meta->id = netbk_gop_frag(netif, head_meta, 0, npo,
-+                                     virt_to_page(skb->data),
-+                                     skb_headlen(skb),
-+                                     offset_in_page(skb->data));
-+
-+      netif->rx.req_cons += nr_frags + extra;
-+}
-+
-+static inline void netbk_free_pages(int nr_frags, struct netbk_rx_meta *meta)
-+{
-+      int i;
-+
-+      for (i = 0; i < nr_frags; i++)
-+              put_page(meta[i].frag.page);
-+}
-+
-+/* This is a twin to netbk_gop_skb.  Assume that netbk_gop_skb was
-+   used to set up the operations on the top of
-+   netrx_pending_operations, which have since been done.  Check that
-+   they didn't give any errors and advance over them. */
-+static int netbk_check_gop(int nr_frags, domid_t domid,
-+                         struct netrx_pending_operations *npo)
-+{
-+      multicall_entry_t *mcl;
-+      gnttab_transfer_t *gop;
-+      gnttab_copy_t     *copy_op;
-+      int status = NETIF_RSP_OKAY;
-+      int i;
-+
-+      for (i = 0; i <= nr_frags; i++) {
-+              if (npo->meta[npo->meta_cons + i].copy) {
-+                      copy_op = npo->copy + npo->copy_cons++;
-+                      if (copy_op->status != GNTST_okay) {
-+                              DPRINTK("Bad status %d from copy to DOM%d.\n",
-+                                      copy_op->status, domid);
-+                              status = NETIF_RSP_ERROR;
-+                      }
-+              } else {
-+                      if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                              mcl = npo->mcl + npo->mcl_cons++;
-+                              /* The update_va_mapping() must not fail. */
-+                              BUG_ON(mcl->result != 0);
-+                      }
-+
-+                      gop = npo->trans + npo->trans_cons++;
-+                      /* Check the reassignment error code. */
-+                      if (gop->status != 0) {
-+                              DPRINTK("Bad status %d from grant transfer to DOM%u\n",
-+                                      gop->status, domid);
-+                              /*
-+                               * Page no longer belongs to us unless
-+                               * GNTST_bad_page, but that should be
-+                               * a fatal error anyway.
-+                               */
-+                              BUG_ON(gop->status == GNTST_bad_page);
-+                              status = NETIF_RSP_ERROR;
-+                      }
-+              }
-+      }
-+
-+      return status;
-+}
-+
-+static void netbk_add_frag_responses(netif_t *netif, int status,
-+                                   struct netbk_rx_meta *meta, int nr_frags)
-+{
-+      int i;
-+      unsigned long offset;
-+
-+      for (i = 0; i < nr_frags; i++) {
-+              int id = meta[i].id;
-+              int flags = (i == nr_frags - 1) ? 0 : NETRXF_more_data;
-+
-+              if (meta[i].copy)
-+                      offset = 0;
-+              else
-+                      offset = meta[i].frag.page_offset;
-+              make_rx_response(netif, id, status, offset,
-+                               meta[i].frag.size, flags);
-+      }
-+}
-+
-+static void net_rx_action(unsigned long unused)
-+{
-+      netif_t *netif = NULL;
-+      s8 status;
-+      u16 id, irq, flags;
-+      netif_rx_response_t *resp;
-+      multicall_entry_t *mcl;
-+      struct sk_buff_head rxq;
-+      struct sk_buff *skb;
-+      int notify_nr = 0;
-+      int ret;
-+      int nr_frags;
-+      int count;
-+      unsigned long offset;
-+
-+      /*
-+       * Putting hundreds of bytes on the stack is considered rude.
-+       * Static works because a tasklet can only be on one CPU at any time.
-+       */
-+      static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+3];
-+      static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
-+      static gnttab_transfer_t grant_trans_op[NET_RX_RING_SIZE];
-+      static gnttab_copy_t grant_copy_op[NET_RX_RING_SIZE];
-+      static unsigned char rx_notify[NR_IRQS];
-+      static u16 notify_list[NET_RX_RING_SIZE];
-+      static struct netbk_rx_meta meta[NET_RX_RING_SIZE];
-+
-+      struct netrx_pending_operations npo = {
-+              mmu: rx_mmu,
-+              trans: grant_trans_op,
-+              copy: grant_copy_op,
-+              mcl: rx_mcl,
-+              meta: meta};
-+
-+      skb_queue_head_init(&rxq);
-+
-+      count = 0;
-+
-+      while ((skb = skb_dequeue(&rx_queue)) != NULL) {
-+              nr_frags = skb_shinfo(skb)->nr_frags;
-+              *(int *)skb->cb = nr_frags;
-+
-+              if (!xen_feature(XENFEAT_auto_translated_physmap) &&
-+                  check_mfn(nr_frags + 1)) {
-+                      /* Memory squeeze? Back off for an arbitrary while. */
-+                      if ( net_ratelimit() )
-+                              WPRINTK("Memory squeeze in netback "
-+                                      "driver.\n");
-+                      mod_timer(&net_timer, jiffies + HZ);
-+                      skb_queue_head(&rx_queue, skb);
-+                      break;
-+              }
-+
-+              netbk_gop_skb(skb, &npo);
-+
-+              count += nr_frags + 1;
-+
-+              __skb_queue_tail(&rxq, skb);
-+
-+              /* Filled the batch queue? */
-+              if (count + MAX_SKB_FRAGS >= NET_RX_RING_SIZE)
-+                      break;
-+      }
-+
-+      if (npo.mcl_prod &&
-+          !xen_feature(XENFEAT_auto_translated_physmap)) {
-+              mcl = npo.mcl + npo.mcl_prod++;
-+
-+              BUG_ON(mcl[-1].op != __HYPERVISOR_update_va_mapping);
-+              mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
-+
-+              mcl->op = __HYPERVISOR_mmu_update;
-+              mcl->args[0] = (unsigned long)rx_mmu;
-+              mcl->args[1] = npo.mmu_prod;
-+              mcl->args[2] = 0;
-+              mcl->args[3] = DOMID_SELF;
-+      }
-+
-+      if (npo.trans_prod) {
-+              mcl = npo.mcl + npo.mcl_prod++;
-+              mcl->op = __HYPERVISOR_grant_table_op;
-+              mcl->args[0] = GNTTABOP_transfer;
-+              mcl->args[1] = (unsigned long)grant_trans_op;
-+              mcl->args[2] = npo.trans_prod;
-+      }
-+
-+      if (npo.copy_prod) {
-+              mcl = npo.mcl + npo.mcl_prod++;
-+              mcl->op = __HYPERVISOR_grant_table_op;
-+              mcl->args[0] = GNTTABOP_copy;
-+              mcl->args[1] = (unsigned long)grant_copy_op;
-+              mcl->args[2] = npo.copy_prod;
-+      }
-+
-+      /* Nothing to do? */
-+      if (!npo.mcl_prod)
-+              return;
-+
-+      BUG_ON(npo.copy_prod > NET_RX_RING_SIZE);
-+      BUG_ON(npo.mmu_prod > NET_RX_RING_SIZE);
-+      BUG_ON(npo.trans_prod > NET_RX_RING_SIZE);
-+      BUG_ON(npo.mcl_prod > NET_RX_RING_SIZE+3);
-+      BUG_ON(npo.meta_prod > NET_RX_RING_SIZE);
-+
-+      ret = HYPERVISOR_multicall(npo.mcl, npo.mcl_prod);
-+      BUG_ON(ret != 0);
-+
-+      while ((skb = __skb_dequeue(&rxq)) != NULL) {
-+              nr_frags = *(int *)skb->cb;
-+
-+              netif = netdev_priv(skb->dev);
-+              /* We can't rely on skb_release_data to release the
-+                 pages used by fragments for us, since it tries to
-+                 touch the pages in the fraglist.  If we're in
-+                 flipping mode, that doesn't work.  In copying mode,
-+                 we still have access to all of the pages, and so
-+                 it's safe to let release_data deal with it. */
-+              /* (Freeing the fragments is safe since we copy
-+                 non-linear skbs destined for flipping interfaces) */
-+              if (!netif->copying_receiver) {
-+                      atomic_set(&(skb_shinfo(skb)->dataref), 1);
-+                      skb_shinfo(skb)->frag_list = NULL;
-+                      skb_shinfo(skb)->nr_frags = 0;
-+                      netbk_free_pages(nr_frags, meta + npo.meta_cons + 1);
-+              }
-+
-+              netif->stats.tx_bytes += skb->len;
-+              netif->stats.tx_packets++;
-+
-+              status = netbk_check_gop(nr_frags, netif->domid, &npo);
-+
-+              id = meta[npo.meta_cons].id;
-+              flags = nr_frags ? NETRXF_more_data : 0;
-+
-+              if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
-+                      flags |= NETRXF_csum_blank | NETRXF_data_validated;
-+              else if (skb->proto_data_valid) /* remote but checksummed? */
-+                      flags |= NETRXF_data_validated;
-+
-+              if (meta[npo.meta_cons].copy)
-+                      offset = 0;
-+              else
-+                      offset = offset_in_page(skb->data);
-+              resp = make_rx_response(netif, id, status, offset,
-+                                      skb_headlen(skb), flags);
-+
-+              if (meta[npo.meta_cons].frag.size) {
-+                      struct netif_extra_info *gso =
-+                              (struct netif_extra_info *)
-+                              RING_GET_RESPONSE(&netif->rx,
-+                                                netif->rx.rsp_prod_pvt++);
-+
-+                      resp->flags |= NETRXF_extra_info;
-+
-+                      gso->u.gso.size = meta[npo.meta_cons].frag.size;
-+                      gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
-+                      gso->u.gso.pad = 0;
-+                      gso->u.gso.features = 0;
-+
-+                      gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
-+                      gso->flags = 0;
-+              }
-+
-+              netbk_add_frag_responses(netif, status,
-+                                       meta + npo.meta_cons + 1,
-+                                       nr_frags);
-+
-+              RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, ret);
-+              irq = netif->irq;
-+              if (ret && !rx_notify[irq]) {
-+                      rx_notify[irq] = 1;
-+                      notify_list[notify_nr++] = irq;
-+              }
-+
-+              if (netif_queue_stopped(netif->dev) &&
-+                  netif_schedulable(netif->dev) &&
-+                  !netbk_queue_full(netif))
-+                      netif_wake_queue(netif->dev);
-+
-+              netif_put(netif);
-+              dev_kfree_skb(skb);
-+              npo.meta_cons += nr_frags + 1;
-+      }
-+
-+      while (notify_nr != 0) {
-+              irq = notify_list[--notify_nr];
-+              rx_notify[irq] = 0;
-+              notify_remote_via_irq(irq);
-+      }
-+
-+      /* More work to do? */
-+      if (!skb_queue_empty(&rx_queue) && !timer_pending(&net_timer))
-+              tasklet_schedule(&net_rx_tasklet);
-+#if 0
-+      else
-+              xen_network_done_notify();
-+#endif
-+}
-+
-+static void net_alarm(unsigned long unused)
-+{
-+      tasklet_schedule(&net_rx_tasklet);
-+}
-+
-+struct net_device_stats *netif_be_get_stats(struct net_device *dev)
-+{
-+      netif_t *netif = netdev_priv(dev);
-+      return &netif->stats;
-+}
-+
-+static int __on_net_schedule_list(netif_t *netif)
-+{
-+      return netif->list.next != NULL;
-+}
-+
-+static void remove_from_net_schedule_list(netif_t *netif)
-+{
-+      spin_lock_irq(&net_schedule_list_lock);
-+      if (likely(__on_net_schedule_list(netif))) {
-+              list_del(&netif->list);
-+              netif->list.next = NULL;
-+              netif_put(netif);
-+      }
-+      spin_unlock_irq(&net_schedule_list_lock);
-+}
-+
-+static void add_to_net_schedule_list_tail(netif_t *netif)
-+{
-+      if (__on_net_schedule_list(netif))
-+              return;
-+
-+      spin_lock_irq(&net_schedule_list_lock);
-+      if (!__on_net_schedule_list(netif) &&
-+          likely(netif_schedulable(netif->dev))) {
-+              list_add_tail(&netif->list, &net_schedule_list);
-+              netif_get(netif);
-+      }
-+      spin_unlock_irq(&net_schedule_list_lock);
-+}
-+
-+/*
-+ * Note on CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER:
-+ * If this driver is pipelining transmit requests then we can be very
-+ * aggressive in avoiding new-packet notifications -- frontend only needs to
-+ * send a notification if there are no outstanding unreceived responses.
-+ * If we may be buffer transmit buffers for any reason then we must be rather
-+ * more conservative and treat this as the final check for pending work.
-+ */
-+void netif_schedule_work(netif_t *netif)
-+{
-+      int more_to_do;
-+
-+#ifdef CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER
-+      more_to_do = RING_HAS_UNCONSUMED_REQUESTS(&netif->tx);
-+#else
-+      RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, more_to_do);
-+#endif
-+
-+      if (more_to_do) {
-+              add_to_net_schedule_list_tail(netif);
-+              maybe_schedule_tx_action();
-+      }
-+}
-+
-+void netif_deschedule_work(netif_t *netif)
-+{
-+      remove_from_net_schedule_list(netif);
-+}
-+
-+
-+static void tx_add_credit(netif_t *netif)
-+{
-+      unsigned long max_burst, max_credit;
-+
-+      /*
-+       * Allow a burst big enough to transmit a jumbo packet of up to 128kB.
-+       * Otherwise the interface can seize up due to insufficient credit.
-+       */
-+      max_burst = RING_GET_REQUEST(&netif->tx, netif->tx.req_cons)->size;
-+      max_burst = min(max_burst, 131072UL);
-+      max_burst = max(max_burst, netif->credit_bytes);
-+
-+      /* Take care that adding a new chunk of credit doesn't wrap to zero. */
-+      max_credit = netif->remaining_credit + netif->credit_bytes;
-+      if (max_credit < netif->remaining_credit)
-+              max_credit = ULONG_MAX; /* wrapped: clamp to ULONG_MAX */
-+
-+      netif->remaining_credit = min(max_credit, max_burst);
-+}
-+
-+static void tx_credit_callback(unsigned long data)
-+{
-+      netif_t *netif = (netif_t *)data;
-+      tx_add_credit(netif);
-+      netif_schedule_work(netif);
-+}
-+
-+inline static void net_tx_action_dealloc(void)
-+{
-+      gnttab_unmap_grant_ref_t *gop;
-+      u16 pending_idx;
-+      PEND_RING_IDX dc, dp;
-+      netif_t *netif;
-+      int ret;
-+
-+      dc = dealloc_cons;
-+      dp = dealloc_prod;
-+
-+      /* Ensure we see all indexes enqueued by netif_idx_release(). */
-+      smp_rmb();
-+
-+      /*
-+       * Free up any grants we have finished using
-+       */
-+      gop = tx_unmap_ops;
-+      while (dc != dp) {
-+              pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
-+              gnttab_set_unmap_op(gop, idx_to_kaddr(pending_idx),
-+                                  GNTMAP_host_map,
-+                                  grant_tx_handle[pending_idx]);
-+              gop++;
-+      }
-+      ret = HYPERVISOR_grant_table_op(
-+              GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops);
-+      BUG_ON(ret);
-+
-+      while (dealloc_cons != dp) {
-+              pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
-+
-+              netif = pending_tx_info[pending_idx].netif;
-+
-+              make_tx_response(netif, &pending_tx_info[pending_idx].req, 
-+                               NETIF_RSP_OKAY);
-+
-+              pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
-+
-+              netif_put(netif);
-+      }
-+}
-+
-+static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end)
-+{
-+      RING_IDX cons = netif->tx.req_cons;
-+
-+      do {
-+              make_tx_response(netif, txp, NETIF_RSP_ERROR);
-+              if (cons >= end)
-+                      break;
-+              txp = RING_GET_REQUEST(&netif->tx, cons++);
-+      } while (1);
-+      netif->tx.req_cons = cons;
-+      netif_schedule_work(netif);
-+      netif_put(netif);
-+}
-+
-+static int netbk_count_requests(netif_t *netif, netif_tx_request_t *first,
-+                              netif_tx_request_t *txp, int work_to_do)
-+{
-+      RING_IDX cons = netif->tx.req_cons;
-+      int frags = 0;
-+
-+      if (!(first->flags & NETTXF_more_data))
-+              return 0;
-+
-+      do {
-+              if (frags >= work_to_do) {
-+                      DPRINTK("Need more frags\n");
-+                      return -frags;
-+              }
-+
-+              if (unlikely(frags >= MAX_SKB_FRAGS)) {
-+                      DPRINTK("Too many frags\n");
-+                      return -frags;
-+              }
-+
-+              memcpy(txp, RING_GET_REQUEST(&netif->tx, cons + frags),
-+                     sizeof(*txp));
-+              if (txp->size > first->size) {
-+                      DPRINTK("Frags galore\n");
-+                      return -frags;
-+              }
-+
-+              first->size -= txp->size;
-+              frags++;
-+
-+              if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
-+                      DPRINTK("txp->offset: %x, size: %u\n",
-+                              txp->offset, txp->size);
-+                      return -frags;
-+              }
-+      } while ((txp++)->flags & NETTXF_more_data);
-+
-+      return frags;
-+}
-+
-+static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif,
-+                                                struct sk_buff *skb,
-+                                                netif_tx_request_t *txp,
-+                                                gnttab_map_grant_ref_t *mop)
-+{
-+      struct skb_shared_info *shinfo = skb_shinfo(skb);
-+      skb_frag_t *frags = shinfo->frags;
-+      unsigned long pending_idx = *((u16 *)skb->data);
-+      int i, start;
-+
-+      /* Skip first skb fragment if it is on same page as header fragment. */
-+      start = ((unsigned long)shinfo->frags[0].page == pending_idx);
-+
-+      for (i = start; i < shinfo->nr_frags; i++, txp++) {
-+              pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
-+
-+              gnttab_set_map_op(mop++, idx_to_kaddr(pending_idx),
-+                                GNTMAP_host_map | GNTMAP_readonly,
-+                                txp->gref, netif->domid);
-+
-+              memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp));
-+              netif_get(netif);
-+              pending_tx_info[pending_idx].netif = netif;
-+              frags[i].page = (void *)pending_idx;
-+      }
-+
-+      return mop;
-+}
-+
-+static int netbk_tx_check_mop(struct sk_buff *skb,
-+                             gnttab_map_grant_ref_t **mopp)
-+{
-+      gnttab_map_grant_ref_t *mop = *mopp;
-+      int pending_idx = *((u16 *)skb->data);
-+      netif_t *netif = pending_tx_info[pending_idx].netif;
-+      netif_tx_request_t *txp;
-+      struct skb_shared_info *shinfo = skb_shinfo(skb);
-+      int nr_frags = shinfo->nr_frags;
-+      int i, err, start;
-+
-+      /* Check status of header. */
-+      err = mop->status;
-+      if (unlikely(err)) {
-+              txp = &pending_tx_info[pending_idx].req;
-+              make_tx_response(netif, txp, NETIF_RSP_ERROR);
-+              pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
-+              netif_put(netif);
-+      } else {
-+              set_phys_to_machine(
-+                      __pa(idx_to_kaddr(pending_idx)) >> PAGE_SHIFT,
-+                      FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
-+              grant_tx_handle[pending_idx] = mop->handle;
-+      }
-+
-+      /* Skip first skb fragment if it is on same page as header fragment. */
-+      start = ((unsigned long)shinfo->frags[0].page == pending_idx);
-+
-+      for (i = start; i < nr_frags; i++) {
-+              int j, newerr;
-+
-+              pending_idx = (unsigned long)shinfo->frags[i].page;
-+
-+              /* Check error status: if okay then remember grant handle. */
-+              newerr = (++mop)->status;
-+              if (likely(!newerr)) {
-+                      set_phys_to_machine(
-+                              __pa(idx_to_kaddr(pending_idx))>>PAGE_SHIFT,
-+                              FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
-+                      grant_tx_handle[pending_idx] = mop->handle;
-+                      /* Had a previous error? Invalidate this fragment. */
-+                      if (unlikely(err))
-+                              netif_idx_release(pending_idx);
-+                      continue;
-+              }
-+
-+              /* Error on this fragment: respond to client with an error. */
-+              txp = &pending_tx_info[pending_idx].req;
-+              make_tx_response(netif, txp, NETIF_RSP_ERROR);
-+              pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
-+              netif_put(netif);
-+
-+              /* Not the first error? Preceding frags already invalidated. */
-+              if (err)
-+                      continue;
-+
-+              /* First error: invalidate header and preceding fragments. */
-+              pending_idx = *((u16 *)skb->data);
-+              netif_idx_release(pending_idx);
-+              for (j = start; j < i; j++) {
-+                      pending_idx = (unsigned long)shinfo->frags[i].page;
-+                      netif_idx_release(pending_idx);
-+              }
-+
-+              /* Remember the error: invalidate all subsequent fragments. */
-+              err = newerr;
-+      }
-+
-+      *mopp = mop + 1;
-+      return err;
-+}
-+
-+static void netbk_fill_frags(struct sk_buff *skb)
-+{
-+      struct skb_shared_info *shinfo = skb_shinfo(skb);
-+      int nr_frags = shinfo->nr_frags;
-+      int i;
-+
-+      for (i = 0; i < nr_frags; i++) {
-+              skb_frag_t *frag = shinfo->frags + i;
-+              netif_tx_request_t *txp;
-+              unsigned long pending_idx;
-+
-+              pending_idx = (unsigned long)frag->page;
-+              txp = &pending_tx_info[pending_idx].req;
-+              frag->page = virt_to_page(idx_to_kaddr(pending_idx));
-+              frag->size = txp->size;
-+              frag->page_offset = txp->offset;
-+
-+              skb->len += txp->size;
-+              skb->data_len += txp->size;
-+              skb->truesize += txp->size;
-+      }
-+}
-+
-+int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
-+                   int work_to_do)
-+{
-+      struct netif_extra_info extra;
-+      RING_IDX cons = netif->tx.req_cons;
-+
-+      do {
-+              if (unlikely(work_to_do-- <= 0)) {
-+                      DPRINTK("Missing extra info\n");
-+                      return -EBADR;
-+              }
-+
-+              memcpy(&extra, RING_GET_REQUEST(&netif->tx, cons),
-+                     sizeof(extra));
-+              if (unlikely(!extra.type ||
-+                           extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
-+                      netif->tx.req_cons = ++cons;
-+                      DPRINTK("Invalid extra type: %d\n", extra.type);
-+                      return -EINVAL;
-+              }
-+
-+              memcpy(&extras[extra.type - 1], &extra, sizeof(extra));
-+              netif->tx.req_cons = ++cons;
-+      } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE);
-+
-+      return work_to_do;
-+}
-+
-+static int netbk_set_skb_gso(struct sk_buff *skb, struct netif_extra_info *gso)
-+{
-+      if (!gso->u.gso.size) {
-+              DPRINTK("GSO size must not be zero.\n");
-+              return -EINVAL;
-+      }
-+
-+      /* Currently only TCPv4 S.O. is supported. */
-+      if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
-+              DPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
-+              return -EINVAL;
-+      }
-+
-+      skb_shinfo(skb)->gso_size = gso->u.gso.size;
-+      skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
-+
-+      /* Header must be checked, and gso_segs computed. */
-+      skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
-+      skb_shinfo(skb)->gso_segs = 0;
-+
-+      return 0;
-+}
-+
-+/* Called after netfront has transmitted */
-+static void net_tx_action(unsigned long unused)
-+{
-+      struct list_head *ent;
-+      struct sk_buff *skb;
-+      netif_t *netif;
-+      netif_tx_request_t txreq;
-+      netif_tx_request_t txfrags[MAX_SKB_FRAGS];
-+      struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
-+      u16 pending_idx;
-+      RING_IDX i;
-+      gnttab_map_grant_ref_t *mop;
-+      unsigned int data_len;
-+      int ret, work_to_do;
-+
-+      if (dealloc_cons != dealloc_prod)
-+              net_tx_action_dealloc();
-+
-+      mop = tx_map_ops;
-+      while (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
-+              !list_empty(&net_schedule_list)) {
-+              /* Get a netif from the list with work to do. */
-+              ent = net_schedule_list.next;
-+              netif = list_entry(ent, netif_t, list);
-+              netif_get(netif);
-+              remove_from_net_schedule_list(netif);
-+
-+              RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, work_to_do);
-+              if (!work_to_do) {
-+                      netif_put(netif);
-+                      continue;
-+              }
-+
-+              i = netif->tx.req_cons;
-+              rmb(); /* Ensure that we see the request before we copy it. */
-+              memcpy(&txreq, RING_GET_REQUEST(&netif->tx, i), sizeof(txreq));
-+
-+              /* Credit-based scheduling. */
-+              if (txreq.size > netif->remaining_credit) {
-+                      unsigned long now = jiffies;
-+                      unsigned long next_credit = 
-+                              netif->credit_timeout.expires +
-+                              msecs_to_jiffies(netif->credit_usec / 1000);
-+
-+                      /* Timer could already be pending in rare cases. */
-+                      if (timer_pending(&netif->credit_timeout)) {
-+                              netif_put(netif);
-+                              continue;
-+                      }
-+
-+                      /* Passed the point where we can replenish credit? */
-+                      if (time_after_eq(now, next_credit)) {
-+                              netif->credit_timeout.expires = now;
-+                              tx_add_credit(netif);
-+                      }
-+
-+                      /* Still too big to send right now? Set a callback. */
-+                      if (txreq.size > netif->remaining_credit) {
-+                              netif->credit_timeout.data     =
-+                                      (unsigned long)netif;
-+                              netif->credit_timeout.function =
-+                                      tx_credit_callback;
-+                              __mod_timer(&netif->credit_timeout,
-+                                          next_credit);
-+                              netif_put(netif);
-+                              continue;
-+                      }
-+              }
-+              netif->remaining_credit -= txreq.size;
-+
-+              work_to_do--;
-+              netif->tx.req_cons = ++i;
-+
-+              memset(extras, 0, sizeof(extras));
-+              if (txreq.flags & NETTXF_extra_info) {
-+                      work_to_do = netbk_get_extras(netif, extras,
-+                                                    work_to_do);
-+                      i = netif->tx.req_cons;
-+                      if (unlikely(work_to_do < 0)) {
-+                              netbk_tx_err(netif, &txreq, i);
-+                              continue;
-+                      }
-+              }
-+
-+              ret = netbk_count_requests(netif, &txreq, txfrags, work_to_do);
-+              if (unlikely(ret < 0)) {
-+                      netbk_tx_err(netif, &txreq, i - ret);
-+                      continue;
-+              }
-+              i += ret;
-+
-+              if (unlikely(txreq.size < ETH_HLEN)) {
-+                      DPRINTK("Bad packet size: %d\n", txreq.size);
-+                      netbk_tx_err(netif, &txreq, i);
-+                      continue;
-+              }
-+
-+              /* No crossing a page as the payload mustn't fragment. */
-+              if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) {
-+                      DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", 
-+                              txreq.offset, txreq.size, 
-+                              (txreq.offset &~PAGE_MASK) + txreq.size);
-+                      netbk_tx_err(netif, &txreq, i);
-+                      continue;
-+              }
-+
-+              pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
-+
-+              data_len = (txreq.size > PKT_PROT_LEN &&
-+                          ret < MAX_SKB_FRAGS) ?
-+                      PKT_PROT_LEN : txreq.size;
-+
-+              skb = alloc_skb(data_len + 16 + NET_IP_ALIGN,
-+                              GFP_ATOMIC | __GFP_NOWARN);
-+              if (unlikely(skb == NULL)) {
-+                      DPRINTK("Can't allocate a skb in start_xmit.\n");
-+                      netbk_tx_err(netif, &txreq, i);
-+                      break;
-+              }
-+
-+              /* Packets passed to netif_rx() must have some headroom. */
-+              skb_reserve(skb, 16 + NET_IP_ALIGN);
-+
-+              if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
-+                      struct netif_extra_info *gso;
-+                      gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
-+
-+                      if (netbk_set_skb_gso(skb, gso)) {
-+                              kfree_skb(skb);
-+                              netbk_tx_err(netif, &txreq, i);
-+                              continue;
-+                      }
-+              }
-+
-+              gnttab_set_map_op(mop, idx_to_kaddr(pending_idx),
-+                                GNTMAP_host_map | GNTMAP_readonly,
-+                                txreq.gref, netif->domid);
-+              mop++;
-+
-+              memcpy(&pending_tx_info[pending_idx].req,
-+                     &txreq, sizeof(txreq));
-+              pending_tx_info[pending_idx].netif = netif;
-+              *((u16 *)skb->data) = pending_idx;
-+
-+              __skb_put(skb, data_len);
-+
-+              skb_shinfo(skb)->nr_frags = ret;
-+              if (data_len < txreq.size) {
-+                      skb_shinfo(skb)->nr_frags++;
-+                      skb_shinfo(skb)->frags[0].page =
-+                              (void *)(unsigned long)pending_idx;
-+              } else {
-+                      /* Discriminate from any valid pending_idx value. */
-+                      skb_shinfo(skb)->frags[0].page = (void *)~0UL;
-+              }
-+
-+              __skb_queue_tail(&tx_queue, skb);
-+
-+              pending_cons++;
-+
-+              mop = netbk_get_requests(netif, skb, txfrags, mop);
-+
-+              netif->tx.req_cons = i;
-+              netif_schedule_work(netif);
-+
-+              if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops))
-+                      break;
-+      }
-+
-+      if (mop == tx_map_ops)
-+              return;
-+
-+      ret = HYPERVISOR_grant_table_op(
-+              GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops);
-+      BUG_ON(ret);
-+
-+      mop = tx_map_ops;
-+      while ((skb = __skb_dequeue(&tx_queue)) != NULL) {
-+              netif_tx_request_t *txp;
-+
-+              pending_idx = *((u16 *)skb->data);
-+              netif       = pending_tx_info[pending_idx].netif;
-+              txp         = &pending_tx_info[pending_idx].req;
-+
-+              /* Check the remap error code. */
-+              if (unlikely(netbk_tx_check_mop(skb, &mop))) {
-+                      printk(KERN_ALERT "#### netback grant fails\n");
-+                      skb_shinfo(skb)->nr_frags = 0;
-+                      kfree_skb(skb);
-+                      continue;
-+              }
-+
-+              data_len = skb->len;
-+              memcpy(skb->data,
-+                     (void *)(idx_to_kaddr(pending_idx)|txp->offset),
-+                     data_len);
-+              if (data_len < txp->size) {
-+                      /* Append the packet payload as a fragment. */
-+                      txp->offset += data_len;
-+                      txp->size -= data_len;
-+              } else {
-+                      /* Schedule a response immediately. */
-+                      netif_idx_release(pending_idx);
-+              }
-+
-+              /*
-+               * Old frontends do not assert data_validated but we
-+               * can infer it from csum_blank so test both flags.
-+               */
-+              if (txp->flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
-+                      skb->ip_summed = CHECKSUM_UNNECESSARY;
-+                      skb->proto_data_valid = 1;
-+              } else {
-+                      skb->ip_summed = CHECKSUM_NONE;
-+                      skb->proto_data_valid = 0;
-+              }
-+              skb->proto_csum_blank = !!(txp->flags & NETTXF_csum_blank);
-+
-+              netbk_fill_frags(skb);
-+
-+              skb->dev      = netif->dev;
-+              skb->protocol = eth_type_trans(skb, skb->dev);
-+
-+              netif->stats.rx_bytes += skb->len;
-+              netif->stats.rx_packets++;
-+
-+              netif_rx(skb);
-+              netif->dev->last_rx = jiffies;
-+      }
-+}
-+
-+static void netif_idx_release(u16 pending_idx)
-+{
-+      static DEFINE_SPINLOCK(_lock);
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&_lock, flags);
-+      dealloc_ring[MASK_PEND_IDX(dealloc_prod)] = pending_idx;
-+      /* Sync with net_tx_action_dealloc: insert idx /then/ incr producer. */
-+      smp_wmb();
-+      dealloc_prod++;
-+      spin_unlock_irqrestore(&_lock, flags);
-+
-+      tasklet_schedule(&net_tx_tasklet);
-+}
-+
-+static void netif_page_release(struct page *page)
-+{
-+      /* Ready for next use. */
-+      set_page_count(page, 1);
-+
-+      netif_idx_release(page->index);
-+}
-+
-+irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      netif_t *netif = dev_id;
-+
-+      add_to_net_schedule_list_tail(netif);
-+      maybe_schedule_tx_action();
-+
-+      if (netif_schedulable(netif->dev) && !netbk_queue_full(netif))
-+              netif_wake_queue(netif->dev);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static void make_tx_response(netif_t *netif, 
-+                           netif_tx_request_t *txp,
-+                           s8       st)
-+{
-+      RING_IDX i = netif->tx.rsp_prod_pvt;
-+      netif_tx_response_t *resp;
-+      int notify;
-+
-+      resp = RING_GET_RESPONSE(&netif->tx, i);
-+      resp->id     = txp->id;
-+      resp->status = st;
-+
-+      if (txp->flags & NETTXF_extra_info)
-+              RING_GET_RESPONSE(&netif->tx, ++i)->status = NETIF_RSP_NULL;
-+
-+      netif->tx.rsp_prod_pvt = ++i;
-+      RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->tx, notify);
-+      if (notify)
-+              notify_remote_via_irq(netif->irq);
-+
-+#ifdef CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER
-+      if (i == netif->tx.req_cons) {
-+              int more_to_do;
-+              RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, more_to_do);
-+              if (more_to_do)
-+                      add_to_net_schedule_list_tail(netif);
-+      }
-+#endif
-+}
-+
-+static netif_rx_response_t *make_rx_response(netif_t *netif, 
-+                                           u16      id, 
-+                                           s8       st,
-+                                           u16      offset,
-+                                           u16      size,
-+                                           u16      flags)
-+{
-+      RING_IDX i = netif->rx.rsp_prod_pvt;
-+      netif_rx_response_t *resp;
-+
-+      resp = RING_GET_RESPONSE(&netif->rx, i);
-+      resp->offset     = offset;
-+      resp->flags      = flags;
-+      resp->id         = id;
-+      resp->status     = (s16)size;
-+      if (st < 0)
-+              resp->status = (s16)st;
-+
-+      netif->rx.rsp_prod_pvt = ++i;
-+
-+      return resp;
-+}
-+
-+#ifdef NETBE_DEBUG_INTERRUPT
-+static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct list_head *ent;
-+      netif_t *netif;
-+      int i = 0;
-+
-+      printk(KERN_ALERT "netif_schedule_list:\n");
-+      spin_lock_irq(&net_schedule_list_lock);
-+
-+      list_for_each (ent, &net_schedule_list) {
-+              netif = list_entry(ent, netif_t, list);
-+              printk(KERN_ALERT " %d: private(rx_req_cons=%08x "
-+                     "rx_resp_prod=%08x\n",
-+                     i, netif->rx.req_cons, netif->rx.rsp_prod_pvt);
-+              printk(KERN_ALERT "   tx_req_cons=%08x tx_resp_prod=%08x)\n",
-+                     netif->tx.req_cons, netif->tx.rsp_prod_pvt);
-+              printk(KERN_ALERT "   shared(rx_req_prod=%08x "
-+                     "rx_resp_prod=%08x\n",
-+                     netif->rx.sring->req_prod, netif->rx.sring->rsp_prod);
-+              printk(KERN_ALERT "   rx_event=%08x tx_req_prod=%08x\n",
-+                     netif->rx.sring->rsp_event, netif->tx.sring->req_prod);
-+              printk(KERN_ALERT "   tx_resp_prod=%08x, tx_event=%08x)\n",
-+                     netif->tx.sring->rsp_prod, netif->tx.sring->rsp_event);
-+              i++;
-+      }
-+
-+      spin_unlock_irq(&net_schedule_list_lock);
-+      printk(KERN_ALERT " ** End of netif_schedule_list **\n");
-+
-+      return IRQ_HANDLED;
-+}
-+#endif
-+
-+static int __init netback_init(void)
-+{
-+      int i;
-+      struct page *page;
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      /* We can increase reservation by this much in net_rx_action(). */
-+      balloon_update_driver_allowance(NET_RX_RING_SIZE);
-+
-+      skb_queue_head_init(&rx_queue);
-+      skb_queue_head_init(&tx_queue);
-+
-+      init_timer(&net_timer);
-+      net_timer.data = 0;
-+      net_timer.function = net_alarm;
-+
-+      mmap_pages = alloc_empty_pages_and_pagevec(MAX_PENDING_REQS);
-+      if (mmap_pages == NULL) {
-+              printk("%s: out of memory\n", __FUNCTION__);
-+              return -ENOMEM;
-+      }
-+
-+      for (i = 0; i < MAX_PENDING_REQS; i++) {
-+              page = mmap_pages[i];
-+              SetPageForeign(page, netif_page_release);
-+              page->index = i;
-+      }
-+
-+      pending_cons = 0;
-+      pending_prod = MAX_PENDING_REQS;
-+      for (i = 0; i < MAX_PENDING_REQS; i++)
-+              pending_ring[i] = i;
-+
-+      spin_lock_init(&net_schedule_list_lock);
-+      INIT_LIST_HEAD(&net_schedule_list);
-+
-+      netif_xenbus_init();
-+
-+#ifdef NETBE_DEBUG_INTERRUPT
-+      (void)bind_virq_to_irqhandler(VIRQ_DEBUG,
-+                                    0,
-+                                    netif_be_dbg,
-+                                    SA_SHIRQ, 
-+                                    "net-be-dbg",
-+                                    &netif_be_dbg);
-+#endif
-+
-+      return 0;
-+}
-+
-+module_init(netback_init);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/netback/xenbus.c linux-2.6.16.33/drivers/xen/netback/xenbus.c
---- linux-2.6.16.33-noxen/drivers/xen/netback/xenbus.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/netback/xenbus.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,450 @@
-+/*  Xenbus code for netif backend
-+    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
-+    Copyright (C) 2005 XenSource Ltd
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+*/
-+
-+#include <stdarg.h>
-+#include <linux/module.h>
-+#include <xen/xenbus.h>
-+#include "common.h"
-+
-+#if 0
-+#undef DPRINTK
-+#define DPRINTK(fmt, args...) \
-+    printk("netback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-+#endif
-+
-+struct backend_info {
-+      struct xenbus_device *dev;
-+      netif_t *netif;
-+      enum xenbus_state frontend_state;
-+};
-+
-+static int connect_rings(struct backend_info *);
-+static void connect(struct backend_info *);
-+static void backend_create_netif(struct backend_info *be);
-+
-+static int netback_remove(struct xenbus_device *dev)
-+{
-+      struct backend_info *be = dev->dev.driver_data;
-+
-+      if (be->netif) {
-+              netif_disconnect(be->netif);
-+              be->netif = NULL;
-+      }
-+      kfree(be);
-+      dev->dev.driver_data = NULL;
-+      return 0;
-+}
-+
-+
-+/**
-+ * Entry point to this code when a new device is created.  Allocate the basic
-+ * structures and switch to InitWait.
-+ */
-+static int netback_probe(struct xenbus_device *dev,
-+                       const struct xenbus_device_id *id)
-+{
-+      const char *message;
-+      struct xenbus_transaction xbt;
-+      int err;
-+      struct backend_info *be = kzalloc(sizeof(struct backend_info),
-+                                        GFP_KERNEL);
-+      if (!be) {
-+              xenbus_dev_fatal(dev, -ENOMEM,
-+                               "allocating backend structure");
-+              return -ENOMEM;
-+      }
-+
-+      be->dev = dev;
-+      dev->dev.driver_data = be;
-+
-+      do {
-+              err = xenbus_transaction_start(&xbt);
-+              if (err) {
-+                      xenbus_dev_fatal(dev, err, "starting transaction");
-+                      goto fail;
-+              }
-+
-+              err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
-+              if (err) {
-+                      message = "writing feature-sg";
-+                      goto abort_transaction;
-+              }
-+
-+              err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4",
-+                                  "%d", 1);
-+              if (err) {
-+                      message = "writing feature-gso-tcpv4";
-+                      goto abort_transaction;
-+              }
-+
-+              /* We support rx-copy path. */
-+              err = xenbus_printf(xbt, dev->nodename,
-+                                  "feature-rx-copy", "%d", 1);
-+              if (err) {
-+                      message = "writing feature-rx-copy";
-+                      goto abort_transaction;
-+              }
-+
-+              /*
-+               * We don't support rx-flip path (except old guests who don't
-+               * grok this feature flag).
-+               */
-+              err = xenbus_printf(xbt, dev->nodename,
-+                                  "feature-rx-flip", "%d", 0);
-+              if (err) {
-+                      message = "writing feature-rx-flip";
-+                      goto abort_transaction;
-+              }
-+
-+              err = xenbus_transaction_end(xbt, 0);
-+      } while (err == -EAGAIN);
-+
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "completing transaction");
-+              goto fail;
-+      }
-+
-+      err = xenbus_switch_state(dev, XenbusStateInitWait);
-+      if (err)
-+              goto fail;
-+
-+      /* This kicks hotplug scripts, so do it immediately. */
-+      backend_create_netif(be);
-+
-+      return 0;
-+
-+abort_transaction:
-+      xenbus_transaction_end(xbt, 1);
-+      xenbus_dev_fatal(dev, err, "%s", message);
-+fail:
-+      DPRINTK("failed");
-+      netback_remove(dev);
-+      return err;
-+}
-+
-+
-+/**
-+ * Handle the creation of the hotplug script environment.  We add the script
-+ * and vif variables to the environment, for the benefit of the vif-* hotplug
-+ * scripts.
-+ */
-+static int netback_uevent(struct xenbus_device *xdev, char **envp,
-+                        int num_envp, char *buffer, int buffer_size)
-+{
-+      struct backend_info *be = xdev->dev.driver_data;
-+      netif_t *netif = be->netif;
-+      int i = 0, length = 0;
-+      char *val;
-+
-+      DPRINTK("netback_uevent");
-+
-+      val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL);
-+      if (IS_ERR(val)) {
-+              int err = PTR_ERR(val);
-+              xenbus_dev_fatal(xdev, err, "reading script");
-+              return err;
-+      }
-+      else {
-+              add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
-+                             &length, "script=%s", val);
-+              kfree(val);
-+      }
-+
-+      add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
-+                     "vif=%s", netif->dev->name);
-+
-+      envp[i] = NULL;
-+
-+      return 0;
-+}
-+
-+
-+static void backend_create_netif(struct backend_info *be)
-+{
-+      int err;
-+      long handle;
-+      struct xenbus_device *dev = be->dev;
-+
-+      if (be->netif != NULL)
-+              return;
-+
-+      err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
-+      if (err != 1) {
-+              xenbus_dev_fatal(dev, err, "reading handle");
-+              return;
-+      }
-+
-+      be->netif = netif_alloc(dev->otherend_id, handle);
-+      if (IS_ERR(be->netif)) {
-+              err = PTR_ERR(be->netif);
-+              be->netif = NULL;
-+              xenbus_dev_fatal(dev, err, "creating interface");
-+              return;
-+      }
-+
-+      kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
-+}
-+
-+
-+/**
-+ * Callback received when the frontend's state changes.
-+ */
-+static void frontend_changed(struct xenbus_device *dev,
-+                           enum xenbus_state frontend_state)
-+{
-+      struct backend_info *be = dev->dev.driver_data;
-+
-+      DPRINTK("%s", xenbus_strstate(frontend_state));
-+
-+      be->frontend_state = frontend_state;
-+
-+      switch (frontend_state) {
-+      case XenbusStateInitialising:
-+              if (dev->state == XenbusStateClosed) {
-+                      printk("%s: %s: prepare for reconnect\n",
-+                             __FUNCTION__, dev->nodename);
-+                      if (be->netif) {
-+                              netif_disconnect(be->netif);
-+                              be->netif = NULL;
-+                      }
-+                      xenbus_switch_state(dev, XenbusStateInitWait);
-+              }
-+              break;
-+
-+      case XenbusStateInitialised:
-+              break;
-+
-+      case XenbusStateConnected:
-+              backend_create_netif(be);
-+              if (be->netif)
-+                      connect(be);
-+              break;
-+
-+      case XenbusStateClosing:
-+              xenbus_switch_state(dev, XenbusStateClosing);
-+              break;
-+
-+      case XenbusStateClosed:
-+              xenbus_switch_state(dev, XenbusStateClosed);
-+              if (xenbus_dev_is_online(dev))
-+                      break;
-+              /* fall through if not online */
-+      case XenbusStateUnknown:
-+              if (be->netif != NULL)
-+                      kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
-+              device_unregister(&dev->dev);
-+              break;
-+
-+      default:
-+              xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
-+                               frontend_state);
-+              break;
-+      }
-+}
-+
-+
-+static void xen_net_read_rate(struct xenbus_device *dev,
-+                            unsigned long *bytes, unsigned long *usec)
-+{
-+      char *s, *e;
-+      unsigned long b, u;
-+      char *ratestr;
-+
-+      /* Default to unlimited bandwidth. */
-+      *bytes = ~0UL;
-+      *usec = 0;
-+
-+      ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL);
-+      if (IS_ERR(ratestr))
-+              return;
-+
-+      s = ratestr;
-+      b = simple_strtoul(s, &e, 10);
-+      if ((s == e) || (*e != ','))
-+              goto fail;
-+
-+      s = e + 1;
-+      u = simple_strtoul(s, &e, 10);
-+      if ((s == e) || (*e != '\0'))
-+              goto fail;
-+
-+      *bytes = b;
-+      *usec = u;
-+
-+      kfree(ratestr);
-+      return;
-+
-+ fail:
-+      WPRINTK("Failed to parse network rate limit. Traffic unlimited.\n");
-+      kfree(ratestr);
-+}
-+
-+static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
-+{
-+      char *s, *e, *macstr;
-+      int i;
-+
-+      macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
-+      if (IS_ERR(macstr))
-+              return PTR_ERR(macstr);
-+
-+      for (i = 0; i < ETH_ALEN; i++) {
-+              mac[i] = simple_strtoul(s, &e, 16);
-+              if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
-+                      kfree(macstr);
-+                      return -ENOENT;
-+              }
-+              s = e+1;
-+      }
-+
-+      kfree(macstr);
-+      return 0;
-+}
-+
-+static void connect(struct backend_info *be)
-+{
-+      int err;
-+      struct xenbus_device *dev = be->dev;
-+
-+      err = connect_rings(be);
-+      if (err)
-+              return;
-+
-+      err = xen_net_read_mac(dev, be->netif->fe_dev_addr);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
-+              return;
-+      }
-+
-+      xen_net_read_rate(dev, &be->netif->credit_bytes,
-+                        &be->netif->credit_usec);
-+      be->netif->remaining_credit = be->netif->credit_bytes;
-+
-+      xenbus_switch_state(dev, XenbusStateConnected);
-+
-+      /* May not get a kick from the frontend, so start the tx_queue now. */
-+      if (!netbk_can_queue(be->netif->dev))
-+              netif_wake_queue(be->netif->dev);
-+}
-+
-+
-+static int connect_rings(struct backend_info *be)
-+{
-+      struct xenbus_device *dev = be->dev;
-+      unsigned long tx_ring_ref, rx_ring_ref;
-+      unsigned int evtchn, rx_copy;
-+      int err;
-+      int val;
-+
-+      DPRINTK("");
-+
-+      err = xenbus_gather(XBT_NIL, dev->otherend,
-+                          "tx-ring-ref", "%lu", &tx_ring_ref,
-+                          "rx-ring-ref", "%lu", &rx_ring_ref,
-+                          "event-channel", "%u", &evtchn, NULL);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err,
-+                               "reading %s/ring-ref and event-channel",
-+                               dev->otherend);
-+              return err;
-+      }
-+
-+      err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u",
-+                         &rx_copy);
-+      if (err == -ENOENT) {
-+              err = 0;
-+              rx_copy = 0;
-+      }
-+      if (err < 0) {
-+              xenbus_dev_fatal(dev, err, "reading %s/request-rx-copy",
-+                               dev->otherend);
-+              return err;
-+      }
-+      be->netif->copying_receiver = !!rx_copy;
-+
-+      if (be->netif->dev->tx_queue_len != 0) {
-+              if (xenbus_scanf(XBT_NIL, dev->otherend,
-+                               "feature-rx-notify", "%d", &val) < 0)
-+                      val = 0;
-+              if (val)
-+                      be->netif->can_queue = 1;
-+              else
-+                      /* Must be non-zero for pfifo_fast to work. */
-+                      be->netif->dev->tx_queue_len = 1;
-+      }
-+
-+      if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", "%d", &val) < 0)
-+              val = 0;
-+      if (val) {
-+              be->netif->features |= NETIF_F_SG;
-+              be->netif->dev->features |= NETIF_F_SG;
-+      }
-+
-+      if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4", "%d",
-+                       &val) < 0)
-+              val = 0;
-+      if (val) {
-+              be->netif->features |= NETIF_F_TSO;
-+              be->netif->dev->features |= NETIF_F_TSO;
-+      }
-+
-+      if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload",
-+                       "%d", &val) < 0)
-+              val = 0;
-+      if (val) {
-+              be->netif->features &= ~NETIF_F_IP_CSUM;
-+              be->netif->dev->features &= ~NETIF_F_IP_CSUM;
-+      }
-+
-+      /* Map the shared frame, irq etc. */
-+      err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err,
-+                               "mapping shared-frames %lu/%lu port %u",
-+                               tx_ring_ref, rx_ring_ref, evtchn);
-+              return err;
-+      }
-+      return 0;
-+}
-+
-+
-+/* ** Driver Registration ** */
-+
-+
-+static struct xenbus_device_id netback_ids[] = {
-+      { "vif" },
-+      { "" }
-+};
-+
-+
-+static struct xenbus_driver netback = {
-+      .name = "vif",
-+      .owner = THIS_MODULE,
-+      .ids = netback_ids,
-+      .probe = netback_probe,
-+      .remove = netback_remove,
-+      .uevent = netback_uevent,
-+      .otherend_changed = frontend_changed,
-+};
-+
-+
-+void netif_xenbus_init(void)
-+{
-+      xenbus_register_backend(&netback);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/netfront/Makefile linux-2.6.16.33/drivers/xen/netfront/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/netfront/Makefile        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/netfront/Makefile      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,4 @@
-+
-+obj-$(CONFIG_XEN_NETDEV_FRONTEND)     := xennet.o
-+
-+xennet-objs := netfront.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/netfront/netfront.c linux-2.6.16.33/drivers/xen/netfront/netfront.c
---- linux-2.6.16.33-noxen/drivers/xen/netfront/netfront.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/netfront/netfront.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2114 @@
-+/******************************************************************************
-+ * Virtual network driver for conversing with remote driver backends.
-+ *
-+ * Copyright (c) 2002-2005, K A Fraser
-+ * Copyright (c) 2005, XenSource Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/netdevice.h>
-+#include <linux/inetdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/init.h>
-+#include <linux/bitops.h>
-+#include <linux/ethtool.h>
-+#include <linux/in.h>
-+#include <linux/if_ether.h>
-+#include <linux/io.h>
-+#include <linux/moduleparam.h>
-+#include <net/sock.h>
-+#include <net/pkt_sched.h>
-+#include <net/arp.h>
-+#include <net/route.h>
-+#include <asm/uaccess.h>
-+#include <xen/evtchn.h>
-+#include <xen/xenbus.h>
-+#include <xen/interface/io/netif.h>
-+#include <xen/interface/memory.h>
-+#include <xen/balloon.h>
-+#include <asm/page.h>
-+#include <asm/maddr.h>
-+#include <asm/uaccess.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/gnttab.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+/*
-+ * Mutually-exclusive module options to select receive data path:
-+ *  rx_copy : Packets are copied by network backend into local memory
-+ *  rx_flip : Page containing packet data is transferred to our ownership
-+ * For fully-virtualised guests there is no option - copying must be used.
-+ * For paravirtualised guests, flipping is the default.
-+ */
-+#ifdef CONFIG_XEN
-+static int MODPARM_rx_copy = 0;
-+module_param_named(rx_copy, MODPARM_rx_copy, bool, 0);
-+MODULE_PARM_DESC(rx_copy, "Copy packets from network card (rather than flip)");
-+static int MODPARM_rx_flip = 0;
-+module_param_named(rx_flip, MODPARM_rx_flip, bool, 0);
-+MODULE_PARM_DESC(rx_flip, "Flip packets from network card (rather than copy)");
-+#else
-+static const int MODPARM_rx_copy = 1;
-+static const int MODPARM_rx_flip = 0;
-+#endif
-+
-+#define RX_COPY_THRESHOLD 256
-+
-+/* If we don't have GSO, fake things up so that we never try to use it. */
-+#if defined(NETIF_F_GSO)
-+#define HAVE_GSO                      1
-+#define HAVE_TSO                      1 /* TSO is a subset of GSO */
-+static inline void dev_disable_gso_features(struct net_device *dev)
-+{
-+      /* Turn off all GSO bits except ROBUST. */
-+      dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1;
-+      dev->features |= NETIF_F_GSO_ROBUST;
-+}
-+#elif defined(NETIF_F_TSO)
-+#define HAVE_TSO                       1
-+
-+/* Some older kernels cannot cope with incorrect checksums,
-+ * particularly in netfilter. I'm not sure there is 100% correlation
-+ * with the presence of NETIF_F_TSO but it appears to be a good first
-+ * approximiation.
-+ */
-+#define HAVE_NO_CSUM_OFFLOAD           1
-+
-+#define gso_size tso_size
-+#define gso_segs tso_segs
-+static inline void dev_disable_gso_features(struct net_device *dev)
-+{
-+       /* Turn off all TSO bits. */
-+       dev->features &= ~NETIF_F_TSO;
-+}
-+static inline int skb_is_gso(const struct sk_buff *skb)
-+{
-+        return skb_shinfo(skb)->tso_size;
-+}
-+static inline int skb_gso_ok(struct sk_buff *skb, int features)
-+{
-+        return (features & NETIF_F_TSO);
-+}
-+
-+static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
-+{
-+        return skb_is_gso(skb) &&
-+               (!skb_gso_ok(skb, dev->features) ||
-+                unlikely(skb->ip_summed != CHECKSUM_HW));
-+}
-+#else
-+#define netif_needs_gso(dev, skb)     0
-+#define dev_disable_gso_features(dev) ((void)0)
-+#endif
-+
-+#define GRANT_INVALID_REF     0
-+
-+#define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
-+#define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)
-+
-+struct netfront_info {
-+      struct list_head list;
-+      struct net_device *netdev;
-+
-+      struct net_device_stats stats;
-+
-+      struct netif_tx_front_ring tx;
-+      struct netif_rx_front_ring rx;
-+
-+      spinlock_t   tx_lock;
-+      spinlock_t   rx_lock;
-+
-+      unsigned int evtchn, irq;
-+      unsigned int copying_receiver;
-+
-+      /* Receive-ring batched refills. */
-+#define RX_MIN_TARGET 8
-+#define RX_DFL_MIN_TARGET 64
-+#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
-+      unsigned rx_min_target, rx_max_target, rx_target;
-+      struct sk_buff_head rx_batch;
-+
-+      struct timer_list rx_refill_timer;
-+
-+      /*
-+       * {tx,rx}_skbs store outstanding skbuffs. The first entry in tx_skbs
-+       * is an index into a chain of free entries.
-+       */
-+      struct sk_buff *tx_skbs[NET_TX_RING_SIZE+1];
-+      struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
-+
-+#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
-+      grant_ref_t gref_tx_head;
-+      grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
-+      grant_ref_t gref_rx_head;
-+      grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
-+
-+      struct xenbus_device *xbdev;
-+      int tx_ring_ref;
-+      int rx_ring_ref;
-+      u8 mac[ETH_ALEN];
-+
-+      unsigned long rx_pfn_array[NET_RX_RING_SIZE];
-+      struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
-+      struct mmu_update rx_mmu[NET_RX_RING_SIZE];
-+};
-+
-+struct netfront_rx_info {
-+      struct netif_rx_response rx;
-+      struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
-+};
-+
-+/*
-+ * Access macros for acquiring freeing slots in tx_skbs[].
-+ */
-+
-+static inline void add_id_to_freelist(struct sk_buff **list, unsigned short id)
-+{
-+      list[id] = list[0];
-+      list[0]  = (void *)(unsigned long)id;
-+}
-+
-+static inline unsigned short get_id_from_freelist(struct sk_buff **list)
-+{
-+      unsigned int id = (unsigned int)(unsigned long)list[0];
-+      list[0] = list[id];
-+      return id;
-+}
-+
-+static inline int xennet_rxidx(RING_IDX idx)
-+{
-+      return idx & (NET_RX_RING_SIZE - 1);
-+}
-+
-+static inline struct sk_buff *xennet_get_rx_skb(struct netfront_info *np,
-+                                              RING_IDX ri)
-+{
-+      int i = xennet_rxidx(ri);
-+      struct sk_buff *skb = np->rx_skbs[i];
-+      np->rx_skbs[i] = NULL;
-+      return skb;
-+}
-+
-+static inline grant_ref_t xennet_get_rx_ref(struct netfront_info *np,
-+                                          RING_IDX ri)
-+{
-+      int i = xennet_rxidx(ri);
-+      grant_ref_t ref = np->grant_rx_ref[i];
-+      np->grant_rx_ref[i] = GRANT_INVALID_REF;
-+      return ref;
-+}
-+
-+#define DPRINTK(fmt, args...)                         \
-+      pr_debug("netfront (%s:%d) " fmt,               \
-+               __FUNCTION__, __LINE__, ##args)
-+#define IPRINTK(fmt, args...)                         \
-+      printk(KERN_INFO "netfront: " fmt, ##args)
-+#define WPRINTK(fmt, args...)                         \
-+      printk(KERN_WARNING "netfront: " fmt, ##args)
-+
-+static int setup_device(struct xenbus_device *, struct netfront_info *);
-+static struct net_device *create_netdev(struct xenbus_device *);
-+
-+static void end_access(int, void *);
-+static void netif_disconnect_backend(struct netfront_info *);
-+
-+static int network_connect(struct net_device *);
-+static void network_tx_buf_gc(struct net_device *);
-+static void network_alloc_rx_buffers(struct net_device *);
-+static int send_fake_arp(struct net_device *);
-+
-+static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs);
-+
-+#ifdef CONFIG_SYSFS
-+static int xennet_sysfs_addif(struct net_device *netdev);
-+static void xennet_sysfs_delif(struct net_device *netdev);
-+#else /* !CONFIG_SYSFS */
-+#define xennet_sysfs_addif(dev) (0)
-+#define xennet_sysfs_delif(dev) do { } while(0)
-+#endif
-+
-+static inline int xennet_can_sg(struct net_device *dev)
-+{
-+      return dev->features & NETIF_F_SG;
-+}
-+
-+/**
-+ * Entry point to this code when a new device is created.  Allocate the basic
-+ * structures and the ring buffers for communication with the backend, and
-+ * inform the backend of the appropriate details for those.
-+ */
-+static int __devinit netfront_probe(struct xenbus_device *dev,
-+                                  const struct xenbus_device_id *id)
-+{
-+      int err;
-+      struct net_device *netdev;
-+      struct netfront_info *info;
-+
-+      netdev = create_netdev(dev);
-+      if (IS_ERR(netdev)) {
-+              err = PTR_ERR(netdev);
-+              xenbus_dev_fatal(dev, err, "creating netdev");
-+              return err;
-+      }
-+
-+      info = netdev_priv(netdev);
-+      dev->dev.driver_data = info;
-+
-+      err = register_netdev(info->netdev);
-+      if (err) {
-+              printk(KERN_WARNING "%s: register_netdev err=%d\n",
-+                     __FUNCTION__, err);
-+              goto fail;
-+      }
-+
-+      err = xennet_sysfs_addif(info->netdev);
-+      if (err) {
-+              unregister_netdev(info->netdev);
-+              printk(KERN_WARNING "%s: add sysfs failed err=%d\n",
-+                     __FUNCTION__, err);
-+              goto fail;
-+      }
-+
-+      return 0;
-+
-+ fail:
-+      free_netdev(netdev);
-+      dev->dev.driver_data = NULL;
-+      return err;
-+}
-+
-+static int __devexit netfront_remove(struct xenbus_device *dev)
-+{
-+      struct netfront_info *info = dev->dev.driver_data;
-+
-+      DPRINTK("%s\n", dev->nodename);
-+
-+      netif_disconnect_backend(info);
-+
-+      del_timer_sync(&info->rx_refill_timer);
-+
-+      xennet_sysfs_delif(info->netdev);
-+
-+      unregister_netdev(info->netdev);
-+
-+      free_netdev(info->netdev);
-+
-+      return 0;
-+}
-+
-+/**
-+ * We are reconnecting to the backend, due to a suspend/resume, or a backend
-+ * driver restart.  We tear down our netif structure and recreate it, but
-+ * leave the device-layer structures intact so that this is transparent to the
-+ * rest of the kernel.
-+ */
-+static int netfront_resume(struct xenbus_device *dev)
-+{
-+      struct netfront_info *info = dev->dev.driver_data;
-+
-+      DPRINTK("%s\n", dev->nodename);
-+
-+      netif_disconnect_backend(info);
-+      return 0;
-+}
-+
-+static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
-+{
-+      char *s, *e, *macstr;
-+      int i;
-+
-+      macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
-+      if (IS_ERR(macstr))
-+              return PTR_ERR(macstr);
-+
-+      for (i = 0; i < ETH_ALEN; i++) {
-+              mac[i] = simple_strtoul(s, &e, 16);
-+              if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
-+                      kfree(macstr);
-+                      return -ENOENT;
-+              }
-+              s = e+1;
-+      }
-+
-+      kfree(macstr);
-+      return 0;
-+}
-+
-+/* Common code used when first setting up, and when resuming. */
-+static int talk_to_backend(struct xenbus_device *dev,
-+                         struct netfront_info *info)
-+{
-+      const char *message;
-+      struct xenbus_transaction xbt;
-+      int err;
-+
-+      err = xen_net_read_mac(dev, info->mac);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
-+              goto out;
-+      }
-+
-+      /* Create shared ring, alloc event channel. */
-+      err = setup_device(dev, info);
-+      if (err)
-+              goto out;
-+
-+again:
-+      err = xenbus_transaction_start(&xbt);
-+      if (err) {
-+              xenbus_dev_fatal(dev, err, "starting transaction");
-+              goto destroy_ring;
-+      }
-+
-+      err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u",
-+                          info->tx_ring_ref);
-+      if (err) {
-+              message = "writing tx ring-ref";
-+              goto abort_transaction;
-+      }
-+      err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u",
-+                          info->rx_ring_ref);
-+      if (err) {
-+              message = "writing rx ring-ref";
-+              goto abort_transaction;
-+      }
-+      err = xenbus_printf(xbt, dev->nodename,
-+                          "event-channel", "%u", info->evtchn);
-+      if (err) {
-+              message = "writing event-channel";
-+              goto abort_transaction;
-+      }
-+
-+      err = xenbus_printf(xbt, dev->nodename, "request-rx-copy", "%u",
-+                          info->copying_receiver);
-+      if (err) {
-+              message = "writing request-rx-copy";
-+              goto abort_transaction;
-+      }
-+
-+      err = xenbus_printf(xbt, dev->nodename, "feature-rx-notify", "%d", 1);
-+      if (err) {
-+              message = "writing feature-rx-notify";
-+              goto abort_transaction;
-+      }
-+
-+#ifdef HAVE_NO_CSUM_OFFLOAD
-+      err = xenbus_printf(xbt, dev->nodename, "feature-no-csum-offload", "%d", 1);
-+      if (err) {
-+              message = "writing feature-no-csum-offload";
-+              goto abort_transaction;
-+      }
-+#endif
-+
-+      err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
-+      if (err) {
-+              message = "writing feature-sg";
-+              goto abort_transaction;
-+      }
-+
-+#ifdef HAVE_TSO
-+      err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1);
-+      if (err) {
-+              message = "writing feature-gso-tcpv4";
-+              goto abort_transaction;
-+      }
-+#endif
-+
-+      err = xenbus_transaction_end(xbt, 0);
-+      if (err) {
-+              if (err == -EAGAIN)
-+                      goto again;
-+              xenbus_dev_fatal(dev, err, "completing transaction");
-+              goto destroy_ring;
-+      }
-+
-+      return 0;
-+
-+ abort_transaction:
-+      xenbus_transaction_end(xbt, 1);
-+      xenbus_dev_fatal(dev, err, "%s", message);
-+ destroy_ring:
-+      netif_disconnect_backend(info);
-+ out:
-+      return err;
-+}
-+
-+static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
-+{
-+      struct netif_tx_sring *txs;
-+      struct netif_rx_sring *rxs;
-+      int err;
-+      struct net_device *netdev = info->netdev;
-+
-+      info->tx_ring_ref = GRANT_INVALID_REF;
-+      info->rx_ring_ref = GRANT_INVALID_REF;
-+      info->rx.sring = NULL;
-+      info->tx.sring = NULL;
-+      info->irq = 0;
-+
-+      txs = (struct netif_tx_sring *)get_zeroed_page(GFP_KERNEL);
-+      if (!txs) {
-+              err = -ENOMEM;
-+              xenbus_dev_fatal(dev, err, "allocating tx ring page");
-+              goto fail;
-+      }
-+      SHARED_RING_INIT(txs);
-+      FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
-+
-+      err = xenbus_grant_ring(dev, virt_to_mfn(txs));
-+      if (err < 0) {
-+              free_page((unsigned long)txs);
-+              goto fail;
-+      }
-+      info->tx_ring_ref = err;
-+
-+      rxs = (struct netif_rx_sring *)get_zeroed_page(GFP_KERNEL);
-+      if (!rxs) {
-+              err = -ENOMEM;
-+              xenbus_dev_fatal(dev, err, "allocating rx ring page");
-+              goto fail;
-+      }
-+      SHARED_RING_INIT(rxs);
-+      FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
-+
-+      err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
-+      if (err < 0) {
-+              free_page((unsigned long)rxs);
-+              goto fail;
-+      }
-+      info->rx_ring_ref = err;
-+
-+      err = xenbus_alloc_evtchn(dev, &info->evtchn);
-+      if (err)
-+              goto fail;
-+
-+      memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
-+      err = bind_evtchn_to_irqhandler(info->evtchn, netif_int,
-+                                      SA_SAMPLE_RANDOM, netdev->name,
-+                                      netdev);
-+      if (err < 0)
-+              goto fail;
-+      info->irq = err;
-+      return 0;
-+
-+ fail:
-+      return err;
-+}
-+
-+/**
-+ * Callback received when the backend's state changes.
-+ */
-+static void backend_changed(struct xenbus_device *dev,
-+                          enum xenbus_state backend_state)
-+{
-+      struct netfront_info *np = dev->dev.driver_data;
-+      struct net_device *netdev = np->netdev;
-+
-+      DPRINTK("%s\n", xenbus_strstate(backend_state));
-+
-+      switch (backend_state) {
-+      case XenbusStateInitialising:
-+      case XenbusStateInitialised:
-+      case XenbusStateConnected:
-+      case XenbusStateUnknown:
-+      case XenbusStateClosed:
-+              break;
-+
-+      case XenbusStateInitWait:
-+              if (dev->state != XenbusStateInitialising)
-+                      break;
-+              if (network_connect(netdev) != 0)
-+                      break;
-+              xenbus_switch_state(dev, XenbusStateConnected);
-+              (void)send_fake_arp(netdev);
-+              break;
-+
-+      case XenbusStateClosing:
-+              xenbus_frontend_closed(dev);
-+              break;
-+      }
-+}
-+
-+/** Send a packet on a net device to encourage switches to learn the
-+ * MAC. We send a fake ARP request.
-+ *
-+ * @param dev device
-+ * @return 0 on success, error code otherwise
-+ */
-+static int send_fake_arp(struct net_device *dev)
-+{
-+      struct sk_buff *skb;
-+      u32             src_ip, dst_ip;
-+
-+      dst_ip = INADDR_BROADCAST;
-+      src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK);
-+
-+      /* No IP? Then nothing to do. */
-+      if (src_ip == 0)
-+              return 0;
-+
-+      skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
-+                       dst_ip, dev, src_ip,
-+                       /*dst_hw*/ NULL, /*src_hw*/ NULL,
-+                       /*target_hw*/ dev->dev_addr);
-+      if (skb == NULL)
-+              return -ENOMEM;
-+
-+      return dev_queue_xmit(skb);
-+}
-+
-+static int network_open(struct net_device *dev)
-+{
-+      struct netfront_info *np = netdev_priv(dev);
-+
-+      memset(&np->stats, 0, sizeof(np->stats));
-+
-+      spin_lock(&np->rx_lock);
-+      if (netif_carrier_ok(dev)) {
-+              network_alloc_rx_buffers(dev);
-+              np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
-+              if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
-+                      netif_rx_schedule(dev);
-+      }
-+      spin_unlock(&np->rx_lock);
-+
-+      netif_start_queue(dev);
-+
-+      return 0;
-+}
-+
-+static inline int netfront_tx_slot_available(struct netfront_info *np)
-+{
-+      return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2;
-+}
-+
-+static inline void network_maybe_wake_tx(struct net_device *dev)
-+{
-+      struct netfront_info *np = netdev_priv(dev);
-+
-+      if (unlikely(netif_queue_stopped(dev)) &&
-+          netfront_tx_slot_available(np) &&
-+          likely(netif_running(dev)))
-+              netif_wake_queue(dev);
-+}
-+
-+static void network_tx_buf_gc(struct net_device *dev)
-+{
-+      RING_IDX cons, prod;
-+      unsigned short id;
-+      struct netfront_info *np = netdev_priv(dev);
-+      struct sk_buff *skb;
-+
-+      BUG_ON(!netif_carrier_ok(dev));
-+
-+      do {
-+              prod = np->tx.sring->rsp_prod;
-+              rmb(); /* Ensure we see responses up to 'rp'. */
-+
-+              for (cons = np->tx.rsp_cons; cons != prod; cons++) {
-+                      struct netif_tx_response *txrsp;
-+
-+                      txrsp = RING_GET_RESPONSE(&np->tx, cons);
-+                      if (txrsp->status == NETIF_RSP_NULL)
-+                              continue;
-+
-+                      id  = txrsp->id;
-+                      skb = np->tx_skbs[id];
-+                      if (unlikely(gnttab_query_foreign_access(
-+                              np->grant_tx_ref[id]) != 0)) {
-+                              printk(KERN_ALERT "network_tx_buf_gc: warning "
-+                                     "-- grant still in use by backend "
-+                                     "domain.\n");
-+                              BUG();
-+                      }
-+                      gnttab_end_foreign_access_ref(
-+                              np->grant_tx_ref[id], GNTMAP_readonly);
-+                      gnttab_release_grant_reference(
-+                              &np->gref_tx_head, np->grant_tx_ref[id]);
-+                      np->grant_tx_ref[id] = GRANT_INVALID_REF;
-+                      add_id_to_freelist(np->tx_skbs, id);
-+                      dev_kfree_skb_irq(skb);
-+              }
-+
-+              np->tx.rsp_cons = prod;
-+
-+              /*
-+               * Set a new event, then check for race with update of tx_cons.
-+               * Note that it is essential to schedule a callback, no matter
-+               * how few buffers are pending. Even if there is space in the
-+               * transmit ring, higher layers may be blocked because too much
-+               * data is outstanding: in such cases notification from Xen is
-+               * likely to be the only kick that we'll get.
-+               */
-+              np->tx.sring->rsp_event =
-+                      prod + ((np->tx.sring->req_prod - prod) >> 1) + 1;
-+              mb();
-+      } while ((cons == prod) && (prod != np->tx.sring->rsp_prod));
-+
-+      network_maybe_wake_tx(dev);
-+}
-+
-+static void rx_refill_timeout(unsigned long data)
-+{
-+      struct net_device *dev = (struct net_device *)data;
-+      netif_rx_schedule(dev);
-+}
-+
-+static void network_alloc_rx_buffers(struct net_device *dev)
-+{
-+      unsigned short id;
-+      struct netfront_info *np = netdev_priv(dev);
-+      struct sk_buff *skb;
-+      struct page *page;
-+      int i, batch_target, notify;
-+      RING_IDX req_prod = np->rx.req_prod_pvt;
-+      struct xen_memory_reservation reservation;
-+      grant_ref_t ref;
-+      unsigned long pfn;
-+      void *vaddr;
-+      int nr_flips;
-+      netif_rx_request_t *req;
-+
-+      if (unlikely(!netif_carrier_ok(dev)))
-+              return;
-+
-+      /*
-+       * Allocate skbuffs greedily, even though we batch updates to the
-+       * receive ring. This creates a less bursty demand on the memory
-+       * allocator, so should reduce the chance of failed allocation requests
-+       * both for ourself and for other kernel subsystems.
-+       */
-+      batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
-+      for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
-+              /*
-+               * Allocate an skb and a page. Do not use __dev_alloc_skb as
-+               * that will allocate page-sized buffers which is not
-+               * necessary here.
-+               * 16 bytes added as necessary headroom for netif_receive_skb.
-+               */
-+              skb = alloc_skb(RX_COPY_THRESHOLD + 16 + NET_IP_ALIGN,
-+                              GFP_ATOMIC | __GFP_NOWARN);
-+              if (unlikely(!skb))
-+                      goto no_skb;
-+
-+              page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
-+              if (!page) {
-+                      kfree_skb(skb);
-+no_skb:
-+                      /* Any skbuffs queued for refill? Force them out. */
-+                      if (i != 0)
-+                              goto refill;
-+                      /* Could not allocate any skbuffs. Try again later. */
-+                      mod_timer(&np->rx_refill_timer,
-+                                jiffies + (HZ/10));
-+                      break;
-+              }
-+
-+              skb_reserve(skb, 16 + NET_IP_ALIGN); /* mimic dev_alloc_skb() */
-+              skb_shinfo(skb)->frags[0].page = page;
-+              skb_shinfo(skb)->nr_frags = 1;
-+              __skb_queue_tail(&np->rx_batch, skb);
-+      }
-+
-+      /* Is the batch large enough to be worthwhile? */
-+      if (i < (np->rx_target/2)) {
-+              if (req_prod > np->rx.sring->req_prod)
-+                      goto push;
-+              return;
-+      }
-+
-+      /* Adjust our fill target if we risked running out of buffers. */
-+      if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
-+          ((np->rx_target *= 2) > np->rx_max_target))
-+              np->rx_target = np->rx_max_target;
-+
-+ refill:
-+      for (nr_flips = i = 0; ; i++) {
-+              if ((skb = __skb_dequeue(&np->rx_batch)) == NULL)
-+                      break;
-+
-+              skb->dev = dev;
-+
-+              id = xennet_rxidx(req_prod + i);
-+
-+              BUG_ON(np->rx_skbs[id]);
-+              np->rx_skbs[id] = skb;
-+
-+              ref = gnttab_claim_grant_reference(&np->gref_rx_head);
-+              BUG_ON((signed short)ref < 0);
-+              np->grant_rx_ref[id] = ref;
-+
-+              pfn = page_to_pfn(skb_shinfo(skb)->frags[0].page);
-+              vaddr = page_address(skb_shinfo(skb)->frags[0].page);
-+
-+              req = RING_GET_REQUEST(&np->rx, req_prod + i);
-+              if (!np->copying_receiver) {
-+                      gnttab_grant_foreign_transfer_ref(ref,
-+                                                        np->xbdev->otherend_id,
-+                                                        pfn);
-+                      np->rx_pfn_array[nr_flips] = pfn_to_mfn(pfn);
-+                      if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                              /* Remove this page before passing
-+                               * back to Xen. */
-+                              set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
-+                              MULTI_update_va_mapping(np->rx_mcl+i,
-+                                                      (unsigned long)vaddr,
-+                                                      __pte(0), 0);
-+                      }
-+                      nr_flips++;
-+              } else {
-+                      gnttab_grant_foreign_access_ref(ref,
-+                                                      np->xbdev->otherend_id,
-+                                                      pfn_to_mfn(pfn),
-+                                                      0);
-+              }
-+
-+              req->id = id;
-+              req->gref = ref;
-+      }
-+
-+      if ( nr_flips != 0 ) {
-+              /* Tell the ballon driver what is going on. */
-+              balloon_update_driver_allowance(i);
-+
-+              set_xen_guest_handle(reservation.extent_start,
-+                                   np->rx_pfn_array);
-+              reservation.nr_extents   = nr_flips;
-+              reservation.extent_order = 0;
-+              reservation.address_bits = 0;
-+              reservation.domid        = DOMID_SELF;
-+
-+              if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      /* After all PTEs have been zapped, flush the TLB. */
-+                      np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
-+                              UVMF_TLB_FLUSH|UVMF_ALL;
-+
-+                      /* Give away a batch of pages. */
-+                      np->rx_mcl[i].op = __HYPERVISOR_memory_op;
-+                      np->rx_mcl[i].args[0] = XENMEM_decrease_reservation;
-+                      np->rx_mcl[i].args[1] = (unsigned long)&reservation;
-+
-+                      /* Zap PTEs and give away pages in one big
-+                       * multicall. */
-+                      (void)HYPERVISOR_multicall(np->rx_mcl, i+1);
-+
-+                      /* Check return status of HYPERVISOR_memory_op(). */
-+                      if (unlikely(np->rx_mcl[i].result != i))
-+                              panic("Unable to reduce memory reservation\n");
-+              } else {
-+                      if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-+                                               &reservation) != i)
-+                              panic("Unable to reduce memory reservation\n");
-+              }
-+      } else {
-+              wmb();
-+      }
-+
-+      /* Above is a suitable barrier to ensure backend will see requests. */
-+      np->rx.req_prod_pvt = req_prod + i;
-+ push:
-+      RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
-+      if (notify)
-+              notify_remote_via_irq(np->irq);
-+}
-+
-+static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
-+                            struct netif_tx_request *tx)
-+{
-+      struct netfront_info *np = netdev_priv(dev);
-+      char *data = skb->data;
-+      unsigned long mfn;
-+      RING_IDX prod = np->tx.req_prod_pvt;
-+      int frags = skb_shinfo(skb)->nr_frags;
-+      unsigned int offset = offset_in_page(data);
-+      unsigned int len = skb_headlen(skb);
-+      unsigned int id;
-+      grant_ref_t ref;
-+      int i;
-+
-+      while (len > PAGE_SIZE - offset) {
-+              tx->size = PAGE_SIZE - offset;
-+              tx->flags |= NETTXF_more_data;
-+              len -= tx->size;
-+              data += tx->size;
-+              offset = 0;
-+
-+              id = get_id_from_freelist(np->tx_skbs);
-+              np->tx_skbs[id] = skb_get(skb);
-+              tx = RING_GET_REQUEST(&np->tx, prod++);
-+              tx->id = id;
-+              ref = gnttab_claim_grant_reference(&np->gref_tx_head);
-+              BUG_ON((signed short)ref < 0);
-+
-+              mfn = virt_to_mfn(data);
-+              gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
-+                                              mfn, GNTMAP_readonly);
-+
-+              tx->gref = np->grant_tx_ref[id] = ref;
-+              tx->offset = offset;
-+              tx->size = len;
-+              tx->flags = 0;
-+      }
-+
-+      for (i = 0; i < frags; i++) {
-+              skb_frag_t *frag = skb_shinfo(skb)->frags + i;
-+
-+              tx->flags |= NETTXF_more_data;
-+
-+              id = get_id_from_freelist(np->tx_skbs);
-+              np->tx_skbs[id] = skb_get(skb);
-+              tx = RING_GET_REQUEST(&np->tx, prod++);
-+              tx->id = id;
-+              ref = gnttab_claim_grant_reference(&np->gref_tx_head);
-+              BUG_ON((signed short)ref < 0);
-+
-+              mfn = pfn_to_mfn(page_to_pfn(frag->page));
-+              gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
-+                                              mfn, GNTMAP_readonly);
-+
-+              tx->gref = np->grant_tx_ref[id] = ref;
-+              tx->offset = frag->page_offset;
-+              tx->size = frag->size;
-+              tx->flags = 0;
-+      }
-+
-+      np->tx.req_prod_pvt = prod;
-+}
-+
-+static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      unsigned short id;
-+      struct netfront_info *np = netdev_priv(dev);
-+      struct netif_tx_request *tx;
-+      struct netif_extra_info *extra;
-+      char *data = skb->data;
-+      RING_IDX i;
-+      grant_ref_t ref;
-+      unsigned long mfn;
-+      int notify;
-+      int frags = skb_shinfo(skb)->nr_frags;
-+      unsigned int offset = offset_in_page(data);
-+      unsigned int len = skb_headlen(skb);
-+
-+      frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE;
-+      if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
-+              printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
-+                     frags);
-+              dump_stack();
-+              goto drop;
-+      }
-+
-+      spin_lock_irq(&np->tx_lock);
-+
-+      if (unlikely(!netif_carrier_ok(dev) ||
-+                   (frags > 1 && !xennet_can_sg(dev)) ||
-+                   netif_needs_gso(dev, skb))) {
-+              spin_unlock_irq(&np->tx_lock);
-+              goto drop;
-+      }
-+
-+      i = np->tx.req_prod_pvt;
-+
-+      id = get_id_from_freelist(np->tx_skbs);
-+      np->tx_skbs[id] = skb;
-+
-+      tx = RING_GET_REQUEST(&np->tx, i);
-+
-+      tx->id   = id;
-+      ref = gnttab_claim_grant_reference(&np->gref_tx_head);
-+      BUG_ON((signed short)ref < 0);
-+      mfn = virt_to_mfn(data);
-+      gnttab_grant_foreign_access_ref(
-+              ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly);
-+      tx->gref = np->grant_tx_ref[id] = ref;
-+      tx->offset = offset;
-+      tx->size = len;
-+
-+      tx->flags = 0;
-+      extra = NULL;
-+
-+      if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
-+              tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
-+#ifdef CONFIG_XEN
-+      if (skb->proto_data_valid) /* remote but checksummed? */
-+              tx->flags |= NETTXF_data_validated;
-+#endif
-+
-+#ifdef HAVE_TSO
-+      if (skb_shinfo(skb)->gso_size) {
-+              struct netif_extra_info *gso = (struct netif_extra_info *)
-+                      RING_GET_REQUEST(&np->tx, ++i);
-+
-+              if (extra)
-+                      extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
-+              else
-+                      tx->flags |= NETTXF_extra_info;
-+
-+              gso->u.gso.size = skb_shinfo(skb)->gso_size;
-+              gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
-+              gso->u.gso.pad = 0;
-+              gso->u.gso.features = 0;
-+
-+              gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
-+              gso->flags = 0;
-+              extra = gso;
-+      }
-+#endif
-+
-+      np->tx.req_prod_pvt = i + 1;
-+
-+      xennet_make_frags(skb, dev, tx);
-+      tx->size = skb->len;
-+
-+      RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
-+      if (notify)
-+              notify_remote_via_irq(np->irq);
-+
-+      network_tx_buf_gc(dev);
-+
-+      if (!netfront_tx_slot_available(np))
-+              netif_stop_queue(dev);
-+
-+      spin_unlock_irq(&np->tx_lock);
-+
-+      np->stats.tx_bytes += skb->len;
-+      np->stats.tx_packets++;
-+
-+      return 0;
-+
-+ drop:
-+      np->stats.tx_dropped++;
-+      dev_kfree_skb(skb);
-+      return 0;
-+}
-+
-+static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
-+{
-+      struct net_device *dev = dev_id;
-+      struct netfront_info *np = netdev_priv(dev);
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&np->tx_lock, flags);
-+
-+      if (likely(netif_carrier_ok(dev))) {
-+              network_tx_buf_gc(dev);
-+              /* Under tx_lock: protects access to rx shared-ring indexes. */
-+              if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
-+                      netif_rx_schedule(dev);
-+      }
-+
-+      spin_unlock_irqrestore(&np->tx_lock, flags);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static void xennet_move_rx_slot(struct netfront_info *np, struct sk_buff *skb,
-+                              grant_ref_t ref)
-+{
-+      int new = xennet_rxidx(np->rx.req_prod_pvt);
-+
-+      BUG_ON(np->rx_skbs[new]);
-+      np->rx_skbs[new] = skb;
-+      np->grant_rx_ref[new] = ref;
-+      RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id = new;
-+      RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref = ref;
-+      np->rx.req_prod_pvt++;
-+}
-+
-+int xennet_get_extras(struct netfront_info *np,
-+                    struct netif_extra_info *extras, RING_IDX rp)
-+
-+{
-+      struct netif_extra_info *extra;
-+      RING_IDX cons = np->rx.rsp_cons;
-+      int err = 0;
-+
-+      do {
-+              struct sk_buff *skb;
-+              grant_ref_t ref;
-+
-+              if (unlikely(cons + 1 == rp)) {
-+                      if (net_ratelimit())
-+                              WPRINTK("Missing extra info\n");
-+                      err = -EBADR;
-+                      break;
-+              }
-+
-+              extra = (struct netif_extra_info *)
-+                      RING_GET_RESPONSE(&np->rx, ++cons);
-+
-+              if (unlikely(!extra->type ||
-+                           extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
-+                      if (net_ratelimit())
-+                              WPRINTK("Invalid extra type: %d\n",
-+                                      extra->type);
-+                      err = -EINVAL;
-+              } else {
-+                      memcpy(&extras[extra->type - 1], extra,
-+                             sizeof(*extra));
-+              }
-+
-+              skb = xennet_get_rx_skb(np, cons);
-+              ref = xennet_get_rx_ref(np, cons);
-+              xennet_move_rx_slot(np, skb, ref);
-+      } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
-+
-+      np->rx.rsp_cons = cons;
-+      return err;
-+}
-+
-+static int xennet_get_responses(struct netfront_info *np,
-+                              struct netfront_rx_info *rinfo, RING_IDX rp,
-+                              struct sk_buff_head *list,
-+                              int *pages_flipped_p)
-+{
-+      int pages_flipped = *pages_flipped_p;
-+      struct mmu_update *mmu;
-+      struct multicall_entry *mcl;
-+      struct netif_rx_response *rx = &rinfo->rx;
-+      struct netif_extra_info *extras = rinfo->extras;
-+      RING_IDX cons = np->rx.rsp_cons;
-+      struct sk_buff *skb = xennet_get_rx_skb(np, cons);
-+      grant_ref_t ref = xennet_get_rx_ref(np, cons);
-+      int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD);
-+      int frags = 1;
-+      int err = 0;
-+      unsigned long ret;
-+
-+      if (rx->flags & NETRXF_extra_info) {
-+              err = xennet_get_extras(np, extras, rp);
-+              cons = np->rx.rsp_cons;
-+      }
-+
-+      for (;;) {
-+              unsigned long mfn;
-+
-+              if (unlikely(rx->status < 0 ||
-+                           rx->offset + rx->status > PAGE_SIZE)) {
-+                      if (net_ratelimit())
-+                              WPRINTK("rx->offset: %x, size: %u\n",
-+                                      rx->offset, rx->status);
-+                      xennet_move_rx_slot(np, skb, ref);
-+                      err = -EINVAL;
-+                      goto next;
-+              }
-+
-+              /*
-+               * This definitely indicates a bug, either in this driver or in
-+               * the backend driver. In future this should flag the bad
-+               * situation to the system controller to reboot the backed.
-+               */
-+              if (ref == GRANT_INVALID_REF) {
-+                      if (net_ratelimit())
-+                              WPRINTK("Bad rx response id %d.\n", rx->id);
-+                      err = -EINVAL;
-+                      goto next;
-+              }
-+
-+              if (!np->copying_receiver) {
-+                      /* Memory pressure, insufficient buffer
-+                       * headroom, ... */
-+                      if (!(mfn = gnttab_end_foreign_transfer_ref(ref))) {
-+                              if (net_ratelimit())
-+                                      WPRINTK("Unfulfilled rx req "
-+                                              "(id=%d, st=%d).\n",
-+                                              rx->id, rx->status);
-+                              xennet_move_rx_slot(np, skb, ref);
-+                              err = -ENOMEM;
-+                              goto next;
-+                      }
-+
-+                      if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                              /* Remap the page. */
-+                              struct page *page =
-+                                      skb_shinfo(skb)->frags[0].page;
-+                              unsigned long pfn = page_to_pfn(page);
-+                              void *vaddr = page_address(page);
-+
-+                              mcl = np->rx_mcl + pages_flipped;
-+                              mmu = np->rx_mmu + pages_flipped;
-+
-+                              MULTI_update_va_mapping(mcl,
-+                                                      (unsigned long)vaddr,
-+                                                      pfn_pte_ma(mfn,
-+                                                                 PAGE_KERNEL),
-+                                                      0);
-+                              mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
-+                                      | MMU_MACHPHYS_UPDATE;
-+                              mmu->val = pfn;
-+
-+                              set_phys_to_machine(pfn, mfn);
-+                      }
-+                      pages_flipped++;
-+              } else {
-+                      ret = gnttab_end_foreign_access_ref(ref, 0);
-+                      BUG_ON(!ret);
-+              }
-+
-+              gnttab_release_grant_reference(&np->gref_rx_head, ref);
-+
-+              __skb_queue_tail(list, skb);
-+
-+next:
-+              if (!(rx->flags & NETRXF_more_data))
-+                      break;
-+
-+              if (cons + frags == rp) {
-+                      if (net_ratelimit())
-+                              WPRINTK("Need more frags\n");
-+                      err = -ENOENT;
-+                      break;
-+              }
-+
-+              rx = RING_GET_RESPONSE(&np->rx, cons + frags);
-+              skb = xennet_get_rx_skb(np, cons + frags);
-+              ref = xennet_get_rx_ref(np, cons + frags);
-+              frags++;
-+      }
-+
-+      if (unlikely(frags > max)) {
-+              if (net_ratelimit())
-+                      WPRINTK("Too many frags\n");
-+              err = -E2BIG;
-+      }
-+
-+      if (unlikely(err))
-+              np->rx.rsp_cons = cons + frags;
-+
-+      *pages_flipped_p = pages_flipped;
-+
-+      return err;
-+}
-+
-+static RING_IDX xennet_fill_frags(struct netfront_info *np,
-+                                struct sk_buff *skb,
-+                                struct sk_buff_head *list)
-+{
-+      struct skb_shared_info *shinfo = skb_shinfo(skb);
-+      int nr_frags = shinfo->nr_frags;
-+      RING_IDX cons = np->rx.rsp_cons;
-+      skb_frag_t *frag = shinfo->frags + nr_frags;
-+      struct sk_buff *nskb;
-+
-+      while ((nskb = __skb_dequeue(list))) {
-+              struct netif_rx_response *rx =
-+                      RING_GET_RESPONSE(&np->rx, ++cons);
-+
-+              frag->page = skb_shinfo(nskb)->frags[0].page;
-+              frag->page_offset = rx->offset;
-+              frag->size = rx->status;
-+
-+              skb->data_len += rx->status;
-+
-+              skb_shinfo(nskb)->nr_frags = 0;
-+              kfree_skb(nskb);
-+
-+              frag++;
-+              nr_frags++;
-+      }
-+
-+      shinfo->nr_frags = nr_frags;
-+      return cons;
-+}
-+
-+static int xennet_set_skb_gso(struct sk_buff *skb,
-+                            struct netif_extra_info *gso)
-+{
-+      if (!gso->u.gso.size) {
-+              if (net_ratelimit())
-+                      WPRINTK("GSO size must not be zero.\n");
-+              return -EINVAL;
-+      }
-+
-+      /* Currently only TCPv4 S.O. is supported. */
-+      if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
-+              if (net_ratelimit())
-+                      WPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
-+              return -EINVAL;
-+      }
-+
-+#ifdef HAVE_TSO
-+      skb_shinfo(skb)->gso_size = gso->u.gso.size;
-+#ifdef HAVE_GSO
-+      skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
-+
-+      /* Header must be checked, and gso_segs computed. */
-+      skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
-+#endif
-+      skb_shinfo(skb)->gso_segs = 0;
-+
-+      return 0;
-+#else
-+      if (net_ratelimit())
-+              WPRINTK("GSO unsupported by this kernel.\n");
-+      return -EINVAL;
-+#endif
-+}
-+
-+static int netif_poll(struct net_device *dev, int *pbudget)
-+{
-+      struct netfront_info *np = netdev_priv(dev);
-+      struct sk_buff *skb;
-+      struct netfront_rx_info rinfo;
-+      struct netif_rx_response *rx = &rinfo.rx;
-+      struct netif_extra_info *extras = rinfo.extras;
-+      RING_IDX i, rp;
-+      struct multicall_entry *mcl;
-+      int work_done, budget, more_to_do = 1;
-+      struct sk_buff_head rxq;
-+      struct sk_buff_head errq;
-+      struct sk_buff_head tmpq;
-+      unsigned long flags;
-+      unsigned int len;
-+      int pages_flipped = 0;
-+      int err;
-+
-+      spin_lock(&np->rx_lock);
-+
-+      if (unlikely(!netif_carrier_ok(dev))) {
-+              spin_unlock(&np->rx_lock);
-+              return 0;
-+      }
-+
-+      skb_queue_head_init(&rxq);
-+      skb_queue_head_init(&errq);
-+      skb_queue_head_init(&tmpq);
-+
-+      if ((budget = *pbudget) > dev->quota)
-+              budget = dev->quota;
-+      rp = np->rx.sring->rsp_prod;
-+      rmb(); /* Ensure we see queued responses up to 'rp'. */
-+
-+      i = np->rx.rsp_cons;
-+      work_done = 0;
-+      while ((i != rp) && (work_done < budget)) {
-+              memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx));
-+              memset(extras, 0, sizeof(extras));
-+
-+              err = xennet_get_responses(np, &rinfo, rp, &tmpq,
-+                                         &pages_flipped);
-+
-+              if (unlikely(err)) {
-+err:  
-+                      while ((skb = __skb_dequeue(&tmpq)))
-+                              __skb_queue_tail(&errq, skb);
-+                      np->stats.rx_errors++;
-+                      i = np->rx.rsp_cons;
-+                      continue;
-+              }
-+
-+              skb = __skb_dequeue(&tmpq);
-+
-+              if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
-+                      struct netif_extra_info *gso;
-+                      gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
-+
-+                      if (unlikely(xennet_set_skb_gso(skb, gso))) {
-+                              __skb_queue_head(&tmpq, skb);
-+                              np->rx.rsp_cons += skb_queue_len(&tmpq);
-+                              goto err;
-+                      }
-+              }
-+
-+              skb->nh.raw = (void *)skb_shinfo(skb)->frags[0].page;
-+              skb->h.raw = skb->nh.raw + rx->offset;
-+
-+              len = rx->status;
-+              if (len > RX_COPY_THRESHOLD)
-+                      len = RX_COPY_THRESHOLD;
-+              skb_put(skb, len);
-+
-+              if (rx->status > len) {
-+                      skb_shinfo(skb)->frags[0].page_offset =
-+                              rx->offset + len;
-+                      skb_shinfo(skb)->frags[0].size = rx->status - len;
-+                      skb->data_len = rx->status - len;
-+              } else {
-+                      skb_shinfo(skb)->frags[0].page = NULL;
-+                      skb_shinfo(skb)->nr_frags = 0;
-+              }
-+
-+              i = xennet_fill_frags(np, skb, &tmpq);
-+
-+              /*
-+               * Truesize must approximates the size of true data plus
-+               * any supervisor overheads. Adding hypervisor overheads
-+               * has been shown to significantly reduce achievable
-+               * bandwidth with the default receive buffer size. It is
-+               * therefore not wise to account for it here.
-+               *
-+               * After alloc_skb(RX_COPY_THRESHOLD), truesize is set to
-+               * RX_COPY_THRESHOLD + the supervisor overheads. Here, we
-+               * add the size of the data pulled in xennet_fill_frags().
-+               *
-+               * We also adjust for any unused space in the main data
-+               * area by subtracting (RX_COPY_THRESHOLD - len). This is
-+               * especially important with drivers which split incoming
-+               * packets into header and data, using only 66 bytes of
-+               * the main data area (see the e1000 driver for example.)
-+               * On such systems, without this last adjustement, our
-+               * achievable receive throughout using the standard receive
-+               * buffer size was cut by 25%(!!!).
-+               */
-+              skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len);
-+              skb->len += skb->data_len;
-+
-+              /*
-+               * Old backends do not assert data_validated but we
-+               * can infer it from csum_blank so test both flags.
-+               */
-+              if (rx->flags & (NETRXF_data_validated|NETRXF_csum_blank))
-+                      skb->ip_summed = CHECKSUM_UNNECESSARY;
-+              else
-+                      skb->ip_summed = CHECKSUM_NONE;
-+#ifdef CONFIG_XEN
-+              skb->proto_data_valid = (skb->ip_summed != CHECKSUM_NONE);
-+              skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank);
-+#endif
-+              np->stats.rx_packets++;
-+              np->stats.rx_bytes += skb->len;
-+
-+              __skb_queue_tail(&rxq, skb);
-+
-+              np->rx.rsp_cons = ++i;
-+              work_done++;
-+      }
-+
-+      if (pages_flipped) {
-+              /* Some pages are no longer absent... */
-+              balloon_update_driver_allowance(-pages_flipped);
-+
-+              /* Do all the remapping work and M2P updates. */
-+              if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      mcl = np->rx_mcl + pages_flipped;
-+                      mcl->op = __HYPERVISOR_mmu_update;
-+                      mcl->args[0] = (unsigned long)np->rx_mmu;
-+                      mcl->args[1] = pages_flipped;
-+                      mcl->args[2] = 0;
-+                      mcl->args[3] = DOMID_SELF;
-+                      (void)HYPERVISOR_multicall(np->rx_mcl,
-+                                                 pages_flipped + 1);
-+              }
-+      }
-+
-+      while ((skb = __skb_dequeue(&errq)))
-+              kfree_skb(skb);
-+
-+      while ((skb = __skb_dequeue(&rxq)) != NULL) {
-+              struct page *page = (struct page *)skb->nh.raw;
-+              void *vaddr = page_address(page);
-+
-+              memcpy(skb->data, vaddr + (skb->h.raw - skb->nh.raw),
-+                     skb_headlen(skb));
-+
-+              if (page != skb_shinfo(skb)->frags[0].page)
-+                      __free_page(page);
-+
-+              /* Ethernet work: Delayed to here as it peeks the header. */
-+              skb->protocol = eth_type_trans(skb, dev);
-+
-+              /* Pass it up. */
-+              netif_receive_skb(skb);
-+              dev->last_rx = jiffies;
-+      }
-+
-+      /* If we get a callback with very few responses, reduce fill target. */
-+      /* NB. Note exponential increase, linear decrease. */
-+      if (((np->rx.req_prod_pvt - np->rx.sring->rsp_prod) >
-+           ((3*np->rx_target) / 4)) &&
-+          (--np->rx_target < np->rx_min_target))
-+              np->rx_target = np->rx_min_target;
-+
-+      network_alloc_rx_buffers(dev);
-+
-+      *pbudget   -= work_done;
-+      dev->quota -= work_done;
-+
-+      if (work_done < budget) {
-+              local_irq_save(flags);
-+
-+              RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do);
-+              if (!more_to_do)
-+                      __netif_rx_complete(dev);
-+
-+              local_irq_restore(flags);
-+      }
-+
-+      spin_unlock(&np->rx_lock);
-+
-+      return more_to_do;
-+}
-+
-+static void netif_release_tx_bufs(struct netfront_info *np)
-+{
-+      struct sk_buff *skb;
-+      int i;
-+
-+      for (i = 1; i <= NET_TX_RING_SIZE; i++) {
-+              if ((unsigned long)np->tx_skbs[i] < PAGE_OFFSET)
-+                      continue;
-+
-+              skb = np->tx_skbs[i];
-+              gnttab_end_foreign_access_ref(
-+                      np->grant_tx_ref[i], GNTMAP_readonly);
-+              gnttab_release_grant_reference(
-+                      &np->gref_tx_head, np->grant_tx_ref[i]);
-+              np->grant_tx_ref[i] = GRANT_INVALID_REF;
-+              add_id_to_freelist(np->tx_skbs, i);
-+              dev_kfree_skb_irq(skb);
-+      }
-+}
-+
-+static void netif_release_rx_bufs(struct netfront_info *np)
-+{
-+      struct mmu_update      *mmu = np->rx_mmu;
-+      struct multicall_entry *mcl = np->rx_mcl;
-+      struct sk_buff_head free_list;
-+      struct sk_buff *skb;
-+      unsigned long mfn;
-+      int xfer = 0, noxfer = 0, unused = 0;
-+      int id, ref;
-+
-+      if (np->copying_receiver) {
-+              printk("%s: fix me for copying receiver.\n", __FUNCTION__);
-+              return;
-+      }
-+
-+      skb_queue_head_init(&free_list);
-+
-+      spin_lock(&np->rx_lock);
-+
-+      for (id = 0; id < NET_RX_RING_SIZE; id++) {
-+              if ((ref = np->grant_rx_ref[id]) == GRANT_INVALID_REF) {
-+                      unused++;
-+                      continue;
-+              }
-+
-+              skb = np->rx_skbs[id];
-+              mfn = gnttab_end_foreign_transfer_ref(ref);
-+              gnttab_release_grant_reference(&np->gref_rx_head, ref);
-+              np->grant_rx_ref[id] = GRANT_INVALID_REF;
-+              add_id_to_freelist(np->rx_skbs, id);
-+
-+              if (0 == mfn) {
-+                      struct page *page = skb_shinfo(skb)->frags[0].page;
-+                      balloon_release_driver_page(page);
-+                      skb_shinfo(skb)->nr_frags = 0;
-+                      dev_kfree_skb(skb);
-+                      noxfer++;
-+                      continue;
-+              }
-+
-+              if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      /* Remap the page. */
-+                      struct page *page = skb_shinfo(skb)->frags[0].page;
-+                      unsigned long pfn = page_to_pfn(page);
-+                      void *vaddr = page_address(page);
-+
-+                      MULTI_update_va_mapping(mcl, (unsigned long)vaddr,
-+                                              pfn_pte_ma(mfn, PAGE_KERNEL),
-+                                              0);
-+                      mcl++;
-+                      mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
-+                              | MMU_MACHPHYS_UPDATE;
-+                      mmu->val = pfn;
-+                      mmu++;
-+
-+                      set_phys_to_machine(pfn, mfn);
-+              }
-+              __skb_queue_tail(&free_list, skb);
-+              xfer++;
-+      }
-+
-+      printk("%s: %d xfer, %d noxfer, %d unused\n",
-+             __FUNCTION__, xfer, noxfer, unused);
-+
-+      if (xfer) {
-+              /* Some pages are no longer absent... */
-+              balloon_update_driver_allowance(-xfer);
-+
-+              if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+                      /* Do all the remapping work and M2P updates. */
-+                      mcl->op = __HYPERVISOR_mmu_update;
-+                      mcl->args[0] = (unsigned long)np->rx_mmu;
-+                      mcl->args[1] = mmu - np->rx_mmu;
-+                      mcl->args[2] = 0;
-+                      mcl->args[3] = DOMID_SELF;
-+                      mcl++;
-+                      HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
-+              }
-+      }
-+
-+      while ((skb = __skb_dequeue(&free_list)) != NULL)
-+              dev_kfree_skb(skb);
-+
-+      spin_unlock(&np->rx_lock);
-+}
-+
-+static int network_close(struct net_device *dev)
-+{
-+      struct netfront_info *np = netdev_priv(dev);
-+      netif_stop_queue(np->netdev);
-+      return 0;
-+}
-+
-+
-+static struct net_device_stats *network_get_stats(struct net_device *dev)
-+{
-+      struct netfront_info *np = netdev_priv(dev);
-+      return &np->stats;
-+}
-+
-+static int xennet_change_mtu(struct net_device *dev, int mtu)
-+{
-+      int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
-+
-+      if (mtu > max)
-+              return -EINVAL;
-+      dev->mtu = mtu;
-+      return 0;
-+}
-+
-+static int xennet_set_sg(struct net_device *dev, u32 data)
-+{
-+      if (data) {
-+              struct netfront_info *np = netdev_priv(dev);
-+              int val;
-+
-+              if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
-+                               "%d", &val) < 0)
-+                      val = 0;
-+              if (!val)
-+                      return -ENOSYS;
-+      } else if (dev->mtu > ETH_DATA_LEN)
-+              dev->mtu = ETH_DATA_LEN;
-+
-+      return ethtool_op_set_sg(dev, data);
-+}
-+
-+static int xennet_set_tso(struct net_device *dev, u32 data)
-+{
-+#ifdef HAVE_TSO
-+      if (data) {
-+              struct netfront_info *np = netdev_priv(dev);
-+              int val;
-+
-+              if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
-+                               "feature-gso-tcpv4", "%d", &val) < 0)
-+                      val = 0;
-+              if (!val)
-+                      return -ENOSYS;
-+      }
-+
-+      return ethtool_op_set_tso(dev, data);
-+#else
-+      return -ENOSYS;
-+#endif
-+}
-+
-+static void xennet_set_features(struct net_device *dev)
-+{
-+      dev_disable_gso_features(dev);
-+      xennet_set_sg(dev, 0);
-+
-+      /* We need checksum offload to enable scatter/gather and TSO. */
-+      if (!(dev->features & NETIF_F_IP_CSUM))
-+              return;
-+
-+      if (xennet_set_sg(dev, 1))
-+              return;
-+
-+      /* Before 2.6.9 TSO seems to be unreliable so do not enable it
-+       * on older kernels.
-+       */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
-+      xennet_set_tso(dev, 1);
-+#endif
-+
-+}
-+
-+static int network_connect(struct net_device *dev)
-+{
-+      struct netfront_info *np = netdev_priv(dev);
-+      int i, requeue_idx, err;
-+      struct sk_buff *skb;
-+      grant_ref_t ref;
-+      netif_rx_request_t *req;
-+      unsigned int feature_rx_copy, feature_rx_flip;
-+
-+      err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
-+                         "feature-rx-copy", "%u", &feature_rx_copy);
-+      if (err != 1)
-+              feature_rx_copy = 0;
-+      err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
-+                         "feature-rx-flip", "%u", &feature_rx_flip);
-+      if (err != 1)
-+              feature_rx_flip = 1;
-+
-+      /*
-+       * Copy packets on receive path if:
-+       *  (a) This was requested by user, and the backend supports it; or
-+       *  (b) Flipping was requested, but this is unsupported by the backend.
-+       */
-+      np->copying_receiver = ((MODPARM_rx_copy && feature_rx_copy) ||
-+                              (MODPARM_rx_flip && !feature_rx_flip));
-+
-+      err = talk_to_backend(np->xbdev, np);
-+      if (err)
-+              return err;
-+
-+      xennet_set_features(dev);
-+
-+      IPRINTK("device %s has %sing receive path.\n",
-+              dev->name, np->copying_receiver ? "copy" : "flipp");
-+
-+      spin_lock_irq(&np->tx_lock);
-+      spin_lock(&np->rx_lock);
-+
-+      /*
-+       * Recovery procedure:
-+       *  NB. Freelist index entries are always going to be less than
-+       *  PAGE_OFFSET, whereas pointers to skbs will always be equal or
-+       *  greater than PAGE_OFFSET: we use this property to distinguish
-+       *  them.
-+       */
-+
-+      /* Step 1: Discard all pending TX packet fragments. */
-+      netif_release_tx_bufs(np);
-+
-+      /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
-+      for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) {
-+              if (!np->rx_skbs[i])
-+                      continue;
-+
-+              skb = np->rx_skbs[requeue_idx] = xennet_get_rx_skb(np, i);
-+              ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i);
-+              req = RING_GET_REQUEST(&np->rx, requeue_idx);
-+
-+              if (!np->copying_receiver) {
-+                      gnttab_grant_foreign_transfer_ref(
-+                              ref, np->xbdev->otherend_id,
-+                              page_to_pfn(skb_shinfo(skb)->frags->page));
-+              } else {
-+                      gnttab_grant_foreign_access_ref(
-+                              ref, np->xbdev->otherend_id,
-+                              pfn_to_mfn(page_to_pfn(skb_shinfo(skb)->
-+                                                     frags->page)),
-+                              0);
-+              }
-+              req->gref = ref;
-+              req->id   = requeue_idx;
-+
-+              requeue_idx++;
-+      }
-+
-+      np->rx.req_prod_pvt = requeue_idx;
-+
-+      /*
-+       * Step 3: All public and private state should now be sane.  Get
-+       * ready to start sending and receiving packets and give the driver
-+       * domain a kick because we've probably just requeued some
-+       * packets.
-+       */
-+      netif_carrier_on(dev);
-+      notify_remote_via_irq(np->irq);
-+      network_tx_buf_gc(dev);
-+      network_alloc_rx_buffers(dev);
-+
-+      spin_unlock(&np->rx_lock);
-+      spin_unlock_irq(&np->tx_lock);
-+
-+      return 0;
-+}
-+
-+static void netif_uninit(struct net_device *dev)
-+{
-+      struct netfront_info *np = netdev_priv(dev);
-+      netif_release_tx_bufs(np);
-+      netif_release_rx_bufs(np);
-+      gnttab_free_grant_references(np->gref_tx_head);
-+      gnttab_free_grant_references(np->gref_rx_head);
-+}
-+
-+static struct ethtool_ops network_ethtool_ops =
-+{
-+      .get_tx_csum = ethtool_op_get_tx_csum,
-+      .set_tx_csum = ethtool_op_set_tx_csum,
-+      .get_sg = ethtool_op_get_sg,
-+      .set_sg = xennet_set_sg,
-+      .get_tso = ethtool_op_get_tso,
-+      .set_tso = xennet_set_tso,
-+      .get_link = ethtool_op_get_link,
-+};
-+
-+#ifdef CONFIG_SYSFS
-+static ssize_t show_rxbuf_min(struct class_device *cd, char *buf)
-+{
-+      struct net_device *netdev = container_of(cd, struct net_device,
-+                                               class_dev);
-+      struct netfront_info *info = netdev_priv(netdev);
-+
-+      return sprintf(buf, "%u\n", info->rx_min_target);
-+}
-+
-+static ssize_t store_rxbuf_min(struct class_device *cd,
-+                             const char *buf, size_t len)
-+{
-+      struct net_device *netdev = container_of(cd, struct net_device,
-+                                               class_dev);
-+      struct netfront_info *np = netdev_priv(netdev);
-+      char *endp;
-+      unsigned long target;
-+
-+      if (!capable(CAP_NET_ADMIN))
-+              return -EPERM;
-+
-+      target = simple_strtoul(buf, &endp, 0);
-+      if (endp == buf)
-+              return -EBADMSG;
-+
-+      if (target < RX_MIN_TARGET)
-+              target = RX_MIN_TARGET;
-+      if (target > RX_MAX_TARGET)
-+              target = RX_MAX_TARGET;
-+
-+      spin_lock(&np->rx_lock);
-+      if (target > np->rx_max_target)
-+              np->rx_max_target = target;
-+      np->rx_min_target = target;
-+      if (target > np->rx_target)
-+              np->rx_target = target;
-+
-+      network_alloc_rx_buffers(netdev);
-+
-+      spin_unlock(&np->rx_lock);
-+      return len;
-+}
-+
-+static ssize_t show_rxbuf_max(struct class_device *cd, char *buf)
-+{
-+      struct net_device *netdev = container_of(cd, struct net_device,
-+                                               class_dev);
-+      struct netfront_info *info = netdev_priv(netdev);
-+
-+      return sprintf(buf, "%u\n", info->rx_max_target);
-+}
-+
-+static ssize_t store_rxbuf_max(struct class_device *cd,
-+                             const char *buf, size_t len)
-+{
-+      struct net_device *netdev = container_of(cd, struct net_device,
-+                                               class_dev);
-+      struct netfront_info *np = netdev_priv(netdev);
-+      char *endp;
-+      unsigned long target;
-+
-+      if (!capable(CAP_NET_ADMIN))
-+              return -EPERM;
-+
-+      target = simple_strtoul(buf, &endp, 0);
-+      if (endp == buf)
-+              return -EBADMSG;
-+
-+      if (target < RX_MIN_TARGET)
-+              target = RX_MIN_TARGET;
-+      if (target > RX_MAX_TARGET)
-+              target = RX_MAX_TARGET;
-+
-+      spin_lock(&np->rx_lock);
-+      if (target < np->rx_min_target)
-+              np->rx_min_target = target;
-+      np->rx_max_target = target;
-+      if (target < np->rx_target)
-+              np->rx_target = target;
-+
-+      network_alloc_rx_buffers(netdev);
-+
-+      spin_unlock(&np->rx_lock);
-+      return len;
-+}
-+
-+static ssize_t show_rxbuf_cur(struct class_device *cd, char *buf)
-+{
-+      struct net_device *netdev = container_of(cd, struct net_device,
-+                                               class_dev);
-+      struct netfront_info *info = netdev_priv(netdev);
-+
-+      return sprintf(buf, "%u\n", info->rx_target);
-+}
-+
-+static const struct class_device_attribute xennet_attrs[] = {
-+      __ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf_min, store_rxbuf_min),
-+      __ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf_max, store_rxbuf_max),
-+      __ATTR(rxbuf_cur, S_IRUGO, show_rxbuf_cur, NULL),
-+};
-+
-+static int xennet_sysfs_addif(struct net_device *netdev)
-+{
-+      int i;
-+      int error = 0;
-+
-+      for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) {
-+              error = class_device_create_file(&netdev->class_dev, 
-+                                               &xennet_attrs[i]);
-+              if (error)
-+                      goto fail;
-+      }
-+      return 0;
-+
-+ fail:
-+      while (--i >= 0)
-+              class_device_remove_file(&netdev->class_dev,
-+                                       &xennet_attrs[i]);
-+      return error;
-+}
-+
-+static void xennet_sysfs_delif(struct net_device *netdev)
-+{
-+      int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) {
-+              class_device_remove_file(&netdev->class_dev,
-+                                       &xennet_attrs[i]);
-+      }
-+}
-+
-+#endif /* CONFIG_SYSFS */
-+
-+
-+/*
-+ * Nothing to do here. Virtual interface is point-to-point and the
-+ * physical interface is probably promiscuous anyway.
-+ */
-+static void network_set_multicast_list(struct net_device *dev)
-+{
-+}
-+
-+static struct net_device * __devinit create_netdev(struct xenbus_device *dev)
-+{
-+      int i, err = 0;
-+      struct net_device *netdev = NULL;
-+      struct netfront_info *np = NULL;
-+
-+      netdev = alloc_etherdev(sizeof(struct netfront_info));
-+      if (!netdev) {
-+              printk(KERN_WARNING "%s> alloc_etherdev failed.\n",
-+                     __FUNCTION__);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      np                   = netdev_priv(netdev);
-+      np->xbdev            = dev;
-+
-+      netif_carrier_off(netdev);
-+
-+      spin_lock_init(&np->tx_lock);
-+      spin_lock_init(&np->rx_lock);
-+
-+      skb_queue_head_init(&np->rx_batch);
-+      np->rx_target     = RX_DFL_MIN_TARGET;
-+      np->rx_min_target = RX_DFL_MIN_TARGET;
-+      np->rx_max_target = RX_MAX_TARGET;
-+
-+      init_timer(&np->rx_refill_timer);
-+      np->rx_refill_timer.data = (unsigned long)netdev;
-+      np->rx_refill_timer.function = rx_refill_timeout;
-+
-+      /* Initialise {tx,rx}_skbs as a free chain containing every entry. */
-+      for (i = 0; i <= NET_TX_RING_SIZE; i++) {
-+              np->tx_skbs[i] = (void *)((unsigned long) i+1);
-+              np->grant_tx_ref[i] = GRANT_INVALID_REF;
-+      }
-+
-+      for (i = 0; i < NET_RX_RING_SIZE; i++) {
-+              np->rx_skbs[i] = NULL;
-+              np->grant_rx_ref[i] = GRANT_INVALID_REF;
-+      }
-+
-+      /* A grant for every tx ring slot */
-+      if (gnttab_alloc_grant_references(TX_MAX_TARGET,
-+                                        &np->gref_tx_head) < 0) {
-+              printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
-+              err = -ENOMEM;
-+              goto exit;
-+      }
-+      /* A grant for every rx ring slot */
-+      if (gnttab_alloc_grant_references(RX_MAX_TARGET,
-+                                        &np->gref_rx_head) < 0) {
-+              printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
-+              err = -ENOMEM;
-+              goto exit_free_tx;
-+      }
-+
-+      netdev->open            = network_open;
-+      netdev->hard_start_xmit = network_start_xmit;
-+      netdev->stop            = network_close;
-+      netdev->get_stats       = network_get_stats;
-+      netdev->poll            = netif_poll;
-+      netdev->set_multicast_list = network_set_multicast_list;
-+      netdev->uninit          = netif_uninit;
-+      netdev->change_mtu      = xennet_change_mtu;
-+      netdev->weight          = 64;
-+      netdev->features        = NETIF_F_IP_CSUM;
-+
-+      SET_ETHTOOL_OPS(netdev, &network_ethtool_ops);
-+      SET_MODULE_OWNER(netdev);
-+      SET_NETDEV_DEV(netdev, &dev->dev);
-+
-+      np->netdev = netdev;
-+      return netdev;
-+
-+ exit_free_tx:
-+      gnttab_free_grant_references(np->gref_tx_head);
-+ exit:
-+      free_netdev(netdev);
-+      return ERR_PTR(err);
-+}
-+
-+/*
-+ * We use this notifier to send out a fake ARP reply to reset switches and
-+ * router ARP caches when an IP interface is brought up on a VIF.
-+ */
-+static int
-+inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
-+{
-+      struct in_ifaddr  *ifa = (struct in_ifaddr *)ptr;
-+      struct net_device *dev = ifa->ifa_dev->dev;
-+
-+      /* UP event and is it one of our devices? */
-+      if (event == NETDEV_UP && dev->open == network_open)
-+              (void)send_fake_arp(dev);
-+
-+      return NOTIFY_DONE;
-+}
-+
-+
-+static void netif_disconnect_backend(struct netfront_info *info)
-+{
-+      /* Stop old i/f to prevent errors whilst we rebuild the state. */
-+      spin_lock_irq(&info->tx_lock);
-+      spin_lock(&info->rx_lock);
-+      netif_carrier_off(info->netdev);
-+      spin_unlock(&info->rx_lock);
-+      spin_unlock_irq(&info->tx_lock);
-+
-+      if (info->irq)
-+              unbind_from_irqhandler(info->irq, info->netdev);
-+      info->evtchn = info->irq = 0;
-+
-+      end_access(info->tx_ring_ref, info->tx.sring);
-+      end_access(info->rx_ring_ref, info->rx.sring);
-+      info->tx_ring_ref = GRANT_INVALID_REF;
-+      info->rx_ring_ref = GRANT_INVALID_REF;
-+      info->tx.sring = NULL;
-+      info->rx.sring = NULL;
-+}
-+
-+
-+static void end_access(int ref, void *page)
-+{
-+      if (ref != GRANT_INVALID_REF)
-+              gnttab_end_foreign_access(ref, 0, (unsigned long)page);
-+}
-+
-+
-+/* ** Driver registration ** */
-+
-+
-+static struct xenbus_device_id netfront_ids[] = {
-+      { "vif" },
-+      { "" }
-+};
-+
-+
-+static struct xenbus_driver netfront = {
-+      .name = "vif",
-+      .owner = THIS_MODULE,
-+      .ids = netfront_ids,
-+      .probe = netfront_probe,
-+      .remove = __devexit_p(netfront_remove),
-+      .resume = netfront_resume,
-+      .otherend_changed = backend_changed,
-+};
-+
-+
-+static struct notifier_block notifier_inetdev = {
-+      .notifier_call  = inetdev_notify,
-+      .next           = NULL,
-+      .priority       = 0
-+};
-+
-+static int __init netif_init(void)
-+{
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+#ifdef CONFIG_XEN
-+      if (MODPARM_rx_flip && MODPARM_rx_copy) {
-+              WPRINTK("Cannot specify both rx_copy and rx_flip.\n");
-+              return -EINVAL;
-+      }
-+
-+      if (!MODPARM_rx_flip && !MODPARM_rx_copy)
-+              MODPARM_rx_flip = 1; /* Default is to flip. */
-+#endif
-+
-+      if (is_initial_xendomain())
-+              return 0;
-+
-+      IPRINTK("Initialising virtual ethernet driver.\n");
-+
-+      (void)register_inetaddr_notifier(&notifier_inetdev);
-+
-+      return xenbus_register_frontend(&netfront);
-+}
-+module_init(netif_init);
-+
-+
-+static void __exit netif_exit(void)
-+{
-+      if (is_initial_xendomain())
-+              return;
-+
-+      unregister_inetaddr_notifier(&notifier_inetdev);
-+
-+      return xenbus_unregister_driver(&netfront);
-+}
-+module_exit(netif_exit);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/Makefile linux-2.6.16.33/drivers/xen/pciback/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/pciback/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,15 @@
-+obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback.o
-+
-+pciback-y := pci_stub.o pciback_ops.o xenbus.o
-+pciback-y += conf_space.o conf_space_header.o \
-+           conf_space_capability.o \
-+           conf_space_capability_vpd.o \
-+           conf_space_capability_pm.o \
-+             conf_space_quirks.o
-+pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
-+pciback-$(CONFIG_XEN_PCIDEV_BACKEND_SLOT) += slot.o
-+pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o
-+
-+ifeq ($(CONFIG_XEN_PCIDEV_BE_DEBUG),y)
-+EXTRA_CFLAGS += -DDEBUG
-+endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space.c linux-2.6.16.33/drivers/xen/pciback/conf_space.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space.c     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space.c   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,425 @@
-+/*
-+ * PCI Backend - Functions for creating a virtual configuration space for
-+ *               exported PCI Devices.
-+ *               It's dangerous to allow PCI Driver Domains to change their
-+ *               device's resources (memory, i/o ports, interrupts). We need to
-+ *               restrict changes to certain PCI Configuration registers:
-+ *               BARs, INTERRUPT_PIN, most registers in the header...
-+ *
-+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include "pciback.h"
-+#include "conf_space.h"
-+#include "conf_space_quirks.h"
-+
-+#define DEFINE_PCI_CONFIG(op,size,type)                       \
-+int pciback_##op##_config_##size                              \
-+(struct pci_dev *dev, int offset, type value, void *data)     \
-+{                                                             \
-+      return pci_##op##_config_##size (dev, offset, value);   \
-+}
-+
-+DEFINE_PCI_CONFIG(read, byte, u8 *)
-+DEFINE_PCI_CONFIG(read, word, u16 *)
-+DEFINE_PCI_CONFIG(read, dword, u32 *)
-+
-+DEFINE_PCI_CONFIG(write, byte, u8)
-+DEFINE_PCI_CONFIG(write, word, u16)
-+DEFINE_PCI_CONFIG(write, dword, u32)
-+
-+static int conf_space_read(struct pci_dev *dev,
-+                         struct config_field_entry *entry, int offset,
-+                         u32 * value)
-+{
-+      int ret = 0;
-+      struct config_field *field = entry->field;
-+
-+      *value = 0;
-+
-+      switch (field->size) {
-+      case 1:
-+              if (field->u.b.read)
-+                      ret = field->u.b.read(dev, offset, (u8 *) value,
-+                                            entry->data);
-+              break;
-+      case 2:
-+              if (field->u.w.read)
-+                      ret = field->u.w.read(dev, offset, (u16 *) value,
-+                                            entry->data);
-+              break;
-+      case 4:
-+              if (field->u.dw.read)
-+                      ret = field->u.dw.read(dev, offset, value, entry->data);
-+              break;
-+      }
-+      return ret;
-+}
-+
-+static int conf_space_write(struct pci_dev *dev,
-+                          struct config_field_entry *entry, int offset,
-+                          u32 value)
-+{
-+      int ret = 0;
-+      struct config_field *field = entry->field;
-+
-+      switch (field->size) {
-+      case 1:
-+              if (field->u.b.write)
-+                      ret = field->u.b.write(dev, offset, (u8) value,
-+                                             entry->data);
-+              break;
-+      case 2:
-+              if (field->u.w.write)
-+                      ret = field->u.w.write(dev, offset, (u16) value,
-+                                             entry->data);
-+              break;
-+      case 4:
-+              if (field->u.dw.write)
-+                      ret = field->u.dw.write(dev, offset, value,
-+                                              entry->data);
-+              break;
-+      }
-+      return ret;
-+}
-+
-+static inline u32 get_mask(int size)
-+{
-+      if (size == 1)
-+              return 0xff;
-+      else if (size == 2)
-+              return 0xffff;
-+      else
-+              return 0xffffffff;
-+}
-+
-+static inline int valid_request(int offset, int size)
-+{
-+      /* Validate request (no un-aligned requests) */
-+      if ((size == 1 || size == 2 || size == 4) && (offset % size) == 0)
-+              return 1;
-+      return 0;
-+}
-+
-+static inline u32 merge_value(u32 val, u32 new_val, u32 new_val_mask,
-+                            int offset)
-+{
-+      if (offset >= 0) {
-+              new_val_mask <<= (offset * 8);
-+              new_val <<= (offset * 8);
-+      } else {
-+              new_val_mask >>= (offset * -8);
-+              new_val >>= (offset * -8);
-+      }
-+      val = (val & ~new_val_mask) | (new_val & new_val_mask);
-+
-+      return val;
-+}
-+
-+static int pcibios_err_to_errno(int err)
-+{
-+      switch (err) {
-+      case PCIBIOS_SUCCESSFUL:
-+              return XEN_PCI_ERR_success;
-+      case PCIBIOS_DEVICE_NOT_FOUND:
-+              return XEN_PCI_ERR_dev_not_found;
-+      case PCIBIOS_BAD_REGISTER_NUMBER:
-+              return XEN_PCI_ERR_invalid_offset;
-+      case PCIBIOS_FUNC_NOT_SUPPORTED:
-+              return XEN_PCI_ERR_not_implemented;
-+      case PCIBIOS_SET_FAILED:
-+              return XEN_PCI_ERR_access_denied;
-+      }
-+      return err;
-+}
-+
-+int pciback_config_read(struct pci_dev *dev, int offset, int size,
-+                      u32 * ret_val)
-+{
-+      int err = 0;
-+      struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
-+      struct config_field_entry *cfg_entry;
-+      struct config_field *field;
-+      int req_start, req_end, field_start, field_end;
-+      /* if read fails for any reason, return 0 (as if device didn't respond) */
-+      u32 value = 0, tmp_val;
-+
-+      if (unlikely(verbose_request))
-+              printk(KERN_DEBUG "pciback: %s: read %d bytes at 0x%x\n",
-+                     pci_name(dev), size, offset);
-+
-+      if (!valid_request(offset, size)) {
-+              err = XEN_PCI_ERR_invalid_offset;
-+              goto out;
-+      }
-+
-+      /* Get the real value first, then modify as appropriate */
-+      switch (size) {
-+      case 1:
-+              err = pci_read_config_byte(dev, offset, (u8 *) & value);
-+              break;
-+      case 2:
-+              err = pci_read_config_word(dev, offset, (u16 *) & value);
-+              break;
-+      case 4:
-+              err = pci_read_config_dword(dev, offset, &value);
-+              break;
-+      }
-+
-+      list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
-+              field = cfg_entry->field;
-+
-+              req_start = offset;
-+              req_end = offset + size;
-+              field_start = OFFSET(cfg_entry);
-+              field_end = OFFSET(cfg_entry) + field->size;
-+
-+              if ((req_start >= field_start && req_start < field_end)
-+                  || (req_end > field_start && req_end <= field_end)) {
-+                      err = conf_space_read(dev, cfg_entry, field_start,
-+                                            &tmp_val);
-+                      if (err)
-+                              goto out;
-+
-+                      value = merge_value(value, tmp_val,
-+                                          get_mask(field->size),
-+                                          field_start - req_start);
-+              }
-+      }
-+
-+      out:
-+      if (unlikely(verbose_request))
-+              printk(KERN_DEBUG "pciback: %s: read %d bytes at 0x%x = %x\n",
-+                     pci_name(dev), size, offset, value);
-+
-+      *ret_val = value;
-+      return pcibios_err_to_errno(err);
-+}
-+
-+int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value)
-+{
-+      int err = 0, handled = 0;
-+      struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
-+      struct config_field_entry *cfg_entry;
-+      struct config_field *field;
-+      u32 tmp_val;
-+      int req_start, req_end, field_start, field_end;
-+
-+      if (unlikely(verbose_request))
-+              printk(KERN_DEBUG
-+                     "pciback: %s: write request %d bytes at 0x%x = %x\n",
-+                     pci_name(dev), size, offset, value);
-+
-+      if (!valid_request(offset, size))
-+              return XEN_PCI_ERR_invalid_offset;
-+
-+      list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
-+              field = cfg_entry->field;
-+
-+              req_start = offset;
-+              req_end = offset + size;
-+              field_start = OFFSET(cfg_entry);
-+              field_end = OFFSET(cfg_entry) + field->size;
-+
-+              if ((req_start >= field_start && req_start < field_end)
-+                  || (req_end > field_start && req_end <= field_end)) {
-+                      tmp_val = 0;
-+
-+                      err = pciback_config_read(dev, field_start,
-+                                                field->size, &tmp_val);
-+                      if (err)
-+                              break;
-+
-+                      tmp_val = merge_value(tmp_val, value, get_mask(size),
-+                                            req_start - field_start);
-+
-+                      err = conf_space_write(dev, cfg_entry, field_start,
-+                                             tmp_val);
-+
-+                      /* handled is set true here, but not every byte
-+                       * may have been written! Properly detecting if
-+                       * every byte is handled is unnecessary as the
-+                       * flag is used to detect devices that need
-+                       * special helpers to work correctly.
-+                       */
-+                      handled = 1;
-+              }
-+      }
-+
-+      if (!handled && !err) {
-+              /* By default, anything not specificially handled above is
-+               * read-only. The permissive flag changes this behavior so
-+               * that anything not specifically handled above is writable.
-+               * This means that some fields may still be read-only because
-+               * they have entries in the config_field list that intercept
-+               * the write and do nothing. */
-+              if (dev_data->permissive) {
-+                      switch (size) {
-+                      case 1:
-+                              err = pci_write_config_byte(dev, offset,
-+                                                          (u8) value);
-+                              break;
-+                      case 2:
-+                              err = pci_write_config_word(dev, offset,
-+                                                          (u16) value);
-+                              break;
-+                      case 4:
-+                              err = pci_write_config_dword(dev, offset,
-+                                                           (u32) value);
-+                              break;
-+                      }
-+              } else if (!dev_data->warned_on_write) {
-+                      dev_data->warned_on_write = 1;
-+                      dev_warn(&dev->dev, "Driver tried to write to a "
-+                               "read-only configuration space field at offset "
-+                               "0x%x, size %d. This may be harmless, but if "
-+                               "you have problems with your device:\n"
-+                               "1) see permissive attribute in sysfs\n"
-+                               "2) report problems to the xen-devel "
-+                               "mailing list along with details of your "
-+                               "device obtained from lspci.\n", offset, size);
-+              }
-+      }
-+
-+      return pcibios_err_to_errno(err);
-+}
-+
-+void pciback_config_free_dyn_fields(struct pci_dev *dev)
-+{
-+      struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
-+      struct config_field_entry *cfg_entry, *t;
-+      struct config_field *field;
-+
-+      dev_dbg(&dev->dev,
-+              "free-ing dynamically allocated virtual configuration space fields\n");
-+
-+      list_for_each_entry_safe(cfg_entry, t, &dev_data->config_fields, list) {
-+              field = cfg_entry->field;
-+
-+              if (field->clean) {
-+                      field->clean(field);
-+
-+                      if (cfg_entry->data)
-+                              kfree(cfg_entry->data);
-+
-+                      list_del(&cfg_entry->list);
-+                      kfree(cfg_entry);
-+              }
-+
-+      }
-+}
-+
-+void pciback_config_reset_dev(struct pci_dev *dev)
-+{
-+      struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
-+      struct config_field_entry *cfg_entry;
-+      struct config_field *field;
-+
-+      dev_dbg(&dev->dev, "resetting virtual configuration space\n");
-+
-+      list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
-+              field = cfg_entry->field;
-+
-+              if (field->reset)
-+                      field->reset(dev, OFFSET(cfg_entry), cfg_entry->data);
-+      }
-+}
-+
-+void pciback_config_free_dev(struct pci_dev *dev)
-+{
-+      struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
-+      struct config_field_entry *cfg_entry, *t;
-+      struct config_field *field;
-+
-+      dev_dbg(&dev->dev, "free-ing virtual configuration space fields\n");
-+
-+      list_for_each_entry_safe(cfg_entry, t, &dev_data->config_fields, list) {
-+              list_del(&cfg_entry->list);
-+
-+              field = cfg_entry->field;
-+
-+              if (field->release)
-+                      field->release(dev, OFFSET(cfg_entry), cfg_entry->data);
-+
-+              kfree(cfg_entry);
-+      }
-+}
-+
-+int pciback_config_add_field_offset(struct pci_dev *dev,
-+                                  struct config_field *field,
-+                                  unsigned int offset)
-+{
-+      int err = 0;
-+      struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
-+      struct config_field_entry *cfg_entry;
-+      void *tmp;
-+
-+      /* silently ignore duplicate fields */
-+      if (pciback_field_is_dup(dev, field->offset))
-+              goto out;
-+
-+      cfg_entry = kmalloc(sizeof(*cfg_entry), GFP_KERNEL);
-+      if (!cfg_entry) {
-+              err = -ENOMEM;
-+              goto out;
-+      }
-+
-+      cfg_entry->data = NULL;
-+      cfg_entry->field = field;
-+      cfg_entry->base_offset = offset;
-+
-+      if (field->init) {
-+              tmp = field->init(dev, OFFSET(cfg_entry));
-+
-+              if (IS_ERR(tmp)) {
-+                      err = PTR_ERR(tmp);
-+                      goto out;
-+              }
-+
-+              cfg_entry->data = tmp;
-+      }
-+
-+      dev_dbg(&dev->dev, "added config field at offset 0x%02x\n",
-+              OFFSET(cfg_entry));
-+      list_add_tail(&cfg_entry->list, &dev_data->config_fields);
-+
-+      out:
-+      if (err)
-+              kfree(cfg_entry);
-+
-+      return err;
-+}
-+
-+/* This sets up the device's virtual configuration space to keep track of 
-+ * certain registers (like the base address registers (BARs) so that we can
-+ * keep the client from manipulating them directly.
-+ */
-+int pciback_config_init_dev(struct pci_dev *dev)
-+{
-+      int err = 0;
-+      struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
-+
-+      dev_dbg(&dev->dev, "initializing virtual configuration space\n");
-+
-+      INIT_LIST_HEAD(&dev_data->config_fields);
-+
-+      err = pciback_config_header_add_fields(dev);
-+      if (err)
-+              goto out;
-+
-+      err = pciback_config_capability_add_fields(dev);
-+      if (err)
-+              goto out;
-+
-+      err = pciback_config_quirks_init(dev);
-+
-+      out:
-+      return err;
-+}
-+
-+int pciback_config_init(void)
-+{
-+      return pciback_config_capability_init();
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space.h linux-2.6.16.33/drivers/xen/pciback/conf_space.h
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space.h   2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,126 @@
-+/*
-+ * PCI Backend - Common data structures for overriding the configuration space
-+ *
-+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#ifndef __XEN_PCIBACK_CONF_SPACE_H__
-+#define __XEN_PCIBACK_CONF_SPACE_H__
-+
-+#include <linux/list.h>
-+#include <linux/err.h>
-+
-+/* conf_field_init can return an errno in a ptr with ERR_PTR() */
-+typedef void *(*conf_field_init) (struct pci_dev * dev, int offset);
-+typedef void (*conf_field_reset) (struct pci_dev * dev, int offset, void *data);
-+typedef void (*conf_field_free) (struct pci_dev * dev, int offset, void *data);
-+
-+typedef int (*conf_dword_write) (struct pci_dev * dev, int offset, u32 value,
-+                               void *data);
-+typedef int (*conf_word_write) (struct pci_dev * dev, int offset, u16 value,
-+                              void *data);
-+typedef int (*conf_byte_write) (struct pci_dev * dev, int offset, u8 value,
-+                              void *data);
-+typedef int (*conf_dword_read) (struct pci_dev * dev, int offset, u32 * value,
-+                              void *data);
-+typedef int (*conf_word_read) (struct pci_dev * dev, int offset, u16 * value,
-+                             void *data);
-+typedef int (*conf_byte_read) (struct pci_dev * dev, int offset, u8 * value,
-+                             void *data);
-+
-+/* These are the fields within the configuration space which we
-+ * are interested in intercepting reads/writes to and changing their
-+ * values.
-+ */
-+struct config_field {
-+      unsigned int offset;
-+      unsigned int size;
-+      unsigned int mask;
-+      conf_field_init init;
-+      conf_field_reset reset;
-+      conf_field_free release;
-+      void (*clean) (struct config_field * field);
-+      union {
-+              struct {
-+                      conf_dword_write write;
-+                      conf_dword_read read;
-+              } dw;
-+              struct {
-+                      conf_word_write write;
-+                      conf_word_read read;
-+              } w;
-+              struct {
-+                      conf_byte_write write;
-+                      conf_byte_read read;
-+              } b;
-+      } u;
-+      struct list_head list;
-+};
-+
-+struct config_field_entry {
-+      struct list_head list;
-+      struct config_field *field;
-+      unsigned int base_offset;
-+      void *data;
-+};
-+
-+#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
-+
-+/* Add fields to a device - the add_fields macro expects to get a pointer to
-+ * the first entry in an array (of which the ending is marked by size==0)
-+ */
-+int pciback_config_add_field_offset(struct pci_dev *dev,
-+                                  struct config_field *field,
-+                                  unsigned int offset);
-+
-+static inline int pciback_config_add_field(struct pci_dev *dev,
-+                                         struct config_field *field)
-+{
-+      return pciback_config_add_field_offset(dev, field, 0);
-+}
-+
-+static inline int pciback_config_add_fields(struct pci_dev *dev,
-+                                          struct config_field *field)
-+{
-+      int i, err = 0;
-+      for (i = 0; field[i].size != 0; i++) {
-+              err = pciback_config_add_field(dev, &field[i]);
-+              if (err)
-+                      break;
-+      }
-+      return err;
-+}
-+
-+static inline int pciback_config_add_fields_offset(struct pci_dev *dev,
-+                                                 struct config_field *field,
-+                                                 unsigned int offset)
-+{
-+      int i, err = 0;
-+      for (i = 0; field[i].size != 0; i++) {
-+              err = pciback_config_add_field_offset(dev, &field[i], offset);
-+              if (err)
-+                      break;
-+      }
-+      return err;
-+}
-+
-+/* Read/Write the real configuration space */
-+int pciback_read_config_byte(struct pci_dev *dev, int offset, u8 * value,
-+                           void *data);
-+int pciback_read_config_word(struct pci_dev *dev, int offset, u16 * value,
-+                           void *data);
-+int pciback_read_config_dword(struct pci_dev *dev, int offset, u32 * value,
-+                            void *data);
-+int pciback_write_config_byte(struct pci_dev *dev, int offset, u8 value,
-+                            void *data);
-+int pciback_write_config_word(struct pci_dev *dev, int offset, u16 value,
-+                            void *data);
-+int pciback_write_config_dword(struct pci_dev *dev, int offset, u32 value,
-+                             void *data);
-+
-+int pciback_config_capability_init(void);
-+
-+int pciback_config_header_add_fields(struct pci_dev *dev);
-+int pciback_config_capability_add_fields(struct pci_dev *dev);
-+
-+#endif                                /* __XEN_PCIBACK_CONF_SPACE_H__ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_capability.c linux-2.6.16.33/drivers/xen/pciback/conf_space_capability.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_capability.c  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space_capability.c        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,71 @@
-+/*
-+ * PCI Backend - Handles the virtual fields found on the capability lists
-+ *               in the configuration space.
-+ *
-+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include "pciback.h"
-+#include "conf_space.h"
-+#include "conf_space_capability.h"
-+
-+static LIST_HEAD(capabilities);
-+
-+static struct config_field caplist_header[] = {
-+      {
-+       .offset    = PCI_CAP_LIST_ID,
-+       .size      = 2, /* encompass PCI_CAP_LIST_ID & PCI_CAP_LIST_NEXT */
-+       .u.w.read  = pciback_read_config_word,
-+       .u.w.write = NULL,
-+      },
-+      {
-+       .size = 0,
-+      },
-+};
-+
-+static inline void register_capability(struct pciback_config_capability *cap)
-+{
-+      list_add_tail(&cap->cap_list, &capabilities);
-+}
-+
-+int pciback_config_capability_add_fields(struct pci_dev *dev)
-+{
-+      int err = 0;
-+      struct pciback_config_capability *cap;
-+      int cap_offset;
-+
-+      list_for_each_entry(cap, &capabilities, cap_list) {
-+              cap_offset = pci_find_capability(dev, cap->capability);
-+              if (cap_offset) {
-+                      dev_dbg(&dev->dev, "Found capability 0x%x at 0x%x\n",
-+                              cap->capability, cap_offset);
-+
-+                      err = pciback_config_add_fields_offset(dev,
-+                                                             caplist_header,
-+                                                             cap_offset);
-+                      if (err)
-+                              goto out;
-+                      err = pciback_config_add_fields_offset(dev,
-+                                                             cap->fields,
-+                                                             cap_offset);
-+                      if (err)
-+                              goto out;
-+              }
-+      }
-+
-+      out:
-+      return err;
-+}
-+
-+extern struct pciback_config_capability pciback_config_capability_vpd;
-+extern struct pciback_config_capability pciback_config_capability_pm;
-+
-+int pciback_config_capability_init(void)
-+{
-+      register_capability(&pciback_config_capability_vpd);
-+      register_capability(&pciback_config_capability_pm);
-+
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_capability.h linux-2.6.16.33/drivers/xen/pciback/conf_space_capability.h
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_capability.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space_capability.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,23 @@
-+/*
-+ * PCI Backend - Data structures for special overlays for structures on
-+ *               the capability list.
-+ *
-+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#ifndef __PCIBACK_CONFIG_CAPABILITY_H__
-+#define __PCIBACK_CONFIG_CAPABILITY_H__
-+
-+#include <linux/pci.h>
-+#include <linux/list.h>
-+
-+struct pciback_config_capability {
-+      struct list_head cap_list;
-+
-+      int capability;
-+
-+      /* If the device has the capability found above, add these fields */
-+      struct config_field *fields;
-+};
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_capability_pm.c linux-2.6.16.33/drivers/xen/pciback/conf_space_capability_pm.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_capability_pm.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space_capability_pm.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,113 @@
-+/*
-+ * PCI Backend - Configuration space overlay for power management
-+ *
-+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#include <linux/pci.h>
-+#include "conf_space.h"
-+#include "conf_space_capability.h"
-+
-+static int pm_caps_read(struct pci_dev *dev, int offset, u16 *value,
-+                      void *data)
-+{
-+      int err;
-+      u16 real_value;
-+
-+      err = pci_read_config_word(dev, offset, &real_value);
-+      if (err)
-+              goto out;
-+
-+      *value = real_value & ~PCI_PM_CAP_PME_MASK;
-+
-+      out:
-+      return err;
-+}
-+
-+/* PM_OK_BITS specifies the bits that the driver domain is allowed to change.
-+ * Can't allow driver domain to enable PMEs - they're shared */
-+#define PM_OK_BITS (PCI_PM_CTRL_PME_STATUS|PCI_PM_CTRL_DATA_SEL_MASK)
-+
-+static int pm_ctrl_write(struct pci_dev *dev, int offset, u16 new_value,
-+                       void *data)
-+{
-+      int err;
-+      u16 cur_value;
-+      pci_power_t new_state;
-+
-+      /* Handle setting power state separately */
-+      new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);
-+
-+      err = pci_read_config_word(dev, offset, &cur_value);
-+      if (err)
-+              goto out;
-+
-+      new_value &= PM_OK_BITS;
-+      if ((cur_value & PM_OK_BITS) != new_value) {
-+              new_value = (cur_value & ~PM_OK_BITS) | new_value;
-+              err = pci_write_config_word(dev, offset, new_value);
-+              if (err)
-+                      goto out;
-+      }
-+
-+      /* Let pci core handle the power management change */
-+      dev_dbg(&dev->dev, "set power state to %x\n", new_state);
-+      err = pci_set_power_state(dev, new_state);
-+      if (err)
-+              err = PCIBIOS_SET_FAILED;
-+
-+      out:
-+      return err;
-+}
-+
-+/* Ensure PMEs are disabled */
-+static void *pm_ctrl_init(struct pci_dev *dev, int offset)
-+{
-+      int err;
-+      u16 value;
-+
-+      err = pci_read_config_word(dev, offset, &value);
-+      if (err)
-+              goto out;
-+
-+      if (value & PCI_PM_CTRL_PME_ENABLE) {
-+              value &= ~PCI_PM_CTRL_PME_ENABLE;
-+              err = pci_write_config_word(dev, offset, value);
-+      }
-+
-+      out:
-+      return ERR_PTR(err);
-+}
-+
-+static struct config_field caplist_pm[] = {
-+      {
-+              .offset     = PCI_PM_PMC,
-+              .size       = 2,
-+              .u.w.read   = pm_caps_read,
-+      },
-+      {
-+              .offset     = PCI_PM_CTRL,
-+              .size       = 2,
-+              .init       = pm_ctrl_init,
-+              .u.w.read   = pciback_read_config_word,
-+              .u.w.write  = pm_ctrl_write,
-+      },
-+      {
-+              .offset     = PCI_PM_PPB_EXTENSIONS,
-+              .size       = 1,
-+              .u.b.read   = pciback_read_config_byte,
-+      },
-+      {
-+              .offset     = PCI_PM_DATA_REGISTER,
-+              .size       = 1,
-+              .u.b.read   = pciback_read_config_byte,
-+      },
-+      {
-+              .size = 0,
-+      },
-+};
-+
-+struct pciback_config_capability pciback_config_capability_pm = {
-+      .capability = PCI_CAP_ID_PM,
-+      .fields = caplist_pm,
-+};
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_capability_vpd.c linux-2.6.16.33/drivers/xen/pciback/conf_space_capability_vpd.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_capability_vpd.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space_capability_vpd.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,42 @@
-+/*
-+ * PCI Backend - Configuration space overlay for Vital Product Data
-+ *
-+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#include <linux/pci.h>
-+#include "conf_space.h"
-+#include "conf_space_capability.h"
-+
-+static int vpd_address_write(struct pci_dev *dev, int offset, u16 value,
-+                           void *data)
-+{
-+      /* Disallow writes to the vital product data */
-+      if (value & PCI_VPD_ADDR_F)
-+              return PCIBIOS_SET_FAILED;
-+      else
-+              return pci_write_config_word(dev, offset, value);
-+}
-+
-+static struct config_field caplist_vpd[] = {
-+      {
-+       .offset    = PCI_VPD_ADDR,
-+       .size      = 2,
-+       .u.w.read  = pciback_read_config_word,
-+       .u.w.write = vpd_address_write,
-+       },
-+      {
-+       .offset     = PCI_VPD_DATA,
-+       .size       = 4,
-+       .u.dw.read  = pciback_read_config_dword,
-+       .u.dw.write = NULL,
-+       },
-+      {
-+       .size = 0,
-+       },
-+};
-+ 
-+struct pciback_config_capability pciback_config_capability_vpd = {
-+      .capability = PCI_CAP_ID_VPD,
-+      .fields = caplist_vpd,
-+};
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_header.c linux-2.6.16.33/drivers/xen/pciback/conf_space_header.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_header.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space_header.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,299 @@
-+/*
-+ * PCI Backend - Handles the virtual fields in the configuration space headers.
-+ *
-+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include "pciback.h"
-+#include "conf_space.h"
-+
-+struct pci_bar_info {
-+      u32 val;
-+      u32 len_val;
-+      int which;
-+};
-+
-+#define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
-+#define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
-+
-+static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
-+{
-+      if (!dev->is_enabled && is_enable_cmd(value)) {
-+              if (unlikely(verbose_request))
-+                      printk(KERN_DEBUG "pciback: %s: enable\n",
-+                             pci_name(dev));
-+              pci_enable_device(dev);
-+      } else if (dev->is_enabled && !is_enable_cmd(value)) {
-+              if (unlikely(verbose_request))
-+                      printk(KERN_DEBUG "pciback: %s: disable\n",
-+                             pci_name(dev));
-+              pci_disable_device(dev);
-+      }
-+
-+      if (!dev->is_busmaster && is_master_cmd(value)) {
-+              if (unlikely(verbose_request))
-+                      printk(KERN_DEBUG "pciback: %s: set bus master\n",
-+                             pci_name(dev));
-+              pci_set_master(dev);
-+      }
-+
-+      if (value & PCI_COMMAND_INVALIDATE) {
-+              if (unlikely(verbose_request))
-+                      printk(KERN_DEBUG
-+                             "pciback: %s: enable memory-write-invalidate\n",
-+                             pci_name(dev));
-+              pci_set_mwi(dev);
-+      }
-+
-+      return pci_write_config_word(dev, offset, value);
-+}
-+
-+static int rom_write(struct pci_dev *dev, int offset, u32 value, void *data)
-+{
-+      struct pci_bar_info *bar = data;
-+
-+      if (unlikely(!bar)) {
-+              printk(KERN_WARNING "pciback: driver data not found for %s\n",
-+                     pci_name(dev));
-+              return XEN_PCI_ERR_op_failed;
-+      }
-+
-+      /* A write to obtain the length must happen as a 32-bit write.
-+       * This does not (yet) support writing individual bytes
-+       */
-+      if (value == ~PCI_ROM_ADDRESS_ENABLE)
-+              bar->which = 1;
-+      else
-+              bar->which = 0;
-+
-+      /* Do we need to support enabling/disabling the rom address here? */
-+
-+      return 0;
-+}
-+
-+/* For the BARs, only allow writes which write ~0 or
-+ * the correct resource information
-+ * (Needed for when the driver probes the resource usage)
-+ */
-+static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data)
-+{
-+      struct pci_bar_info *bar = data;
-+
-+      if (unlikely(!bar)) {
-+              printk(KERN_WARNING "pciback: driver data not found for %s\n",
-+                     pci_name(dev));
-+              return XEN_PCI_ERR_op_failed;
-+      }
-+
-+      /* A write to obtain the length must happen as a 32-bit write.
-+       * This does not (yet) support writing individual bytes
-+       */
-+      if (value == ~0)
-+              bar->which = 1;
-+      else
-+              bar->which = 0;
-+
-+      return 0;
-+}
-+
-+static int bar_read(struct pci_dev *dev, int offset, u32 * value, void *data)
-+{
-+      struct pci_bar_info *bar = data;
-+
-+      if (unlikely(!bar)) {
-+              printk(KERN_WARNING "pciback: driver data not found for %s\n",
-+                     pci_name(dev));
-+              return XEN_PCI_ERR_op_failed;
-+      }
-+
-+      *value = bar->which ? bar->len_val : bar->val;
-+
-+      return 0;
-+}
-+
-+static inline void read_dev_bar(struct pci_dev *dev,
-+                              struct pci_bar_info *bar_info, int offset,
-+                              u32 len_mask)
-+{
-+      pci_read_config_dword(dev, offset, &bar_info->val);
-+      pci_write_config_dword(dev, offset, len_mask);
-+      pci_read_config_dword(dev, offset, &bar_info->len_val);
-+      pci_write_config_dword(dev, offset, bar_info->val);
-+}
-+
-+static void *bar_init(struct pci_dev *dev, int offset)
-+{
-+      struct pci_bar_info *bar = kmalloc(sizeof(*bar), GFP_KERNEL);
-+
-+      if (!bar)
-+              return ERR_PTR(-ENOMEM);
-+
-+      read_dev_bar(dev, bar, offset, ~0);
-+      bar->which = 0;
-+
-+      return bar;
-+}
-+
-+static void *rom_init(struct pci_dev *dev, int offset)
-+{
-+      struct pci_bar_info *bar = kmalloc(sizeof(*bar), GFP_KERNEL);
-+
-+      if (!bar)
-+              return ERR_PTR(-ENOMEM);
-+
-+      read_dev_bar(dev, bar, offset, ~PCI_ROM_ADDRESS_ENABLE);
-+      bar->which = 0;
-+
-+      return bar;
-+}
-+
-+static void bar_reset(struct pci_dev *dev, int offset, void *data)
-+{
-+      struct pci_bar_info *bar = data;
-+
-+      bar->which = 0;
-+}
-+
-+static void bar_release(struct pci_dev *dev, int offset, void *data)
-+{
-+      kfree(data);
-+}
-+
-+static int interrupt_read(struct pci_dev *dev, int offset, u8 * value,
-+                        void *data)
-+{
-+      *value = (u8) dev->irq;
-+
-+      return 0;
-+}
-+
-+static int bist_write(struct pci_dev *dev, int offset, u8 value, void *data)
-+{
-+      u8 cur_value;
-+      int err;
-+
-+      err = pci_read_config_byte(dev, offset, &cur_value);
-+      if (err)
-+              goto out;
-+
-+      if ((cur_value & ~PCI_BIST_START) == (value & ~PCI_BIST_START)
-+          || value == PCI_BIST_START)
-+              err = pci_write_config_byte(dev, offset, value);
-+
-+      out:
-+      return err;
-+}
-+
-+static struct config_field header_common[] = {
-+      {
-+       .offset    = PCI_COMMAND,
-+       .size      = 2,
-+       .u.w.read  = pciback_read_config_word,
-+       .u.w.write = command_write,
-+      },
-+      {
-+       .offset    = PCI_INTERRUPT_LINE,
-+       .size      = 1,
-+       .u.b.read  = interrupt_read,
-+      },
-+      {
-+       .offset    = PCI_INTERRUPT_PIN,
-+       .size      = 1,
-+       .u.b.read  = pciback_read_config_byte,
-+      },
-+      {
-+       /* Any side effects of letting driver domain control cache line? */
-+       .offset    = PCI_CACHE_LINE_SIZE,
-+       .size      = 1,
-+       .u.b.read  = pciback_read_config_byte,
-+       .u.b.write = pciback_write_config_byte,
-+      },
-+      {
-+       .offset    = PCI_LATENCY_TIMER,
-+       .size      = 1,
-+       .u.b.read  = pciback_read_config_byte,
-+      },
-+      {
-+       .offset    = PCI_BIST,
-+       .size      = 1,
-+       .u.b.read  = pciback_read_config_byte,
-+       .u.b.write = bist_write,
-+      },
-+      {
-+       .size = 0,
-+      },
-+};
-+
-+#define CFG_FIELD_BAR(reg_offset)                     \
-+      {                                               \
-+       .offset     = reg_offset,                      \
-+       .size       = 4,                               \
-+       .init       = bar_init,                        \
-+       .reset      = bar_reset,                       \
-+       .release    = bar_release,                     \
-+       .u.dw.read  = bar_read,                        \
-+       .u.dw.write = bar_write,                       \
-+       }
-+
-+#define CFG_FIELD_ROM(reg_offset)                     \
-+      {                                               \
-+       .offset     = reg_offset,                      \
-+       .size       = 4,                               \
-+       .init       = rom_init,                        \
-+       .reset      = bar_reset,                       \
-+       .release    = bar_release,                     \
-+       .u.dw.read  = bar_read,                        \
-+       .u.dw.write = rom_write,                       \
-+       }
-+
-+static struct config_field header_0[] = {
-+      CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
-+      CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
-+      CFG_FIELD_BAR(PCI_BASE_ADDRESS_2),
-+      CFG_FIELD_BAR(PCI_BASE_ADDRESS_3),
-+      CFG_FIELD_BAR(PCI_BASE_ADDRESS_4),
-+      CFG_FIELD_BAR(PCI_BASE_ADDRESS_5),
-+      CFG_FIELD_ROM(PCI_ROM_ADDRESS),
-+      {
-+       .size = 0,
-+      },
-+};
-+
-+static struct config_field header_1[] = {
-+      CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
-+      CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
-+      CFG_FIELD_ROM(PCI_ROM_ADDRESS1),
-+      {
-+       .size = 0,
-+      },
-+};
-+
-+int pciback_config_header_add_fields(struct pci_dev *dev)
-+{
-+      int err;
-+
-+      err = pciback_config_add_fields(dev, header_common);
-+      if (err)
-+              goto out;
-+
-+      switch (dev->hdr_type) {
-+      case PCI_HEADER_TYPE_NORMAL:
-+              err = pciback_config_add_fields(dev, header_0);
-+              break;
-+
-+      case PCI_HEADER_TYPE_BRIDGE:
-+              err = pciback_config_add_fields(dev, header_1);
-+              break;
-+
-+      default:
-+              err = -EINVAL;
-+              printk(KERN_ERR "pciback: %s: Unsupported header type %d!\n",
-+                     pci_name(dev), dev->hdr_type);
-+              break;
-+      }
-+
-+      out:
-+      return err;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_quirks.c linux-2.6.16.33/drivers/xen/pciback/conf_space_quirks.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_quirks.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space_quirks.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,128 @@
-+/*
-+ * PCI Backend - Handle special overlays for broken devices.
-+ *
-+ * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ * Author: Chris Bookholt <hap10@epoch.ncsc.mil>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include "pciback.h"
-+#include "conf_space.h"
-+#include "conf_space_quirks.h"
-+
-+LIST_HEAD(pciback_quirks);
-+
-+struct pciback_config_quirk *pciback_find_quirk(struct pci_dev *dev)
-+{
-+      struct pciback_config_quirk *tmp_quirk;
-+
-+      list_for_each_entry(tmp_quirk, &pciback_quirks, quirks_list)
-+          if (pci_match_id(&tmp_quirk->devid, dev))
-+              goto out;
-+      tmp_quirk = NULL;
-+      printk(KERN_DEBUG
-+             "quirk didn't match any device pciback knows about\n");
-+      out:
-+      return tmp_quirk;
-+}
-+
-+static inline void register_quirk(struct pciback_config_quirk *quirk)
-+{
-+      list_add_tail(&quirk->quirks_list, &pciback_quirks);
-+}
-+
-+int pciback_field_is_dup(struct pci_dev *dev, int reg)
-+{
-+      int ret = 0;
-+      struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
-+      struct config_field *field;
-+      struct config_field_entry *cfg_entry;
-+
-+      list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
-+              field = cfg_entry->field;
-+              if (field->offset == reg) {
-+                      ret = 1;
-+                      break;
-+              }
-+      }
-+      return ret;
-+}
-+
-+int pciback_config_quirks_add_field(struct pci_dev *dev, struct config_field
-+                                  *field)
-+{
-+      int err = 0;
-+
-+      switch (field->size) {
-+      case 1:
-+              field->u.b.read = pciback_read_config_byte;
-+              field->u.b.write = pciback_write_config_byte;
-+              break;
-+      case 2:
-+              field->u.w.read = pciback_read_config_word;
-+              field->u.w.write = pciback_write_config_word;
-+              break;
-+      case 4:
-+              field->u.dw.read = pciback_read_config_dword;
-+              field->u.dw.write = pciback_write_config_dword;
-+              break;
-+      default:
-+              err = -EINVAL;
-+              goto out;
-+      }
-+
-+      pciback_config_add_field(dev, field);
-+
-+      out:
-+      return err;
-+}
-+
-+int pciback_config_quirks_init(struct pci_dev *dev)
-+{
-+      struct pciback_config_quirk *quirk;
-+      int ret = 0;
-+
-+      quirk = kzalloc(sizeof(*quirk), GFP_ATOMIC);
-+      if (!quirk) {
-+              ret = -ENOMEM;
-+              goto out;
-+      }
-+
-+      quirk->devid.vendor = dev->vendor;
-+      quirk->devid.device = dev->device;
-+      quirk->devid.subvendor = dev->subsystem_vendor;
-+      quirk->devid.subdevice = dev->subsystem_device;
-+      quirk->devid.class = 0;
-+      quirk->devid.class_mask = 0;
-+      quirk->devid.driver_data = 0UL;
-+
-+      quirk->pdev = dev;
-+
-+      register_quirk(quirk);
-+      out:
-+      return ret;
-+}
-+
-+void pciback_config_field_free(struct config_field *field)
-+{
-+      kfree(field);
-+}
-+
-+int pciback_config_quirk_release(struct pci_dev *dev)
-+{
-+      struct pciback_config_quirk *quirk;
-+      int ret = 0;
-+
-+      quirk = pciback_find_quirk(dev);
-+      if (!quirk) {
-+              ret = -ENXIO;
-+              goto out;
-+      }
-+
-+      list_del(&quirk->quirks_list);
-+      kfree(quirk);
-+
-+      out:
-+      return ret;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_quirks.h linux-2.6.16.33/drivers/xen/pciback/conf_space_quirks.h
---- linux-2.6.16.33-noxen/drivers/xen/pciback/conf_space_quirks.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/conf_space_quirks.h    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,35 @@
-+/*
-+ * PCI Backend - Data structures for special overlays for broken devices.
-+ *
-+ * Ryan Wilson <hap9@epoch.ncsc.mil>
-+ * Chris Bookholt <hap10@epoch.ncsc.mil>
-+ */
-+
-+#ifndef __XEN_PCIBACK_CONF_SPACE_QUIRKS_H__
-+#define __XEN_PCIBACK_CONF_SPACE_QUIRKS_H__
-+
-+#include <linux/pci.h>
-+#include <linux/list.h>
-+
-+struct pciback_config_quirk {
-+      struct list_head quirks_list;
-+      struct pci_device_id devid;
-+      struct pci_dev *pdev;
-+};
-+
-+struct pciback_config_quirk *pciback_find_quirk(struct pci_dev *dev);
-+
-+int pciback_config_quirks_add_field(struct pci_dev *dev, struct config_field
-+                                  *field);
-+
-+int pciback_config_quirks_remove_field(struct pci_dev *dev, int reg);
-+
-+int pciback_config_quirks_init(struct pci_dev *dev);
-+
-+void pciback_config_field_free(struct config_field *field);
-+
-+int pciback_config_quirk_release(struct pci_dev *dev);
-+
-+int pciback_field_is_dup(struct pci_dev *dev, int reg);
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/passthrough.c linux-2.6.16.33/drivers/xen/pciback/passthrough.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/passthrough.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/passthrough.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,157 @@
-+/*
-+ * PCI Backend - Provides restricted access to the real PCI bus topology
-+ *               to the frontend
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#include <linux/list.h>
-+#include <linux/pci.h>
-+#include <linux/spinlock.h>
-+#include "pciback.h"
-+
-+struct passthrough_dev_data {
-+      /* Access to dev_list must be protected by lock */
-+      struct list_head dev_list;
-+      spinlock_t lock;
-+};
-+
-+struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
-+                                  unsigned int domain, unsigned int bus,
-+                                  unsigned int devfn)
-+{
-+      struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
-+      struct pci_dev_entry *dev_entry;
-+      struct pci_dev *dev = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&dev_data->lock, flags);
-+
-+      list_for_each_entry(dev_entry, &dev_data->dev_list, list) {
-+              if (domain == (unsigned int)pci_domain_nr(dev_entry->dev->bus)
-+                  && bus == (unsigned int)dev_entry->dev->bus->number
-+                  && devfn == dev_entry->dev->devfn) {
-+                      dev = dev_entry->dev;
-+                      break;
-+              }
-+      }
-+
-+      spin_unlock_irqrestore(&dev_data->lock, flags);
-+
-+      return dev;
-+}
-+
-+int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
-+{
-+      struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
-+      struct pci_dev_entry *dev_entry;
-+      unsigned long flags;
-+
-+      dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL);
-+      if (!dev_entry)
-+              return -ENOMEM;
-+      dev_entry->dev = dev;
-+
-+      spin_lock_irqsave(&dev_data->lock, flags);
-+      list_add_tail(&dev_entry->list, &dev_data->dev_list);
-+      spin_unlock_irqrestore(&dev_data->lock, flags);
-+
-+      return 0;
-+}
-+
-+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
-+{
-+      struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
-+      struct pci_dev_entry *dev_entry, *t;
-+      struct pci_dev *found_dev = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&dev_data->lock, flags);
-+
-+      list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
-+              if (dev_entry->dev == dev) {
-+                      list_del(&dev_entry->list);
-+                      found_dev = dev_entry->dev;
-+                      kfree(dev_entry);
-+              }
-+      }
-+
-+      spin_unlock_irqrestore(&dev_data->lock, flags);
-+
-+      if (found_dev)
-+              pcistub_put_pci_dev(found_dev);
-+}
-+
-+int pciback_init_devices(struct pciback_device *pdev)
-+{
-+      struct passthrough_dev_data *dev_data;
-+
-+      dev_data = kmalloc(sizeof(*dev_data), GFP_KERNEL);
-+      if (!dev_data)
-+              return -ENOMEM;
-+
-+      spin_lock_init(&dev_data->lock);
-+
-+      INIT_LIST_HEAD(&dev_data->dev_list);
-+
-+      pdev->pci_dev_data = dev_data;
-+
-+      return 0;
-+}
-+
-+int pciback_publish_pci_roots(struct pciback_device *pdev,
-+                            publish_pci_root_cb publish_root_cb)
-+{
-+      int err = 0;
-+      struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
-+      struct pci_dev_entry *dev_entry, *e;
-+      struct pci_dev *dev;
-+      int found;
-+      unsigned int domain, bus;
-+
-+      spin_lock(&dev_data->lock);
-+
-+      list_for_each_entry(dev_entry, &dev_data->dev_list, list) {
-+              /* Only publish this device as a root if none of its
-+               * parent bridges are exported
-+               */
-+              found = 0;
-+              dev = dev_entry->dev->bus->self;
-+              for (; !found && dev != NULL; dev = dev->bus->self) {
-+                      list_for_each_entry(e, &dev_data->dev_list, list) {
-+                              if (dev == e->dev) {
-+                                      found = 1;
-+                                      break;
-+                              }
-+                      }
-+              }
-+
-+              domain = (unsigned int)pci_domain_nr(dev_entry->dev->bus);
-+              bus = (unsigned int)dev_entry->dev->bus->number;
-+
-+              if (!found) {
-+                      err = publish_root_cb(pdev, domain, bus);
-+                      if (err)
-+                              break;
-+              }
-+      }
-+
-+      spin_unlock(&dev_data->lock);
-+
-+      return err;
-+}
-+
-+void pciback_release_devices(struct pciback_device *pdev)
-+{
-+      struct passthrough_dev_data *dev_data = pdev->pci_dev_data;
-+      struct pci_dev_entry *dev_entry, *t;
-+
-+      list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) {
-+              list_del(&dev_entry->list);
-+              pcistub_put_pci_dev(dev_entry->dev);
-+              kfree(dev_entry);
-+      }
-+
-+      kfree(dev_data);
-+      pdev->pci_dev_data = NULL;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/pci_stub.c linux-2.6.16.33/drivers/xen/pciback/pci_stub.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/pci_stub.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/pci_stub.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,916 @@
-+/*
-+ * PCI Stub Driver - Grabs devices in backend to be exported later
-+ *
-+ * Ryan Wilson <hap9@epoch.ncsc.mil>
-+ * Chris Bookholt <hap10@epoch.ncsc.mil>
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/spinlock.h>
-+#include <linux/kref.h>
-+#include <asm/atomic.h>
-+#include "pciback.h"
-+#include "conf_space.h"
-+#include "conf_space_quirks.h"
-+
-+static char *pci_devs_to_hide = NULL;
-+module_param_named(hide, pci_devs_to_hide, charp, 0444);
-+
-+struct pcistub_device_id {
-+      struct list_head slot_list;
-+      int domain;
-+      unsigned char bus;
-+      unsigned int devfn;
-+};
-+static LIST_HEAD(pcistub_device_ids);
-+static DEFINE_SPINLOCK(device_ids_lock);
-+
-+struct pcistub_device {
-+      struct kref kref;
-+      struct list_head dev_list;
-+      spinlock_t lock;
-+
-+      struct pci_dev *dev;
-+      struct pciback_device *pdev;    /* non-NULL if struct pci_dev is in use */
-+};
-+
-+/* Access to pcistub_devices & seized_devices lists and the initialize_devices
-+ * flag must be locked with pcistub_devices_lock
-+ */
-+static DEFINE_SPINLOCK(pcistub_devices_lock);
-+static LIST_HEAD(pcistub_devices);
-+
-+/* wait for device_initcall before initializing our devices
-+ * (see pcistub_init_devices_late)
-+ */
-+static int initialize_devices = 0;
-+static LIST_HEAD(seized_devices);
-+
-+static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
-+{
-+      struct pcistub_device *psdev;
-+
-+      dev_dbg(&dev->dev, "pcistub_device_alloc\n");
-+
-+      psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC);
-+      if (!psdev)
-+              return NULL;
-+
-+      psdev->dev = pci_dev_get(dev);
-+      if (!psdev->dev) {
-+              kfree(psdev);
-+              return NULL;
-+      }
-+
-+      kref_init(&psdev->kref);
-+      spin_lock_init(&psdev->lock);
-+
-+      return psdev;
-+}
-+
-+/* Don't call this directly as it's called by pcistub_device_put */
-+static void pcistub_device_release(struct kref *kref)
-+{
-+      struct pcistub_device *psdev;
-+
-+      psdev = container_of(kref, struct pcistub_device, kref);
-+
-+      dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
-+
-+      /* Clean-up the device */
-+      pciback_reset_device(psdev->dev);
-+      pciback_config_free_dyn_fields(psdev->dev);
-+      pciback_config_free_dev(psdev->dev);
-+      kfree(pci_get_drvdata(psdev->dev));
-+      pci_set_drvdata(psdev->dev, NULL);
-+
-+      pci_dev_put(psdev->dev);
-+
-+      kfree(psdev);
-+}
-+
-+static inline void pcistub_device_get(struct pcistub_device *psdev)
-+{
-+      kref_get(&psdev->kref);
-+}
-+
-+static inline void pcistub_device_put(struct pcistub_device *psdev)
-+{
-+      kref_put(&psdev->kref, pcistub_device_release);
-+}
-+
-+static struct pcistub_device *pcistub_device_find(int domain, int bus,
-+                                                int slot, int func)
-+{
-+      struct pcistub_device *psdev = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+      list_for_each_entry(psdev, &pcistub_devices, dev_list) {
-+              if (psdev->dev != NULL
-+                  && domain == pci_domain_nr(psdev->dev->bus)
-+                  && bus == psdev->dev->bus->number
-+                  && PCI_DEVFN(slot, func) == psdev->dev->devfn) {
-+                      pcistub_device_get(psdev);
-+                      goto out;
-+              }
-+      }
-+
-+      /* didn't find it */
-+      psdev = NULL;
-+
-+      out:
-+      spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+      return psdev;
-+}
-+
-+static struct pci_dev *pcistub_device_get_pci_dev(struct pciback_device *pdev,
-+                                                struct pcistub_device *psdev)
-+{
-+      struct pci_dev *pci_dev = NULL;
-+      unsigned long flags;
-+
-+      pcistub_device_get(psdev);
-+
-+      spin_lock_irqsave(&psdev->lock, flags);
-+      if (!psdev->pdev) {
-+              psdev->pdev = pdev;
-+              pci_dev = psdev->dev;
-+      }
-+      spin_unlock_irqrestore(&psdev->lock, flags);
-+
-+      if (!pci_dev)
-+              pcistub_device_put(psdev);
-+
-+      return pci_dev;
-+}
-+
-+struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev,
-+                                          int domain, int bus,
-+                                          int slot, int func)
-+{
-+      struct pcistub_device *psdev;
-+      struct pci_dev *found_dev = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+      list_for_each_entry(psdev, &pcistub_devices, dev_list) {
-+              if (psdev->dev != NULL
-+                  && domain == pci_domain_nr(psdev->dev->bus)
-+                  && bus == psdev->dev->bus->number
-+                  && PCI_DEVFN(slot, func) == psdev->dev->devfn) {
-+                      found_dev = pcistub_device_get_pci_dev(pdev, psdev);
-+                      break;
-+              }
-+      }
-+
-+      spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+      return found_dev;
-+}
-+
-+struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
-+                                  struct pci_dev *dev)
-+{
-+      struct pcistub_device *psdev;
-+      struct pci_dev *found_dev = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+      list_for_each_entry(psdev, &pcistub_devices, dev_list) {
-+              if (psdev->dev == dev) {
-+                      found_dev = pcistub_device_get_pci_dev(pdev, psdev);
-+                      break;
-+              }
-+      }
-+
-+      spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+      return found_dev;
-+}
-+
-+void pcistub_put_pci_dev(struct pci_dev *dev)
-+{
-+      struct pcistub_device *psdev, *found_psdev = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+      list_for_each_entry(psdev, &pcistub_devices, dev_list) {
-+              if (psdev->dev == dev) {
-+                      found_psdev = psdev;
-+                      break;
-+              }
-+      }
-+
-+      spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+
-+      /* Cleanup our device
-+       * (so it's ready for the next domain)
-+       */
-+      pciback_reset_device(found_psdev->dev);
-+      pciback_config_free_dyn_fields(found_psdev->dev);
-+      pciback_config_reset_dev(found_psdev->dev);
-+
-+      spin_lock_irqsave(&found_psdev->lock, flags);
-+      found_psdev->pdev = NULL;
-+      spin_unlock_irqrestore(&found_psdev->lock, flags);
-+
-+      pcistub_device_put(found_psdev);
-+}
-+
-+static int __devinit pcistub_match_one(struct pci_dev *dev,
-+                                     struct pcistub_device_id *pdev_id)
-+{
-+      /* Match the specified device by domain, bus, slot, func and also if
-+       * any of the device's parent bridges match.
-+       */
-+      for (; dev != NULL; dev = dev->bus->self) {
-+              if (pci_domain_nr(dev->bus) == pdev_id->domain
-+                  && dev->bus->number == pdev_id->bus
-+                  && dev->devfn == pdev_id->devfn)
-+                      return 1;
-+
-+              /* Sometimes topmost bridge links to itself. */
-+              if (dev == dev->bus->self)
-+                      break;
-+      }
-+
-+      return 0;
-+}
-+
-+static int __devinit pcistub_match(struct pci_dev *dev)
-+{
-+      struct pcistub_device_id *pdev_id;
-+      unsigned long flags;
-+      int found = 0;
-+
-+      spin_lock_irqsave(&device_ids_lock, flags);
-+      list_for_each_entry(pdev_id, &pcistub_device_ids, slot_list) {
-+              if (pcistub_match_one(dev, pdev_id)) {
-+                      found = 1;
-+                      break;
-+              }
-+      }
-+      spin_unlock_irqrestore(&device_ids_lock, flags);
-+
-+      return found;
-+}
-+
-+static int __devinit pcistub_init_device(struct pci_dev *dev)
-+{
-+      struct pciback_dev_data *dev_data;
-+      int err = 0;
-+
-+      dev_dbg(&dev->dev, "initializing...\n");
-+
-+      /* The PCI backend is not intended to be a module (or to work with
-+       * removable PCI devices (yet). If it were, pciback_config_free()
-+       * would need to be called somewhere to free the memory allocated
-+       * here and then to call kfree(pci_get_drvdata(psdev->dev)).
-+       */
-+      dev_data = kzalloc(sizeof(*dev_data), GFP_ATOMIC);
-+      if (!dev_data) {
-+              err = -ENOMEM;
-+              goto out;
-+      }
-+      pci_set_drvdata(dev, dev_data);
-+
-+      dev_dbg(&dev->dev, "initializing config\n");
-+      err = pciback_config_init_dev(dev);
-+      if (err)
-+              goto out;
-+
-+      /* HACK: Force device (& ACPI) to determine what IRQ it's on - we
-+       * must do this here because pcibios_enable_device may specify
-+       * the pci device's true irq (and possibly its other resources)
-+       * if they differ from what's in the configuration space.
-+       * This makes the assumption that the device's resources won't
-+       * change after this point (otherwise this code may break!)
-+       */
-+      dev_dbg(&dev->dev, "enabling device\n");
-+      err = pci_enable_device(dev);
-+      if (err)
-+              goto config_release;
-+
-+      /* Now disable the device (this also ensures some private device
-+       * data is setup before we export)
-+       */
-+      dev_dbg(&dev->dev, "reset device\n");
-+      pciback_reset_device(dev);
-+
-+      return 0;
-+
-+      config_release:
-+      pciback_config_free_dev(dev);
-+
-+      out:
-+      pci_set_drvdata(dev, NULL);
-+      kfree(dev_data);
-+      return err;
-+}
-+
-+/*
-+ * Because some initialization still happens on
-+ * devices during fs_initcall, we need to defer
-+ * full initialization of our devices until
-+ * device_initcall.
-+ */
-+static int __init pcistub_init_devices_late(void)
-+{
-+      struct pcistub_device *psdev;
-+      unsigned long flags;
-+      int err = 0;
-+
-+      pr_debug("pciback: pcistub_init_devices_late\n");
-+
-+      spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+      while (!list_empty(&seized_devices)) {
-+              psdev = container_of(seized_devices.next,
-+                                   struct pcistub_device, dev_list);
-+              list_del(&psdev->dev_list);
-+
-+              spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+
-+              err = pcistub_init_device(psdev->dev);
-+              if (err) {
-+                      dev_err(&psdev->dev->dev,
-+                              "error %d initializing device\n", err);
-+                      kfree(psdev);
-+                      psdev = NULL;
-+              }
-+
-+              spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+              if (psdev)
-+                      list_add_tail(&psdev->dev_list, &pcistub_devices);
-+      }
-+
-+      initialize_devices = 1;
-+
-+      spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int __devinit pcistub_seize(struct pci_dev *dev)
-+{
-+      struct pcistub_device *psdev;
-+      unsigned long flags;
-+      int err = 0;
-+
-+      psdev = pcistub_device_alloc(dev);
-+      if (!psdev)
-+              return -ENOMEM;
-+
-+      spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+      if (initialize_devices) {
-+              spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+
-+              /* don't want irqs disabled when calling pcistub_init_device */
-+              err = pcistub_init_device(psdev->dev);
-+
-+              spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+              if (!err)
-+                      list_add(&psdev->dev_list, &pcistub_devices);
-+      } else {
-+              dev_dbg(&dev->dev, "deferring initialization\n");
-+              list_add(&psdev->dev_list, &seized_devices);
-+      }
-+
-+      spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+
-+      if (err)
-+              pcistub_device_put(psdev);
-+
-+      return err;
-+}
-+
-+static int __devinit pcistub_probe(struct pci_dev *dev,
-+                                 const struct pci_device_id *id)
-+{
-+      int err = 0;
-+
-+      dev_dbg(&dev->dev, "probing...\n");
-+
-+      if (pcistub_match(dev)) {
-+
-+              if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL
-+                  && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+                      dev_err(&dev->dev, "can't export pci devices that "
-+                              "don't have a normal (0) or bridge (1) "
-+                              "header type!\n");
-+                      err = -ENODEV;
-+                      goto out;
-+              }
-+
-+              dev_info(&dev->dev, "seizing device\n");
-+              err = pcistub_seize(dev);
-+      } else
-+              /* Didn't find the device */
-+              err = -ENODEV;
-+
-+      out:
-+      return err;
-+}
-+
-+static void pcistub_remove(struct pci_dev *dev)
-+{
-+      struct pcistub_device *psdev, *found_psdev = NULL;
-+      unsigned long flags;
-+
-+      dev_dbg(&dev->dev, "removing\n");
-+
-+      spin_lock_irqsave(&pcistub_devices_lock, flags);
-+
-+      pciback_config_quirk_release(dev);
-+
-+      list_for_each_entry(psdev, &pcistub_devices, dev_list) {
-+              if (psdev->dev == dev) {
-+                      found_psdev = psdev;
-+                      break;
-+              }
-+      }
-+
-+      spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+
-+      if (found_psdev) {
-+              dev_dbg(&dev->dev, "found device to remove - in use? %p\n",
-+                      found_psdev->pdev);
-+
-+              if (found_psdev->pdev) {
-+                      printk(KERN_WARNING "pciback: ****** removing device "
-+                             "%s while still in-use! ******\n",
-+                             pci_name(found_psdev->dev));
-+                      printk(KERN_WARNING "pciback: ****** driver domain may "
-+                             "still access this device's i/o resources!\n");
-+                      printk(KERN_WARNING "pciback: ****** shutdown driver "
-+                             "domain before binding device\n");
-+                      printk(KERN_WARNING "pciback: ****** to other drivers "
-+                             "or domains\n");
-+
-+                      pciback_release_pci_dev(found_psdev->pdev,
-+                                              found_psdev->dev);
-+              }
-+
-+              spin_lock_irqsave(&pcistub_devices_lock, flags);
-+              list_del(&found_psdev->dev_list);
-+              spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+
-+              /* the final put for releasing from the list */
-+              pcistub_device_put(found_psdev);
-+      }
-+}
-+
-+static struct pci_device_id pcistub_ids[] = {
-+      {
-+       .vendor = PCI_ANY_ID,
-+       .device = PCI_ANY_ID,
-+       .subvendor = PCI_ANY_ID,
-+       .subdevice = PCI_ANY_ID,
-+       },
-+      {0,},
-+};
-+
-+/*
-+ * Note: There is no MODULE_DEVICE_TABLE entry here because this isn't
-+ * for a normal device. I don't want it to be loaded automatically.
-+ */
-+
-+static struct pci_driver pciback_pci_driver = {
-+      .name = "pciback",
-+      .id_table = pcistub_ids,
-+      .probe = pcistub_probe,
-+      .remove = pcistub_remove,
-+};
-+
-+static inline int str_to_slot(const char *buf, int *domain, int *bus,
-+                            int *slot, int *func)
-+{
-+      int err;
-+
-+      err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func);
-+      if (err == 4)
-+              return 0;
-+      else if (err < 0)
-+              return -EINVAL;
-+
-+      /* try again without domain */
-+      *domain = 0;
-+      err = sscanf(buf, " %x:%x.%x", bus, slot, func);
-+      if (err == 3)
-+              return 0;
-+
-+      return -EINVAL;
-+}
-+
-+static inline int str_to_quirk(const char *buf, int *domain, int *bus, int
-+                             *slot, int *func, int *reg, int *size, int *mask)
-+{
-+      int err;
-+
-+      err =
-+          sscanf(buf, " %04x:%02x:%02x.%1x-%08x:%1x:%08x", domain, bus, slot,
-+                 func, reg, size, mask);
-+      if (err == 7)
-+              return 0;
-+      return -EINVAL;
-+}
-+
-+static int pcistub_device_id_add(int domain, int bus, int slot, int func)
-+{
-+      struct pcistub_device_id *pci_dev_id;
-+      unsigned long flags;
-+
-+      pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
-+      if (!pci_dev_id)
-+              return -ENOMEM;
-+
-+      pci_dev_id->domain = domain;
-+      pci_dev_id->bus = bus;
-+      pci_dev_id->devfn = PCI_DEVFN(slot, func);
-+
-+      pr_debug("pciback: wants to seize %04x:%02x:%02x.%01x\n",
-+               domain, bus, slot, func);
-+
-+      spin_lock_irqsave(&device_ids_lock, flags);
-+      list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids);
-+      spin_unlock_irqrestore(&device_ids_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
-+{
-+      struct pcistub_device_id *pci_dev_id, *t;
-+      int devfn = PCI_DEVFN(slot, func);
-+      int err = -ENOENT;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&device_ids_lock, flags);
-+      list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids, slot_list) {
-+
-+              if (pci_dev_id->domain == domain
-+                  && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) {
-+                      /* Don't break; here because it's possible the same
-+                       * slot could be in the list more than once
-+                       */
-+                      list_del(&pci_dev_id->slot_list);
-+                      kfree(pci_dev_id);
-+
-+                      err = 0;
-+
-+                      pr_debug("pciback: removed %04x:%02x:%02x.%01x from "
-+                               "seize list\n", domain, bus, slot, func);
-+              }
-+      }
-+      spin_unlock_irqrestore(&device_ids_lock, flags);
-+
-+      return err;
-+}
-+
-+static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
-+                         int size, int mask)
-+{
-+      int err = 0;
-+      struct pcistub_device *psdev;
-+      struct pci_dev *dev;
-+      struct config_field *field;
-+
-+      psdev = pcistub_device_find(domain, bus, slot, func);
-+      if (!psdev || !psdev->dev) {
-+              err = -ENODEV;
-+              goto out;
-+      }
-+      dev = psdev->dev;
-+
-+      /* check for duplicate field */
-+      if (pciback_field_is_dup(dev, reg))
-+              goto out;
-+
-+      field = kzalloc(sizeof(*field), GFP_ATOMIC);
-+      if (!field) {
-+              err = -ENOMEM;
-+              goto out;
-+      }
-+
-+      field->offset = reg;
-+      field->size = size;
-+      field->mask = mask;
-+      field->init = NULL;
-+      field->reset = NULL;
-+      field->release = NULL;
-+      field->clean = pciback_config_field_free;
-+
-+      err = pciback_config_quirks_add_field(dev, field);
-+      if (err)
-+              kfree(field);
-+      out:
-+      return err;
-+}
-+
-+static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf,
-+                              size_t count)
-+{
-+      int domain, bus, slot, func;
-+      int err;
-+
-+      err = str_to_slot(buf, &domain, &bus, &slot, &func);
-+      if (err)
-+              goto out;
-+
-+      err = pcistub_device_id_add(domain, bus, slot, func);
-+
-+      out:
-+      if (!err)
-+              err = count;
-+      return err;
-+}
-+
-+DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);
-+
-+static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf,
-+                                 size_t count)
-+{
-+      int domain, bus, slot, func;
-+      int err;
-+
-+      err = str_to_slot(buf, &domain, &bus, &slot, &func);
-+      if (err)
-+              goto out;
-+
-+      err = pcistub_device_id_remove(domain, bus, slot, func);
-+
-+      out:
-+      if (!err)
-+              err = count;
-+      return err;
-+}
-+
-+DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);
-+
-+static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
-+{
-+      struct pcistub_device_id *pci_dev_id;
-+      size_t count = 0;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&device_ids_lock, flags);
-+      list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) {
-+              if (count >= PAGE_SIZE)
-+                      break;
-+
-+              count += scnprintf(buf + count, PAGE_SIZE - count,
-+                                 "%04x:%02x:%02x.%01x\n",
-+                                 pci_dev_id->domain, pci_dev_id->bus,
-+                                 PCI_SLOT(pci_dev_id->devfn),
-+                                 PCI_FUNC(pci_dev_id->devfn));
-+      }
-+      spin_unlock_irqrestore(&device_ids_lock, flags);
-+
-+      return count;
-+}
-+
-+DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);
-+
-+static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf,
-+                               size_t count)
-+{
-+      int domain, bus, slot, func, reg, size, mask;
-+      int err;
-+
-+      err = str_to_quirk(buf, &domain, &bus, &slot, &func, &reg, &size,
-+                         &mask);
-+      if (err)
-+              goto out;
-+
-+      err = pcistub_reg_add(domain, bus, slot, func, reg, size, mask);
-+
-+      out:
-+      if (!err)
-+              err = count;
-+      return err;
-+}
-+
-+static ssize_t pcistub_quirk_show(struct device_driver *drv, char *buf)
-+{
-+      int count = 0;
-+      unsigned long flags;
-+      extern struct list_head pciback_quirks;
-+      struct pciback_config_quirk *quirk;
-+      struct pciback_dev_data *dev_data;
-+      struct config_field *field;
-+      struct config_field_entry *cfg_entry;
-+
-+      spin_lock_irqsave(&device_ids_lock, flags);
-+      list_for_each_entry(quirk, &pciback_quirks, quirks_list) {
-+              if (count >= PAGE_SIZE)
-+                      goto out;
-+
-+              count += scnprintf(buf + count, PAGE_SIZE - count,
-+                                 "%02x:%02x.%01x\n\t%04x:%04x:%04x:%04x\n",
-+                                 quirk->pdev->bus->number,
-+                                 PCI_SLOT(quirk->pdev->devfn),
-+                                 PCI_FUNC(quirk->pdev->devfn),
-+                                 quirk->devid.vendor, quirk->devid.device,
-+                                 quirk->devid.subvendor,
-+                                 quirk->devid.subdevice);
-+
-+              dev_data = pci_get_drvdata(quirk->pdev);
-+
-+              list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
-+                      field = cfg_entry->field;
-+                      if (count >= PAGE_SIZE)
-+                              goto out;
-+
-+                      count += scnprintf(buf + count, PAGE_SIZE -
-+                                         count, "\t\t%08x:%01x:%08x\n",
-+                                         field->offset, field->size,
-+                                         field->mask);
-+              }
-+      }
-+
-+      out:
-+      spin_unlock_irqrestore(&device_ids_lock, flags);
-+
-+      return count;
-+}
-+
-+DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show, pcistub_quirk_add);
-+
-+static ssize_t permissive_add(struct device_driver *drv, const char *buf,
-+                            size_t count)
-+{
-+      int domain, bus, slot, func;
-+      int err;
-+      struct pcistub_device *psdev;
-+      struct pciback_dev_data *dev_data;
-+      err = str_to_slot(buf, &domain, &bus, &slot, &func);
-+      if (err)
-+              goto out;
-+      psdev = pcistub_device_find(domain, bus, slot, func);
-+      if (!psdev) {
-+              err = -ENODEV;
-+              goto out;
-+      }
-+      if (!psdev->dev) {
-+              err = -ENODEV;
-+              goto release;
-+      }
-+      dev_data = pci_get_drvdata(psdev->dev);
-+      /* the driver data for a device should never be null at this point */
-+      if (!dev_data) {
-+              err = -ENXIO;
-+              goto release;
-+      }
-+      if (!dev_data->permissive) {
-+              dev_data->permissive = 1;
-+              /* Let user know that what they're doing could be unsafe */
-+              dev_warn(&psdev->dev->dev,
-+                       "enabling permissive mode configuration space accesses!\n");
-+              dev_warn(&psdev->dev->dev,
-+                       "permissive mode is potentially unsafe!\n");
-+      }
-+      release:
-+      pcistub_device_put(psdev);
-+      out:
-+      if (!err)
-+              err = count;
-+      return err;
-+}
-+
-+static ssize_t permissive_show(struct device_driver *drv, char *buf)
-+{
-+      struct pcistub_device *psdev;
-+      struct pciback_dev_data *dev_data;
-+      size_t count = 0;
-+      unsigned long flags;
-+      spin_lock_irqsave(&pcistub_devices_lock, flags);
-+      list_for_each_entry(psdev, &pcistub_devices, dev_list) {
-+              if (count >= PAGE_SIZE)
-+                      break;
-+              if (!psdev->dev)
-+                      continue;
-+              dev_data = pci_get_drvdata(psdev->dev);
-+              if (!dev_data || !dev_data->permissive)
-+                      continue;
-+              count +=
-+                  scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
-+                            pci_name(psdev->dev));
-+      }
-+      spin_unlock_irqrestore(&pcistub_devices_lock, flags);
-+      return count;
-+}
-+
-+DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
-+
-+static int __init pcistub_init(void)
-+{
-+      int pos = 0;
-+      int err = 0;
-+      int domain, bus, slot, func;
-+      int parsed;
-+
-+      if (pci_devs_to_hide && *pci_devs_to_hide) {
-+              do {
-+                      parsed = 0;
-+
-+                      err = sscanf(pci_devs_to_hide + pos,
-+                                   " (%x:%x:%x.%x) %n",
-+                                   &domain, &bus, &slot, &func, &parsed);
-+                      if (err != 4) {
-+                              domain = 0;
-+                              err = sscanf(pci_devs_to_hide + pos,
-+                                           " (%x:%x.%x) %n",
-+                                           &bus, &slot, &func, &parsed);
-+                              if (err != 3)
-+                                      goto parse_error;
-+                      }
-+
-+                      err = pcistub_device_id_add(domain, bus, slot, func);
-+                      if (err)
-+                              goto out;
-+
-+                      /* if parsed<=0, we've reached the end of the string */
-+                      pos += parsed;
-+              } while (parsed > 0 && pci_devs_to_hide[pos]);
-+      }
-+
-+      /* If we're the first PCI Device Driver to register, we're the
-+       * first one to get offered PCI devices as they become
-+       * available (and thus we can be the first to grab them)
-+       */
-+      err = pci_register_driver(&pciback_pci_driver);
-+      if (err < 0)
-+              goto out;
-+
-+      driver_create_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
-+      driver_create_file(&pciback_pci_driver.driver,
-+                         &driver_attr_remove_slot);
-+      driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots);
-+      driver_create_file(&pciback_pci_driver.driver, &driver_attr_quirks);
-+      driver_create_file(&pciback_pci_driver.driver, &driver_attr_permissive);
-+
-+      out:
-+      return err;
-+
-+      parse_error:
-+      printk(KERN_ERR "pciback: Error parsing pci_devs_to_hide at \"%s\"\n",
-+             pci_devs_to_hide + pos);
-+      return -EINVAL;
-+}
-+
-+#ifndef MODULE
-+/*
-+ * fs_initcall happens before device_initcall
-+ * so pciback *should* get called first (b/c we 
-+ * want to suck up any device before other drivers
-+ * get a chance by being the first pci device
-+ * driver to register)
-+ */
-+fs_initcall(pcistub_init);
-+#endif
-+
-+static int __init pciback_init(void)
-+{
-+      int err;
-+
-+      err = pciback_config_init();
-+      if (err)
-+              return err;
-+
-+#ifdef MODULE
-+      err = pcistub_init();
-+      if (err < 0)
-+              return err;
-+#endif
-+
-+      pcistub_init_devices_late();
-+      pciback_xenbus_register();
-+
-+      return 0;
-+}
-+
-+static void __exit pciback_cleanup(void)
-+{
-+      pciback_xenbus_unregister();
-+
-+      driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
-+      driver_remove_file(&pciback_pci_driver.driver,
-+                         &driver_attr_remove_slot);
-+      driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
-+      driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
-+      driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
-+
-+      pci_unregister_driver(&pciback_pci_driver);
-+}
-+
-+module_init(pciback_init);
-+module_exit(pciback_cleanup);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/pciback.h linux-2.6.16.33/drivers/xen/pciback/pciback.h
---- linux-2.6.16.33-noxen/drivers/xen/pciback/pciback.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/pciback.h      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,93 @@
-+/*
-+ * PCI Backend Common Data Structures & Function Declarations
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#ifndef __XEN_PCIBACK_H__
-+#define __XEN_PCIBACK_H__
-+
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+#include <xen/xenbus.h>
-+#include <linux/list.h>
-+#include <linux/spinlock.h>
-+#include <linux/workqueue.h>
-+#include <asm/atomic.h>
-+#include <xen/interface/io/pciif.h>
-+
-+struct pci_dev_entry {
-+      struct list_head list;
-+      struct pci_dev *dev;
-+};
-+
-+#define _PDEVF_op_active      (0)
-+#define PDEVF_op_active       (1<<(_PDEVF_op_active))
-+
-+struct pciback_device {
-+      void *pci_dev_data;
-+      spinlock_t dev_lock;
-+
-+      struct xenbus_device *xdev;
-+
-+      struct xenbus_watch be_watch;
-+      u8 be_watching;
-+
-+      int evtchn_irq;
-+
-+      struct vm_struct *sh_area;
-+      struct xen_pci_sharedinfo *sh_info;
-+
-+      unsigned long flags;
-+
-+      struct work_struct op_work;
-+};
-+
-+struct pciback_dev_data {
-+      struct list_head config_fields;
-+      int permissive;
-+      int warned_on_write;
-+};
-+
-+/* Get/Put PCI Devices that are hidden from the PCI Backend Domain */
-+struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev,
-+                                          int domain, int bus,
-+                                          int slot, int func);
-+struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
-+                                  struct pci_dev *dev);
-+void pcistub_put_pci_dev(struct pci_dev *dev);
-+
-+/* Ensure a device is turned off or reset */
-+void pciback_reset_device(struct pci_dev *pdev);
-+
-+/* Access a virtual configuration space for a PCI device */
-+int pciback_config_init(void);
-+int pciback_config_init_dev(struct pci_dev *dev);
-+void pciback_config_free_dyn_fields(struct pci_dev *dev);
-+void pciback_config_reset_dev(struct pci_dev *dev);
-+void pciback_config_free_dev(struct pci_dev *dev);
-+int pciback_config_read(struct pci_dev *dev, int offset, int size,
-+                      u32 * ret_val);
-+int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value);
-+
-+/* Handle requests for specific devices from the frontend */
-+typedef int (*publish_pci_root_cb) (struct pciback_device * pdev,
-+                                  unsigned int domain, unsigned int bus);
-+int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev);
-+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev);
-+struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
-+                                  unsigned int domain, unsigned int bus,
-+                                  unsigned int devfn);
-+int pciback_init_devices(struct pciback_device *pdev);
-+int pciback_publish_pci_roots(struct pciback_device *pdev,
-+                            publish_pci_root_cb cb);
-+void pciback_release_devices(struct pciback_device *pdev);
-+
-+/* Handles events from front-end */
-+irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs);
-+void pciback_do_op(void *data);
-+
-+int pciback_xenbus_register(void);
-+void pciback_xenbus_unregister(void);
-+
-+extern int verbose_request;
-+#endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/pciback_ops.c linux-2.6.16.33/drivers/xen/pciback/pciback_ops.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/pciback_ops.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/pciback_ops.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,95 @@
-+/*
-+ * PCI Backend Operations - respond to PCI requests from Frontend
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#include <linux/module.h>
-+#include <asm/bitops.h>
-+#include <xen/evtchn.h>
-+#include "pciback.h"
-+
-+int verbose_request = 0;
-+module_param(verbose_request, int, 0644);
-+
-+/* Ensure a device is "turned off" and ready to be exported.
-+ * (Also see pciback_config_reset to ensure virtual configuration space is
-+ * ready to be re-exported)
-+ */
-+void pciback_reset_device(struct pci_dev *dev)
-+{
-+      u16 cmd;
-+
-+      /* Disable devices (but not bridges) */
-+      if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
-+              pci_disable_device(dev);
-+
-+              pci_write_config_word(dev, PCI_COMMAND, 0);
-+
-+              dev->is_enabled = 0;
-+              dev->is_busmaster = 0;
-+      } else {
-+              pci_read_config_word(dev, PCI_COMMAND, &cmd);
-+              if (cmd & (PCI_COMMAND_INVALIDATE)) {
-+                      cmd &= ~(PCI_COMMAND_INVALIDATE);
-+                      pci_write_config_word(dev, PCI_COMMAND, cmd);
-+
-+                      dev->is_busmaster = 0;
-+              }
-+      }
-+}
-+
-+static inline void test_and_schedule_op(struct pciback_device *pdev)
-+{
-+      /* Check that frontend is requesting an operation and that we are not
-+       * already processing a request */
-+      if (test_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags)
-+          && !test_and_set_bit(_PDEVF_op_active, &pdev->flags))
-+              schedule_work(&pdev->op_work);
-+}
-+
-+/* Performing the configuration space reads/writes must not be done in atomic
-+ * context because some of the pci_* functions can sleep (mostly due to ACPI
-+ * use of semaphores). This function is intended to be called from a work
-+ * queue in process context taking a struct pciback_device as a parameter */
-+void pciback_do_op(void *data)
-+{
-+      struct pciback_device *pdev = data;
-+      struct pci_dev *dev;
-+      struct xen_pci_op *op = &pdev->sh_info->op;
-+
-+      dev = pciback_get_pci_dev(pdev, op->domain, op->bus, op->devfn);
-+
-+      if (dev == NULL)
-+              op->err = XEN_PCI_ERR_dev_not_found;
-+      else if (op->cmd == XEN_PCI_OP_conf_read)
-+              op->err = pciback_config_read(dev, op->offset, op->size,
-+                                            &op->value);
-+      else if (op->cmd == XEN_PCI_OP_conf_write)
-+              op->err = pciback_config_write(dev, op->offset, op->size,
-+                                             op->value);
-+      else
-+              op->err = XEN_PCI_ERR_not_implemented;
-+
-+      /* Tell the driver domain that we're done. */ 
-+      wmb();
-+      clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
-+      notify_remote_via_irq(pdev->evtchn_irq);
-+
-+      /* Mark that we're done. */
-+      smp_mb__before_clear_bit(); /* /after/ clearing PCIF_active */
-+      clear_bit(_PDEVF_op_active, &pdev->flags);
-+      smp_mb__after_clear_bit(); /* /before/ final check for work */
-+
-+      /* Check to see if the driver domain tried to start another request in
-+       * between clearing _XEN_PCIF_active and clearing _PDEVF_op_active. */
-+      test_and_schedule_op(pdev);
-+}
-+
-+irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct pciback_device *pdev = dev_id;
-+
-+      test_and_schedule_op(pdev);
-+
-+      return IRQ_HANDLED;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/slot.c linux-2.6.16.33/drivers/xen/pciback/slot.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/slot.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/slot.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,151 @@
-+/*
-+ * PCI Backend - Provides a Virtual PCI bus (with real devices)
-+ *               to the frontend
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil> (vpci.c)
-+ *   Author: Tristan Gingold <tristan.gingold@bull.net>, from vpci.c
-+ */
-+
-+#include <linux/list.h>
-+#include <linux/slab.h>
-+#include <linux/pci.h>
-+#include <linux/spinlock.h>
-+#include "pciback.h"
-+
-+/* There are at most 32 slots in a pci bus.  */
-+#define PCI_SLOT_MAX 32
-+
-+#define PCI_BUS_NBR 2
-+
-+struct slot_dev_data {
-+      /* Access to dev_list must be protected by lock */
-+      struct pci_dev *slots[PCI_BUS_NBR][PCI_SLOT_MAX];
-+      spinlock_t lock;
-+};
-+
-+struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
-+                                  unsigned int domain, unsigned int bus,
-+                                  unsigned int devfn)
-+{
-+      struct pci_dev *dev = NULL;
-+      struct slot_dev_data *slot_dev = pdev->pci_dev_data;
-+      unsigned long flags;
-+
-+      if (domain != 0 || PCI_FUNC(devfn) != 0)
-+              return NULL;
-+
-+      if (PCI_SLOT(devfn) >= PCI_SLOT_MAX || bus >= PCI_BUS_NBR)
-+              return NULL;
-+
-+      spin_lock_irqsave(&slot_dev->lock, flags);
-+      dev = slot_dev->slots[bus][PCI_SLOT(devfn)];
-+      spin_unlock_irqrestore(&slot_dev->lock, flags);
-+
-+      return dev;
-+}
-+
-+int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
-+{
-+      int err = 0, slot, bus;
-+      struct slot_dev_data *slot_dev = pdev->pci_dev_data;
-+      unsigned long flags;
-+
-+      if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
-+              err = -EFAULT;
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Can't export bridges on the virtual PCI bus");
-+              goto out;
-+      }
-+
-+      spin_lock_irqsave(&slot_dev->lock, flags);
-+
-+      /* Assign to a new slot on the virtual PCI bus */
-+      for (bus = 0; bus < PCI_BUS_NBR; bus++)
-+              for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-+                      if (slot_dev->slots[bus][slot] == NULL) {
-+                              printk(KERN_INFO
-+                                     "pciback: slot: %s: assign to virtual slot %d, bus %d\n",
-+                                     pci_name(dev), slot, bus);
-+                              slot_dev->slots[bus][slot] = dev;
-+                              goto unlock;
-+                      }
-+              }
-+
-+      err = -ENOMEM;
-+      xenbus_dev_fatal(pdev->xdev, err,
-+                       "No more space on root virtual PCI bus");
-+
-+      unlock:
-+      spin_unlock_irqrestore(&slot_dev->lock, flags);
-+      out:
-+      return err;
-+}
-+
-+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
-+{
-+      int slot, bus;
-+      struct slot_dev_data *slot_dev = pdev->pci_dev_data;
-+      struct pci_dev *found_dev = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&slot_dev->lock, flags);
-+
-+      for (bus = 0; bus < PCI_BUS_NBR; bus++)
-+              for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-+                      if (slot_dev->slots[bus][slot] == dev) {
-+                              slot_dev->slots[bus][slot] = NULL;
-+                              found_dev = dev;
-+                              goto out;
-+                      }
-+              }
-+
-+      out:
-+      spin_unlock_irqrestore(&slot_dev->lock, flags);
-+
-+      if (found_dev)
-+              pcistub_put_pci_dev(found_dev);
-+}
-+
-+int pciback_init_devices(struct pciback_device *pdev)
-+{
-+      int slot, bus;
-+      struct slot_dev_data *slot_dev;
-+
-+      slot_dev = kmalloc(sizeof(*slot_dev), GFP_KERNEL);
-+      if (!slot_dev)
-+              return -ENOMEM;
-+
-+      spin_lock_init(&slot_dev->lock);
-+
-+      for (bus = 0; bus < PCI_BUS_NBR; bus++)
-+              for (slot = 0; slot < PCI_SLOT_MAX; slot++)
-+                      slot_dev->slots[bus][slot] = NULL;
-+
-+      pdev->pci_dev_data = slot_dev;
-+
-+      return 0;
-+}
-+
-+int pciback_publish_pci_roots(struct pciback_device *pdev,
-+                            publish_pci_root_cb publish_cb)
-+{
-+      /* The Virtual PCI bus has only one root */
-+      return publish_cb(pdev, 0, 0);
-+}
-+
-+void pciback_release_devices(struct pciback_device *pdev)
-+{
-+      int slot, bus;
-+      struct slot_dev_data *slot_dev = pdev->pci_dev_data;
-+      struct pci_dev *dev;
-+
-+      for (bus = 0; bus < PCI_BUS_NBR; bus++)
-+              for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-+                      dev = slot_dev->slots[bus][slot];
-+                      if (dev != NULL)
-+                              pcistub_put_pci_dev(dev);
-+              }
-+
-+      kfree(slot_dev);
-+      pdev->pci_dev_data = NULL;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/vpci.c linux-2.6.16.33/drivers/xen/pciback/vpci.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/vpci.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/vpci.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,204 @@
-+/*
-+ * PCI Backend - Provides a Virtual PCI bus (with real devices)
-+ *               to the frontend
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+
-+#include <linux/list.h>
-+#include <linux/slab.h>
-+#include <linux/pci.h>
-+#include <linux/spinlock.h>
-+#include "pciback.h"
-+
-+#define PCI_SLOT_MAX 32
-+
-+struct vpci_dev_data {
-+      /* Access to dev_list must be protected by lock */
-+      struct list_head dev_list[PCI_SLOT_MAX];
-+      spinlock_t lock;
-+};
-+
-+static inline struct list_head *list_first(struct list_head *head)
-+{
-+      return head->next;
-+}
-+
-+struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev,
-+                                  unsigned int domain, unsigned int bus,
-+                                  unsigned int devfn)
-+{
-+      struct pci_dev_entry *entry;
-+      struct pci_dev *dev = NULL;
-+      struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
-+      unsigned long flags;
-+
-+      if (domain != 0 || bus != 0)
-+              return NULL;
-+
-+      if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
-+              spin_lock_irqsave(&vpci_dev->lock, flags);
-+
-+              list_for_each_entry(entry,
-+                                  &vpci_dev->dev_list[PCI_SLOT(devfn)],
-+                                  list) {
-+                      if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) {
-+                              dev = entry->dev;
-+                              break;
-+                      }
-+              }
-+
-+              spin_unlock_irqrestore(&vpci_dev->lock, flags);
-+      }
-+      return dev;
-+}
-+
-+static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
-+{
-+      if (pci_domain_nr(l->bus) == pci_domain_nr(r->bus)
-+          && l->bus == r->bus && PCI_SLOT(l->devfn) == PCI_SLOT(r->devfn))
-+              return 1;
-+
-+      return 0;
-+}
-+
-+int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
-+{
-+      int err = 0, slot;
-+      struct pci_dev_entry *t, *dev_entry;
-+      struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
-+      unsigned long flags;
-+
-+      if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
-+              err = -EFAULT;
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Can't export bridges on the virtual PCI bus");
-+              goto out;
-+      }
-+
-+      dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL);
-+      if (!dev_entry) {
-+              err = -ENOMEM;
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error adding entry to virtual PCI bus");
-+              goto out;
-+      }
-+
-+      dev_entry->dev = dev;
-+
-+      spin_lock_irqsave(&vpci_dev->lock, flags);
-+
-+      /* Keep multi-function devices together on the virtual PCI bus */
-+      for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-+              if (!list_empty(&vpci_dev->dev_list[slot])) {
-+                      t = list_entry(list_first(&vpci_dev->dev_list[slot]),
-+                                     struct pci_dev_entry, list);
-+
-+                      if (match_slot(dev, t->dev)) {
-+                              pr_info("pciback: vpci: %s: "
-+                                      "assign to virtual slot %d func %d\n",
-+                                      pci_name(dev), slot,
-+                                      PCI_FUNC(dev->devfn));
-+                              list_add_tail(&dev_entry->list,
-+                                            &vpci_dev->dev_list[slot]);
-+                              goto unlock;
-+                      }
-+              }
-+      }
-+
-+      /* Assign to a new slot on the virtual PCI bus */
-+      for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-+              if (list_empty(&vpci_dev->dev_list[slot])) {
-+                      printk(KERN_INFO
-+                             "pciback: vpci: %s: assign to virtual slot %d\n",
-+                             pci_name(dev), slot);
-+                      list_add_tail(&dev_entry->list,
-+                                    &vpci_dev->dev_list[slot]);
-+                      goto unlock;
-+              }
-+      }
-+
-+      err = -ENOMEM;
-+      xenbus_dev_fatal(pdev->xdev, err,
-+                       "No more space on root virtual PCI bus");
-+
-+      unlock:
-+      spin_unlock_irqrestore(&vpci_dev->lock, flags);
-+      out:
-+      return err;
-+}
-+
-+void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev)
-+{
-+      int slot;
-+      struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
-+      struct pci_dev *found_dev = NULL;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&vpci_dev->lock, flags);
-+
-+      for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-+              struct pci_dev_entry *e, *tmp;
-+              list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
-+                                       list) {
-+                      if (e->dev == dev) {
-+                              list_del(&e->list);
-+                              found_dev = e->dev;
-+                              kfree(e);
-+                              goto out;
-+                      }
-+              }
-+      }
-+
-+      out:
-+      spin_unlock_irqrestore(&vpci_dev->lock, flags);
-+
-+      if (found_dev)
-+              pcistub_put_pci_dev(found_dev);
-+}
-+
-+int pciback_init_devices(struct pciback_device *pdev)
-+{
-+      int slot;
-+      struct vpci_dev_data *vpci_dev;
-+
-+      vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL);
-+      if (!vpci_dev)
-+              return -ENOMEM;
-+
-+      spin_lock_init(&vpci_dev->lock);
-+
-+      for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-+              INIT_LIST_HEAD(&vpci_dev->dev_list[slot]);
-+      }
-+
-+      pdev->pci_dev_data = vpci_dev;
-+
-+      return 0;
-+}
-+
-+int pciback_publish_pci_roots(struct pciback_device *pdev,
-+                            publish_pci_root_cb publish_cb)
-+{
-+      /* The Virtual PCI bus has only one root */
-+      return publish_cb(pdev, 0, 0);
-+}
-+
-+void pciback_release_devices(struct pciback_device *pdev)
-+{
-+      int slot;
-+      struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
-+
-+      for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
-+              struct pci_dev_entry *e, *tmp;
-+              list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
-+                                       list) {
-+                      list_del(&e->list);
-+                      pcistub_put_pci_dev(e->dev);
-+                      kfree(e);
-+              }
-+      }
-+
-+      kfree(vpci_dev);
-+      pdev->pci_dev_data = NULL;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pciback/xenbus.c linux-2.6.16.33/drivers/xen/pciback/xenbus.c
---- linux-2.6.16.33-noxen/drivers/xen/pciback/xenbus.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pciback/xenbus.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,458 @@
-+/*
-+ * PCI Backend Xenbus Setup - handles setup with frontend and xend
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/vmalloc.h>
-+#include <xen/xenbus.h>
-+#include <xen/evtchn.h>
-+#include "pciback.h"
-+
-+#define INVALID_EVTCHN_IRQ  (-1)
-+
-+static struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
-+{
-+      struct pciback_device *pdev;
-+
-+      pdev = kzalloc(sizeof(struct pciback_device), GFP_KERNEL);
-+      if (pdev == NULL)
-+              goto out;
-+      dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);
-+
-+      pdev->xdev = xdev;
-+      xdev->dev.driver_data = pdev;
-+
-+      spin_lock_init(&pdev->dev_lock);
-+
-+      pdev->sh_area = NULL;
-+      pdev->sh_info = NULL;
-+      pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
-+      pdev->be_watching = 0;
-+
-+      INIT_WORK(&pdev->op_work, pciback_do_op, pdev);
-+
-+      if (pciback_init_devices(pdev)) {
-+              kfree(pdev);
-+              pdev = NULL;
-+      }
-+      out:
-+      return pdev;
-+}
-+
-+static void free_pdev(struct pciback_device *pdev)
-+{
-+      if (pdev->be_watching)
-+              unregister_xenbus_watch(&pdev->be_watch);
-+
-+      /* Ensure the guest can't trigger our handler before removing devices */
-+      if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ)
-+              unbind_from_irqhandler(pdev->evtchn_irq, pdev);
-+
-+      /* If the driver domain started an op, make sure we complete it or
-+       * delete it before releasing the shared memory */
-+      cancel_delayed_work(&pdev->op_work);
-+      flush_scheduled_work();
-+
-+      if (pdev->sh_info)
-+              xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_area);
-+
-+      pciback_release_devices(pdev);
-+
-+      pdev->xdev->dev.driver_data = NULL;
-+      pdev->xdev = NULL;
-+
-+      kfree(pdev);
-+}
-+
-+static int pciback_do_attach(struct pciback_device *pdev, int gnt_ref,
-+                           int remote_evtchn)
-+{
-+      int err = 0;
-+      int evtchn;
-+      struct vm_struct *area;
-+
-+      dev_dbg(&pdev->xdev->dev,
-+              "Attaching to frontend resources - gnt_ref=%d evtchn=%d\n",
-+              gnt_ref, remote_evtchn);
-+
-+      area = xenbus_map_ring_valloc(pdev->xdev, gnt_ref);
-+      if (IS_ERR(area)) {
-+              err = PTR_ERR(area);
-+              goto out;
-+      }
-+      pdev->sh_area = area;
-+      pdev->sh_info = area->addr;
-+
-+      err = xenbus_bind_evtchn(pdev->xdev, remote_evtchn, &evtchn);
-+      if (err)
-+              goto out;
-+
-+      err = bind_evtchn_to_irqhandler(evtchn, pciback_handle_event,
-+                                      SA_SAMPLE_RANDOM, "pciback", pdev);
-+      if (err < 0) {
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error binding event channel to IRQ");
-+              goto out;
-+      }
-+      pdev->evtchn_irq = err;
-+      err = 0;
-+
-+      dev_dbg(&pdev->xdev->dev, "Attached!\n");
-+      out:
-+      return err;
-+}
-+
-+static int pciback_attach(struct pciback_device *pdev)
-+{
-+      int err = 0;
-+      int gnt_ref, remote_evtchn;
-+      char *magic = NULL;
-+
-+      spin_lock(&pdev->dev_lock);
-+
-+      /* Make sure we only do this setup once */
-+      if (xenbus_read_driver_state(pdev->xdev->nodename) !=
-+          XenbusStateInitialised)
-+              goto out;
-+
-+      /* Wait for frontend to state that it has published the configuration */
-+      if (xenbus_read_driver_state(pdev->xdev->otherend) !=
-+          XenbusStateInitialised)
-+              goto out;
-+
-+      dev_dbg(&pdev->xdev->dev, "Reading frontend config\n");
-+
-+      err = xenbus_gather(XBT_NIL, pdev->xdev->otherend,
-+                          "pci-op-ref", "%u", &gnt_ref,
-+                          "event-channel", "%u", &remote_evtchn,
-+                          "magic", NULL, &magic, NULL);
-+      if (err) {
-+              /* If configuration didn't get read correctly, wait longer */
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error reading configuration from frontend");
-+              goto out;
-+      }
-+
-+      if (magic == NULL || strcmp(magic, XEN_PCI_MAGIC) != 0) {
-+              xenbus_dev_fatal(pdev->xdev, -EFAULT,
-+                               "version mismatch (%s/%s) with pcifront - "
-+                               "halting pciback",
-+                               magic, XEN_PCI_MAGIC);
-+              goto out;
-+      }
-+
-+      err = pciback_do_attach(pdev, gnt_ref, remote_evtchn);
-+      if (err)
-+              goto out;
-+
-+      dev_dbg(&pdev->xdev->dev, "Connecting...\n");
-+
-+      err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);
-+      if (err)
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error switching to connected state!");
-+
-+      dev_dbg(&pdev->xdev->dev, "Connected? %d\n", err);
-+      out:
-+      spin_unlock(&pdev->dev_lock);
-+
-+      if (magic)
-+              kfree(magic);
-+
-+      return err;
-+}
-+
-+static void pciback_frontend_changed(struct xenbus_device *xdev,
-+                                   enum xenbus_state fe_state)
-+{
-+      struct pciback_device *pdev = xdev->dev.driver_data;
-+
-+      dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state);
-+
-+      switch (fe_state) {
-+      case XenbusStateInitialised:
-+              pciback_attach(pdev);
-+              break;
-+
-+      case XenbusStateClosing:
-+              xenbus_switch_state(xdev, XenbusStateClosing);
-+              break;
-+
-+      case XenbusStateUnknown:
-+      case XenbusStateClosed:
-+              dev_dbg(&xdev->dev, "frontend is gone! unregister device\n");
-+              device_unregister(&xdev->dev);
-+              break;
-+
-+      default:
-+              break;
-+      }
-+}
-+
-+static int pciback_publish_pci_root(struct pciback_device *pdev,
-+                                  unsigned int domain, unsigned int bus)
-+{
-+      unsigned int d, b;
-+      int i, root_num, len, err;
-+      char str[64];
-+
-+      dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n");
-+
-+      err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
-+                         "root_num", "%d", &root_num);
-+      if (err == 0 || err == -ENOENT)
-+              root_num = 0;
-+      else if (err < 0)
-+              goto out;
-+
-+      /* Verify that we haven't already published this pci root */
-+      for (i = 0; i < root_num; i++) {
-+              len = snprintf(str, sizeof(str), "root-%d", i);
-+              if (unlikely(len >= (sizeof(str) - 1))) {
-+                      err = -ENOMEM;
-+                      goto out;
-+              }
-+
-+              err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
-+                                 str, "%x:%x", &d, &b);
-+              if (err < 0)
-+                      goto out;
-+              if (err != 2) {
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              if (d == domain && b == bus) {
-+                      err = 0;
-+                      goto out;
-+              }
-+      }
-+
-+      len = snprintf(str, sizeof(str), "root-%d", root_num);
-+      if (unlikely(len >= (sizeof(str) - 1))) {
-+              err = -ENOMEM;
-+              goto out;
-+      }
-+
-+      dev_dbg(&pdev->xdev->dev, "writing root %d at %04x:%02x\n",
-+              root_num, domain, bus);
-+
-+      err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
-+                          "%04x:%02x", domain, bus);
-+      if (err)
-+              goto out;
-+
-+      err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,
-+                          "root_num", "%d", (root_num + 1));
-+
-+      out:
-+      return err;
-+}
-+
-+static int pciback_export_device(struct pciback_device *pdev,
-+                               int domain, int bus, int slot, int func)
-+{
-+      struct pci_dev *dev;
-+      int err = 0;
-+
-+      dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n",
-+              domain, bus, slot, func);
-+
-+      dev = pcistub_get_pci_dev_by_slot(pdev, domain, bus, slot, func);
-+      if (!dev) {
-+              err = -EINVAL;
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Couldn't locate PCI device "
-+                               "(%04x:%02x:%02x.%01x)! "
-+                               "perhaps already in-use?",
-+                               domain, bus, slot, func);
-+              goto out;
-+      }
-+
-+      err = pciback_add_pci_dev(pdev, dev);
-+      if (err)
-+              goto out;
-+
-+      /* TODO: It'd be nice to export a bridge and have all of its children
-+       * get exported with it. This may be best done in xend (which will
-+       * have to calculate resource usage anyway) but we probably want to
-+       * put something in here to ensure that if a bridge gets given to a
-+       * driver domain, that all devices under that bridge are not given
-+       * to other driver domains (as he who controls the bridge can disable
-+       * it and stop the other devices from working).
-+       */
-+      out:
-+      return err;
-+}
-+
-+static int pciback_setup_backend(struct pciback_device *pdev)
-+{
-+      /* Get configuration from xend (if available now) */
-+      int domain, bus, slot, func;
-+      int err = 0;
-+      int i, num_devs;
-+      char dev_str[64];
-+
-+      spin_lock(&pdev->dev_lock);
-+
-+      /* It's possible we could get the call to setup twice, so make sure
-+       * we're not already connected.
-+       */
-+      if (xenbus_read_driver_state(pdev->xdev->nodename) !=
-+          XenbusStateInitWait)
-+              goto out;
-+
-+      dev_dbg(&pdev->xdev->dev, "getting be setup\n");
-+
-+      err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
-+                         &num_devs);
-+      if (err != 1) {
-+              if (err >= 0)
-+                      err = -EINVAL;
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error reading number of devices");
-+              goto out;
-+      }
-+
-+      for (i = 0; i < num_devs; i++) {
-+              int l = snprintf(dev_str, sizeof(dev_str), "dev-%d", i);
-+              if (unlikely(l >= (sizeof(dev_str) - 1))) {
-+                      err = -ENOMEM;
-+                      xenbus_dev_fatal(pdev->xdev, err,
-+                                       "String overflow while reading "
-+                                       "configuration");
-+                      goto out;
-+              }
-+
-+              err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, dev_str,
-+                                 "%x:%x:%x.%x", &domain, &bus, &slot, &func);
-+              if (err < 0) {
-+                      xenbus_dev_fatal(pdev->xdev, err,
-+                                       "Error reading device configuration");
-+                      goto out;
-+              }
-+              if (err != 4) {
-+                      err = -EINVAL;
-+                      xenbus_dev_fatal(pdev->xdev, err,
-+                                       "Error parsing pci device "
-+                                       "configuration");
-+                      goto out;
-+              }
-+
-+              err = pciback_export_device(pdev, domain, bus, slot, func);
-+              if (err)
-+                      goto out;
-+      }
-+
-+      err = pciback_publish_pci_roots(pdev, pciback_publish_pci_root);
-+      if (err) {
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error while publish PCI root buses "
-+                               "for frontend");
-+              goto out;
-+      }
-+
-+      err = xenbus_switch_state(pdev->xdev, XenbusStateInitialised);
-+      if (err)
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error switching to initialised state!");
-+
-+      out:
-+      spin_unlock(&pdev->dev_lock);
-+
-+      if (!err)
-+              /* see if pcifront is already configured (if not, we'll wait) */
-+              pciback_attach(pdev);
-+
-+      return err;
-+}
-+
-+static void pciback_be_watch(struct xenbus_watch *watch,
-+                           const char **vec, unsigned int len)
-+{
-+      struct pciback_device *pdev =
-+          container_of(watch, struct pciback_device, be_watch);
-+
-+      switch (xenbus_read_driver_state(pdev->xdev->nodename)) {
-+      case XenbusStateInitWait:
-+              pciback_setup_backend(pdev);
-+              break;
-+
-+      default:
-+              break;
-+      }
-+}
-+
-+static int pciback_xenbus_probe(struct xenbus_device *dev,
-+                              const struct xenbus_device_id *id)
-+{
-+      int err = 0;
-+      struct pciback_device *pdev = alloc_pdev(dev);
-+
-+      if (pdev == NULL) {
-+              err = -ENOMEM;
-+              xenbus_dev_fatal(dev, err,
-+                               "Error allocating pciback_device struct");
-+              goto out;
-+      }
-+
-+      /* wait for xend to configure us */
-+      err = xenbus_switch_state(dev, XenbusStateInitWait);
-+      if (err)
-+              goto out;
-+
-+      /* watch the backend node for backend configuration information */
-+      err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch,
-+                              pciback_be_watch);
-+      if (err)
-+              goto out;
-+      pdev->be_watching = 1;
-+
-+      /* We need to force a call to our callback here in case
-+       * xend already configured us!
-+       */
-+      pciback_be_watch(&pdev->be_watch, NULL, 0);
-+
-+      out:
-+      return err;
-+}
-+
-+static int pciback_xenbus_remove(struct xenbus_device *dev)
-+{
-+      struct pciback_device *pdev = dev->dev.driver_data;
-+
-+      if (pdev != NULL)
-+              free_pdev(pdev);
-+
-+      return 0;
-+}
-+
-+static struct xenbus_device_id xenpci_ids[] = {
-+      {"pci"},
-+      {{0}},
-+};
-+
-+static struct xenbus_driver xenbus_pciback_driver = {
-+      .name                   = "pciback",
-+      .owner                  = THIS_MODULE,
-+      .ids                    = xenpci_ids,
-+      .probe                  = pciback_xenbus_probe,
-+      .remove                 = pciback_xenbus_remove,
-+      .otherend_changed       = pciback_frontend_changed,
-+};
-+
-+int __init pciback_xenbus_register(void)
-+{
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      return xenbus_register_backend(&xenbus_pciback_driver);
-+}
-+
-+void __exit pciback_xenbus_unregister(void)
-+{
-+      xenbus_unregister_driver(&xenbus_pciback_driver);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pcifront/Makefile linux-2.6.16.33/drivers/xen/pcifront/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/pcifront/Makefile        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pcifront/Makefile      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,7 @@
-+obj-y += pcifront.o
-+
-+pcifront-y := pci_op.o xenbus.o pci.o
-+
-+ifeq ($(CONFIG_XEN_PCIDEV_FE_DEBUG),y)
-+EXTRA_CFLAGS += -DDEBUG
-+endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pcifront/pci.c linux-2.6.16.33/drivers/xen/pcifront/pci.c
---- linux-2.6.16.33-noxen/drivers/xen/pcifront/pci.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pcifront/pci.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,46 @@
-+/*
-+ * PCI Frontend Operations - ensure only one PCI frontend runs at a time
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <linux/spinlock.h>
-+#include "pcifront.h"
-+
-+DEFINE_SPINLOCK(pcifront_dev_lock);
-+static struct pcifront_device *pcifront_dev = NULL;
-+
-+int pcifront_connect(struct pcifront_device *pdev)
-+{
-+      int err = 0;
-+
-+      spin_lock(&pcifront_dev_lock);
-+
-+      if (!pcifront_dev) {
-+              dev_info(&pdev->xdev->dev, "Installing PCI frontend\n");
-+              pcifront_dev = pdev;
-+      }
-+      else {
-+              dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n");
-+              err = -EEXIST;
-+      }
-+
-+      spin_unlock(&pcifront_dev_lock);
-+
-+      return err;
-+}
-+
-+void pcifront_disconnect(struct pcifront_device *pdev)
-+{
-+      spin_lock(&pcifront_dev_lock);
-+
-+      if (pdev == pcifront_dev) {
-+              dev_info(&pdev->xdev->dev,
-+                       "Disconnecting PCI Frontend Buses\n");
-+              pcifront_dev = NULL;
-+      }
-+
-+      spin_unlock(&pcifront_dev_lock);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pcifront/pci_op.c linux-2.6.16.33/drivers/xen/pcifront/pci_op.c
---- linux-2.6.16.33-noxen/drivers/xen/pcifront/pci_op.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pcifront/pci_op.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,273 @@
-+/*
-+ * PCI Frontend Operations - Communicates with frontend
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <linux/spinlock.h>
-+#include <linux/time.h>
-+#include <xen/evtchn.h>
-+#include "pcifront.h"
-+
-+static int verbose_request = 0;
-+module_param(verbose_request, int, 0644);
-+
-+static int errno_to_pcibios_err(int errno)
-+{
-+      switch (errno) {
-+      case XEN_PCI_ERR_success:
-+              return PCIBIOS_SUCCESSFUL;
-+
-+      case XEN_PCI_ERR_dev_not_found:
-+              return PCIBIOS_DEVICE_NOT_FOUND;
-+
-+      case XEN_PCI_ERR_invalid_offset:
-+      case XEN_PCI_ERR_op_failed:
-+              return PCIBIOS_BAD_REGISTER_NUMBER;
-+
-+      case XEN_PCI_ERR_not_implemented:
-+              return PCIBIOS_FUNC_NOT_SUPPORTED;
-+
-+      case XEN_PCI_ERR_access_denied:
-+              return PCIBIOS_SET_FAILED;
-+      }
-+      return errno;
-+}
-+
-+static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
-+{
-+      int err = 0;
-+      struct xen_pci_op *active_op = &pdev->sh_info->op;
-+      unsigned long irq_flags;
-+      evtchn_port_t port = pdev->evtchn;
-+      nsec_t ns, ns_timeout;
-+      struct timeval tv;
-+
-+      spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
-+
-+      memcpy(active_op, op, sizeof(struct xen_pci_op));
-+
-+      /* Go */
-+      wmb();
-+      set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
-+      notify_remote_via_evtchn(port);
-+
-+      /*
-+       * We set a poll timeout of 3 seconds but give up on return after
-+       * 2 seconds. It is better to time out too late rather than too early
-+       * (in the latter case we end up continually re-executing poll() with a
-+       * timeout in the past). 1s difference gives plenty of slack for error.
-+       */
-+      do_gettimeofday(&tv);
-+      ns_timeout = timeval_to_ns(&tv) + 2 * (nsec_t)NSEC_PER_SEC;
-+
-+      clear_evtchn(port);
-+
-+      while (test_bit(_XEN_PCIF_active,
-+                      (unsigned long *)&pdev->sh_info->flags)) {
-+              if (HYPERVISOR_poll(&port, 1, jiffies + 3*HZ))
-+                      BUG();
-+              clear_evtchn(port);
-+              do_gettimeofday(&tv);
-+              ns = timeval_to_ns(&tv);
-+              if (ns > ns_timeout) {
-+                      dev_err(&pdev->xdev->dev,
-+                              "pciback not responding!!!\n");
-+                      clear_bit(_XEN_PCIF_active,
-+                                (unsigned long *)&pdev->sh_info->flags);
-+                      err = XEN_PCI_ERR_dev_not_found;
-+                      goto out;
-+              }
-+      }
-+
-+      memcpy(op, active_op, sizeof(struct xen_pci_op));
-+
-+      err = op->err;
-+      out:
-+      spin_unlock_irqrestore(&pdev->sh_info_lock, irq_flags);
-+      return err;
-+}
-+
-+/* Access to this function is spinlocked in drivers/pci/access.c */
-+static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn,
-+                           int where, int size, u32 * val)
-+{
-+      int err = 0;
-+      struct xen_pci_op op = {
-+              .cmd    = XEN_PCI_OP_conf_read,
-+              .domain = pci_domain_nr(bus),
-+              .bus    = bus->number,
-+              .devfn  = devfn,
-+              .offset = where,
-+              .size   = size,
-+      };
-+      struct pcifront_sd *sd = bus->sysdata;
-+      struct pcifront_device *pdev = pcifront_get_pdev(sd);
-+
-+      if (verbose_request)
-+              dev_info(&pdev->xdev->dev,
-+                       "read dev=%04x:%02x:%02x.%01x - offset %x size %d\n",
-+                       pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
-+                       PCI_FUNC(devfn), where, size);
-+
-+      err = do_pci_op(pdev, &op);
-+
-+      if (likely(!err)) {
-+              if (verbose_request)
-+                      dev_info(&pdev->xdev->dev, "read got back value %x\n",
-+                               op.value);
-+
-+              *val = op.value;
-+      } else if (err == -ENODEV) {
-+              /* No device here, pretend that it just returned 0 */
-+              err = 0;
-+              *val = 0;
-+      }
-+
-+      return errno_to_pcibios_err(err);
-+}
-+
-+/* Access to this function is spinlocked in drivers/pci/access.c */
-+static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn,
-+                            int where, int size, u32 val)
-+{
-+      struct xen_pci_op op = {
-+              .cmd    = XEN_PCI_OP_conf_write,
-+              .domain = pci_domain_nr(bus),
-+              .bus    = bus->number,
-+              .devfn  = devfn,
-+              .offset = where,
-+              .size   = size,
-+              .value  = val,
-+      };
-+      struct pcifront_sd *sd = bus->sysdata;
-+      struct pcifront_device *pdev = pcifront_get_pdev(sd);
-+
-+      if (verbose_request)
-+              dev_info(&pdev->xdev->dev,
-+                       "write dev=%04x:%02x:%02x.%01x - "
-+                       "offset %x size %d val %x\n",
-+                       pci_domain_nr(bus), bus->number,
-+                       PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
-+
-+      return errno_to_pcibios_err(do_pci_op(pdev, &op));
-+}
-+
-+struct pci_ops pcifront_bus_ops = {
-+      .read = pcifront_bus_read,
-+      .write = pcifront_bus_write,
-+};
-+
-+/* Claim resources for the PCI frontend as-is, backend won't allow changes */
-+static void pcifront_claim_resource(struct pci_dev *dev, void *data)
-+{
-+      struct pcifront_device *pdev = data;
-+      int i;
-+      struct resource *r;
-+
-+      for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-+              r = &dev->resource[i];
-+
-+              if (!r->parent && r->start && r->flags) {
-+                      dev_dbg(&pdev->xdev->dev, "claiming resource %s/%d\n",
-+                              pci_name(dev), i);
-+                      pci_claim_resource(dev, i);
-+              }
-+      }
-+}
-+
-+int pcifront_scan_root(struct pcifront_device *pdev,
-+                     unsigned int domain, unsigned int bus)
-+{
-+      struct pci_bus *b;
-+      struct pcifront_sd *sd = NULL;
-+      struct pci_bus_entry *bus_entry = NULL;
-+      int err = 0;
-+
-+#ifndef CONFIG_PCI_DOMAINS
-+      if (domain != 0) {
-+              dev_err(&pdev->xdev->dev,
-+                      "PCI Root in non-zero PCI Domain! domain=%d\n", domain);
-+              dev_err(&pdev->xdev->dev,
-+                      "Please compile with CONFIG_PCI_DOMAINS\n");
-+              err = -EINVAL;
-+              goto err_out;
-+      }
-+#endif
-+
-+      dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n",
-+               domain, bus);
-+
-+      bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL);
-+      sd = kmalloc(sizeof(*sd), GFP_KERNEL);
-+      if (!bus_entry || !sd) {
-+              err = -ENOMEM;
-+              goto err_out;
-+      }
-+      pcifront_init_sd(sd, domain, pdev);
-+
-+      b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
-+                                &pcifront_bus_ops, sd);
-+      if (!b) {
-+              dev_err(&pdev->xdev->dev,
-+                      "Error creating PCI Frontend Bus!\n");
-+              err = -ENOMEM;
-+              goto err_out;
-+      }
-+      bus_entry->bus = b;
-+
-+      list_add(&bus_entry->list, &pdev->root_buses);
-+
-+      /* Claim resources before going "live" with our devices */
-+      pci_walk_bus(b, pcifront_claim_resource, pdev);
-+
-+      pci_bus_add_devices(b);
-+
-+      return 0;
-+
-+      err_out:
-+      kfree(bus_entry);
-+      kfree(sd);
-+
-+      return err;
-+}
-+
-+static void free_root_bus_devs(struct pci_bus *bus)
-+{
-+      struct pci_dev *dev;
-+
-+      spin_lock(&pci_bus_lock);
-+      while (!list_empty(&bus->devices)) {
-+              dev = container_of(bus->devices.next, struct pci_dev, bus_list);
-+              spin_unlock(&pci_bus_lock);
-+
-+              dev_dbg(&dev->dev, "removing device\n");
-+              pci_remove_bus_device(dev);
-+
-+              spin_lock(&pci_bus_lock);
-+      }
-+      spin_unlock(&pci_bus_lock);
-+}
-+
-+void pcifront_free_roots(struct pcifront_device *pdev)
-+{
-+      struct pci_bus_entry *bus_entry, *t;
-+
-+      dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
-+
-+      list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
-+              list_del(&bus_entry->list);
-+
-+              free_root_bus_devs(bus_entry->bus);
-+
-+              kfree(bus_entry->bus->sysdata);
-+
-+              device_unregister(bus_entry->bus->bridge);
-+              pci_remove_bus(bus_entry->bus);
-+
-+              kfree(bus_entry);
-+      }
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pcifront/pcifront.h linux-2.6.16.33/drivers/xen/pcifront/pcifront.h
---- linux-2.6.16.33-noxen/drivers/xen/pcifront/pcifront.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pcifront/pcifront.h    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,40 @@
-+/*
-+ * PCI Frontend - Common data structures & function declarations
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#ifndef __XEN_PCIFRONT_H__
-+#define __XEN_PCIFRONT_H__
-+
-+#include <linux/spinlock.h>
-+#include <linux/pci.h>
-+#include <xen/xenbus.h>
-+#include <xen/interface/io/pciif.h>
-+#include <xen/pcifront.h>
-+
-+struct pci_bus_entry {
-+      struct list_head list;
-+      struct pci_bus *bus;
-+};
-+
-+struct pcifront_device {
-+      struct xenbus_device *xdev;
-+      struct list_head root_buses;
-+      spinlock_t dev_lock;
-+
-+      int evtchn;
-+      int gnt_ref;
-+
-+      /* Lock this when doing any operations in sh_info */
-+      spinlock_t sh_info_lock;
-+      struct xen_pci_sharedinfo *sh_info;
-+};
-+
-+int pcifront_connect(struct pcifront_device *pdev);
-+void pcifront_disconnect(struct pcifront_device *pdev);
-+
-+int pcifront_scan_root(struct pcifront_device *pdev,
-+                     unsigned int domain, unsigned int bus);
-+void pcifront_free_roots(struct pcifront_device *pdev);
-+
-+#endif        /* __XEN_PCIFRONT_H__ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/pcifront/xenbus.c linux-2.6.16.33/drivers/xen/pcifront/xenbus.c
---- linux-2.6.16.33-noxen/drivers/xen/pcifront/xenbus.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/pcifront/xenbus.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,295 @@
-+/*
-+ * PCI Frontend Xenbus Setup - handles setup with backend (imports page/evtchn)
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/mm.h>
-+#include <xen/xenbus.h>
-+#include <xen/gnttab.h>
-+#include "pcifront.h"
-+
-+#define INVALID_GRANT_REF (0)
-+#define INVALID_EVTCHN    (-1)
-+
-+static struct pcifront_device *alloc_pdev(struct xenbus_device *xdev)
-+{
-+      struct pcifront_device *pdev;
-+
-+      pdev = kmalloc(sizeof(struct pcifront_device), GFP_KERNEL);
-+      if (pdev == NULL)
-+              goto out;
-+
-+      pdev->sh_info =
-+          (struct xen_pci_sharedinfo *)__get_free_page(GFP_KERNEL);
-+      if (pdev->sh_info == NULL) {
-+              kfree(pdev);
-+              pdev = NULL;
-+              goto out;
-+      }
-+      pdev->sh_info->flags = 0;
-+
-+      xdev->dev.driver_data = pdev;
-+      pdev->xdev = xdev;
-+
-+      INIT_LIST_HEAD(&pdev->root_buses);
-+
-+      spin_lock_init(&pdev->dev_lock);
-+      spin_lock_init(&pdev->sh_info_lock);
-+
-+      pdev->evtchn = INVALID_EVTCHN;
-+      pdev->gnt_ref = INVALID_GRANT_REF;
-+
-+      dev_dbg(&xdev->dev, "Allocated pdev @ 0x%p pdev->sh_info @ 0x%p\n",
-+              pdev, pdev->sh_info);
-+      out:
-+      return pdev;
-+}
-+
-+static void free_pdev(struct pcifront_device *pdev)
-+{
-+      dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev);
-+
-+      pcifront_free_roots(pdev);
-+
-+      if (pdev->evtchn != INVALID_EVTCHN)
-+              xenbus_free_evtchn(pdev->xdev, pdev->evtchn);
-+
-+      if (pdev->gnt_ref != INVALID_GRANT_REF)
-+              gnttab_end_foreign_access(pdev->gnt_ref, 0,
-+                                        (unsigned long)pdev->sh_info);
-+
-+      pdev->xdev->dev.driver_data = NULL;
-+
-+      kfree(pdev);
-+}
-+
-+static int pcifront_publish_info(struct pcifront_device *pdev)
-+{
-+      int err = 0;
-+      struct xenbus_transaction trans;
-+
-+      err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info));
-+      if (err < 0)
-+              goto out;
-+
-+      pdev->gnt_ref = err;
-+
-+      err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn);
-+      if (err)
-+              goto out;
-+
-+      do_publish:
-+      err = xenbus_transaction_start(&trans);
-+      if (err) {
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error writing configuration for backend "
-+                               "(start transaction)");
-+              goto out;
-+      }
-+
-+      err = xenbus_printf(trans, pdev->xdev->nodename,
-+                          "pci-op-ref", "%u", pdev->gnt_ref);
-+      if (!err)
-+              err = xenbus_printf(trans, pdev->xdev->nodename,
-+                                  "event-channel", "%u", pdev->evtchn);
-+      if (!err)
-+              err = xenbus_printf(trans, pdev->xdev->nodename,
-+                                  "magic", XEN_PCI_MAGIC);
-+
-+      if (err) {
-+              xenbus_transaction_end(trans, 1);
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error writing configuration for backend");
-+              goto out;
-+      } else {
-+              err = xenbus_transaction_end(trans, 0);
-+              if (err == -EAGAIN)
-+                      goto do_publish;
-+              else if (err) {
-+                      xenbus_dev_fatal(pdev->xdev, err,
-+                                       "Error completing transaction "
-+                                       "for backend");
-+                      goto out;
-+              }
-+      }
-+
-+      xenbus_switch_state(pdev->xdev, XenbusStateInitialised);
-+
-+      dev_dbg(&pdev->xdev->dev, "publishing successful!\n");
-+
-+      out:
-+      return err;
-+}
-+
-+static int pcifront_try_connect(struct pcifront_device *pdev)
-+{
-+      int err = -EFAULT;
-+      int i, num_roots, len;
-+      char str[64];
-+      unsigned int domain, bus;
-+
-+      spin_lock(&pdev->dev_lock);
-+
-+      /* Only connect once */
-+      if (xenbus_read_driver_state(pdev->xdev->nodename) !=
-+          XenbusStateInitialised)
-+              goto out;
-+
-+      err = pcifront_connect(pdev);
-+      if (err) {
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error connecting PCI Frontend");
-+              goto out;
-+      }
-+
-+      err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
-+                         "root_num", "%d", &num_roots);
-+      if (err == -ENOENT) {
-+              xenbus_dev_error(pdev->xdev, err,
-+                               "No PCI Roots found, trying 0000:00");
-+              err = pcifront_scan_root(pdev, 0, 0);
-+              num_roots = 0;
-+      } else if (err != 1) {
-+              if (err == 0)
-+                      err = -EINVAL;
-+              xenbus_dev_fatal(pdev->xdev, err,
-+                               "Error reading number of PCI roots");
-+              goto out;
-+      }
-+
-+      for (i = 0; i < num_roots; i++) {
-+              len = snprintf(str, sizeof(str), "root-%d", i);
-+              if (unlikely(len >= (sizeof(str) - 1))) {
-+                      err = -ENOMEM;
-+                      goto out;
-+              }
-+
-+              err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
-+                                 "%x:%x", &domain, &bus);
-+              if (err != 2) {
-+                      if (err >= 0)
-+                              err = -EINVAL;
-+                      xenbus_dev_fatal(pdev->xdev, err,
-+                                       "Error reading PCI root %d", i);
-+                      goto out;
-+              }
-+
-+              err = pcifront_scan_root(pdev, domain, bus);
-+              if (err) {
-+                      xenbus_dev_fatal(pdev->xdev, err,
-+                                       "Error scanning PCI root %04x:%02x",
-+                                       domain, bus);
-+                      goto out;
-+              }
-+      }
-+
-+      err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);
-+      if (err)
-+              goto out;
-+
-+      out:
-+      spin_unlock(&pdev->dev_lock);
-+      return err;
-+}
-+
-+static int pcifront_try_disconnect(struct pcifront_device *pdev)
-+{
-+      int err = 0;
-+      enum xenbus_state prev_state;
-+
-+      spin_lock(&pdev->dev_lock);
-+
-+      prev_state = xenbus_read_driver_state(pdev->xdev->nodename);
-+
-+      if (prev_state < XenbusStateClosing)
-+              err = xenbus_switch_state(pdev->xdev, XenbusStateClosing);
-+
-+      if (!err && prev_state == XenbusStateConnected)
-+              pcifront_disconnect(pdev);
-+
-+      spin_unlock(&pdev->dev_lock);
-+
-+      return err;
-+}
-+
-+static void pcifront_backend_changed(struct xenbus_device *xdev,
-+                                   enum xenbus_state be_state)
-+{
-+      struct pcifront_device *pdev = xdev->dev.driver_data;
-+
-+      switch (be_state) {
-+      case XenbusStateClosing:
-+              dev_warn(&xdev->dev, "backend going away!\n");
-+              pcifront_try_disconnect(pdev);
-+              break;
-+
-+      case XenbusStateUnknown:
-+      case XenbusStateClosed:
-+              dev_warn(&xdev->dev, "backend went away!\n");
-+              pcifront_try_disconnect(pdev);
-+
-+              device_unregister(&pdev->xdev->dev);
-+              break;
-+
-+      case XenbusStateConnected:
-+              pcifront_try_connect(pdev);
-+              break;
-+
-+      default:
-+              break;
-+      }
-+}
-+
-+static int pcifront_xenbus_probe(struct xenbus_device *xdev,
-+                               const struct xenbus_device_id *id)
-+{
-+      int err = 0;
-+      struct pcifront_device *pdev = alloc_pdev(xdev);
-+
-+      if (pdev == NULL) {
-+              err = -ENOMEM;
-+              xenbus_dev_fatal(xdev, err,
-+                               "Error allocating pcifront_device struct");
-+              goto out;
-+      }
-+
-+      err = pcifront_publish_info(pdev);
-+
-+      out:
-+      return err;
-+}
-+
-+static int pcifront_xenbus_remove(struct xenbus_device *xdev)
-+{
-+      if (xdev->dev.driver_data)
-+              free_pdev(xdev->dev.driver_data);
-+
-+      return 0;
-+}
-+
-+static struct xenbus_device_id xenpci_ids[] = {
-+      {"pci"},
-+      {{0}},
-+};
-+
-+static struct xenbus_driver xenbus_pcifront_driver = {
-+      .name                   = "pcifront",
-+      .owner                  = THIS_MODULE,
-+      .ids                    = xenpci_ids,
-+      .probe                  = pcifront_xenbus_probe,
-+      .remove                 = pcifront_xenbus_remove,
-+      .otherend_changed       = pcifront_backend_changed,
-+};
-+
-+static int __init pcifront_init(void)
-+{
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      return xenbus_register_frontend(&xenbus_pcifront_driver);
-+}
-+
-+/* Initialize after the Xen PCI Frontend Stub is initialized */
-+subsys_initcall(pcifront_init);
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/privcmd/Makefile linux-2.6.16.33/drivers/xen/privcmd/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/privcmd/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/privcmd/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,2 @@
-+
-+obj-$(CONFIG_XEN_PRIVCMD)     := privcmd.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/privcmd/privcmd.c linux-2.6.16.33/drivers/xen/privcmd/privcmd.c
---- linux-2.6.16.33-noxen/drivers/xen/privcmd/privcmd.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/privcmd/privcmd.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,286 @@
-+/******************************************************************************
-+ * privcmd.c
-+ * 
-+ * Interface to privileged domain-0 commands.
-+ * 
-+ * Copyright (c) 2002-2004, K A Fraser, B Dragovic
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/mm.h>
-+#include <linux/mman.h>
-+#include <linux/swap.h>
-+#include <linux/smp_lock.h>
-+#include <linux/highmem.h>
-+#include <linux/pagemap.h>
-+#include <linux/seq_file.h>
-+#include <linux/kthread.h>
-+#include <asm/hypervisor.h>
-+
-+#include <asm/pgalloc.h>
-+#include <asm/pgtable.h>
-+#include <asm/uaccess.h>
-+#include <asm/tlb.h>
-+#include <asm/hypervisor.h>
-+#include <xen/public/privcmd.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/dom0_ops.h>
-+#include <xen/xen_proc.h>
-+
-+static struct proc_dir_entry *privcmd_intf;
-+static struct proc_dir_entry *capabilities_intf;
-+
-+#ifndef HAVE_ARCH_PRIVCMD_MMAP
-+static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
-+#endif
-+
-+static int privcmd_ioctl(struct inode *inode, struct file *file,
-+                       unsigned int cmd, unsigned long data)
-+{
-+      int ret = -ENOSYS;
-+      void __user *udata = (void __user *) data;
-+
-+      switch (cmd) {
-+      case IOCTL_PRIVCMD_HYPERCALL: {
-+              privcmd_hypercall_t hypercall;
-+  
-+              if (copy_from_user(&hypercall, udata, sizeof(hypercall)))
-+                      return -EFAULT;
-+
-+#if defined(__i386__)
-+              if (hypercall.op >= (PAGE_SIZE >> 5))
-+                      break;
-+              __asm__ __volatile__ (
-+                      "pushl %%ebx; pushl %%ecx; pushl %%edx; "
-+                      "pushl %%esi; pushl %%edi; "
-+                      "movl  8(%%eax),%%ebx ;"
-+                      "movl 16(%%eax),%%ecx ;"
-+                      "movl 24(%%eax),%%edx ;"
-+                      "movl 32(%%eax),%%esi ;"
-+                      "movl 40(%%eax),%%edi ;"
-+                      "movl   (%%eax),%%eax ;"
-+                      "shll $5,%%eax ;"
-+                      "addl $hypercall_page,%%eax ;"
-+                      "call *%%eax ;"
-+                      "popl %%edi; popl %%esi; popl %%edx; "
-+                      "popl %%ecx; popl %%ebx"
-+                      : "=a" (ret) : "0" (&hypercall) : "memory" );
-+#elif defined (__x86_64__)
-+              if (hypercall.op < (PAGE_SIZE >> 5)) {
-+                      long ign1, ign2, ign3;
-+                      __asm__ __volatile__ (
-+                              "movq %8,%%r10; movq %9,%%r8;"
-+                              "shll $5,%%eax ;"
-+                              "addq $hypercall_page,%%rax ;"
-+                              "call *%%rax"
-+                              : "=a" (ret), "=D" (ign1),
-+                                "=S" (ign2), "=d" (ign3)
-+                              : "0" ((unsigned int)hypercall.op),
-+                              "1" (hypercall.arg[0]),
-+                              "2" (hypercall.arg[1]),
-+                              "3" (hypercall.arg[2]),
-+                              "g" (hypercall.arg[3]),
-+                              "g" (hypercall.arg[4])
-+                              : "r8", "r10", "memory" );
-+              }
-+#elif defined (__ia64__)
-+              ret = privcmd_hypercall(&hypercall);
-+#endif
-+      }
-+      break;
-+
-+      case IOCTL_PRIVCMD_MMAP: {
-+              privcmd_mmap_t mmapcmd;
-+              privcmd_mmap_entry_t msg;
-+              privcmd_mmap_entry_t __user *p;
-+              struct mm_struct *mm = current->mm;
-+              struct vm_area_struct *vma;
-+              unsigned long va;
-+              int i, rc;
-+
-+              if (!is_initial_xendomain())
-+                      return -EPERM;
-+
-+              if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd)))
-+                      return -EFAULT;
-+
-+              p = mmapcmd.entry;
-+              if (copy_from_user(&msg, p, sizeof(msg)))
-+                      return -EFAULT;
-+
-+              down_read(&mm->mmap_sem);
-+
-+              vma = find_vma(mm, msg.va);
-+              rc = -EINVAL;
-+              if (!vma || (msg.va != vma->vm_start) ||
-+                  !privcmd_enforce_singleshot_mapping(vma))
-+                      goto mmap_out;
-+
-+              va = vma->vm_start;
-+
-+              for (i = 0; i < mmapcmd.num; i++) {
-+                      rc = -EFAULT;
-+                      if (copy_from_user(&msg, p, sizeof(msg)))
-+                              goto mmap_out;
-+
-+                      /* Do not allow range to wrap the address space. */
-+                      rc = -EINVAL;
-+                      if ((msg.npages > (LONG_MAX >> PAGE_SHIFT)) ||
-+                          ((unsigned long)(msg.npages << PAGE_SHIFT) >= -va))
-+                              goto mmap_out;
-+
-+                      /* Range chunks must be contiguous in va space. */
-+                      if ((msg.va != va) ||
-+                          ((msg.va+(msg.npages<<PAGE_SHIFT)) > vma->vm_end))
-+                              goto mmap_out;
-+
-+                      if ((rc = direct_remap_pfn_range(
-+                              vma,
-+                              msg.va & PAGE_MASK, 
-+                              msg.mfn, 
-+                              msg.npages << PAGE_SHIFT, 
-+                              vma->vm_page_prot,
-+                              mmapcmd.dom)) < 0)
-+                              goto mmap_out;
-+
-+                      p++;
-+                      va += msg.npages << PAGE_SHIFT;
-+              }
-+
-+              rc = 0;
-+
-+      mmap_out:
-+              up_read(&mm->mmap_sem);
-+              ret = rc;
-+      }
-+      break;
-+
-+      case IOCTL_PRIVCMD_MMAPBATCH: {
-+              privcmd_mmapbatch_t m;
-+              struct mm_struct *mm = current->mm;
-+              struct vm_area_struct *vma;
-+              xen_pfn_t __user *p;
-+              unsigned long addr, mfn, nr_pages;
-+              int i;
-+
-+              if (!is_initial_xendomain())
-+                      return -EPERM;
-+
-+              if (copy_from_user(&m, udata, sizeof(m)))
-+                      return -EFAULT;
-+
-+              nr_pages = m.num;
-+              if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
-+                      return -EINVAL;
-+
-+              down_read(&mm->mmap_sem);
-+
-+              vma = find_vma(mm, m.addr);
-+              if (!vma ||
-+                  (m.addr != vma->vm_start) ||
-+                  ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) ||
-+                  !privcmd_enforce_singleshot_mapping(vma)) {
-+                      up_read(&mm->mmap_sem);
-+                      return -EINVAL;
-+              }
-+
-+              p = m.arr;
-+              addr = m.addr;
-+              for (i = 0; i < nr_pages; i++, addr += PAGE_SIZE, p++) {
-+                      if (get_user(mfn, p)) {
-+                              up_read(&mm->mmap_sem);
-+                              return -EFAULT;
-+                      }
-+
-+                      ret = direct_remap_pfn_range(vma, addr & PAGE_MASK,
-+                                                   mfn, PAGE_SIZE,
-+                                                   vma->vm_page_prot, m.dom);
-+                      if (ret < 0)
-+                              put_user(0xF0000000 | mfn, p);
-+              }
-+
-+              up_read(&mm->mmap_sem);
-+              ret = 0;
-+      }
-+      break;
-+
-+      default:
-+              ret = -EINVAL;
-+              break;
-+      }
-+
-+      return ret;
-+}
-+
-+#ifndef HAVE_ARCH_PRIVCMD_MMAP
-+static struct page *privcmd_nopage(struct vm_area_struct *vma,
-+                                 unsigned long address,
-+                                 int *type)
-+{
-+      return NOPAGE_SIGBUS;
-+}
-+
-+static struct vm_operations_struct privcmd_vm_ops = {
-+      .nopage = privcmd_nopage
-+};
-+
-+static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
-+{
-+      /* Unsupported for auto-translate guests. */
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return -ENOSYS;
-+
-+      /* DONTCOPY is essential for Xen as copy_page_range is broken. */
-+      vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
-+      vma->vm_ops = &privcmd_vm_ops;
-+      vma->vm_private_data = NULL;
-+
-+      return 0;
-+}
-+
-+static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
-+{
-+      return (xchg(&vma->vm_private_data, (void *)1) == NULL);
-+}
-+#endif
-+
-+static struct file_operations privcmd_file_ops = {
-+      .ioctl = privcmd_ioctl,
-+      .mmap  = privcmd_mmap,
-+};
-+
-+static int capabilities_read(char *page, char **start, off_t off,
-+                           int count, int *eof, void *data)
-+{
-+      int len = 0;
-+      *page = 0;
-+
-+      if (is_initial_xendomain())
-+              len = sprintf( page, "control_d\n" );
-+
-+      *eof = 1;
-+      return len;
-+}
-+
-+static int __init privcmd_init(void)
-+{
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      privcmd_intf = create_xen_proc_entry("privcmd", 0400);
-+      if (privcmd_intf != NULL)
-+              privcmd_intf->proc_fops = &privcmd_file_ops;
-+
-+      capabilities_intf = create_xen_proc_entry("capabilities", 0400 );
-+      if (capabilities_intf != NULL)
-+              capabilities_intf->read_proc = capabilities_read;
-+
-+      return 0;
-+}
-+
-+__initcall(privcmd_init);
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/tpmback/Makefile linux-2.6.16.33/drivers/xen/tpmback/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/tpmback/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/tpmback/Makefile       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,4 @@
-+
-+obj-$(CONFIG_XEN_TPMDEV_BACKEND)      += tpmbk.o
-+
-+tpmbk-y += tpmback.o interface.o xenbus.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/tpmback/common.h linux-2.6.16.33/drivers/xen/tpmback/common.h
---- linux-2.6.16.33-noxen/drivers/xen/tpmback/common.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/tpmback/common.h       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,87 @@
-+/******************************************************************************
-+ * drivers/xen/tpmback/common.h
-+ */
-+
-+#ifndef __NETIF__BACKEND__COMMON_H__
-+#define __NETIF__BACKEND__COMMON_H__
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <xen/evtchn.h>
-+#include <xen/driver_util.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/interface/io/tpmif.h>
-+#include <asm/io.h>
-+#include <asm/pgalloc.h>
-+
-+#define DPRINTK(_f, _a...)                    \
-+      pr_debug("(file=%s, line=%d) " _f,      \
-+               __FILE__ , __LINE__ , ## _a )
-+
-+struct backend_info;
-+
-+typedef struct tpmif_st {
-+      struct list_head tpmif_list;
-+      /* Unique identifier for this interface. */
-+      domid_t domid;
-+      unsigned int handle;
-+
-+      /* Physical parameters of the comms window. */
-+      unsigned int evtchn;
-+      unsigned int irq;
-+
-+      /* The shared rings and indexes. */
-+      tpmif_tx_interface_t *tx;
-+      struct vm_struct *tx_area;
-+
-+      /* Miscellaneous private stuff. */
-+      enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
-+      int active;
-+
-+      struct tpmif_st *hash_next;
-+      struct list_head list;  /* scheduling list */
-+      atomic_t refcnt;
-+
-+      struct backend_info *bi;
-+
-+      grant_handle_t shmem_handle;
-+      grant_ref_t shmem_ref;
-+      struct page **mmap_pages;
-+
-+      char devname[20];
-+} tpmif_t;
-+
-+void tpmif_disconnect_complete(tpmif_t * tpmif);
-+tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi);
-+void tpmif_interface_init(void);
-+void tpmif_interface_exit(void);
-+void tpmif_schedule_work(tpmif_t * tpmif);
-+void tpmif_deschedule_work(tpmif_t * tpmif);
-+void tpmif_xenbus_init(void);
-+void tpmif_xenbus_exit(void);
-+int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
-+irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
-+
-+long int tpmback_get_instance(struct backend_info *bi);
-+
-+int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
-+
-+
-+#define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
-+#define tpmif_put(_b)                                 \
-+      do {                                            \
-+              if (atomic_dec_and_test(&(_b)->refcnt)) \
-+                      tpmif_disconnect_complete(_b);  \
-+      } while (0)
-+
-+extern int num_frontends;
-+
-+static inline unsigned long idx_to_kaddr(tpmif_t *t, unsigned int idx)
-+{
-+      return (unsigned long)pfn_to_kaddr(page_to_pfn(t->mmap_pages[idx]));
-+}
-+
-+#endif /* __TPMIF__BACKEND__COMMON_H__ */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/tpmback/interface.c linux-2.6.16.33/drivers/xen/tpmback/interface.c
---- linux-2.6.16.33-noxen/drivers/xen/tpmback/interface.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/tpmback/interface.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,182 @@
-+ /*****************************************************************************
-+ * drivers/xen/tpmback/interface.c
-+ *
-+ * Vritual TPM interface management.
-+ *
-+ * Copyright (c) 2005, IBM Corporation
-+ *
-+ * Author: Stefan Berger, stefanb@us.ibm.com
-+ *
-+ * This code has been derived from drivers/xen/netback/interface.c
-+ * Copyright (c) 2004, Keir Fraser
-+ */
-+
-+#include "common.h"
-+#include <xen/balloon.h>
-+#include <xen/gnttab.h>
-+
-+static kmem_cache_t *tpmif_cachep;
-+int num_frontends = 0;
-+
-+LIST_HEAD(tpmif_list);
-+
-+static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi)
-+{
-+      tpmif_t *tpmif;
-+
-+      tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
-+      if (tpmif == NULL)
-+              goto out_of_memory;
-+
-+      memset(tpmif, 0, sizeof (*tpmif));
-+      tpmif->domid = domid;
-+      tpmif->status = DISCONNECTED;
-+      tpmif->bi = bi;
-+      snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
-+      atomic_set(&tpmif->refcnt, 1);
-+
-+      tpmif->mmap_pages = alloc_empty_pages_and_pagevec(TPMIF_TX_RING_SIZE);
-+      if (tpmif->mmap_pages == NULL)
-+              goto out_of_memory;
-+
-+      list_add(&tpmif->tpmif_list, &tpmif_list);
-+      num_frontends++;
-+
-+      return tpmif;
-+
-+ out_of_memory:
-+      if (tpmif != NULL)
-+              kmem_cache_free(tpmif_cachep, tpmif);
-+      printk("%s: out of memory\n", __FUNCTION__);
-+      return ERR_PTR(-ENOMEM);
-+}
-+
-+static void free_tpmif(tpmif_t * tpmif)
-+{
-+      num_frontends--;
-+      list_del(&tpmif->tpmif_list);
-+      free_empty_pages_and_pagevec(tpmif->mmap_pages, TPMIF_TX_RING_SIZE);
-+      kmem_cache_free(tpmif_cachep, tpmif);
-+}
-+
-+tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi)
-+{
-+      tpmif_t *tpmif;
-+
-+      list_for_each_entry(tpmif, &tpmif_list, tpmif_list) {
-+              if (tpmif->bi == bi) {
-+                      if (tpmif->domid == domid) {
-+                              tpmif_get(tpmif);
-+                              return tpmif;
-+                      } else {
-+                              return ERR_PTR(-EEXIST);
-+                      }
-+              }
-+      }
-+
-+      return alloc_tpmif(domid, bi);
-+}
-+
-+static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
-+{
-+      int ret;
-+      struct gnttab_map_grant_ref op;
-+
-+      gnttab_set_map_op(&op, (unsigned long)tpmif->tx_area->addr,
-+                        GNTMAP_host_map, shared_page, tpmif->domid);
-+
-+      lock_vm_area(tpmif->tx_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
-+      unlock_vm_area(tpmif->tx_area);
-+      BUG_ON(ret);
-+
-+      if (op.status) {
-+              DPRINTK(" Grant table operation failure !\n");
-+              return op.status;
-+      }
-+
-+      tpmif->shmem_ref = shared_page;
-+      tpmif->shmem_handle = op.handle;
-+
-+      return 0;
-+}
-+
-+static void unmap_frontend_page(tpmif_t *tpmif)
-+{
-+      struct gnttab_unmap_grant_ref op;
-+      int ret;
-+
-+      gnttab_set_unmap_op(&op, (unsigned long)tpmif->tx_area->addr,
-+                          GNTMAP_host_map, tpmif->shmem_handle);
-+
-+      lock_vm_area(tpmif->tx_area);
-+      ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
-+      unlock_vm_area(tpmif->tx_area);
-+      BUG_ON(ret);
-+}
-+
-+int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
-+{
-+      int err;
-+      struct evtchn_bind_interdomain bind_interdomain;
-+
-+      if (tpmif->irq) {
-+              return 0;
-+      }
-+
-+      if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
-+              return -ENOMEM;
-+
-+      err = map_frontend_page(tpmif, shared_page);
-+      if (err) {
-+              free_vm_area(tpmif->tx_area);
-+              return err;
-+      }
-+
-+
-+      bind_interdomain.remote_dom  = tpmif->domid;
-+      bind_interdomain.remote_port = evtchn;
-+
-+      err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-+                                        &bind_interdomain);
-+      if (err) {
-+              unmap_frontend_page(tpmif);
-+              free_vm_area(tpmif->tx_area);
-+              return err;
-+      }
-+
-+      tpmif->evtchn = bind_interdomain.local_port;
-+
-+      tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
-+
-+      tpmif->irq = bind_evtchn_to_irqhandler(
-+              tpmif->evtchn, tpmif_be_int, 0, tpmif->devname, tpmif);
-+      tpmif->shmem_ref = shared_page;
-+      tpmif->active = 1;
-+
-+      return 0;
-+}
-+
-+void tpmif_disconnect_complete(tpmif_t *tpmif)
-+{
-+      if (tpmif->irq)
-+              unbind_from_irqhandler(tpmif->irq, tpmif);
-+
-+      if (tpmif->tx) {
-+              unmap_frontend_page(tpmif);
-+              free_vm_area(tpmif->tx_area);
-+      }
-+
-+      free_tpmif(tpmif);
-+}
-+
-+void __init tpmif_interface_init(void)
-+{
-+      tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof (tpmif_t),
-+                                       0, 0, NULL, NULL);
-+}
-+
-+void __exit tpmif_interface_exit(void)
-+{
-+      kmem_cache_destroy(tpmif_cachep);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/tpmback/tpmback.c linux-2.6.16.33/drivers/xen/tpmback/tpmback.c
---- linux-2.6.16.33-noxen/drivers/xen/tpmback/tpmback.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/tpmback/tpmback.c      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,944 @@
-+/******************************************************************************
-+ * drivers/xen/tpmback/tpmback.c
-+ *
-+ * Copyright (c) 2005, IBM Corporation
-+ *
-+ * Author: Stefan Berger, stefanb@us.ibm.com
-+ * Grant table support: Mahadevan Gomathisankaran
-+ *
-+ * This code has been derived from drivers/xen/netback/netback.c
-+ * Copyright (c) 2002-2004, K A Fraser
-+ *
-+ */
-+
-+#include "common.h"
-+#include <xen/evtchn.h>
-+
-+#include <linux/types.h>
-+#include <linux/list.h>
-+#include <linux/miscdevice.h>
-+#include <linux/poll.h>
-+#include <asm/uaccess.h>
-+#include <xen/xenbus.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/gnttab.h>
-+
-+/* local data structures */
-+struct data_exchange {
-+      struct list_head pending_pak;
-+      struct list_head current_pak;
-+      unsigned int copied_so_far;
-+      u8 has_opener:1;
-+      u8 aborted:1;
-+      rwlock_t pak_lock;      // protects all of the previous fields
-+      wait_queue_head_t wait_queue;
-+};
-+
-+struct vtpm_resp_hdr {
-+      uint32_t instance_no;
-+      uint16_t tag_no;
-+      uint32_t len_no;
-+      uint32_t ordinal_no;
-+} __attribute__ ((packed));
-+
-+struct packet {
-+      struct list_head next;
-+      unsigned int data_len;
-+      u8 *data_buffer;
-+      tpmif_t *tpmif;
-+      u32 tpm_instance;
-+      u8 req_tag;
-+      u32 last_read;
-+      u8 flags;
-+      struct timer_list processing_timer;
-+};
-+
-+enum {
-+      PACKET_FLAG_DISCARD_RESPONSE = 1,
-+};
-+
-+/* local variables */
-+static struct data_exchange dataex;
-+
-+/* local function prototypes */
-+static int _packet_write(struct packet *pak,
-+                       const char *data, size_t size, int userbuffer);
-+static void processing_timeout(unsigned long ptr);
-+static int packet_read_shmem(struct packet *pak,
-+                           tpmif_t * tpmif,
-+                           u32 offset,
-+                           char *buffer, int isuserbuffer, u32 left);
-+static int vtpm_queue_packet(struct packet *pak);
-+
-+/***************************************************************
-+ Buffer copying fo user and kernel space buffes.
-+***************************************************************/
-+static inline int copy_from_buffer(void *to,
-+                                 const void *from, unsigned long size,
-+                                 int isuserbuffer)
-+{
-+      if (isuserbuffer) {
-+              if (copy_from_user(to, (void __user *)from, size))
-+                      return -EFAULT;
-+      } else {
-+              memcpy(to, from, size);
-+      }
-+      return 0;
-+}
-+
-+static inline int copy_to_buffer(void *to,
-+                               const void *from, unsigned long size,
-+                               int isuserbuffer)
-+{
-+      if (isuserbuffer) {
-+              if (copy_to_user((void __user *)to, from, size))
-+                      return -EFAULT;
-+      } else {
-+              memcpy(to, from, size);
-+      }
-+      return 0;
-+}
-+
-+
-+static void dataex_init(struct data_exchange *dataex)
-+{
-+      INIT_LIST_HEAD(&dataex->pending_pak);
-+      INIT_LIST_HEAD(&dataex->current_pak);
-+      dataex->has_opener = 0;
-+      rwlock_init(&dataex->pak_lock);
-+      init_waitqueue_head(&dataex->wait_queue);
-+}
-+
-+/***************************************************************
-+ Packet-related functions
-+***************************************************************/
-+
-+static struct packet *packet_find_instance(struct list_head *head,
-+                                         u32 tpm_instance)
-+{
-+      struct packet *pak;
-+      struct list_head *p;
-+
-+      /*
-+       * traverse the list of packets and return the first
-+       * one with the given instance number
-+       */
-+      list_for_each(p, head) {
-+              pak = list_entry(p, struct packet, next);
-+
-+              if (pak->tpm_instance == tpm_instance) {
-+                      return pak;
-+              }
-+      }
-+      return NULL;
-+}
-+
-+static struct packet *packet_find_packet(struct list_head *head, void *packet)
-+{
-+      struct packet *pak;
-+      struct list_head *p;
-+
-+      /*
-+       * traverse the list of packets and return the first
-+       * one with the given instance number
-+       */
-+      list_for_each(p, head) {
-+              pak = list_entry(p, struct packet, next);
-+
-+              if (pak == packet) {
-+                      return pak;
-+              }
-+      }
-+      return NULL;
-+}
-+
-+static struct packet *packet_alloc(tpmif_t * tpmif,
-+                                 u32 size, u8 req_tag, u8 flags)
-+{
-+      struct packet *pak = NULL;
-+      pak = kzalloc(sizeof (struct packet), GFP_ATOMIC);
-+      if (NULL != pak) {
-+              if (tpmif) {
-+                      pak->tpmif = tpmif;
-+                      pak->tpm_instance = tpmback_get_instance(tpmif->bi);
-+                      tpmif_get(tpmif);
-+              }
-+              pak->data_len = size;
-+              pak->req_tag = req_tag;
-+              pak->last_read = 0;
-+              pak->flags = flags;
-+
-+              /*
-+               * cannot do tpmif_get(tpmif); bad things happen
-+               * on the last tpmif_put()
-+               */
-+              init_timer(&pak->processing_timer);
-+              pak->processing_timer.function = processing_timeout;
-+              pak->processing_timer.data = (unsigned long)pak;
-+      }
-+      return pak;
-+}
-+
-+static void inline packet_reset(struct packet *pak)
-+{
-+      pak->last_read = 0;
-+}
-+
-+static void packet_free(struct packet *pak)
-+{
-+      if (timer_pending(&pak->processing_timer)) {
-+              BUG();
-+      }
-+
-+      if (pak->tpmif)
-+              tpmif_put(pak->tpmif);
-+      kfree(pak->data_buffer);
-+      /*
-+       * cannot do tpmif_put(pak->tpmif); bad things happen
-+       * on the last tpmif_put()
-+       */
-+      kfree(pak);
-+}
-+
-+
-+/*
-+ * Write data to the shared memory and send it to the FE.
-+ */
-+static int packet_write(struct packet *pak,
-+                      const char *data, size_t size, int isuserbuffer)
-+{
-+      int rc = 0;
-+
-+      if (0 != (pak->flags & PACKET_FLAG_DISCARD_RESPONSE)) {
-+              /* Don't send a respone to this packet. Just acknowledge it. */
-+              rc = size;
-+      } else {
-+              rc = _packet_write(pak, data, size, isuserbuffer);
-+      }
-+
-+      return rc;
-+}
-+
-+int _packet_write(struct packet *pak,
-+                const char *data, size_t size, int isuserbuffer)
-+{
-+      /*
-+       * Write into the shared memory pages directly
-+       * and send it to the front end.
-+       */
-+      tpmif_t *tpmif = pak->tpmif;
-+      grant_handle_t handle;
-+      int rc = 0;
-+      unsigned int i = 0;
-+      unsigned int offset = 0;
-+
-+      if (tpmif == NULL) {
-+              return -EFAULT;
-+      }
-+
-+      if (tpmif->status == DISCONNECTED) {
-+              return size;
-+      }
-+
-+      while (offset < size && i < TPMIF_TX_RING_SIZE) {
-+              unsigned int tocopy;
-+              struct gnttab_map_grant_ref map_op;
-+              struct gnttab_unmap_grant_ref unmap_op;
-+              tpmif_tx_request_t *tx;
-+
-+              tx = &tpmif->tx->ring[i].req;
-+
-+              if (0 == tx->addr) {
-+                      DPRINTK("ERROR: Buffer for outgoing packet NULL?! i=%d\n", i);
-+                      return 0;
-+              }
-+
-+              gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
-+                                GNTMAP_host_map, tx->ref, tpmif->domid);
-+
-+              if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
-+                                                     &map_op, 1))) {
-+                      BUG();
-+              }
-+
-+              handle = map_op.handle;
-+
-+              if (map_op.status) {
-+                      DPRINTK(" Grant table operation failure !\n");
-+                      return 0;
-+              }
-+
-+              tocopy = min_t(size_t, size - offset, PAGE_SIZE);
-+
-+              if (copy_from_buffer((void *)(idx_to_kaddr(tpmif, i) |
-+                                            (tx->addr & ~PAGE_MASK)),
-+                                   &data[offset], tocopy, isuserbuffer)) {
-+                      tpmif_put(tpmif);
-+                      return -EFAULT;
-+              }
-+              tx->size = tocopy;
-+
-+              gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
-+                                  GNTMAP_host_map, handle);
-+
-+              if (unlikely
-+                  (HYPERVISOR_grant_table_op
-+                   (GNTTABOP_unmap_grant_ref, &unmap_op, 1))) {
-+                      BUG();
-+              }
-+
-+              offset += tocopy;
-+              i++;
-+      }
-+
-+      rc = offset;
-+      DPRINTK("Notifying frontend via irq %d\n", tpmif->irq);
-+      notify_remote_via_irq(tpmif->irq);
-+
-+      return rc;
-+}
-+
-+/*
-+ * Read data from the shared memory and copy it directly into the
-+ * provided buffer. Advance the read_last indicator which tells
-+ * how many bytes have already been read.
-+ */
-+static int packet_read(struct packet *pak, size_t numbytes,
-+                     char *buffer, size_t buffersize, int isuserbuffer)
-+{
-+      tpmif_t *tpmif = pak->tpmif;
-+
-+      /*
-+       * Read 'numbytes' of data from the buffer. The first 4
-+       * bytes are the instance number in network byte order,
-+       * after that come the data from the shared memory buffer.
-+       */
-+      u32 to_copy;
-+      u32 offset = 0;
-+      u32 room_left = buffersize;
-+
-+      if (pak->last_read < 4) {
-+              /*
-+               * copy the instance number into the buffer
-+               */
-+              u32 instance_no = htonl(pak->tpm_instance);
-+              u32 last_read = pak->last_read;
-+
-+              to_copy = min_t(size_t, 4 - last_read, numbytes);
-+
-+              if (copy_to_buffer(&buffer[0],
-+                                 &(((u8 *) & instance_no)[last_read]),
-+                                 to_copy, isuserbuffer)) {
-+                      return -EFAULT;
-+              }
-+
-+              pak->last_read += to_copy;
-+              offset += to_copy;
-+              room_left -= to_copy;
-+      }
-+
-+      /*
-+       * If the packet has a data buffer appended, read from it...
-+       */
-+
-+      if (room_left > 0) {
-+              if (pak->data_buffer) {
-+                      u32 to_copy = min_t(u32, pak->data_len - offset, room_left);
-+                      u32 last_read = pak->last_read - 4;
-+
-+                      if (copy_to_buffer(&buffer[offset],
-+                                         &pak->data_buffer[last_read],
-+                                         to_copy, isuserbuffer)) {
-+                              return -EFAULT;
-+                      }
-+                      pak->last_read += to_copy;
-+                      offset += to_copy;
-+              } else {
-+                      offset = packet_read_shmem(pak,
-+                                                 tpmif,
-+                                                 offset,
-+                                                 buffer,
-+                                                 isuserbuffer, room_left);
-+              }
-+      }
-+      return offset;
-+}
-+
-+static int packet_read_shmem(struct packet *pak,
-+                           tpmif_t * tpmif,
-+                           u32 offset, char *buffer, int isuserbuffer,
-+                           u32 room_left)
-+{
-+      u32 last_read = pak->last_read - 4;
-+      u32 i = (last_read / PAGE_SIZE);
-+      u32 pg_offset = last_read & (PAGE_SIZE - 1);
-+      u32 to_copy;
-+      grant_handle_t handle;
-+
-+      tpmif_tx_request_t *tx;
-+
-+      tx = &tpmif->tx->ring[0].req;
-+      /*
-+       * Start copying data at the page with index 'index'
-+       * and within that page at offset 'offset'.
-+       * Copy a maximum of 'room_left' bytes.
-+       */
-+      to_copy = min_t(u32, PAGE_SIZE - pg_offset, room_left);
-+      while (to_copy > 0) {
-+              void *src;
-+              struct gnttab_map_grant_ref map_op;
-+              struct gnttab_unmap_grant_ref unmap_op;
-+
-+              tx = &tpmif->tx->ring[i].req;
-+
-+              gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
-+                                GNTMAP_host_map, tx->ref, tpmif->domid);
-+
-+              if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
-+                                                     &map_op, 1))) {
-+                      BUG();
-+              }
-+
-+              if (map_op.status) {
-+                      DPRINTK(" Grant table operation failure !\n");
-+                      return -EFAULT;
-+              }
-+
-+              handle = map_op.handle;
-+
-+              if (to_copy > tx->size) {
-+                      /*
-+                       * User requests more than what's available
-+                       */
-+                      to_copy = min_t(u32, tx->size, to_copy);
-+              }
-+
-+              DPRINTK("Copying from mapped memory at %08lx\n",
-+                      (unsigned long)(idx_to_kaddr(tpmif, i) |
-+                                      (tx->addr & ~PAGE_MASK)));
-+
-+              src = (void *)(idx_to_kaddr(tpmif, i) |
-+                             ((tx->addr & ~PAGE_MASK) + pg_offset));
-+              if (copy_to_buffer(&buffer[offset],
-+                                 src, to_copy, isuserbuffer)) {
-+                      return -EFAULT;
-+              }
-+
-+              DPRINTK("Data from TPM-FE of domain %d are %d %d %d %d\n",
-+                      tpmif->domid, buffer[offset], buffer[offset + 1],
-+                      buffer[offset + 2], buffer[offset + 3]);
-+
-+              gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
-+                                  GNTMAP_host_map, handle);
-+
-+              if (unlikely
-+                  (HYPERVISOR_grant_table_op
-+                   (GNTTABOP_unmap_grant_ref, &unmap_op, 1))) {
-+                      BUG();
-+              }
-+
-+              offset += to_copy;
-+              pg_offset = 0;
-+              last_read += to_copy;
-+              room_left -= to_copy;
-+
-+              to_copy = min_t(u32, PAGE_SIZE, room_left);
-+              i++;
-+      }                       /* while (to_copy > 0) */
-+      /*
-+       * Adjust the last_read pointer
-+       */
-+      pak->last_read = last_read + 4;
-+      return offset;
-+}
-+
-+/* ============================================================
-+ * The file layer for reading data from this device
-+ * ============================================================
-+ */
-+static int vtpm_op_open(struct inode *inode, struct file *f)
-+{
-+      int rc = 0;
-+      unsigned long flags;
-+
-+      write_lock_irqsave(&dataex.pak_lock, flags);
-+      if (dataex.has_opener == 0) {
-+              dataex.has_opener = 1;
-+      } else {
-+              rc = -EPERM;
-+      }
-+      write_unlock_irqrestore(&dataex.pak_lock, flags);
-+      return rc;
-+}
-+
-+static ssize_t vtpm_op_read(struct file *file,
-+                          char __user * data, size_t size, loff_t * offset)
-+{
-+      int ret_size = -ENODATA;
-+      struct packet *pak = NULL;
-+      unsigned long flags;
-+
-+      write_lock_irqsave(&dataex.pak_lock, flags);
-+      if (dataex.aborted) {
-+              dataex.aborted = 0;
-+              dataex.copied_so_far = 0;
-+              write_unlock_irqrestore(&dataex.pak_lock, flags);
-+              return -EIO;
-+      }
-+
-+      if (list_empty(&dataex.pending_pak)) {
-+              write_unlock_irqrestore(&dataex.pak_lock, flags);
-+              wait_event_interruptible(dataex.wait_queue,
-+                                       !list_empty(&dataex.pending_pak));
-+              write_lock_irqsave(&dataex.pak_lock, flags);
-+              dataex.copied_so_far = 0;
-+      }
-+
-+      if (!list_empty(&dataex.pending_pak)) {
-+              unsigned int left;
-+
-+              pak = list_entry(dataex.pending_pak.next, struct packet, next);
-+              left = pak->data_len - dataex.copied_so_far;
-+              list_del(&pak->next);
-+              write_unlock_irqrestore(&dataex.pak_lock, flags);
-+
-+              DPRINTK("size given by app: %d, available: %d\n", size, left);
-+
-+              ret_size = min_t(size_t, size, left);
-+
-+              ret_size = packet_read(pak, ret_size, data, size, 1);
-+
-+              write_lock_irqsave(&dataex.pak_lock, flags);
-+
-+              if (ret_size < 0) {
-+                      del_singleshot_timer_sync(&pak->processing_timer);
-+                      packet_free(pak);
-+                      dataex.copied_so_far = 0;
-+              } else {
-+                      DPRINTK("Copied %d bytes to user buffer\n", ret_size);
-+
-+                      dataex.copied_so_far += ret_size;
-+                      if (dataex.copied_so_far >= pak->data_len + 4) {
-+                              DPRINTK("All data from this packet given to app.\n");
-+                              /* All data given to app */
-+
-+                              del_singleshot_timer_sync(&pak->
-+                                                        processing_timer);
-+                              list_add_tail(&pak->next, &dataex.current_pak);
-+                              /*
-+                               * The more fontends that are handled at the same time,
-+                               * the more time we give the TPM to process the request.
-+                               */
-+                              mod_timer(&pak->processing_timer,
-+                                        jiffies + (num_frontends * 60 * HZ));
-+                              dataex.copied_so_far = 0;
-+                      } else {
-+                              list_add(&pak->next, &dataex.pending_pak);
-+                      }
-+              }
-+      }
-+      write_unlock_irqrestore(&dataex.pak_lock, flags);
-+
-+      DPRINTK("Returning result from read to app: %d\n", ret_size);
-+
-+      return ret_size;
-+}
-+
-+/*
-+ * Write operation - only works after a previous read operation!
-+ */
-+static ssize_t vtpm_op_write(struct file *file,
-+                           const char __user * data, size_t size,
-+                           loff_t * offset)
-+{
-+      struct packet *pak;
-+      int rc = 0;
-+      unsigned int off = 4;
-+      unsigned long flags;
-+      struct vtpm_resp_hdr vrh;
-+
-+      /*
-+       * Minimum required packet size is:
-+       * 4 bytes for instance number
-+       * 2 bytes for tag
-+       * 4 bytes for paramSize
-+       * 4 bytes for the ordinal
-+       * sum: 14 bytes
-+       */
-+      if (size < sizeof (vrh))
-+              return -EFAULT;
-+
-+      if (copy_from_user(&vrh, data, sizeof (vrh)))
-+              return -EFAULT;
-+
-+      /* malformed packet? */
-+      if ((off + ntohl(vrh.len_no)) != size)
-+              return -EFAULT;
-+
-+      write_lock_irqsave(&dataex.pak_lock, flags);
-+      pak = packet_find_instance(&dataex.current_pak,
-+                                 ntohl(vrh.instance_no));
-+
-+      if (pak == NULL) {
-+              write_unlock_irqrestore(&dataex.pak_lock, flags);
-+              DPRINTK(KERN_ALERT "No associated packet! (inst=%d)\n",
-+                      ntohl(vrh.instance_no));
-+              return -EFAULT;
-+      }
-+
-+      del_singleshot_timer_sync(&pak->processing_timer);
-+      list_del(&pak->next);
-+
-+      write_unlock_irqrestore(&dataex.pak_lock, flags);
-+
-+      /*
-+       * The first 'offset' bytes must be the instance number - skip them.
-+       */
-+      size -= off;
-+
-+      rc = packet_write(pak, &data[off], size, 1);
-+
-+      if (rc > 0) {
-+              /* I neglected the first 4 bytes */
-+              rc += off;
-+      }
-+      packet_free(pak);
-+      return rc;
-+}
-+
-+static int vtpm_op_release(struct inode *inode, struct file *file)
-+{
-+      unsigned long flags;
-+
-+      vtpm_release_packets(NULL, 1);
-+      write_lock_irqsave(&dataex.pak_lock, flags);
-+      dataex.has_opener = 0;
-+      write_unlock_irqrestore(&dataex.pak_lock, flags);
-+      return 0;
-+}
-+
-+static unsigned int vtpm_op_poll(struct file *file,
-+                               struct poll_table_struct *pts)
-+{
-+      unsigned int flags = POLLOUT | POLLWRNORM;
-+
-+      poll_wait(file, &dataex.wait_queue, pts);
-+      if (!list_empty(&dataex.pending_pak)) {
-+              flags |= POLLIN | POLLRDNORM;
-+      }
-+      return flags;
-+}
-+
-+static struct file_operations vtpm_ops = {
-+      .owner = THIS_MODULE,
-+      .llseek = no_llseek,
-+      .open = vtpm_op_open,
-+      .read = vtpm_op_read,
-+      .write = vtpm_op_write,
-+      .release = vtpm_op_release,
-+      .poll = vtpm_op_poll,
-+};
-+
-+static struct miscdevice vtpms_miscdevice = {
-+      .minor = 225,
-+      .name = "vtpm",
-+      .fops = &vtpm_ops,
-+};
-+
-+/***************************************************************
-+ Utility functions
-+***************************************************************/
-+
-+static int tpm_send_fail_message(struct packet *pak, u8 req_tag)
-+{
-+      int rc;
-+      static const unsigned char tpm_error_message_fail[] = {
-+              0x00, 0x00,
-+              0x00, 0x00, 0x00, 0x0a,
-+              0x00, 0x00, 0x00, 0x09  /* TPM_FAIL */
-+      };
-+      unsigned char buffer[sizeof (tpm_error_message_fail)];
-+
-+      memcpy(buffer, tpm_error_message_fail,
-+             sizeof (tpm_error_message_fail));
-+      /*
-+       * Insert the right response tag depending on the given tag
-+       * All response tags are '+3' to the request tag.
-+       */
-+      buffer[1] = req_tag + 3;
-+
-+      /*
-+       * Write the data to shared memory and notify the front-end
-+       */
-+      rc = packet_write(pak, buffer, sizeof (buffer), 0);
-+
-+      return rc;
-+}
-+
-+static int _vtpm_release_packets(struct list_head *head,
-+                               tpmif_t * tpmif, int send_msgs)
-+{
-+      int aborted = 0;
-+      int c = 0;
-+      struct packet *pak;
-+      struct list_head *pos, *tmp;
-+
-+      list_for_each_safe(pos, tmp, head) {
-+              pak = list_entry(pos, struct packet, next);
-+              c += 1;
-+
-+              if (tpmif == NULL || pak->tpmif == tpmif) {
-+                      int can_send = 0;
-+
-+                      del_singleshot_timer_sync(&pak->processing_timer);
-+                      list_del(&pak->next);
-+
-+                      if (pak->tpmif && pak->tpmif->status == CONNECTED) {
-+                              can_send = 1;
-+                      }
-+
-+                      if (send_msgs && can_send) {
-+                              tpm_send_fail_message(pak, pak->req_tag);
-+                      }
-+                      packet_free(pak);
-+                      if (c == 1)
-+                              aborted = 1;
-+              }
-+      }
-+      return aborted;
-+}
-+
-+int vtpm_release_packets(tpmif_t * tpmif, int send_msgs)
-+{
-+      unsigned long flags;
-+
-+      write_lock_irqsave(&dataex.pak_lock, flags);
-+
-+      dataex.aborted = _vtpm_release_packets(&dataex.pending_pak,
-+                                             tpmif,
-+                                             send_msgs);
-+      _vtpm_release_packets(&dataex.current_pak, tpmif, send_msgs);
-+
-+      write_unlock_irqrestore(&dataex.pak_lock, flags);
-+      return 0;
-+}
-+
-+static int vtpm_queue_packet(struct packet *pak)
-+{
-+      int rc = 0;
-+
-+      if (dataex.has_opener) {
-+              unsigned long flags;
-+
-+              write_lock_irqsave(&dataex.pak_lock, flags);
-+              list_add_tail(&pak->next, &dataex.pending_pak);
-+              /* give the TPM some time to pick up the request */
-+              mod_timer(&pak->processing_timer, jiffies + (30 * HZ));
-+              write_unlock_irqrestore(&dataex.pak_lock, flags);
-+
-+              wake_up_interruptible(&dataex.wait_queue);
-+      } else {
-+              rc = -EFAULT;
-+      }
-+      return rc;
-+}
-+
-+static int vtpm_receive(tpmif_t * tpmif, u32 size)
-+{
-+      int rc = 0;
-+      unsigned char buffer[10];
-+      __be32 *native_size;
-+      struct packet *pak = packet_alloc(tpmif, size, 0, 0);
-+
-+      if (!pak)
-+              return -ENOMEM;
-+      /*
-+       * Read 10 bytes from the received buffer to test its
-+       * content for validity.
-+       */
-+      if (sizeof (buffer) != packet_read(pak,
-+                                         sizeof (buffer), buffer,
-+                                         sizeof (buffer), 0)) {
-+              goto failexit;
-+      }
-+      /*
-+       * Reset the packet read pointer so we can read all its
-+       * contents again.
-+       */
-+      packet_reset(pak);
-+
-+      native_size = (__force __be32 *) (&buffer[4 + 2]);
-+      /*
-+       * Verify that the size of the packet is correct
-+       * as indicated and that there's actually someone reading packets.
-+       * The minimum size of the packet is '10' for tag, size indicator
-+       * and ordinal.
-+       */
-+      if (size < 10 ||
-+          be32_to_cpu(*native_size) != size ||
-+          0 == dataex.has_opener || tpmif->status != CONNECTED) {
-+              rc = -EINVAL;
-+              goto failexit;
-+      } else {
-+              rc = vtpm_queue_packet(pak);
-+              if (rc < 0)
-+                      goto failexit;
-+      }
-+      return 0;
-+
-+      failexit:
-+      if (pak) {
-+              tpm_send_fail_message(pak, buffer[4 + 1]);
-+              packet_free(pak);
-+      }
-+      return rc;
-+}
-+
-+/*
-+ * Timeout function that gets invoked when a packet has not been processed
-+ * during the timeout period.
-+ * The packet must be on a list when this function is invoked. This
-+ * also means that once its taken off a list, the timer must be
-+ * destroyed as well.
-+ */
-+static void processing_timeout(unsigned long ptr)
-+{
-+      struct packet *pak = (struct packet *)ptr;
-+      unsigned long flags;
-+
-+      write_lock_irqsave(&dataex.pak_lock, flags);
-+      /*
-+       * The packet needs to be searched whether it
-+       * is still on the list.
-+       */
-+      if (pak == packet_find_packet(&dataex.pending_pak, pak) ||
-+          pak == packet_find_packet(&dataex.current_pak, pak)) {
-+              if ((pak->flags & PACKET_FLAG_DISCARD_RESPONSE) == 0) {
-+                      tpm_send_fail_message(pak, pak->req_tag);
-+              }
-+              /* discard future responses */
-+              pak->flags |= PACKET_FLAG_DISCARD_RESPONSE;
-+      }
-+
-+      write_unlock_irqrestore(&dataex.pak_lock, flags);
-+}
-+
-+static void tpm_tx_action(unsigned long unused);
-+static DECLARE_TASKLET(tpm_tx_tasklet, tpm_tx_action, 0);
-+
-+static struct list_head tpm_schedule_list;
-+static spinlock_t tpm_schedule_list_lock;
-+
-+static inline void maybe_schedule_tx_action(void)
-+{
-+      smp_mb();
-+      tasklet_schedule(&tpm_tx_tasklet);
-+}
-+
-+static inline int __on_tpm_schedule_list(tpmif_t * tpmif)
-+{
-+      return tpmif->list.next != NULL;
-+}
-+
-+static void remove_from_tpm_schedule_list(tpmif_t * tpmif)
-+{
-+      spin_lock_irq(&tpm_schedule_list_lock);
-+      if (likely(__on_tpm_schedule_list(tpmif))) {
-+              list_del(&tpmif->list);
-+              tpmif->list.next = NULL;
-+              tpmif_put(tpmif);
-+      }
-+      spin_unlock_irq(&tpm_schedule_list_lock);
-+}
-+
-+static void add_to_tpm_schedule_list_tail(tpmif_t * tpmif)
-+{
-+      if (__on_tpm_schedule_list(tpmif))
-+              return;
-+
-+      spin_lock_irq(&tpm_schedule_list_lock);
-+      if (!__on_tpm_schedule_list(tpmif) && tpmif->active) {
-+              list_add_tail(&tpmif->list, &tpm_schedule_list);
-+              tpmif_get(tpmif);
-+      }
-+      spin_unlock_irq(&tpm_schedule_list_lock);
-+}
-+
-+void tpmif_schedule_work(tpmif_t * tpmif)
-+{
-+      add_to_tpm_schedule_list_tail(tpmif);
-+      maybe_schedule_tx_action();
-+}
-+
-+void tpmif_deschedule_work(tpmif_t * tpmif)
-+{
-+      remove_from_tpm_schedule_list(tpmif);
-+}
-+
-+static void tpm_tx_action(unsigned long unused)
-+{
-+      struct list_head *ent;
-+      tpmif_t *tpmif;
-+      tpmif_tx_request_t *tx;
-+
-+      DPRINTK("%s: Getting data from front-end(s)!\n", __FUNCTION__);
-+
-+      while (!list_empty(&tpm_schedule_list)) {
-+              /* Get a tpmif from the list with work to do. */
-+              ent = tpm_schedule_list.next;
-+              tpmif = list_entry(ent, tpmif_t, list);
-+              tpmif_get(tpmif);
-+              remove_from_tpm_schedule_list(tpmif);
-+
-+              tx = &tpmif->tx->ring[0].req;
-+
-+              /* pass it up */
-+              vtpm_receive(tpmif, tx->size);
-+
-+              tpmif_put(tpmif);
-+      }
-+}
-+
-+irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      tpmif_t *tpmif = (tpmif_t *) dev_id;
-+
-+      add_to_tpm_schedule_list_tail(tpmif);
-+      maybe_schedule_tx_action();
-+      return IRQ_HANDLED;
-+}
-+
-+static int __init tpmback_init(void)
-+{
-+      int rc;
-+
-+      if ((rc = misc_register(&vtpms_miscdevice)) != 0) {
-+              printk(KERN_ALERT
-+                     "Could not register misc device for TPM BE.\n");
-+              return rc;
-+      }
-+
-+      dataex_init(&dataex);
-+
-+      spin_lock_init(&tpm_schedule_list_lock);
-+      INIT_LIST_HEAD(&tpm_schedule_list);
-+
-+      tpmif_interface_init();
-+      tpmif_xenbus_init();
-+
-+      printk(KERN_ALERT "Successfully initialized TPM backend driver.\n");
-+
-+      return 0;
-+}
-+
-+module_init(tpmback_init);
-+
-+void __exit tpmback_exit(void)
-+{
-+      vtpm_release_packets(NULL, 0);
-+      tpmif_xenbus_exit();
-+      tpmif_interface_exit();
-+      misc_deregister(&vtpms_miscdevice);
-+}
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/tpmback/xenbus.c linux-2.6.16.33/drivers/xen/tpmback/xenbus.c
---- linux-2.6.16.33-noxen/drivers/xen/tpmback/xenbus.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/tpmback/xenbus.c       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,289 @@
-+/*  Xenbus code for tpmif backend
-+    Copyright (C) 2005 IBM Corporation
-+    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+*/
-+#include <stdarg.h>
-+#include <linux/module.h>
-+#include <xen/xenbus.h>
-+#include "common.h"
-+
-+struct backend_info
-+{
-+      struct xenbus_device *dev;
-+
-+      /* our communications channel */
-+      tpmif_t *tpmif;
-+
-+      long int frontend_id;
-+      long int instance; // instance of TPM
-+      u8 is_instance_set;// whether instance number has been set
-+
-+      /* watch front end for changes */
-+      struct xenbus_watch backend_watch;
-+};
-+
-+static void maybe_connect(struct backend_info *be);
-+static void connect(struct backend_info *be);
-+static int connect_ring(struct backend_info *be);
-+static void backend_changed(struct xenbus_watch *watch,
-+                          const char **vec, unsigned int len);
-+static void frontend_changed(struct xenbus_device *dev,
-+                           enum xenbus_state frontend_state);
-+
-+long int tpmback_get_instance(struct backend_info *bi)
-+{
-+      long int res = -1;
-+      if (bi && bi->is_instance_set)
-+              res = bi->instance;
-+      return res;
-+}
-+
-+static int tpmback_remove(struct xenbus_device *dev)
-+{
-+      struct backend_info *be = dev->dev.driver_data;
-+
-+      if (!be) return 0;
-+
-+      if (be->backend_watch.node) {
-+              unregister_xenbus_watch(&be->backend_watch);
-+              kfree(be->backend_watch.node);
-+              be->backend_watch.node = NULL;
-+      }
-+      if (be->tpmif) {
-+              be->tpmif->bi = NULL;
-+              vtpm_release_packets(be->tpmif, 0);
-+              tpmif_put(be->tpmif);
-+              be->tpmif = NULL;
-+      }
-+      kfree(be);
-+      dev->dev.driver_data = NULL;
-+      return 0;
-+}
-+
-+static int tpmback_probe(struct xenbus_device *dev,
-+                       const struct xenbus_device_id *id)
-+{
-+      int err;
-+      struct backend_info *be = kzalloc(sizeof(struct backend_info),
-+                                        GFP_KERNEL);
-+
-+      if (!be) {
-+              xenbus_dev_fatal(dev, -ENOMEM,
-+                               "allocating backend structure");
-+              return -ENOMEM;
-+      }
-+
-+      be->is_instance_set = 0;
-+      be->dev = dev;
-+      dev->dev.driver_data = be;
-+
-+      err = xenbus_watch_path2(dev, dev->nodename,
-+                               "instance", &be->backend_watch,
-+                               backend_changed);
-+      if (err) {
-+              goto fail;
-+      }
-+
-+      err = xenbus_switch_state(dev, XenbusStateInitWait);
-+      if (err) {
-+              goto fail;
-+      }
-+      return 0;
-+fail:
-+      tpmback_remove(dev);
-+      return err;
-+}
-+
-+
-+static void backend_changed(struct xenbus_watch *watch,
-+                          const char **vec, unsigned int len)
-+{
-+      int err;
-+      long instance;
-+      struct backend_info *be
-+              = container_of(watch, struct backend_info, backend_watch);
-+      struct xenbus_device *dev = be->dev;
-+
-+      err = xenbus_scanf(XBT_NIL, dev->nodename,
-+                         "instance","%li", &instance);
-+      if (XENBUS_EXIST_ERR(err)) {
-+              return;
-+      }
-+
-+      if (err != 1) {
-+              xenbus_dev_fatal(dev, err, "reading instance");
-+              return;
-+      }
-+
-+      if (be->is_instance_set == 0) {
-+              be->instance = instance;
-+              be->is_instance_set = 1;
-+      }
-+}
-+
-+
-+static void frontend_changed(struct xenbus_device *dev,
-+                           enum xenbus_state frontend_state)
-+{
-+      struct backend_info *be = dev->dev.driver_data;
-+      int err;
-+
-+      switch (frontend_state) {
-+      case XenbusStateInitialising:
-+      case XenbusStateInitialised:
-+              break;
-+
-+      case XenbusStateConnected:
-+              err = connect_ring(be);
-+              if (err) {
-+                      return;
-+              }
-+              maybe_connect(be);
-+              break;
-+
-+      case XenbusStateClosing:
-+              be->instance = -1;
-+              xenbus_switch_state(dev, XenbusStateClosing);
-+              break;
-+
-+      case XenbusStateUnknown: /* keep it here */
-+      case XenbusStateClosed:
-+              xenbus_switch_state(dev, XenbusStateClosed);
-+              device_unregister(&be->dev->dev);
-+              tpmback_remove(dev);
-+              break;
-+
-+      default:
-+              xenbus_dev_fatal(dev, -EINVAL,
-+                               "saw state %d at frontend",
-+                               frontend_state);
-+              break;
-+      }
-+}
-+
-+
-+
-+static void maybe_connect(struct backend_info *be)
-+{
-+      if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
-+              return;
-+
-+      connect(be);
-+}
-+
-+
-+static void connect(struct backend_info *be)
-+{
-+      struct xenbus_transaction xbt;
-+      int err;
-+      struct xenbus_device *dev = be->dev;
-+      unsigned long ready = 1;
-+
-+again:
-+      err = xenbus_transaction_start(&xbt);
-+      if (err) {
-+              xenbus_dev_fatal(be->dev, err, "starting transaction");
-+              return;
-+      }
-+
-+      err = xenbus_printf(xbt, be->dev->nodename,
-+                          "ready", "%lu", ready);
-+      if (err) {
-+              xenbus_dev_fatal(be->dev, err, "writing 'ready'");
-+              goto abort;
-+      }
-+
-+      err = xenbus_transaction_end(xbt, 0);
-+      if (err == -EAGAIN)
-+              goto again;
-+      if (err)
-+              xenbus_dev_fatal(be->dev, err, "end of transaction");
-+
-+      err = xenbus_switch_state(dev, XenbusStateConnected);
-+      if (!err)
-+              be->tpmif->status = CONNECTED;
-+      return;
-+abort:
-+      xenbus_transaction_end(xbt, 1);
-+}
-+
-+
-+static int connect_ring(struct backend_info *be)
-+{
-+      struct xenbus_device *dev = be->dev;
-+      unsigned long ring_ref;
-+      unsigned int evtchn;
-+      int err;
-+
-+      err = xenbus_gather(XBT_NIL, dev->otherend,
-+                          "ring-ref", "%lu", &ring_ref,
-+                          "event-channel", "%u", &evtchn, NULL);
-+      if (err) {
-+              xenbus_dev_error(dev, err,
-+                               "reading %s/ring-ref and event-channel",
-+                               dev->otherend);
-+              return err;
-+      }
-+
-+      if (!be->tpmif) {
-+              be->tpmif = tpmif_find(dev->otherend_id, be);
-+              if (IS_ERR(be->tpmif)) {
-+                      err = PTR_ERR(be->tpmif);
-+                      be->tpmif = NULL;
-+                      xenbus_dev_fatal(dev,err,"creating vtpm interface");
-+                      return err;
-+              }
-+      }
-+
-+      if (be->tpmif != NULL) {
-+              err = tpmif_map(be->tpmif, ring_ref, evtchn);
-+              if (err) {
-+                      xenbus_dev_error(dev, err,
-+                                       "mapping shared-frame %lu port %u",
-+                                       ring_ref, evtchn);
-+                      return err;
-+              }
-+      }
-+      return 0;
-+}
-+
-+
-+static struct xenbus_device_id tpmback_ids[] = {
-+      { "vtpm" },
-+      { "" }
-+};
-+
-+
-+static struct xenbus_driver tpmback = {
-+      .name = "vtpm",
-+      .owner = THIS_MODULE,
-+      .ids = tpmback_ids,
-+      .probe = tpmback_probe,
-+      .remove = tpmback_remove,
-+      .otherend_changed = frontend_changed,
-+};
-+
-+
-+void tpmif_xenbus_init(void)
-+{
-+      xenbus_register_backend(&tpmback);
-+}
-+
-+void tpmif_xenbus_exit(void)
-+{
-+      xenbus_unregister_driver(&tpmback);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/util.c linux-2.6.16.33/drivers/xen/util.c
---- linux-2.6.16.33-noxen/drivers/xen/util.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/util.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,70 @@
-+#include <linux/config.h>
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <asm/uaccess.h>
-+#include <xen/driver_util.h>
-+
-+static int f(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
-+{
-+      /* apply_to_page_range() does all the hard work. */
-+      return 0;
-+}
-+
-+struct vm_struct *alloc_vm_area(unsigned long size)
-+{
-+      struct vm_struct *area;
-+
-+      area = get_vm_area(size, VM_IOREMAP);
-+      if (area == NULL)
-+              return NULL;
-+
-+      /*
-+       * This ensures that page tables are constructed for this region
-+       * of kernel virtual address space and mapped into init_mm.
-+       */
-+      if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
-+                              area->size, f, NULL)) {
-+              free_vm_area(area);
-+              return NULL;
-+      }
-+
-+      return area;
-+}
-+EXPORT_SYMBOL_GPL(alloc_vm_area);
-+
-+void free_vm_area(struct vm_struct *area)
-+{
-+      struct vm_struct *ret;
-+      ret = remove_vm_area(area->addr);
-+      BUG_ON(ret != area);
-+      kfree(area);
-+}
-+EXPORT_SYMBOL_GPL(free_vm_area);
-+
-+void lock_vm_area(struct vm_struct *area)
-+{
-+      unsigned long i;
-+      char c;
-+
-+      /*
-+       * Prevent context switch to a lazy mm that doesn't have this area
-+       * mapped into its page tables.
-+       */
-+      preempt_disable();
-+
-+      /*
-+       * Ensure that the page tables are mapped into the current mm. The
-+       * page-fault path will copy the page directory pointers from init_mm.
-+       */
-+      for (i = 0; i < area->size; i += PAGE_SIZE)
-+              (void)__get_user(c, (char __user *)area->addr + i);
-+}
-+EXPORT_SYMBOL_GPL(lock_vm_area);
-+
-+void unlock_vm_area(struct vm_struct *area)
-+{
-+      preempt_enable();
-+}
-+EXPORT_SYMBOL_GPL(unlock_vm_area);
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/Makefile linux-2.6.16.33/drivers/xen/xenbus/Makefile
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/Makefile  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/Makefile        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,9 @@
-+obj-y += xenbus_client.o xenbus_comms.o xenbus_xs.o xenbus_probe.o
-+obj-$(CONFIG_XEN_BACKEND) += xenbus_be.o
-+
-+xenbus_be-objs =
-+xenbus_be-objs += xenbus_backend_client.o
-+
-+xenbus-$(CONFIG_XEN_BACKEND) += xenbus_probe_backend.o
-+obj-y += $(xenbus-y) $(xenbus-m)
-+obj-$(CONFIG_XEN_XENBUS_DEV) += xenbus_dev.o
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_backend_client.c linux-2.6.16.33/drivers/xen/xenbus/xenbus_backend_client.c
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_backend_client.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_backend_client.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,147 @@
-+/******************************************************************************
-+ * Backend-client-facing interface for the Xenbus driver.  In other words, the
-+ * interface between the Xenbus and the device-specific code in the backend
-+ * driver.
-+ *
-+ * Copyright (C) 2005-2006 XenSource Ltd
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/err.h>
-+#include <xen/gnttab.h>
-+#include <xen/xenbus.h>
-+#include <xen/driver_util.h>
-+
-+/* Based on Rusty Russell's skeleton driver's map_page */
-+struct vm_struct *xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref)
-+{
-+      struct gnttab_map_grant_ref op;
-+      struct vm_struct *area;
-+
-+      area = alloc_vm_area(PAGE_SIZE);
-+      if (!area)
-+              return ERR_PTR(-ENOMEM);
-+
-+      gnttab_set_map_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
-+                        gnt_ref, dev->otherend_id);
-+      
-+      lock_vm_area(area);
-+      BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
-+      unlock_vm_area(area);
-+
-+      if (op.status != GNTST_okay) {
-+              free_vm_area(area);
-+              xenbus_dev_fatal(dev, op.status,
-+                               "mapping in shared page %d from domain %d",
-+                               gnt_ref, dev->otherend_id);
-+              BUG_ON(!IS_ERR(ERR_PTR(op.status)));
-+              return ERR_PTR(op.status);
-+      }
-+
-+      /* Stuff the handle in an unused field */
-+      area->phys_addr = (unsigned long)op.handle;
-+
-+      return area;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
-+
-+
-+int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
-+                 grant_handle_t *handle, void *vaddr)
-+{
-+      struct gnttab_map_grant_ref op;
-+      
-+      gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
-+                        gnt_ref, dev->otherend_id);
-+      BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
-+
-+      if (op.status != GNTST_okay) {
-+              xenbus_dev_fatal(dev, op.status,
-+                               "mapping in shared page %d from domain %d",
-+                               gnt_ref, dev->otherend_id);
-+      } else
-+              *handle = op.handle;
-+
-+      return op.status;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_map_ring);
-+
-+
-+/* Based on Rusty Russell's skeleton driver's unmap_page */
-+int xenbus_unmap_ring_vfree(struct xenbus_device *dev, struct vm_struct *area)
-+{
-+      struct gnttab_unmap_grant_ref op;
-+
-+      gnttab_set_unmap_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
-+                          (grant_handle_t)area->phys_addr);
-+
-+      lock_vm_area(area);
-+      BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-+      unlock_vm_area(area);
-+
-+      if (op.status == GNTST_okay)
-+              free_vm_area(area);
-+      else
-+              xenbus_dev_error(dev, op.status,
-+                               "unmapping page at handle %d error %d",
-+                               (int16_t)area->phys_addr, op.status);
-+
-+      return op.status;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
-+
-+
-+int xenbus_unmap_ring(struct xenbus_device *dev,
-+                   grant_handle_t handle, void *vaddr)
-+{
-+      struct gnttab_unmap_grant_ref op;
-+
-+      gnttab_set_unmap_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
-+                          handle);
-+      BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-+
-+      if (op.status != GNTST_okay)
-+              xenbus_dev_error(dev, op.status,
-+                               "unmapping page at handle %d error %d",
-+                               handle, op.status);
-+
-+      return op.status;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
-+
-+int xenbus_dev_is_online(struct xenbus_device *dev)
-+{
-+      int rc, val;
-+
-+      rc = xenbus_scanf(XBT_NIL, dev->nodename, "online", "%d", &val);
-+      if (rc != 1)
-+              val = 0; /* no online node present */
-+
-+      return val;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_dev_is_online);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_client.c linux-2.6.16.33/drivers/xen/xenbus/xenbus_client.c
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_client.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_client.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,304 @@
-+/******************************************************************************
-+ * Client-facing interface for the Xenbus driver.  In other words, the
-+ * interface between the Xenbus and the device-specific code, be it the
-+ * frontend or the backend of that driver.
-+ *
-+ * Copyright (C) 2005 XenSource Ltd
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <xen/evtchn.h>
-+#include <xen/gnttab.h>
-+#include <xen/xenbus.h>
-+#include <xen/driver_util.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+#define DPRINTK(fmt, args...) \
-+    pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-+
-+char *xenbus_strstate(enum xenbus_state state)
-+{
-+      static char *name[] = {
-+              [ XenbusStateUnknown      ] = "Unknown",
-+              [ XenbusStateInitialising ] = "Initialising",
-+              [ XenbusStateInitWait     ] = "InitWait",
-+              [ XenbusStateInitialised  ] = "Initialised",
-+              [ XenbusStateConnected    ] = "Connected",
-+              [ XenbusStateClosing      ] = "Closing",
-+              [ XenbusStateClosed       ] = "Closed",
-+      };
-+      return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
-+}
-+
-+int xenbus_watch_path(struct xenbus_device *dev, const char *path,
-+                    struct xenbus_watch *watch,
-+                    void (*callback)(struct xenbus_watch *,
-+                                     const char **, unsigned int))
-+{
-+      int err;
-+
-+      watch->node = path;
-+      watch->callback = callback;
-+
-+      err = register_xenbus_watch(watch);
-+
-+      if (err) {
-+              watch->node = NULL;
-+              watch->callback = NULL;
-+              xenbus_dev_fatal(dev, err, "adding watch on %s", path);
-+      }
-+
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_watch_path);
-+
-+
-+int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
-+                     const char *path2, struct xenbus_watch *watch,
-+                     void (*callback)(struct xenbus_watch *,
-+                                      const char **, unsigned int))
-+{
-+      int err;
-+      char *state = kasprintf(GFP_KERNEL, "%s/%s", path, path2);
-+      if (!state) {
-+              xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
-+              return -ENOMEM;
-+      }
-+      err = xenbus_watch_path(dev, state, watch, callback);
-+
-+      if (err)
-+              kfree(state);
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_watch_path2);
-+
-+
-+int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
-+{
-+      /* We check whether the state is currently set to the given value, and
-+         if not, then the state is set.  We don't want to unconditionally
-+         write the given state, because we don't want to fire watches
-+         unnecessarily.  Furthermore, if the node has gone, we don't write
-+         to it, as the device will be tearing down, and we don't want to
-+         resurrect that directory.
-+
-+         Note that, because of this cached value of our state, this function
-+         will not work inside a Xenstore transaction (something it was
-+         trying to in the past) because dev->state would not get reset if
-+         the transaction was aborted.
-+
-+       */
-+
-+      int current_state;
-+      int err;
-+
-+      if (state == dev->state)
-+              return 0;
-+
-+      err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
-+                         &current_state);
-+      if (err != 1)
-+              return 0;
-+
-+      err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
-+      if (err) {
-+              if (state != XenbusStateClosing) /* Avoid looping */
-+                      xenbus_dev_fatal(dev, err, "writing new state");
-+              return err;
-+      }
-+
-+      dev->state = state;
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_switch_state);
-+
-+int xenbus_frontend_closed(struct xenbus_device *dev)
-+{
-+      xenbus_switch_state(dev, XenbusStateClosed);
-+      complete(&dev->down);
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_frontend_closed);
-+
-+/**
-+ * Return the path to the error node for the given device, or NULL on failure.
-+ * If the value returned is non-NULL, then it is the caller's to kfree.
-+ */
-+static char *error_path(struct xenbus_device *dev)
-+{
-+      return kasprintf(GFP_KERNEL, "error/%s", dev->nodename);
-+}
-+
-+
-+void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
-+              va_list ap)
-+{
-+      int ret;
-+      unsigned int len;
-+      char *printf_buffer = NULL, *path_buffer = NULL;
-+
-+#define PRINTF_BUFFER_SIZE 4096
-+      printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
-+      if (printf_buffer == NULL)
-+              goto fail;
-+
-+      len = sprintf(printf_buffer, "%i ", -err);
-+      ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
-+
-+      BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
-+
-+      dev_err(&dev->dev, "%s\n", printf_buffer);
-+
-+      path_buffer = error_path(dev);
-+
-+      if (path_buffer == NULL) {
-+              printk("xenbus: failed to write error node for %s (%s)\n",
-+                     dev->nodename, printf_buffer);
-+              goto fail;
-+      }
-+
-+      if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
-+              printk("xenbus: failed to write error node for %s (%s)\n",
-+                     dev->nodename, printf_buffer);
-+              goto fail;
-+      }
-+
-+fail:
-+      if (printf_buffer)
-+              kfree(printf_buffer);
-+      if (path_buffer)
-+              kfree(path_buffer);
-+}
-+
-+
-+void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
-+                    ...)
-+{
-+      va_list ap;
-+
-+      va_start(ap, fmt);
-+      _dev_error(dev, err, fmt, ap);
-+      va_end(ap);
-+}
-+EXPORT_SYMBOL_GPL(xenbus_dev_error);
-+
-+
-+void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
-+                    ...)
-+{
-+      va_list ap;
-+
-+      va_start(ap, fmt);
-+      _dev_error(dev, err, fmt, ap);
-+      va_end(ap);
-+
-+      xenbus_switch_state(dev, XenbusStateClosing);
-+}
-+EXPORT_SYMBOL_GPL(xenbus_dev_fatal);
-+
-+
-+int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn)
-+{
-+      int err = gnttab_grant_foreign_access(dev->otherend_id, ring_mfn, 0);
-+      if (err < 0)
-+              xenbus_dev_fatal(dev, err, "granting access to ring page");
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_grant_ring);
-+
-+
-+int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
-+{
-+      struct evtchn_alloc_unbound alloc_unbound;
-+      int err;
-+
-+      alloc_unbound.dom        = DOMID_SELF;
-+      alloc_unbound.remote_dom = dev->otherend_id;
-+
-+      err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
-+                                        &alloc_unbound);
-+      if (err)
-+              xenbus_dev_fatal(dev, err, "allocating event channel");
-+      else
-+              *port = alloc_unbound.port;
-+
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
-+
-+
-+int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
-+{
-+      struct evtchn_bind_interdomain bind_interdomain;
-+      int err;
-+
-+      bind_interdomain.remote_dom  = dev->otherend_id;
-+      bind_interdomain.remote_port = remote_port,
-+
-+      err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-+                                        &bind_interdomain);
-+      if (err)
-+              xenbus_dev_fatal(dev, err,
-+                               "binding to event channel %d from domain %d",
-+                               remote_port, dev->otherend_id);
-+      else
-+              *port = bind_interdomain.local_port;
-+
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
-+
-+
-+int xenbus_free_evtchn(struct xenbus_device *dev, int port)
-+{
-+      struct evtchn_close close;
-+      int err;
-+
-+      close.port = port;
-+
-+      err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
-+      if (err)
-+              xenbus_dev_error(dev, err, "freeing event channel %d", port);
-+
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
-+
-+
-+enum xenbus_state xenbus_read_driver_state(const char *path)
-+{
-+      enum xenbus_state result;
-+      int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
-+      if (err)
-+              result = XenbusStateUnknown;
-+
-+      return result;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_read_driver_state);
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_comms.c linux-2.6.16.33/drivers/xen/xenbus/xenbus_comms.c
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_comms.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_comms.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,210 @@
-+/******************************************************************************
-+ * xenbus_comms.c
-+ *
-+ * Low level code to talks to Xen Store: ringbuffer and event channel.
-+ *
-+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/wait.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/err.h>
-+#include <linux/ptrace.h>
-+#include <xen/evtchn.h>
-+#include <xen/xenbus.h>
-+
-+#include <asm/hypervisor.h>
-+
-+#include "xenbus_comms.h"
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+static int xenbus_irq;
-+
-+extern void xenbus_probe(void *);
-+extern int xenstored_ready;
-+static DECLARE_WORK(probe_work, xenbus_probe, NULL);
-+
-+static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
-+
-+static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
-+{
-+      if (unlikely(xenstored_ready == 0)) {
-+              xenstored_ready = 1;
-+              schedule_work(&probe_work);
-+      }
-+
-+      wake_up(&xb_waitq);
-+      return IRQ_HANDLED;
-+}
-+
-+static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
-+{
-+      return ((prod - cons) <= XENSTORE_RING_SIZE);
-+}
-+
-+static void *get_output_chunk(XENSTORE_RING_IDX cons,
-+                            XENSTORE_RING_IDX prod,
-+                            char *buf, uint32_t *len)
-+{
-+      *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
-+      if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
-+              *len = XENSTORE_RING_SIZE - (prod - cons);
-+      return buf + MASK_XENSTORE_IDX(prod);
-+}
-+
-+static const void *get_input_chunk(XENSTORE_RING_IDX cons,
-+                                 XENSTORE_RING_IDX prod,
-+                                 const char *buf, uint32_t *len)
-+{
-+      *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
-+      if ((prod - cons) < *len)
-+              *len = prod - cons;
-+      return buf + MASK_XENSTORE_IDX(cons);
-+}
-+
-+int xb_write(const void *data, unsigned len)
-+{
-+      struct xenstore_domain_interface *intf = xen_store_interface;
-+      XENSTORE_RING_IDX cons, prod;
-+      int rc;
-+
-+      while (len != 0) {
-+              void *dst;
-+              unsigned int avail;
-+
-+              rc = wait_event_interruptible(
-+                      xb_waitq,
-+                      (intf->req_prod - intf->req_cons) !=
-+                      XENSTORE_RING_SIZE);
-+              if (rc < 0)
-+                      return rc;
-+
-+              /* Read indexes, then verify. */
-+              cons = intf->req_cons;
-+              prod = intf->req_prod;
-+              mb();
-+              if (!check_indexes(cons, prod)) {
-+                      intf->req_cons = intf->req_prod = 0;
-+                      return -EIO;
-+              }
-+
-+              dst = get_output_chunk(cons, prod, intf->req, &avail);
-+              if (avail == 0)
-+                      continue;
-+              if (avail > len)
-+                      avail = len;
-+
-+              memcpy(dst, data, avail);
-+              data += avail;
-+              len -= avail;
-+
-+              /* Other side must not see new header until data is there. */
-+              wmb();
-+              intf->req_prod += avail;
-+
-+              /* This implies mb() before other side sees interrupt. */
-+              notify_remote_via_evtchn(xen_store_evtchn);
-+      }
-+
-+      return 0;
-+}
-+
-+int xb_read(void *data, unsigned len)
-+{
-+      struct xenstore_domain_interface *intf = xen_store_interface;
-+      XENSTORE_RING_IDX cons, prod;
-+      int rc;
-+
-+      while (len != 0) {
-+              unsigned int avail;
-+              const char *src;
-+
-+              rc = wait_event_interruptible(
-+                      xb_waitq,
-+                      intf->rsp_cons != intf->rsp_prod);
-+              if (rc < 0)
-+                      return rc;
-+
-+              /* Read indexes, then verify. */
-+              cons = intf->rsp_cons;
-+              prod = intf->rsp_prod;
-+              mb();
-+              if (!check_indexes(cons, prod)) {
-+                      intf->rsp_cons = intf->rsp_prod = 0;
-+                      return -EIO;
-+              }
-+
-+              src = get_input_chunk(cons, prod, intf->rsp, &avail);
-+              if (avail == 0)
-+                      continue;
-+              if (avail > len)
-+                      avail = len;
-+
-+              /* We must read header before we read data. */
-+              rmb();
-+
-+              memcpy(data, src, avail);
-+              data += avail;
-+              len -= avail;
-+
-+              /* Other side must not see free space until we've copied out */
-+              mb();
-+              intf->rsp_cons += avail;
-+
-+              pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
-+
-+              /* Implies mb(): they will see new header. */
-+              notify_remote_via_evtchn(xen_store_evtchn);
-+      }
-+
-+      return 0;
-+}
-+
-+/* Set up interrupt handler off store event channel. */
-+int xb_init_comms(void)
-+{
-+      int err;
-+
-+      if (xenbus_irq)
-+              unbind_from_irqhandler(xenbus_irq, &xb_waitq);
-+
-+      err = bind_evtchn_to_irqhandler(
-+              xen_store_evtchn, wake_waiting,
-+              0, "xenbus", &xb_waitq);
-+      if (err <= 0) {
-+              printk(KERN_ERR "XENBUS request irq failed %i\n", err);
-+              return err;
-+      }
-+
-+      xenbus_irq = err;
-+
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_comms.h linux-2.6.16.33/drivers/xen/xenbus/xenbus_comms.h
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_comms.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_comms.h  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,44 @@
-+/*
-+ * Private include for xenbus communications.
-+ * 
-+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef _XENBUS_COMMS_H
-+#define _XENBUS_COMMS_H
-+
-+int xs_init(void);
-+int xb_init_comms(void);
-+
-+/* Low level routines. */
-+int xb_write(const void *data, unsigned len);
-+int xb_read(void *data, unsigned len);
-+int xs_input_avail(void);
-+extern struct xenstore_domain_interface *xen_store_interface;
-+extern int xen_store_evtchn;
-+
-+#endif /* _XENBUS_COMMS_H */
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_dev.c linux-2.6.16.33/drivers/xen/xenbus/xenbus_dev.c
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_dev.c      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_dev.c    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,362 @@
-+/*
-+ * xenbus_dev.c
-+ * 
-+ * Driver giving user-space access to the kernel's xenbus connection
-+ * to xenstore.
-+ * 
-+ * Copyright (c) 2005, Christian Limpach
-+ * Copyright (c) 2005, Rusty Russell, IBM Corporation
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/uio.h>
-+#include <linux/notifier.h>
-+#include <linux/wait.h>
-+#include <linux/fs.h>
-+#include <linux/poll.h>
-+#include <linux/mutex.h>
-+
-+#include "xenbus_comms.h"
-+
-+#include <asm/uaccess.h>
-+#include <asm/hypervisor.h>
-+#include <xen/xenbus.h>
-+#include <xen/xen_proc.h>
-+#include <asm/hypervisor.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+struct xenbus_dev_transaction {
-+      struct list_head list;
-+      struct xenbus_transaction handle;
-+};
-+
-+struct xenbus_dev_data {
-+      /* In-progress transaction. */
-+      struct list_head transactions;
-+
-+      /* Active watches. */
-+      struct list_head watches;
-+
-+      /* Partial request. */
-+      unsigned int len;
-+      union {
-+              struct xsd_sockmsg msg;
-+              char buffer[PAGE_SIZE];
-+      } u;
-+
-+      /* Response queue. */
-+#define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1))
-+      char read_buffer[PAGE_SIZE];
-+      unsigned int read_cons, read_prod;
-+      wait_queue_head_t read_waitq;
-+
-+      struct mutex reply_mutex;
-+};
-+
-+static struct proc_dir_entry *xenbus_dev_intf;
-+
-+static ssize_t xenbus_dev_read(struct file *filp,
-+                             char __user *ubuf,
-+                             size_t len, loff_t *ppos)
-+{
-+      struct xenbus_dev_data *u = filp->private_data;
-+      int i;
-+
-+      if (wait_event_interruptible(u->read_waitq,
-+                                   u->read_prod != u->read_cons))
-+              return -EINTR;
-+
-+      for (i = 0; i < len; i++) {
-+              if (u->read_cons == u->read_prod)
-+                      break;
-+              put_user(u->read_buffer[MASK_READ_IDX(u->read_cons)], ubuf+i);
-+              u->read_cons++;
-+      }
-+
-+      return i;
-+}
-+
-+static void queue_reply(struct xenbus_dev_data *u,
-+                      char *data, unsigned int len)
-+{
-+      int i;
-+
-+      mutex_lock(&u->reply_mutex);
-+
-+      for (i = 0; i < len; i++, u->read_prod++)
-+              u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i];
-+
-+      BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer));
-+
-+      mutex_unlock(&u->reply_mutex);
-+
-+      wake_up(&u->read_waitq);
-+}
-+
-+struct watch_adapter
-+{
-+      struct list_head list;
-+      struct xenbus_watch watch;
-+      struct xenbus_dev_data *dev_data;
-+      char *token;
-+};
-+
-+static void free_watch_adapter (struct watch_adapter *watch)
-+{
-+      kfree(watch->watch.node);
-+      kfree(watch->token);
-+      kfree(watch);
-+}
-+
-+static void watch_fired(struct xenbus_watch *watch,
-+                      const char **vec,
-+                      unsigned int len)
-+{
-+      struct watch_adapter *adap =
-+            container_of(watch, struct watch_adapter, watch);
-+      struct xsd_sockmsg hdr;
-+      const char *path, *token;
-+      int path_len, tok_len, body_len;
-+
-+      path = vec[XS_WATCH_PATH];
-+      token = adap->token;
-+
-+      path_len = strlen(path) + 1;
-+      tok_len = strlen(token) + 1;
-+      body_len = path_len + tok_len;
-+
-+      hdr.type = XS_WATCH_EVENT;
-+      hdr.len = body_len;
-+      
-+      queue_reply(adap->dev_data, (char *)&hdr, sizeof(hdr));
-+      queue_reply(adap->dev_data, (char *)path, path_len);
-+      queue_reply(adap->dev_data, (char *)token, tok_len);
-+}
-+
-+static LIST_HEAD(watch_list);
-+
-+static ssize_t xenbus_dev_write(struct file *filp,
-+                              const char __user *ubuf,
-+                              size_t len, loff_t *ppos)
-+{
-+      struct xenbus_dev_data *u = filp->private_data;
-+      struct xenbus_dev_transaction *trans = NULL;
-+      uint32_t msg_type;
-+      void *reply;
-+      char *path, *token;
-+      struct watch_adapter *watch, *tmp_watch;
-+      int err;
-+
-+      if ((len + u->len) > sizeof(u->u.buffer))
-+              return -EINVAL;
-+
-+      if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0)
-+              return -EFAULT;
-+
-+      u->len += len;
-+      if (u->len < (sizeof(u->u.msg) + u->u.msg.len))
-+              return len;
-+
-+      msg_type = u->u.msg.type;
-+
-+      switch (msg_type) {
-+      case XS_TRANSACTION_START:
-+      case XS_TRANSACTION_END:
-+      case XS_DIRECTORY:
-+      case XS_READ:
-+      case XS_GET_PERMS:
-+      case XS_RELEASE:
-+      case XS_GET_DOMAIN_PATH:
-+      case XS_WRITE:
-+      case XS_MKDIR:
-+      case XS_RM:
-+      case XS_SET_PERMS:
-+              if (msg_type == XS_TRANSACTION_START) {
-+                      trans = kmalloc(sizeof(*trans), GFP_KERNEL);
-+                      if (!trans)
-+                              return -ENOMEM;
-+              }
-+
-+              reply = xenbus_dev_request_and_reply(&u->u.msg);
-+              if (IS_ERR(reply)) {
-+                      kfree(trans);
-+                      return PTR_ERR(reply);
-+              }
-+
-+              if (msg_type == XS_TRANSACTION_START) {
-+                      trans->handle.id = simple_strtoul(reply, NULL, 0);
-+                      list_add(&trans->list, &u->transactions);
-+              } else if (msg_type == XS_TRANSACTION_END) {
-+                      list_for_each_entry(trans, &u->transactions, list)
-+                              if (trans->handle.id == u->u.msg.tx_id)
-+                                      break;
-+                      BUG_ON(&trans->list == &u->transactions);
-+                      list_del(&trans->list);
-+                      kfree(trans);
-+              }
-+              queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
-+              queue_reply(u, (char *)reply, u->u.msg.len);
-+              kfree(reply);
-+              break;
-+
-+      case XS_WATCH:
-+      case XS_UNWATCH:
-+              path = u->u.buffer + sizeof(u->u.msg);
-+              token = memchr(path, 0, u->u.msg.len);
-+              if (token == NULL)
-+                      return -EILSEQ;
-+              token++;
-+
-+              if (msg_type == XS_WATCH) {
-+                      static const char * XS_WATCH_RESP = "OK";
-+                      struct xsd_sockmsg hdr;
-+
-+                      watch = kmalloc(sizeof(*watch), GFP_KERNEL);
-+                      watch->watch.node = kmalloc(strlen(path)+1,
-+                                                    GFP_KERNEL);
-+                      strcpy((char *)watch->watch.node, path);
-+                      watch->watch.callback = watch_fired;
-+                      watch->token = kmalloc(strlen(token)+1, GFP_KERNEL);
-+                      strcpy(watch->token, token);
-+                      watch->dev_data = u;
-+
-+                      err = register_xenbus_watch(&watch->watch);
-+                      if (err) {
-+                              free_watch_adapter(watch);
-+                              return err;
-+                      }
-+                      
-+                      list_add(&watch->list, &u->watches);
-+
-+                      hdr.type = XS_WATCH;
-+                      hdr.len = strlen(XS_WATCH_RESP) + 1;
-+                      queue_reply(u, (char *)&hdr, sizeof(hdr));
-+                      queue_reply(u, (char *)XS_WATCH_RESP, hdr.len);
-+              } else {
-+                      list_for_each_entry_safe(watch, tmp_watch,
-+                                                 &u->watches, list) {
-+                              if (!strcmp(watch->token, token) &&
-+                                  !strcmp(watch->watch.node, path))
-+                                      break;
-+                              {
-+                                      unregister_xenbus_watch(&watch->watch);
-+                                      list_del(&watch->list);
-+                                      free_watch_adapter(watch);
-+                                      break;
-+                              }
-+                      }
-+              }
-+
-+              break;
-+
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      u->len = 0;
-+      return len;
-+}
-+
-+static int xenbus_dev_open(struct inode *inode, struct file *filp)
-+{
-+      struct xenbus_dev_data *u;
-+
-+      if (xen_store_evtchn == 0)
-+              return -ENOENT;
-+
-+      nonseekable_open(inode, filp);
-+
-+      u = kzalloc(sizeof(*u), GFP_KERNEL);
-+      if (u == NULL)
-+              return -ENOMEM;
-+
-+      INIT_LIST_HEAD(&u->transactions);
-+      INIT_LIST_HEAD(&u->watches);
-+      init_waitqueue_head(&u->read_waitq);
-+
-+      mutex_init(&u->reply_mutex);
-+
-+      filp->private_data = u;
-+
-+      return 0;
-+}
-+
-+static int xenbus_dev_release(struct inode *inode, struct file *filp)
-+{
-+      struct xenbus_dev_data *u = filp->private_data;
-+      struct xenbus_dev_transaction *trans, *tmp;
-+      struct watch_adapter *watch, *tmp_watch;
-+
-+      list_for_each_entry_safe(trans, tmp, &u->transactions, list) {
-+              xenbus_transaction_end(trans->handle, 1);
-+              list_del(&trans->list);
-+              kfree(trans);
-+      }
-+
-+      list_for_each_entry_safe(watch, tmp_watch, &u->watches, list) {
-+              unregister_xenbus_watch(&watch->watch);
-+              list_del(&watch->list);
-+              free_watch_adapter(watch);
-+      }
-+
-+      kfree(u);
-+
-+      return 0;
-+}
-+
-+static unsigned int xenbus_dev_poll(struct file *file, poll_table *wait)
-+{
-+      struct xenbus_dev_data *u = file->private_data;
-+
-+      poll_wait(file, &u->read_waitq, wait);
-+      if (u->read_cons != u->read_prod)
-+              return POLLIN | POLLRDNORM;
-+      return 0;
-+}
-+
-+static struct file_operations xenbus_dev_file_ops = {
-+      .read = xenbus_dev_read,
-+      .write = xenbus_dev_write,
-+      .open = xenbus_dev_open,
-+      .release = xenbus_dev_release,
-+      .poll = xenbus_dev_poll,
-+};
-+
-+int __init
-+xenbus_dev_init(void)
-+{
-+      xenbus_dev_intf = create_xen_proc_entry("xenbus", 0400);
-+      if (xenbus_dev_intf)
-+              xenbus_dev_intf->proc_fops = &xenbus_dev_file_ops;
-+
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_probe.c linux-2.6.16.33/drivers/xen/xenbus/xenbus_probe.c
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_probe.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_probe.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,1017 @@
-+/******************************************************************************
-+ * Talks to Xen Store to figure out what devices we have.
-+ *
-+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
-+ * Copyright (C) 2005 Mike Wray, Hewlett-Packard
-+ * Copyright (C) 2005, 2006 XenSource Ltd
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#define DPRINTK(fmt, args...)                         \
-+      pr_debug("xenbus_probe (%s:%d) " fmt ".\n",     \
-+               __FUNCTION__, __LINE__, ##args)
-+
-+#include <linux/kernel.h>
-+#include <linux/err.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/fcntl.h>
-+#include <linux/mm.h>
-+#include <linux/notifier.h>
-+#include <linux/kthread.h>
-+#include <linux/mutex.h>
-+
-+#include <asm/io.h>
-+#include <asm/page.h>
-+#include <asm/maddr.h>
-+#include <asm/pgtable.h>
-+#include <asm/hypervisor.h>
-+#include <xen/xenbus.h>
-+#include <xen/xen_proc.h>
-+#include <xen/evtchn.h>
-+#include <xen/features.h>
-+#include <xen/hvm.h>
-+
-+#include "xenbus_comms.h"
-+#include "xenbus_probe.h"
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+int xen_store_evtchn;
-+struct xenstore_domain_interface *xen_store_interface;
-+static unsigned long xen_store_mfn;
-+
-+extern struct mutex xenwatch_mutex;
-+
-+static struct notifier_block *xenstore_chain;
-+
-+static void wait_for_devices(struct xenbus_driver *xendrv);
-+
-+static int xenbus_probe_frontend(const char *type, const char *name);
-+
-+static void xenbus_dev_shutdown(struct device *_dev);
-+
-+/* If something in array of ids matches this device, return it. */
-+static const struct xenbus_device_id *
-+match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
-+{
-+      for (; *arr->devicetype != '\0'; arr++) {
-+              if (!strcmp(arr->devicetype, dev->devicetype))
-+                      return arr;
-+      }
-+      return NULL;
-+}
-+
-+int xenbus_match(struct device *_dev, struct device_driver *_drv)
-+{
-+      struct xenbus_driver *drv = to_xenbus_driver(_drv);
-+
-+      if (!drv->ids)
-+              return 0;
-+
-+      return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
-+}
-+
-+/* device/<type>/<id> => <type>-<id> */
-+static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
-+{
-+      nodename = strchr(nodename, '/');
-+      if (!nodename || strlen(nodename + 1) >= BUS_ID_SIZE) {
-+              printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename);
-+              return -EINVAL;
-+      }
-+
-+      strlcpy(bus_id, nodename + 1, BUS_ID_SIZE);
-+      if (!strchr(bus_id, '/')) {
-+              printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id);
-+              return -EINVAL;
-+      }
-+      *strchr(bus_id, '/') = '-';
-+      return 0;
-+}
-+
-+
-+static void free_otherend_details(struct xenbus_device *dev)
-+{
-+      kfree(dev->otherend);
-+      dev->otherend = NULL;
-+}
-+
-+
-+static void free_otherend_watch(struct xenbus_device *dev)
-+{
-+      if (dev->otherend_watch.node) {
-+              unregister_xenbus_watch(&dev->otherend_watch);
-+              kfree(dev->otherend_watch.node);
-+              dev->otherend_watch.node = NULL;
-+      }
-+}
-+
-+
-+int read_otherend_details(struct xenbus_device *xendev,
-+                               char *id_node, char *path_node)
-+{
-+      int err = xenbus_gather(XBT_NIL, xendev->nodename,
-+                              id_node, "%i", &xendev->otherend_id,
-+                              path_node, NULL, &xendev->otherend,
-+                              NULL);
-+      if (err) {
-+              xenbus_dev_fatal(xendev, err,
-+                               "reading other end details from %s",
-+                               xendev->nodename);
-+              return err;
-+      }
-+      if (strlen(xendev->otherend) == 0 ||
-+          !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
-+              xenbus_dev_fatal(xendev, -ENOENT,
-+                               "unable to read other end from %s.  "
-+                               "missing or inaccessible.",
-+                               xendev->nodename);
-+              free_otherend_details(xendev);
-+              return -ENOENT;
-+      }
-+
-+      return 0;
-+}
-+
-+
-+static int read_backend_details(struct xenbus_device *xendev)
-+{
-+      return read_otherend_details(xendev, "backend-id", "backend");
-+}
-+
-+
-+/* Bus type for frontend drivers. */
-+static struct xen_bus_type xenbus_frontend = {
-+      .root = "device",
-+      .levels = 2,            /* device/type/<id> */
-+      .get_bus_id = frontend_bus_id,
-+      .probe = xenbus_probe_frontend,
-+      .bus = {
-+              .name     = "xen",
-+              .match    = xenbus_match,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-+              .probe    = xenbus_dev_probe,
-+              .remove   = xenbus_dev_remove,
-+              .shutdown = xenbus_dev_shutdown,
-+#endif
-+      },
-+      .dev = {
-+              .bus_id = "xen",
-+      },
-+};
-+
-+static void otherend_changed(struct xenbus_watch *watch,
-+                           const char **vec, unsigned int len)
-+{
-+      struct xenbus_device *dev =
-+              container_of(watch, struct xenbus_device, otherend_watch);
-+      struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
-+      enum xenbus_state state;
-+
-+      /* Protect us against watches firing on old details when the otherend
-+         details change, say immediately after a resume. */
-+      if (!dev->otherend ||
-+          strncmp(dev->otherend, vec[XS_WATCH_PATH],
-+                  strlen(dev->otherend))) {
-+              DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
-+              return;
-+      }
-+
-+      state = xenbus_read_driver_state(dev->otherend);
-+
-+      DPRINTK("state is %d (%s), %s, %s", state, xenbus_strstate(state),
-+              dev->otherend_watch.node, vec[XS_WATCH_PATH]);
-+
-+      /*
-+       * Ignore xenbus transitions during shutdown. This prevents us doing
-+       * work that can fail e.g., when the rootfs is gone.
-+       */
-+      if (system_state > SYSTEM_RUNNING) {
-+              struct xen_bus_type *bus = bus;
-+              bus = container_of(dev->dev.bus, struct xen_bus_type, bus);
-+              /* If we're frontend, drive the state machine to Closed. */
-+              /* This should cause the backend to release our resources. */
-+              if ((bus == &xenbus_frontend) && (state == XenbusStateClosing))
-+                      xenbus_frontend_closed(dev);
-+              return;
-+      }
-+
-+      if (drv->otherend_changed)
-+              drv->otherend_changed(dev, state);
-+}
-+
-+
-+static int talk_to_otherend(struct xenbus_device *dev)
-+{
-+      struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
-+
-+      free_otherend_watch(dev);
-+      free_otherend_details(dev);
-+
-+      return drv->read_otherend_details(dev);
-+}
-+
-+
-+static int watch_otherend(struct xenbus_device *dev)
-+{
-+      return xenbus_watch_path2(dev, dev->otherend, "state",
-+                                &dev->otherend_watch, otherend_changed);
-+}
-+
-+
-+int xenbus_dev_probe(struct device *_dev)
-+{
-+      struct xenbus_device *dev = to_xenbus_device(_dev);
-+      struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
-+      const struct xenbus_device_id *id;
-+      int err;
-+
-+      DPRINTK("%s", dev->nodename);
-+
-+      if (!drv->probe) {
-+              err = -ENODEV;
-+              goto fail;
-+      }
-+
-+      id = match_device(drv->ids, dev);
-+      if (!id) {
-+              err = -ENODEV;
-+              goto fail;
-+      }
-+
-+      err = talk_to_otherend(dev);
-+      if (err) {
-+              printk(KERN_WARNING
-+                     "xenbus_probe: talk_to_otherend on %s failed.\n",
-+                     dev->nodename);
-+              return err;
-+      }
-+
-+      err = drv->probe(dev, id);
-+      if (err)
-+              goto fail;
-+
-+      err = watch_otherend(dev);
-+      if (err) {
-+              printk(KERN_WARNING
-+                     "xenbus_probe: watch_otherend on %s failed.\n",
-+                     dev->nodename);
-+              return err;
-+      }
-+
-+      return 0;
-+fail:
-+      xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
-+      xenbus_switch_state(dev, XenbusStateClosed);
-+      return -ENODEV;
-+}
-+
-+int xenbus_dev_remove(struct device *_dev)
-+{
-+      struct xenbus_device *dev = to_xenbus_device(_dev);
-+      struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
-+
-+      DPRINTK("%s", dev->nodename);
-+
-+      free_otherend_watch(dev);
-+      free_otherend_details(dev);
-+
-+      if (drv->remove)
-+              drv->remove(dev);
-+
-+      xenbus_switch_state(dev, XenbusStateClosed);
-+      return 0;
-+}
-+
-+static void xenbus_dev_shutdown(struct device *_dev)
-+{
-+      struct xenbus_device *dev = to_xenbus_device(_dev);
-+      unsigned long timeout = 5*HZ;
-+
-+      DPRINTK("%s", dev->nodename);
-+
-+      get_device(&dev->dev);
-+      if (dev->state != XenbusStateConnected) {
-+              printk("%s: %s: %s != Connected, skipping\n", __FUNCTION__,
-+                     dev->nodename, xenbus_strstate(dev->state));
-+              goto out;
-+      }
-+      xenbus_switch_state(dev, XenbusStateClosing);
-+      timeout = wait_for_completion_timeout(&dev->down, timeout);
-+      if (!timeout)
-+              printk("%s: %s timeout closing device\n", __FUNCTION__, dev->nodename);
-+ out:
-+      put_device(&dev->dev);
-+}
-+
-+int xenbus_register_driver_common(struct xenbus_driver *drv,
-+                                struct xen_bus_type *bus)
-+{
-+      int ret;
-+
-+      drv->driver.name = drv->name;
-+      drv->driver.bus = &bus->bus;
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
-+      drv->driver.owner = drv->owner;
-+#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
-+      drv->driver.probe = xenbus_dev_probe;
-+      drv->driver.remove = xenbus_dev_remove;
-+      drv->driver.shutdown = xenbus_dev_shutdown;
-+#endif
-+
-+      mutex_lock(&xenwatch_mutex);
-+      ret = driver_register(&drv->driver);
-+      mutex_unlock(&xenwatch_mutex);
-+      return ret;
-+}
-+
-+int xenbus_register_frontend(struct xenbus_driver *drv)
-+{
-+      int ret;
-+
-+      drv->read_otherend_details = read_backend_details;
-+
-+      ret = xenbus_register_driver_common(drv, &xenbus_frontend);
-+      if (ret)
-+              return ret;
-+
-+      /* If this driver is loaded as a module wait for devices to attach. */
-+      wait_for_devices(drv);
-+
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_register_frontend);
-+
-+void xenbus_unregister_driver(struct xenbus_driver *drv)
-+{
-+      driver_unregister(&drv->driver);
-+}
-+EXPORT_SYMBOL_GPL(xenbus_unregister_driver);
-+
-+struct xb_find_info
-+{
-+      struct xenbus_device *dev;
-+      const char *nodename;
-+};
-+
-+static int cmp_dev(struct device *dev, void *data)
-+{
-+      struct xenbus_device *xendev = to_xenbus_device(dev);
-+      struct xb_find_info *info = data;
-+
-+      if (!strcmp(xendev->nodename, info->nodename)) {
-+              info->dev = xendev;
-+              get_device(dev);
-+              return 1;
-+      }
-+      return 0;
-+}
-+
-+struct xenbus_device *xenbus_device_find(const char *nodename,
-+                                       struct bus_type *bus)
-+{
-+      struct xb_find_info info = { .dev = NULL, .nodename = nodename };
-+
-+      bus_for_each_dev(bus, NULL, &info, cmp_dev);
-+      return info.dev;
-+}
-+
-+static int cleanup_dev(struct device *dev, void *data)
-+{
-+      struct xenbus_device *xendev = to_xenbus_device(dev);
-+      struct xb_find_info *info = data;
-+      int len = strlen(info->nodename);
-+
-+      DPRINTK("%s", info->nodename);
-+
-+      /* Match the info->nodename path, or any subdirectory of that path. */
-+      if (strncmp(xendev->nodename, info->nodename, len))
-+              return 0;
-+
-+      /* If the node name is longer, ensure it really is a subdirectory. */
-+      if ((strlen(xendev->nodename) > len) && (xendev->nodename[len] != '/'))
-+              return 0;
-+
-+      info->dev = xendev;
-+      get_device(dev);
-+      return 1;
-+}
-+
-+static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
-+{
-+      struct xb_find_info info = { .nodename = path };
-+
-+      do {
-+              info.dev = NULL;
-+              bus_for_each_dev(bus, NULL, &info, cleanup_dev);
-+              if (info.dev) {
-+                      device_unregister(&info.dev->dev);
-+                      put_device(&info.dev->dev);
-+              }
-+      } while (info.dev);
-+}
-+
-+static void xenbus_dev_release(struct device *dev)
-+{
-+      if (dev)
-+              kfree(to_xenbus_device(dev));
-+}
-+
-+static ssize_t xendev_show_nodename(struct device *dev,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
-+                                  struct device_attribute *attr,
-+#endif
-+                                  char *buf)
-+{
-+      return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
-+}
-+DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
-+
-+static ssize_t xendev_show_devtype(struct device *dev,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
-+                                 struct device_attribute *attr,
-+#endif
-+                                 char *buf)
-+{
-+      return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
-+}
-+DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
-+
-+
-+int xenbus_probe_node(struct xen_bus_type *bus,
-+                    const char *type,
-+                    const char *nodename)
-+{
-+      int err;
-+      struct xenbus_device *xendev;
-+      size_t stringlen;
-+      char *tmpstring;
-+
-+      enum xenbus_state state = xenbus_read_driver_state(nodename);
-+
-+      if (state != XenbusStateInitialising) {
-+              /* Device is not new, so ignore it.  This can happen if a
-+                 device is going away after switching to Closed.  */
-+              return 0;
-+      }
-+
-+      stringlen = strlen(nodename) + 1 + strlen(type) + 1;
-+      xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
-+      if (!xendev)
-+              return -ENOMEM;
-+
-+      xendev->state = XenbusStateInitialising;
-+
-+      /* Copy the strings into the extra space. */
-+
-+      tmpstring = (char *)(xendev + 1);
-+      strcpy(tmpstring, nodename);
-+      xendev->nodename = tmpstring;
-+
-+      tmpstring += strlen(tmpstring) + 1;
-+      strcpy(tmpstring, type);
-+      xendev->devicetype = tmpstring;
-+      init_completion(&xendev->down);
-+
-+      xendev->dev.parent = &bus->dev;
-+      xendev->dev.bus = &bus->bus;
-+      xendev->dev.release = xenbus_dev_release;
-+
-+      err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
-+      if (err)
-+              goto fail;
-+
-+      /* Register with generic device framework. */
-+      err = device_register(&xendev->dev);
-+      if (err)
-+              goto fail;
-+
-+      device_create_file(&xendev->dev, &dev_attr_nodename);
-+      device_create_file(&xendev->dev, &dev_attr_devtype);
-+
-+      return 0;
-+fail:
-+      kfree(xendev);
-+      return err;
-+}
-+
-+/* device/<typename>/<name> */
-+static int xenbus_probe_frontend(const char *type, const char *name)
-+{
-+      char *nodename;
-+      int err;
-+
-+      nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_frontend.root, type, name);
-+      if (!nodename)
-+              return -ENOMEM;
-+
-+      DPRINTK("%s", nodename);
-+
-+      err = xenbus_probe_node(&xenbus_frontend, type, nodename);
-+      kfree(nodename);
-+      return err;
-+}
-+
-+static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
-+{
-+      int err = 0;
-+      char **dir;
-+      unsigned int dir_n = 0;
-+      int i;
-+
-+      dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n);
-+      if (IS_ERR(dir))
-+              return PTR_ERR(dir);
-+
-+      for (i = 0; i < dir_n; i++) {
-+              err = bus->probe(type, dir[i]);
-+              if (err)
-+                      break;
-+      }
-+      kfree(dir);
-+      return err;
-+}
-+
-+int xenbus_probe_devices(struct xen_bus_type *bus)
-+{
-+      int err = 0;
-+      char **dir;
-+      unsigned int i, dir_n;
-+
-+      dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
-+      if (IS_ERR(dir))
-+              return PTR_ERR(dir);
-+
-+      for (i = 0; i < dir_n; i++) {
-+              err = xenbus_probe_device_type(bus, dir[i]);
-+              if (err)
-+                      break;
-+      }
-+      kfree(dir);
-+      return err;
-+}
-+
-+static unsigned int char_count(const char *str, char c)
-+{
-+      unsigned int i, ret = 0;
-+
-+      for (i = 0; str[i]; i++)
-+              if (str[i] == c)
-+                      ret++;
-+      return ret;
-+}
-+
-+static int strsep_len(const char *str, char c, unsigned int len)
-+{
-+      unsigned int i;
-+
-+      for (i = 0; str[i]; i++)
-+              if (str[i] == c) {
-+                      if (len == 0)
-+                              return i;
-+                      len--;
-+              }
-+      return (len == 0) ? i : -ERANGE;
-+}
-+
-+void dev_changed(const char *node, struct xen_bus_type *bus)
-+{
-+      int exists, rootlen;
-+      struct xenbus_device *dev;
-+      char type[BUS_ID_SIZE];
-+      const char *p, *root;
-+
-+      if (char_count(node, '/') < 2)
-+              return;
-+
-+      exists = xenbus_exists(XBT_NIL, node, "");
-+      if (!exists) {
-+              xenbus_cleanup_devices(node, &bus->bus);
-+              return;
-+      }
-+
-+      /* backend/<type>/... or device/<type>/... */
-+      p = strchr(node, '/') + 1;
-+      snprintf(type, BUS_ID_SIZE, "%.*s", (int)strcspn(p, "/"), p);
-+      type[BUS_ID_SIZE-1] = '\0';
-+
-+      rootlen = strsep_len(node, '/', bus->levels);
-+      if (rootlen < 0)
-+              return;
-+      root = kasprintf(GFP_KERNEL, "%.*s", rootlen, node);
-+      if (!root)
-+              return;
-+
-+      dev = xenbus_device_find(root, &bus->bus);
-+      if (!dev)
-+              xenbus_probe_node(bus, type, root);
-+      else
-+              put_device(&dev->dev);
-+
-+      kfree(root);
-+}
-+
-+static void frontend_changed(struct xenbus_watch *watch,
-+                           const char **vec, unsigned int len)
-+{
-+      DPRINTK("");
-+
-+      dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
-+}
-+
-+/* We watch for devices appearing and vanishing. */
-+static struct xenbus_watch fe_watch = {
-+      .node = "device",
-+      .callback = frontend_changed,
-+};
-+
-+static int suspend_dev(struct device *dev, void *data)
-+{
-+      int err = 0;
-+      struct xenbus_driver *drv;
-+      struct xenbus_device *xdev;
-+
-+      DPRINTK("");
-+
-+      if (dev->driver == NULL)
-+              return 0;
-+      drv = to_xenbus_driver(dev->driver);
-+      xdev = container_of(dev, struct xenbus_device, dev);
-+      if (drv->suspend)
-+              err = drv->suspend(xdev);
-+      if (err)
-+              printk(KERN_WARNING
-+                     "xenbus: suspend %s failed: %i\n", dev->bus_id, err);
-+      return 0;
-+}
-+
-+static int resume_dev(struct device *dev, void *data)
-+{
-+      int err;
-+      struct xenbus_driver *drv;
-+      struct xenbus_device *xdev;
-+
-+      DPRINTK("");
-+
-+      if (dev->driver == NULL)
-+              return 0;
-+
-+      drv = to_xenbus_driver(dev->driver);
-+      xdev = container_of(dev, struct xenbus_device, dev);
-+
-+      err = talk_to_otherend(xdev);
-+      if (err) {
-+              printk(KERN_WARNING
-+                     "xenbus: resume (talk_to_otherend) %s failed: %i\n",
-+                     dev->bus_id, err);
-+              return err;
-+      }
-+
-+      xdev->state = XenbusStateInitialising;
-+
-+      if (drv->resume) {
-+              err = drv->resume(xdev);
-+              if (err) { 
-+                      printk(KERN_WARNING
-+                             "xenbus: resume %s failed: %i\n", 
-+                             dev->bus_id, err);
-+                      return err;
-+              }
-+      }
-+
-+      err = watch_otherend(xdev);
-+      if (err) {
-+              printk(KERN_WARNING
-+                     "xenbus_probe: resume (watch_otherend) %s failed: "
-+                     "%d.\n", dev->bus_id, err);
-+              return err;
-+      }
-+
-+      return 0;
-+}
-+
-+void xenbus_suspend(void)
-+{
-+      DPRINTK("");
-+
-+      bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
-+      xenbus_backend_suspend(suspend_dev);
-+      xs_suspend();
-+}
-+EXPORT_SYMBOL_GPL(xenbus_suspend);
-+
-+void xenbus_resume(void)
-+{
-+      xb_init_comms();
-+      xs_resume();
-+      bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
-+      xenbus_backend_resume(resume_dev);
-+}
-+EXPORT_SYMBOL_GPL(xenbus_resume);
-+
-+
-+/* A flag to determine if xenstored is 'ready' (i.e. has started) */
-+int xenstored_ready = 0;
-+
-+
-+int register_xenstore_notifier(struct notifier_block *nb)
-+{
-+      int ret = 0;
-+
-+      if (xenstored_ready > 0)
-+              ret = nb->notifier_call(nb, 0, NULL);
-+      else
-+              notifier_chain_register(&xenstore_chain, nb);
-+
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(register_xenstore_notifier);
-+
-+void unregister_xenstore_notifier(struct notifier_block *nb)
-+{
-+      notifier_chain_unregister(&xenstore_chain, nb);
-+}
-+EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
-+
-+
-+void xenbus_probe(void *unused)
-+{
-+      BUG_ON((xenstored_ready <= 0));
-+
-+      /* Enumerate devices in xenstore and watch for changes. */
-+      xenbus_probe_devices(&xenbus_frontend);
-+      register_xenbus_watch(&fe_watch);
-+      xenbus_backend_probe_and_watch();
-+
-+      /* Notify others that xenstore is up */
-+      notifier_call_chain(&xenstore_chain, 0, NULL);
-+}
-+
-+
-+#if defined(CONFIG_PROC_FS) && defined(CONFIG_XEN_PRIVILEGED_GUEST)
-+static struct file_operations xsd_kva_fops;
-+static struct proc_dir_entry *xsd_kva_intf;
-+static struct proc_dir_entry *xsd_port_intf;
-+
-+static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+      size_t size = vma->vm_end - vma->vm_start;
-+
-+      if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
-+              return -EINVAL;
-+
-+      if (remap_pfn_range(vma, vma->vm_start, mfn_to_pfn(xen_store_mfn),
-+                          size, vma->vm_page_prot))
-+              return -EAGAIN;
-+
-+      return 0;
-+}
-+
-+static int xsd_kva_read(char *page, char **start, off_t off,
-+                      int count, int *eof, void *data)
-+{
-+      int len;
-+
-+      len  = sprintf(page, "0x%p", xen_store_interface);
-+      *eof = 1;
-+      return len;
-+}
-+
-+static int xsd_port_read(char *page, char **start, off_t off,
-+                       int count, int *eof, void *data)
-+{
-+      int len;
-+
-+      len  = sprintf(page, "%d", xen_store_evtchn);
-+      *eof = 1;
-+      return len;
-+}
-+#endif
-+
-+static int __init xenbus_probe_init(void)
-+{
-+      int err = 0;
-+      unsigned long page = 0;
-+
-+      DPRINTK("");
-+
-+      if (!is_running_on_xen())
-+              return -ENODEV;
-+
-+      /* Register ourselves with the kernel bus subsystem */
-+      bus_register(&xenbus_frontend.bus);
-+      xenbus_backend_bus_register();
-+
-+      /*
-+       * Domain0 doesn't have a store_evtchn or store_mfn yet.
-+       */
-+      if (is_initial_xendomain()) {
-+              struct evtchn_alloc_unbound alloc_unbound;
-+
-+              /* Allocate page. */
-+              page = get_zeroed_page(GFP_KERNEL);
-+              if (!page)
-+                      return -ENOMEM;
-+
-+              xen_store_mfn = xen_start_info->store_mfn =
-+                      pfn_to_mfn(virt_to_phys((void *)page) >>
-+                                 PAGE_SHIFT);
-+
-+              /* Next allocate a local port which xenstored can bind to */
-+              alloc_unbound.dom        = DOMID_SELF;
-+              alloc_unbound.remote_dom = 0;
-+
-+              err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
-+                                                &alloc_unbound);
-+              if (err == -ENOSYS)
-+                      goto err;
-+              BUG_ON(err);
-+              xen_store_evtchn = xen_start_info->store_evtchn =
-+                      alloc_unbound.port;
-+
-+#if defined(CONFIG_PROC_FS) && defined(CONFIG_XEN_PRIVILEGED_GUEST)
-+              /* And finally publish the above info in /proc/xen */
-+              xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600);
-+              if (xsd_kva_intf) {
-+                      memcpy(&xsd_kva_fops, xsd_kva_intf->proc_fops,
-+                             sizeof(xsd_kva_fops));
-+                      xsd_kva_fops.mmap = xsd_kva_mmap;
-+                      xsd_kva_intf->proc_fops = &xsd_kva_fops;
-+                      xsd_kva_intf->read_proc = xsd_kva_read;
-+              }
-+              xsd_port_intf = create_xen_proc_entry("xsd_port", 0400);
-+              if (xsd_port_intf)
-+                      xsd_port_intf->read_proc = xsd_port_read;
-+#endif
-+              xen_store_interface = mfn_to_virt(xen_store_mfn);
-+      } else {
-+              xenstored_ready = 1;
-+#ifdef CONFIG_XEN
-+              xen_store_evtchn = xen_start_info->store_evtchn;
-+              xen_store_mfn = xen_start_info->store_mfn;
-+              xen_store_interface = mfn_to_virt(xen_store_mfn);
-+#else
-+              xen_store_evtchn = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN);
-+              xen_store_mfn = hvm_get_parameter(HVM_PARAM_STORE_PFN);
-+              xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT,
-+                                            PAGE_SIZE);
-+#endif
-+      }
-+
-+
-+      xenbus_dev_init();
-+
-+      /* Initialize the interface to xenstore. */
-+      err = xs_init();
-+      if (err) {
-+              printk(KERN_WARNING
-+                     "XENBUS: Error initializing xenstore comms: %i\n", err);
-+              goto err;
-+      }
-+
-+      /* Register ourselves with the kernel device subsystem */
-+      device_register(&xenbus_frontend.dev);
-+      xenbus_backend_device_register();
-+
-+      if (!is_initial_xendomain())
-+              xenbus_probe(NULL);
-+
-+      return 0;
-+
-+ err:
-+      if (page)
-+              free_page(page);
-+
-+      /*
-+       * Do not unregister the xenbus front/backend buses here. The buses
-+       * must exist because front/backend drivers will use them when they are
-+       * registered.
-+       */
-+
-+      return err;
-+}
-+
-+postcore_initcall(xenbus_probe_init);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-+
-+
-+static int is_disconnected_device(struct device *dev, void *data)
-+{
-+      struct xenbus_device *xendev = to_xenbus_device(dev);
-+      struct device_driver *drv = data;
-+
-+      /*
-+       * A device with no driver will never connect. We care only about
-+       * devices which should currently be in the process of connecting.
-+       */
-+      if (!dev->driver)
-+              return 0;
-+
-+      /* Is this search limited to a particular driver? */
-+      if (drv && (dev->driver != drv))
-+              return 0;
-+
-+      return (xendev->state != XenbusStateConnected);
-+}
-+
-+static int exists_disconnected_device(struct device_driver *drv)
-+{
-+      return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
-+                              is_disconnected_device);
-+}
-+
-+static int print_device_status(struct device *dev, void *data)
-+{
-+      struct xenbus_device *xendev = to_xenbus_device(dev);
-+      struct device_driver *drv = data;
-+
-+      /* Is this operation limited to a particular driver? */
-+      if (drv && (dev->driver != drv))
-+              return 0;
-+
-+      if (!dev->driver) {
-+              /* Information only: is this too noisy? */
-+              printk(KERN_INFO "XENBUS: Device with no driver: %s\n",
-+                     xendev->nodename);
-+      } else if (xendev->state != XenbusStateConnected) {
-+              printk(KERN_WARNING "XENBUS: Timeout connecting "
-+                     "to device: %s (state %d)\n",
-+                     xendev->nodename, xendev->state);
-+      }
-+
-+      return 0;
-+}
-+
-+/* We only wait for device setup after most initcalls have run. */
-+static int ready_to_wait_for_devices;
-+
-+/*
-+ * On a 10 second timeout, wait for all devices currently configured.  We need
-+ * to do this to guarantee that the filesystems and / or network devices
-+ * needed for boot are available, before we can allow the boot to proceed.
-+ *
-+ * This needs to be on a late_initcall, to happen after the frontend device
-+ * drivers have been initialised, but before the root fs is mounted.
-+ *
-+ * A possible improvement here would be to have the tools add a per-device
-+ * flag to the store entry, indicating whether it is needed at boot time.
-+ * This would allow people who knew what they were doing to accelerate their
-+ * boot slightly, but of course needs tools or manual intervention to set up
-+ * those flags correctly.
-+ */
-+static void wait_for_devices(struct xenbus_driver *xendrv)
-+{
-+      unsigned long timeout = jiffies + 10*HZ;
-+      struct device_driver *drv = xendrv ? &xendrv->driver : NULL;
-+
-+      if (!ready_to_wait_for_devices || !is_running_on_xen())
-+              return;
-+
-+      while (exists_disconnected_device(drv)) {
-+              if (time_after(jiffies, timeout))
-+                      break;
-+              schedule_timeout_interruptible(HZ/10);
-+      }
-+
-+      bus_for_each_dev(&xenbus_frontend.bus, NULL, drv,
-+                       print_device_status);
-+}
-+
-+#ifndef MODULE
-+static int __init boot_wait_for_devices(void)
-+{
-+      ready_to_wait_for_devices = 1;
-+      wait_for_devices(NULL);
-+      return 0;
-+}
-+
-+late_initcall(boot_wait_for_devices);
-+#endif
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_probe.h linux-2.6.16.33/drivers/xen/xenbus/xenbus_probe.h
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_probe.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_probe.h  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,74 @@
-+/******************************************************************************
-+ * xenbus_probe.h
-+ *
-+ * Talks to Xen Store to figure out what devices we have.
-+ *
-+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
-+ * Copyright (C) 2005 XenSource Ltd.
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef _XENBUS_PROBE_H
-+#define _XENBUS_PROBE_H
-+
-+#if defined(CONFIG_XEN_BACKEND) || defined(CONFIG_XEN_BACKEND_MODULE)
-+extern void xenbus_backend_suspend(int (*fn)(struct device *, void *));
-+extern void xenbus_backend_resume(int (*fn)(struct device *, void *));
-+extern void xenbus_backend_probe_and_watch(void);
-+extern void xenbus_backend_bus_register(void);
-+extern void xenbus_backend_device_register(void);
-+#else
-+static inline void xenbus_backend_suspend(int (*fn)(struct device *, void *)) {}
-+static inline void xenbus_backend_resume(int (*fn)(struct device *, void *)) {}
-+static inline void xenbus_backend_probe_and_watch(void) {}
-+static inline void xenbus_backend_bus_register(void) {}
-+static inline void xenbus_backend_device_register(void) {}
-+#endif
-+
-+struct xen_bus_type
-+{
-+      char *root;
-+      unsigned int levels;
-+      int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
-+      int (*probe)(const char *type, const char *dir);
-+      struct bus_type bus;
-+      struct device dev;
-+};
-+
-+extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
-+extern int xenbus_dev_probe(struct device *_dev);
-+extern int xenbus_dev_remove(struct device *_dev);
-+extern int xenbus_register_driver_common(struct xenbus_driver *drv,
-+                                       struct xen_bus_type *bus);
-+extern int xenbus_probe_node(struct xen_bus_type *bus,
-+                           const char *type,
-+                           const char *nodename);
-+extern int xenbus_probe_devices(struct xen_bus_type *bus);
-+
-+extern void dev_changed(const char *node, struct xen_bus_type *bus);
-+
-+#endif
-+
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_probe_backend.c linux-2.6.16.33/drivers/xen/xenbus/xenbus_probe_backend.c
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_probe_backend.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_probe_backend.c  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,271 @@
-+/******************************************************************************
-+ * Talks to Xen Store to figure out what devices we have (backend half).
-+ *
-+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
-+ * Copyright (C) 2005 Mike Wray, Hewlett-Packard
-+ * Copyright (C) 2005, 2006 XenSource Ltd
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#define DPRINTK(fmt, args...)                         \
-+      pr_debug("xenbus_probe (%s:%d) " fmt ".\n",     \
-+               __FUNCTION__, __LINE__, ##args)
-+
-+#include <linux/kernel.h>
-+#include <linux/err.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/fcntl.h>
-+#include <linux/mm.h>
-+#include <linux/notifier.h>
-+#include <linux/kthread.h>
-+
-+#include <asm/io.h>
-+#include <asm/page.h>
-+#include <asm/maddr.h>
-+#include <asm/pgtable.h>
-+#include <asm/hypervisor.h>
-+#include <xen/xenbus.h>
-+#include <xen/xen_proc.h>
-+#include <xen/evtchn.h>
-+#include <xen/features.h>
-+#include <xen/hvm.h>
-+
-+#include "xenbus_comms.h"
-+#include "xenbus_probe.h"
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+static int xenbus_uevent_backend(struct device *dev, char **envp,
-+                               int num_envp, char *buffer, int buffer_size);
-+static int xenbus_probe_backend(const char *type, const char *domid);
-+
-+extern int read_otherend_details(struct xenbus_device *xendev,
-+                               char *id_node, char *path_node);
-+
-+static int read_frontend_details(struct xenbus_device *xendev)
-+{
-+      return read_otherend_details(xendev, "frontend-id", "frontend");
-+}
-+
-+/* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
-+static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
-+{
-+      int domid, err;
-+      const char *devid, *type, *frontend;
-+      unsigned int typelen;
-+
-+      type = strchr(nodename, '/');
-+      if (!type)
-+              return -EINVAL;
-+      type++;
-+      typelen = strcspn(type, "/");
-+      if (!typelen || type[typelen] != '/')
-+              return -EINVAL;
-+
-+      devid = strrchr(nodename, '/') + 1;
-+
-+      err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
-+                          "frontend", NULL, &frontend,
-+                          NULL);
-+      if (err)
-+              return err;
-+      if (strlen(frontend) == 0)
-+              err = -ERANGE;
-+      if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
-+              err = -ENOENT;
-+      kfree(frontend);
-+
-+      if (err)
-+              return err;
-+
-+      if (snprintf(bus_id, BUS_ID_SIZE,
-+                   "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
-+              return -ENOSPC;
-+      return 0;
-+}
-+
-+static struct xen_bus_type xenbus_backend = {
-+      .root = "backend",
-+      .levels = 3,            /* backend/type/<frontend>/<id> */
-+      .get_bus_id = backend_bus_id,
-+      .probe = xenbus_probe_backend,
-+      .bus = {
-+              .name     = "xen-backend",
-+              .match    = xenbus_match,
-+              .probe    = xenbus_dev_probe,
-+              .remove   = xenbus_dev_remove,
-+//            .shutdown = xenbus_dev_shutdown,
-+              .uevent   = xenbus_uevent_backend,
-+      },
-+      .dev = {
-+              .bus_id = "xen-backend",
-+      },
-+};
-+
-+static int xenbus_uevent_backend(struct device *dev, char **envp,
-+                               int num_envp, char *buffer, int buffer_size)
-+{
-+      struct xenbus_device *xdev;
-+      struct xenbus_driver *drv;
-+      int i = 0;
-+      int length = 0;
-+
-+      DPRINTK("");
-+
-+      if (dev == NULL)
-+              return -ENODEV;
-+
-+      xdev = to_xenbus_device(dev);
-+      if (xdev == NULL)
-+              return -ENODEV;
-+
-+      /* stuff we want to pass to /sbin/hotplug */
-+      add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
-+                     "XENBUS_TYPE=%s", xdev->devicetype);
-+
-+      add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
-+                     "XENBUS_PATH=%s", xdev->nodename);
-+
-+      add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
-+                     "XENBUS_BASE_PATH=%s", xenbus_backend.root);
-+
-+      /* terminate, set to next free slot, shrink available space */
-+      envp[i] = NULL;
-+      envp = &envp[i];
-+      num_envp -= i;
-+      buffer = &buffer[length];
-+      buffer_size -= length;
-+
-+      if (dev->driver) {
-+              drv = to_xenbus_driver(dev->driver);
-+              if (drv && drv->uevent)
-+                      return drv->uevent(xdev, envp, num_envp, buffer,
-+                                         buffer_size);
-+      }
-+
-+      return 0;
-+}
-+
-+int xenbus_register_backend(struct xenbus_driver *drv)
-+{
-+      drv->read_otherend_details = read_frontend_details;
-+
-+      return xenbus_register_driver_common(drv, &xenbus_backend);
-+}
-+EXPORT_SYMBOL_GPL(xenbus_register_backend);
-+
-+/* backend/<typename>/<frontend-uuid>/<name> */
-+static int xenbus_probe_backend_unit(const char *dir,
-+                                   const char *type,
-+                                   const char *name)
-+{
-+      char *nodename;
-+      int err;
-+
-+      nodename = kasprintf(GFP_KERNEL, "%s/%s", dir, name);
-+      if (!nodename)
-+              return -ENOMEM;
-+
-+      DPRINTK("%s\n", nodename);
-+
-+      err = xenbus_probe_node(&xenbus_backend, type, nodename);
-+      kfree(nodename);
-+      return err;
-+}
-+
-+/* backend/<typename>/<frontend-domid> */
-+static int xenbus_probe_backend(const char *type, const char *domid)
-+{
-+      char *nodename;
-+      int err = 0;
-+      char **dir;
-+      unsigned int i, dir_n = 0;
-+
-+      DPRINTK("");
-+
-+      nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_backend.root, type, domid);
-+      if (!nodename)
-+              return -ENOMEM;
-+
-+      dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
-+      if (IS_ERR(dir)) {
-+              kfree(nodename);
-+              return PTR_ERR(dir);
-+      }
-+
-+      for (i = 0; i < dir_n; i++) {
-+              err = xenbus_probe_backend_unit(nodename, type, dir[i]);
-+              if (err)
-+                      break;
-+      }
-+      kfree(dir);
-+      kfree(nodename);
-+      return err;
-+}
-+
-+static void backend_changed(struct xenbus_watch *watch,
-+                          const char **vec, unsigned int len)
-+{
-+      DPRINTK("");
-+
-+      dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
-+}
-+
-+static struct xenbus_watch be_watch = {
-+      .node = "backend",
-+      .callback = backend_changed,
-+};
-+
-+void xenbus_backend_suspend(int (*fn)(struct device *, void *))
-+{
-+      DPRINTK("");
-+      bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
-+}
-+
-+void xenbus_backend_resume(int (*fn)(struct device *, void *))
-+{
-+      DPRINTK("");
-+      bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
-+}
-+
-+void xenbus_backend_probe_and_watch(void)
-+{
-+      xenbus_probe_devices(&xenbus_backend);
-+      register_xenbus_watch(&be_watch);
-+}
-+
-+void xenbus_backend_bus_register(void)
-+{
-+      bus_register(&xenbus_backend.bus);
-+}
-+
-+void xenbus_backend_device_register(void)
-+{
-+      device_register(&xenbus_backend.dev);
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_xs.c linux-2.6.16.33/drivers/xen/xenbus/xenbus_xs.c
---- linux-2.6.16.33-noxen/drivers/xen/xenbus/xenbus_xs.c       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenbus/xenbus_xs.c     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,859 @@
-+/******************************************************************************
-+ * xenbus_xs.c
-+ *
-+ * This is the kernel equivalent of the "xs" library.  We don't need everything
-+ * and we use xenbus_comms for communication.
-+ *
-+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#include <linux/unistd.h>
-+#include <linux/errno.h>
-+#include <linux/types.h>
-+#include <linux/uio.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/err.h>
-+#include <linux/slab.h>
-+#include <linux/fcntl.h>
-+#include <linux/kthread.h>
-+#include <linux/rwsem.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <xen/xenbus.h>
-+#include "xenbus_comms.h"
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+struct xs_stored_msg {
-+      struct list_head list;
-+
-+      struct xsd_sockmsg hdr;
-+
-+      union {
-+              /* Queued replies. */
-+              struct {
-+                      char *body;
-+              } reply;
-+
-+              /* Queued watch events. */
-+              struct {
-+                      struct xenbus_watch *handle;
-+                      char **vec;
-+                      unsigned int vec_size;
-+              } watch;
-+      } u;
-+};
-+
-+struct xs_handle {
-+      /* A list of replies. Currently only one will ever be outstanding. */
-+      struct list_head reply_list;
-+      spinlock_t reply_lock;
-+      wait_queue_head_t reply_waitq;
-+
-+      /* One request at a time. */
-+      struct mutex request_mutex;
-+
-+      /* Protect transactions against save/restore. */
-+      struct rw_semaphore suspend_mutex;
-+};
-+
-+static struct xs_handle xs_state;
-+
-+/* List of registered watches, and a lock to protect it. */
-+static LIST_HEAD(watches);
-+static DEFINE_SPINLOCK(watches_lock);
-+
-+/* List of pending watch callback events, and a lock to protect it. */
-+static LIST_HEAD(watch_events);
-+static DEFINE_SPINLOCK(watch_events_lock);
-+
-+/*
-+ * Details of the xenwatch callback kernel thread. The thread waits on the
-+ * watch_events_waitq for work to do (queued on watch_events list). When it
-+ * wakes up it acquires the xenwatch_mutex before reading the list and
-+ * carrying out work.
-+ */
-+static pid_t xenwatch_pid;
-+/* static */ DEFINE_MUTEX(xenwatch_mutex);
-+static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq);
-+
-+static int get_error(const char *errorstring)
-+{
-+      unsigned int i;
-+
-+      for (i = 0; strcmp(errorstring, xsd_errors[i].errstring) != 0; i++) {
-+              if (i == ARRAY_SIZE(xsd_errors) - 1) {
-+                      printk(KERN_WARNING
-+                             "XENBUS xen store gave: unknown error %s",
-+                             errorstring);
-+                      return EINVAL;
-+              }
-+      }
-+      return xsd_errors[i].errnum;
-+}
-+
-+static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
-+{
-+      struct xs_stored_msg *msg;
-+      char *body;
-+
-+      spin_lock(&xs_state.reply_lock);
-+
-+      while (list_empty(&xs_state.reply_list)) {
-+              spin_unlock(&xs_state.reply_lock);
-+              /* XXX FIXME: Avoid synchronous wait for response here. */
-+              wait_event(xs_state.reply_waitq,
-+                         !list_empty(&xs_state.reply_list));
-+              spin_lock(&xs_state.reply_lock);
-+      }
-+
-+      msg = list_entry(xs_state.reply_list.next,
-+                       struct xs_stored_msg, list);
-+      list_del(&msg->list);
-+
-+      spin_unlock(&xs_state.reply_lock);
-+
-+      *type = msg->hdr.type;
-+      if (len)
-+              *len = msg->hdr.len;
-+      body = msg->u.reply.body;
-+
-+      kfree(msg);
-+
-+      return body;
-+}
-+
-+/* Emergency write. */
-+void xenbus_debug_write(const char *str, unsigned int count)
-+{
-+      struct xsd_sockmsg msg = { 0 };
-+
-+      msg.type = XS_DEBUG;
-+      msg.len = sizeof("print") + count + 1;
-+
-+      mutex_lock(&xs_state.request_mutex);
-+      xb_write(&msg, sizeof(msg));
-+      xb_write("print", sizeof("print"));
-+      xb_write(str, count);
-+      xb_write("", 1);
-+      mutex_unlock(&xs_state.request_mutex);
-+}
-+
-+void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
-+{
-+      void *ret;
-+      struct xsd_sockmsg req_msg = *msg;
-+      int err;
-+
-+      if (req_msg.type == XS_TRANSACTION_START)
-+              down_read(&xs_state.suspend_mutex);
-+
-+      mutex_lock(&xs_state.request_mutex);
-+
-+      err = xb_write(msg, sizeof(*msg) + msg->len);
-+      if (err) {
-+              msg->type = XS_ERROR;
-+              ret = ERR_PTR(err);
-+      } else
-+              ret = read_reply(&msg->type, &msg->len);
-+
-+      mutex_unlock(&xs_state.request_mutex);
-+
-+      if ((req_msg.type == XS_TRANSACTION_END) ||
-+          ((req_msg.type == XS_TRANSACTION_START) &&
-+           (msg->type == XS_ERROR)))
-+              up_read(&xs_state.suspend_mutex);
-+
-+      return ret;
-+}
-+
-+/* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
-+static void *xs_talkv(struct xenbus_transaction t,
-+                    enum xsd_sockmsg_type type,
-+                    const struct kvec *iovec,
-+                    unsigned int num_vecs,
-+                    unsigned int *len)
-+{
-+      struct xsd_sockmsg msg;
-+      void *ret = NULL;
-+      unsigned int i;
-+      int err;
-+
-+      msg.tx_id = t.id;
-+      msg.req_id = 0;
-+      msg.type = type;
-+      msg.len = 0;
-+      for (i = 0; i < num_vecs; i++)
-+              msg.len += iovec[i].iov_len;
-+
-+      mutex_lock(&xs_state.request_mutex);
-+
-+      err = xb_write(&msg, sizeof(msg));
-+      if (err) {
-+              mutex_unlock(&xs_state.request_mutex);
-+              return ERR_PTR(err);
-+      }
-+
-+      for (i = 0; i < num_vecs; i++) {
-+              err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
-+              if (err) {
-+                      mutex_unlock(&xs_state.request_mutex);
-+                      return ERR_PTR(err);
-+              }
-+      }
-+
-+      ret = read_reply(&msg.type, len);
-+
-+      mutex_unlock(&xs_state.request_mutex);
-+
-+      if (IS_ERR(ret))
-+              return ret;
-+
-+      if (msg.type == XS_ERROR) {
-+              err = get_error(ret);
-+              kfree(ret);
-+              return ERR_PTR(-err);
-+      }
-+
-+      if (msg.type != type) {
-+              if (printk_ratelimit())
-+                      printk(KERN_WARNING
-+                             "XENBUS unexpected type [%d], expected [%d]\n",
-+                             msg.type, type);
-+              kfree(ret);
-+              return ERR_PTR(-EINVAL);
-+      }
-+      return ret;
-+}
-+
-+/* Simplified version of xs_talkv: single message. */
-+static void *xs_single(struct xenbus_transaction t,
-+                     enum xsd_sockmsg_type type,
-+                     const char *string,
-+                     unsigned int *len)
-+{
-+      struct kvec iovec;
-+
-+      iovec.iov_base = (void *)string;
-+      iovec.iov_len = strlen(string) + 1;
-+      return xs_talkv(t, type, &iovec, 1, len);
-+}
-+
-+/* Many commands only need an ack, don't care what it says. */
-+static int xs_error(char *reply)
-+{
-+      if (IS_ERR(reply))
-+              return PTR_ERR(reply);
-+      kfree(reply);
-+      return 0;
-+}
-+
-+static unsigned int count_strings(const char *strings, unsigned int len)
-+{
-+      unsigned int num;
-+      const char *p;
-+
-+      for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
-+              num++;
-+
-+      return num;
-+}
-+
-+/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
-+static char *join(const char *dir, const char *name)
-+{
-+      char *buffer;
-+
-+      if (strlen(name) == 0)
-+              buffer = kasprintf(GFP_KERNEL, "%s", dir);
-+      else
-+              buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name);
-+      return (!buffer) ? ERR_PTR(-ENOMEM) : buffer;
-+}
-+
-+static char **split(char *strings, unsigned int len, unsigned int *num)
-+{
-+      char *p, **ret;
-+
-+      /* Count the strings. */
-+      *num = count_strings(strings, len);
-+
-+      /* Transfer to one big alloc for easy freeing. */
-+      ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL);
-+      if (!ret) {
-+              kfree(strings);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+      memcpy(&ret[*num], strings, len);
-+      kfree(strings);
-+
-+      strings = (char *)&ret[*num];
-+      for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
-+              ret[(*num)++] = p;
-+
-+      return ret;
-+}
-+
-+char **xenbus_directory(struct xenbus_transaction t,
-+                      const char *dir, const char *node, unsigned int *num)
-+{
-+      char *strings, *path;
-+      unsigned int len;
-+
-+      path = join(dir, node);
-+      if (IS_ERR(path))
-+              return (char **)path;
-+
-+      strings = xs_single(t, XS_DIRECTORY, path, &len);
-+      kfree(path);
-+      if (IS_ERR(strings))
-+              return (char **)strings;
-+
-+      return split(strings, len, num);
-+}
-+EXPORT_SYMBOL_GPL(xenbus_directory);
-+
-+/* Check if a path exists. Return 1 if it does. */
-+int xenbus_exists(struct xenbus_transaction t,
-+                const char *dir, const char *node)
-+{
-+      char **d;
-+      int dir_n;
-+
-+      d = xenbus_directory(t, dir, node, &dir_n);
-+      if (IS_ERR(d))
-+              return 0;
-+      kfree(d);
-+      return 1;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_exists);
-+
-+/* Get the value of a single file.
-+ * Returns a kmalloced value: call free() on it after use.
-+ * len indicates length in bytes.
-+ */
-+void *xenbus_read(struct xenbus_transaction t,
-+                const char *dir, const char *node, unsigned int *len)
-+{
-+      char *path;
-+      void *ret;
-+
-+      path = join(dir, node);
-+      if (IS_ERR(path))
-+              return (void *)path;
-+
-+      ret = xs_single(t, XS_READ, path, len);
-+      kfree(path);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_read);
-+
-+/* Write the value of a single file.
-+ * Returns -err on failure.
-+ */
-+int xenbus_write(struct xenbus_transaction t,
-+               const char *dir, const char *node, const char *string)
-+{
-+      const char *path;
-+      struct kvec iovec[2];
-+      int ret;
-+
-+      path = join(dir, node);
-+      if (IS_ERR(path))
-+              return PTR_ERR(path);
-+
-+      iovec[0].iov_base = (void *)path;
-+      iovec[0].iov_len = strlen(path) + 1;
-+      iovec[1].iov_base = (void *)string;
-+      iovec[1].iov_len = strlen(string);
-+
-+      ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
-+      kfree(path);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_write);
-+
-+/* Create a new directory. */
-+int xenbus_mkdir(struct xenbus_transaction t,
-+               const char *dir, const char *node)
-+{
-+      char *path;
-+      int ret;
-+
-+      path = join(dir, node);
-+      if (IS_ERR(path))
-+              return PTR_ERR(path);
-+
-+      ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
-+      kfree(path);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_mkdir);
-+
-+/* Destroy a file or directory (directories must be empty). */
-+int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
-+{
-+      char *path;
-+      int ret;
-+
-+      path = join(dir, node);
-+      if (IS_ERR(path))
-+              return PTR_ERR(path);
-+
-+      ret = xs_error(xs_single(t, XS_RM, path, NULL));
-+      kfree(path);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_rm);
-+
-+/* Start a transaction: changes by others will not be seen during this
-+ * transaction, and changes will not be visible to others until end.
-+ */
-+int xenbus_transaction_start(struct xenbus_transaction *t)
-+{
-+      char *id_str;
-+
-+      down_read(&xs_state.suspend_mutex);
-+
-+      id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL);
-+      if (IS_ERR(id_str)) {
-+              up_read(&xs_state.suspend_mutex);
-+              return PTR_ERR(id_str);
-+      }
-+
-+      t->id = simple_strtoul(id_str, NULL, 0);
-+      kfree(id_str);
-+      return 0;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_transaction_start);
-+
-+/* End a transaction.
-+ * If abandon is true, transaction is discarded instead of committed.
-+ */
-+int xenbus_transaction_end(struct xenbus_transaction t, int abort)
-+{
-+      char abortstr[2];
-+      int err;
-+
-+      if (abort)
-+              strcpy(abortstr, "F");
-+      else
-+              strcpy(abortstr, "T");
-+
-+      err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
-+
-+      up_read(&xs_state.suspend_mutex);
-+
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_transaction_end);
-+
-+/* Single read and scanf: returns -errno or num scanned. */
-+int xenbus_scanf(struct xenbus_transaction t,
-+               const char *dir, const char *node, const char *fmt, ...)
-+{
-+      va_list ap;
-+      int ret;
-+      char *val;
-+
-+      val = xenbus_read(t, dir, node, NULL);
-+      if (IS_ERR(val))
-+              return PTR_ERR(val);
-+
-+      va_start(ap, fmt);
-+      ret = vsscanf(val, fmt, ap);
-+      va_end(ap);
-+      kfree(val);
-+      /* Distinctive errno. */
-+      if (ret == 0)
-+              return -ERANGE;
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_scanf);
-+
-+/* Single printf and write: returns -errno or 0. */
-+int xenbus_printf(struct xenbus_transaction t,
-+                const char *dir, const char *node, const char *fmt, ...)
-+{
-+      va_list ap;
-+      int ret;
-+#define PRINTF_BUFFER_SIZE 4096
-+      char *printf_buffer;
-+
-+      printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
-+      if (printf_buffer == NULL)
-+              return -ENOMEM;
-+
-+      va_start(ap, fmt);
-+      ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
-+      va_end(ap);
-+
-+      BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
-+      ret = xenbus_write(t, dir, node, printf_buffer);
-+
-+      kfree(printf_buffer);
-+
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_printf);
-+
-+/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-+int xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
-+{
-+      va_list ap;
-+      const char *name;
-+      int ret = 0;
-+
-+      va_start(ap, dir);
-+      while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
-+              const char *fmt = va_arg(ap, char *);
-+              void *result = va_arg(ap, void *);
-+              char *p;
-+
-+              p = xenbus_read(t, dir, name, NULL);
-+              if (IS_ERR(p)) {
-+                      ret = PTR_ERR(p);
-+                      break;
-+              }
-+              if (fmt) {
-+                      if (sscanf(p, fmt, result) == 0)
-+                              ret = -EINVAL;
-+                      kfree(p);
-+              } else
-+                      *(char **)result = p;
-+      }
-+      va_end(ap);
-+      return ret;
-+}
-+EXPORT_SYMBOL_GPL(xenbus_gather);
-+
-+static int xs_watch(const char *path, const char *token)
-+{
-+      struct kvec iov[2];
-+
-+      iov[0].iov_base = (void *)path;
-+      iov[0].iov_len = strlen(path) + 1;
-+      iov[1].iov_base = (void *)token;
-+      iov[1].iov_len = strlen(token) + 1;
-+
-+      return xs_error(xs_talkv(XBT_NIL, XS_WATCH, iov,
-+                               ARRAY_SIZE(iov), NULL));
-+}
-+
-+static int xs_unwatch(const char *path, const char *token)
-+{
-+      struct kvec iov[2];
-+
-+      iov[0].iov_base = (char *)path;
-+      iov[0].iov_len = strlen(path) + 1;
-+      iov[1].iov_base = (char *)token;
-+      iov[1].iov_len = strlen(token) + 1;
-+
-+      return xs_error(xs_talkv(XBT_NIL, XS_UNWATCH, iov,
-+                               ARRAY_SIZE(iov), NULL));
-+}
-+
-+static struct xenbus_watch *find_watch(const char *token)
-+{
-+      struct xenbus_watch *i, *cmp;
-+
-+      cmp = (void *)simple_strtoul(token, NULL, 16);
-+
-+      list_for_each_entry(i, &watches, list)
-+              if (i == cmp)
-+                      return i;
-+
-+      return NULL;
-+}
-+
-+/* Register callback to watch this node. */
-+int register_xenbus_watch(struct xenbus_watch *watch)
-+{
-+      /* Pointer in ascii is the token. */
-+      char token[sizeof(watch) * 2 + 1];
-+      int err;
-+
-+      sprintf(token, "%lX", (long)watch);
-+
-+      down_read(&xs_state.suspend_mutex);
-+
-+      spin_lock(&watches_lock);
-+      BUG_ON(find_watch(token));
-+      list_add(&watch->list, &watches);
-+      spin_unlock(&watches_lock);
-+
-+      err = xs_watch(watch->node, token);
-+
-+      /* Ignore errors due to multiple registration. */
-+      if ((err != 0) && (err != -EEXIST)) {
-+              spin_lock(&watches_lock);
-+              list_del(&watch->list);
-+              spin_unlock(&watches_lock);
-+      }
-+
-+      up_read(&xs_state.suspend_mutex);
-+
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(register_xenbus_watch);
-+
-+void unregister_xenbus_watch(struct xenbus_watch *watch)
-+{
-+      struct xs_stored_msg *msg, *tmp;
-+      char token[sizeof(watch) * 2 + 1];
-+      int err;
-+
-+      sprintf(token, "%lX", (long)watch);
-+
-+      down_read(&xs_state.suspend_mutex);
-+
-+      spin_lock(&watches_lock);
-+      BUG_ON(!find_watch(token));
-+      list_del(&watch->list);
-+      spin_unlock(&watches_lock);
-+
-+      err = xs_unwatch(watch->node, token);
-+      if (err)
-+              printk(KERN_WARNING
-+                     "XENBUS Failed to release watch %s: %i\n",
-+                     watch->node, err);
-+
-+      up_read(&xs_state.suspend_mutex);
-+
-+      /* Cancel pending watch events. */
-+      spin_lock(&watch_events_lock);
-+      list_for_each_entry_safe(msg, tmp, &watch_events, list) {
-+              if (msg->u.watch.handle != watch)
-+                      continue;
-+              list_del(&msg->list);
-+              kfree(msg->u.watch.vec);
-+              kfree(msg);
-+      }
-+      spin_unlock(&watch_events_lock);
-+
-+      /* Flush any currently-executing callback, unless we are it. :-) */
-+      if (current->pid != xenwatch_pid) {
-+              mutex_lock(&xenwatch_mutex);
-+              mutex_unlock(&xenwatch_mutex);
-+      }
-+}
-+EXPORT_SYMBOL_GPL(unregister_xenbus_watch);
-+
-+void xs_suspend(void)
-+{
-+      struct xenbus_watch *watch;
-+      char token[sizeof(watch) * 2 + 1];
-+
-+      down_write(&xs_state.suspend_mutex);
-+
-+      /* No need for watches_lock: the suspend_mutex is sufficient. */
-+      list_for_each_entry(watch, &watches, list) {
-+              sprintf(token, "%lX", (long)watch);
-+              xs_unwatch(watch->node, token);
-+      }
-+
-+      mutex_lock(&xs_state.request_mutex);
-+}
-+
-+void xs_resume(void)
-+{
-+      struct xenbus_watch *watch;
-+      char token[sizeof(watch) * 2 + 1];
-+
-+      mutex_unlock(&xs_state.request_mutex);
-+
-+      /* No need for watches_lock: the suspend_mutex is sufficient. */
-+      list_for_each_entry(watch, &watches, list) {
-+              sprintf(token, "%lX", (long)watch);
-+              xs_watch(watch->node, token);
-+      }
-+
-+      up_write(&xs_state.suspend_mutex);
-+}
-+
-+static int xenwatch_handle_callback(void *data)
-+{
-+      struct xs_stored_msg *msg = data;
-+
-+      msg->u.watch.handle->callback(msg->u.watch.handle,
-+                                    (const char **)msg->u.watch.vec,
-+                                    msg->u.watch.vec_size);
-+
-+      kfree(msg->u.watch.vec);
-+      kfree(msg);
-+
-+      /* Kill this kthread if we were spawned just for this callback. */
-+      if (current->pid != xenwatch_pid)
-+              do_exit(0);
-+
-+      return 0;
-+}
-+
-+static int xenwatch_thread(void *unused)
-+{
-+      struct list_head *ent;
-+      struct xs_stored_msg *msg;
-+
-+      for (;;) {
-+              wait_event_interruptible(watch_events_waitq,
-+                                       !list_empty(&watch_events));
-+
-+              if (kthread_should_stop())
-+                      break;
-+
-+              mutex_lock(&xenwatch_mutex);
-+
-+              spin_lock(&watch_events_lock);
-+              ent = watch_events.next;
-+              if (ent != &watch_events)
-+                      list_del(ent);
-+              spin_unlock(&watch_events_lock);
-+
-+              if (ent != &watch_events) {
-+                      msg = list_entry(ent, struct xs_stored_msg, list);
-+                      if (msg->u.watch.handle->flags & XBWF_new_thread)
-+                              kthread_run(xenwatch_handle_callback,
-+                                          msg, "xenwatch_cb");
-+                      else
-+                              xenwatch_handle_callback(msg);
-+              }
-+
-+              mutex_unlock(&xenwatch_mutex);
-+      }
-+
-+      return 0;
-+}
-+
-+static int process_msg(void)
-+{
-+      struct xs_stored_msg *msg;
-+      char *body;
-+      int err;
-+
-+      msg = kmalloc(sizeof(*msg), GFP_KERNEL);
-+      if (msg == NULL)
-+              return -ENOMEM;
-+
-+      err = xb_read(&msg->hdr, sizeof(msg->hdr));
-+      if (err) {
-+              kfree(msg);
-+              return err;
-+      }
-+
-+      body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
-+      if (body == NULL) {
-+              kfree(msg);
-+              return -ENOMEM;
-+      }
-+
-+      err = xb_read(body, msg->hdr.len);
-+      if (err) {
-+              kfree(body);
-+              kfree(msg);
-+              return err;
-+      }
-+      body[msg->hdr.len] = '\0';
-+
-+      if (msg->hdr.type == XS_WATCH_EVENT) {
-+              msg->u.watch.vec = split(body, msg->hdr.len,
-+                                       &msg->u.watch.vec_size);
-+              if (IS_ERR(msg->u.watch.vec)) {
-+                      kfree(msg);
-+                      return PTR_ERR(msg->u.watch.vec);
-+              }
-+
-+              spin_lock(&watches_lock);
-+              msg->u.watch.handle = find_watch(
-+                      msg->u.watch.vec[XS_WATCH_TOKEN]);
-+              if (msg->u.watch.handle != NULL) {
-+                      spin_lock(&watch_events_lock);
-+                      list_add_tail(&msg->list, &watch_events);
-+                      wake_up(&watch_events_waitq);
-+                      spin_unlock(&watch_events_lock);
-+              } else {
-+                      kfree(msg->u.watch.vec);
-+                      kfree(msg);
-+              }
-+              spin_unlock(&watches_lock);
-+      } else {
-+              msg->u.reply.body = body;
-+              spin_lock(&xs_state.reply_lock);
-+              list_add_tail(&msg->list, &xs_state.reply_list);
-+              spin_unlock(&xs_state.reply_lock);
-+              wake_up(&xs_state.reply_waitq);
-+      }
-+
-+      return 0;
-+}
-+
-+static int xenbus_thread(void *unused)
-+{
-+      int err;
-+
-+      for (;;) {
-+              err = process_msg();
-+              if (err)
-+                      printk(KERN_WARNING "XENBUS error %d while reading "
-+                             "message\n", err);
-+              if (kthread_should_stop())
-+                      break;
-+      }
-+
-+      return 0;
-+}
-+
-+int xs_init(void)
-+{
-+      int err;
-+      struct task_struct *task;
-+
-+      INIT_LIST_HEAD(&xs_state.reply_list);
-+      spin_lock_init(&xs_state.reply_lock);
-+      init_waitqueue_head(&xs_state.reply_waitq);
-+
-+      mutex_init(&xs_state.request_mutex);
-+      init_rwsem(&xs_state.suspend_mutex);
-+
-+      /* Initialize the shared memory rings to talk to xenstored */
-+      err = xb_init_comms();
-+      if (err)
-+              return err;
-+
-+      task = kthread_run(xenwatch_thread, NULL, "xenwatch");
-+      if (IS_ERR(task))
-+              return PTR_ERR(task);
-+      xenwatch_pid = task->pid;
-+
-+      task = kthread_run(xenbus_thread, NULL, "xenbus");
-+      if (IS_ERR(task))
-+              return PTR_ERR(task);
-+
-+      return 0;
-+}
-diff -Nur linux-2.6.16.33-noxen/drivers/xen/xenoprof/xenoprofile.c linux-2.6.16.33/drivers/xen/xenoprof/xenoprofile.c
---- linux-2.6.16.33-noxen/drivers/xen/xenoprof/xenoprofile.c   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/drivers/xen/xenoprof/xenoprofile.c 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,500 @@
-+/**
-+ * @file xenoprofile.c
-+ *
-+ * @remark Copyright 2002 OProfile authors
-+ * @remark Read the file COPYING
-+ *
-+ * @author John Levon <levon@movementarian.org>
-+ *
-+ * Modified by Aravind Menon and Jose Renato Santos for Xen
-+ * These modifications are:
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ *
-+ * Separated out arch-generic part
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/notifier.h>
-+#include <linux/smp.h>
-+#include <linux/oprofile.h>
-+#include <linux/sysdev.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/vmalloc.h>
-+#include <asm/pgtable.h>
-+#include <xen/evtchn.h>
-+#include <xen/xenoprof.h>
-+#include <xen/driver_util.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/xenoprof.h>
-+#include "../../../drivers/oprofile/cpu_buffer.h"
-+#include "../../../drivers/oprofile/event_buffer.h"
-+
-+#define MAX_XENOPROF_SAMPLES 16
-+
-+/* sample buffers shared with Xen */
-+xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS];
-+/* Shared buffer area */
-+struct xenoprof_shared_buffer shared_buffer;
-+
-+/* Passive sample buffers shared with Xen */
-+xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS];
-+/* Passive shared buffer area */
-+struct xenoprof_shared_buffer p_shared_buffer[MAX_OPROF_DOMAINS];
-+
-+static int xenoprof_start(void);
-+static void xenoprof_stop(void);
-+
-+static int xenoprof_enabled = 0;
-+static int xenoprof_is_primary = 0;
-+static int active_defined;
-+
-+/* Number of buffers in shared area (one per VCPU) */
-+int nbuf;
-+/* Mappings of VIRQ_XENOPROF to irq number (per cpu) */
-+int ovf_irq[NR_CPUS];
-+/* cpu model type string - copied from Xen memory space on XENOPROF_init command */
-+char cpu_type[XENOPROF_CPU_TYPE_SIZE];
-+
-+#ifdef CONFIG_PM
-+
-+static int xenoprof_suspend(struct sys_device * dev, pm_message_t state)
-+{
-+      if (xenoprof_enabled == 1)
-+              xenoprof_stop();
-+      return 0;
-+}
-+
-+
-+static int xenoprof_resume(struct sys_device * dev)
-+{
-+      if (xenoprof_enabled == 1)
-+              xenoprof_start();
-+      return 0;
-+}
-+
-+
-+static struct sysdev_class oprofile_sysclass = {
-+      set_kset_name("oprofile"),
-+      .resume         = xenoprof_resume,
-+      .suspend        = xenoprof_suspend
-+};
-+
-+
-+static struct sys_device device_oprofile = {
-+      .id     = 0,
-+      .cls    = &oprofile_sysclass,
-+};
-+
-+
-+static int __init init_driverfs(void)
-+{
-+      int error;
-+      if (!(error = sysdev_class_register(&oprofile_sysclass)))
-+              error = sysdev_register(&device_oprofile);
-+      return error;
-+}
-+
-+
-+static void exit_driverfs(void)
-+{
-+      sysdev_unregister(&device_oprofile);
-+      sysdev_class_unregister(&oprofile_sysclass);
-+}
-+
-+#else
-+#define init_driverfs() do { } while (0)
-+#define exit_driverfs() do { } while (0)
-+#endif /* CONFIG_PM */
-+
-+unsigned long long oprofile_samples = 0;
-+unsigned long long p_oprofile_samples = 0;
-+
-+unsigned int pdomains;
-+struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS];
-+
-+static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive)
-+{
-+      int head, tail, size;
-+
-+      head = buf->event_head;
-+      tail = buf->event_tail;
-+      size = buf->event_size;
-+
-+      if (tail > head) {
-+              while (tail < size) {
-+                      oprofile_add_pc(buf->event_log[tail].eip,
-+                                      buf->event_log[tail].mode,
-+                                      buf->event_log[tail].event);
-+                      if (!is_passive)
-+                              oprofile_samples++;
-+                      else
-+                              p_oprofile_samples++;
-+                      tail++;
-+              }
-+              tail = 0;
-+      }
-+      while (tail < head) {
-+              oprofile_add_pc(buf->event_log[tail].eip,
-+                              buf->event_log[tail].mode,
-+                              buf->event_log[tail].event);
-+              if (!is_passive)
-+                      oprofile_samples++;
-+              else
-+                      p_oprofile_samples++;
-+              tail++;
-+      }
-+
-+      buf->event_tail = tail;
-+}
-+
-+static void xenoprof_handle_passive(void)
-+{
-+      int i, j;
-+      int flag_domain, flag_switch = 0;
-+      
-+      for (i = 0; i < pdomains; i++) {
-+              flag_domain = 0;
-+              for (j = 0; j < passive_domains[i].nbuf; j++) {
-+                      xenoprof_buf_t *buf = p_xenoprof_buf[i][j];
-+                      if (buf->event_head == buf->event_tail)
-+                              continue;
-+                      if (!flag_domain) {
-+                              if (!oprofile_add_domain_switch(passive_domains[i].
-+                                                              domain_id))
-+                                      goto done;
-+                              flag_domain = 1;
-+                      }
-+                      xenoprof_add_pc(buf, 1);
-+                      flag_switch = 1;
-+              }
-+      }
-+done:
-+      if (flag_switch)
-+              oprofile_add_domain_switch(COORDINATOR_DOMAIN);
-+}
-+
-+static irqreturn_t 
-+xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
-+{
-+      struct xenoprof_buf * buf;
-+      int cpu;
-+      static unsigned long flag;
-+
-+      cpu = smp_processor_id();
-+      buf = xenoprof_buf[cpu];
-+
-+      xenoprof_add_pc(buf, 0);
-+
-+      if (xenoprof_is_primary && !test_and_set_bit(0, &flag)) {
-+              xenoprof_handle_passive();
-+              smp_mb__before_clear_bit();
-+              clear_bit(0, &flag);
-+      }
-+
-+      return IRQ_HANDLED;
-+}
-+
-+
-+static void unbind_virq(void)
-+{
-+      int i;
-+
-+      for_each_online_cpu(i) {
-+              if (ovf_irq[i] >= 0) {
-+                      unbind_from_irqhandler(ovf_irq[i], NULL);
-+                      ovf_irq[i] = -1;
-+              }
-+      }
-+}
-+
-+
-+static int bind_virq(void)
-+{
-+      int i, result;
-+
-+      for_each_online_cpu(i) {
-+              result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
-+                                               i,
-+                                               xenoprof_ovf_interrupt,
-+                                               SA_INTERRUPT,
-+                                               "xenoprof",
-+                                               NULL);
-+
-+              if (result < 0) {
-+                      unbind_virq();
-+                      return result;
-+              }
-+
-+              ovf_irq[i] = result;
-+      }
-+              
-+      return 0;
-+}
-+
-+
-+static void unmap_passive_list(void)
-+{
-+      int i;
-+      for (i = 0; i < pdomains; i++)
-+              xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]);
-+      pdomains = 0;
-+}
-+
-+
-+static int map_xenoprof_buffer(int max_samples)
-+{
-+      struct xenoprof_get_buffer get_buffer;
-+      struct xenoprof_buf *buf;
-+      int ret, i;
-+
-+      if ( shared_buffer.buffer )
-+              return 0;
-+
-+      get_buffer.max_samples = max_samples;
-+      ret = xenoprof_arch_map_shared_buffer(&get_buffer, &shared_buffer);
-+      if (ret)
-+              return ret;
-+      nbuf = get_buffer.nbuf;
-+
-+      for (i=0; i< nbuf; i++) {
-+              buf = (struct xenoprof_buf*) 
-+                      &shared_buffer.buffer[i * get_buffer.bufsize];
-+              BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
-+              xenoprof_buf[buf->vcpu_id] = buf;
-+      }
-+
-+      return 0;
-+}
-+
-+
-+static int xenoprof_setup(void)
-+{
-+      int ret;
-+
-+      if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) )
-+              return ret;
-+
-+      if ( (ret = bind_virq()) )
-+              return ret;
-+
-+      if (xenoprof_is_primary) {
-+              /* Define dom0 as an active domain if not done yet */
-+              if (!active_defined) {
-+                      domid_t domid;
-+                      ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
-+                      if (ret)
-+                              goto err;
-+                      domid = 0;
-+                      ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
-+                      if (ret)
-+                              goto err;
-+                      active_defined = 1;
-+              }
-+
-+              ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters, NULL);
-+              if (ret)
-+                      goto err;
-+              xenoprof_arch_counter();
-+              ret = HYPERVISOR_xenoprof_op(XENOPROF_setup_events, NULL);
-+
-+              if (ret)
-+                      goto err;
-+      }
-+
-+      ret = HYPERVISOR_xenoprof_op(XENOPROF_enable_virq, NULL);
-+      if (ret)
-+              goto err;
-+
-+      xenoprof_enabled = 1;
-+      return 0;
-+ err:
-+      unbind_virq();
-+      return ret;
-+}
-+
-+
-+static void xenoprof_shutdown(void)
-+{
-+      xenoprof_enabled = 0;
-+
-+      HYPERVISOR_xenoprof_op(XENOPROF_disable_virq, NULL);
-+
-+      if (xenoprof_is_primary) {
-+              HYPERVISOR_xenoprof_op(XENOPROF_release_counters, NULL);
-+              active_defined = 0;
-+      }
-+
-+      unbind_virq();
-+
-+      xenoprof_arch_unmap_shared_buffer(&shared_buffer);
-+      if (xenoprof_is_primary)
-+              unmap_passive_list();
-+}
-+
-+
-+static int xenoprof_start(void)
-+{
-+      int ret = 0;
-+
-+      if (xenoprof_is_primary)
-+              ret = HYPERVISOR_xenoprof_op(XENOPROF_start, NULL);
-+      if (!ret)
-+              xenoprof_arch_start();
-+      return ret;
-+}
-+
-+
-+static void xenoprof_stop(void)
-+{
-+      if (xenoprof_is_primary)
-+              HYPERVISOR_xenoprof_op(XENOPROF_stop, NULL);
-+      xenoprof_arch_stop();
-+}
-+
-+
-+static int xenoprof_set_active(int * active_domains,
-+                             unsigned int adomains)
-+{
-+      int ret = 0;
-+      int i;
-+      int set_dom0 = 0;
-+      domid_t domid;
-+
-+      if (!xenoprof_is_primary)
-+              return 0;
-+
-+      if (adomains > MAX_OPROF_DOMAINS)
-+              return -E2BIG;
-+
-+      ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
-+      if (ret)
-+              return ret;
-+
-+      for (i=0; i<adomains; i++) {
-+              domid = active_domains[i];
-+              if (domid != active_domains[i]) {
-+                      ret = -EINVAL;
-+                      goto out;
-+              }
-+              ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
-+              if (ret)
-+                      goto out;
-+              if (active_domains[i] == 0)
-+                      set_dom0 = 1;
-+      }
-+      /* dom0 must always be active but may not be in the list */ 
-+      if (!set_dom0) {
-+              domid = 0;
-+              ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
-+      }
-+
-+out:
-+      if (ret)
-+              HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
-+      active_defined = !ret;
-+      return ret;
-+}
-+
-+static int xenoprof_set_passive(int * p_domains,
-+                                unsigned int pdoms)
-+{
-+      int ret;
-+      int i, j;
-+      struct xenoprof_buf *buf;
-+
-+      if (!xenoprof_is_primary)
-+              return 0;
-+
-+      if (pdoms > MAX_OPROF_DOMAINS)
-+              return -E2BIG;
-+
-+      ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL);
-+      if (ret)
-+              return ret;
-+      unmap_passive_list();
-+
-+      for (i = 0; i < pdoms; i++) {
-+              passive_domains[i].domain_id = p_domains[i];
-+              passive_domains[i].max_samples = 2048;
-+              ret = xenoprof_arch_set_passive(&passive_domains[i],
-+                                              &p_shared_buffer[i]);
-+              if (ret)
-+                      goto out;
-+              for (j = 0; j < passive_domains[i].nbuf; j++) {
-+                      buf = (struct xenoprof_buf *)
-+                              &p_shared_buffer[i].buffer[j * passive_domains[i].bufsize];
-+                      BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
-+                      p_xenoprof_buf[i][buf->vcpu_id] = buf;
-+              }
-+      }
-+
-+      pdomains = pdoms;
-+      return 0;
-+
-+out:
-+      for (j = 0; j < i; j++)
-+              xenoprof_arch_unmap_shared_buffer(&p_shared_buffer[i]);
-+
-+      return ret;
-+}
-+
-+struct oprofile_operations xenoprof_ops = {
-+#ifdef HAVE_XENOPROF_CREATE_FILES
-+      .create_files   = xenoprof_create_files,
-+#endif
-+      .set_active     = xenoprof_set_active,
-+      .set_passive    = xenoprof_set_passive,
-+      .setup          = xenoprof_setup,
-+      .shutdown       = xenoprof_shutdown,
-+      .start          = xenoprof_start,
-+      .stop           = xenoprof_stop
-+};
-+
-+
-+/* in order to get driverfs right */
-+static int using_xenoprof;
-+
-+int __init xenoprofile_init(struct oprofile_operations * ops)
-+{
-+      struct xenoprof_init init;
-+      int ret, i;
-+
-+      ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init);
-+      if (!ret) {
-+              xenoprof_arch_init_counter(&init);
-+              xenoprof_is_primary = init.is_primary;
-+
-+              /*  cpu_type is detected by Xen */
-+              cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0;
-+              strncpy(cpu_type, init.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1);
-+              xenoprof_ops.cpu_type = cpu_type;
-+
-+              init_driverfs();
-+              using_xenoprof = 1;
-+              *ops = xenoprof_ops;
-+
-+              for (i=0; i<NR_CPUS; i++)
-+                      ovf_irq[i] = -1;
-+
-+              active_defined = 0;
-+      }
-+      printk(KERN_INFO "%s: ret %d, events %d, xenoprof_is_primary %d\n",
-+             __func__, ret, init.num_events, xenoprof_is_primary);
-+      return ret;
-+}
-+
-+
-+void xenoprofile_exit(void)
-+{
-+      if (using_xenoprof)
-+              exit_driverfs();
-+
-+      xenoprof_arch_unmap_shared_buffer(&shared_buffer);
-+      if (xenoprof_is_primary) {
-+              unmap_passive_list();
-+              HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL);
-+        }
-+}
-diff -Nur linux-2.6.16.33-noxen/fs/Kconfig linux-2.6.16.33/fs/Kconfig
---- linux-2.6.16.33-noxen/fs/Kconfig   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/fs/Kconfig 2007-01-08 15:00:45.000000000 +0000
-@@ -841,6 +841,7 @@
- config HUGETLBFS
-       bool "HugeTLB file system support"
-       depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
-+      depends !XEN
- config HUGETLB_PAGE
-       def_bool HUGETLBFS
-diff -Nur linux-2.6.16.33-noxen/fs/aio.c linux-2.6.16.33/fs/aio.c
---- linux-2.6.16.33-noxen/fs/aio.c     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/fs/aio.c   2007-05-23 21:00:01.000000000 +0000
-@@ -34,6 +34,11 @@
- #include <asm/uaccess.h>
- #include <asm/mmu_context.h>
-+#ifdef CONFIG_EPOLL
-+#include <linux/poll.h>
-+#include <linux/eventpoll.h>
-+#endif
-+
- #if DEBUG > 1
- #define dprintk               printk
- #else
-@@ -1016,6 +1021,10 @@
-       if (waitqueue_active(&ctx->wait))
-               wake_up(&ctx->wait);
-+#ifdef CONFIG_EPOLL
-+      if (ctx->file && waitqueue_active(&ctx->poll_wait))
-+              wake_up(&ctx->poll_wait);
-+#endif
-       if (ret)
-               put_ioctx(ctx);
-@@ -1025,6 +1034,8 @@
- /* aio_read_evt
-  *    Pull an event off of the ioctx's event ring.  Returns the number of 
-  *    events fetched (0 or 1 ;-)
-+ *    If ent parameter is 0, just returns the number of events that would
-+ *    be fetched.
-  *    FIXME: make this use cmpxchg.
-  *    TODO: make the ringbuffer user mmap()able (requires FIXME).
-  */
-@@ -1047,13 +1058,18 @@
-       head = ring->head % info->nr;
-       if (head != ring->tail) {
--              struct io_event *evp = aio_ring_event(info, head, KM_USER1);
--              *ent = *evp;
--              head = (head + 1) % info->nr;
--              smp_mb(); /* finish reading the event before updatng the head */
--              ring->head = head;
--              ret = 1;
--              put_aio_ring_event(evp, KM_USER1);
-+              if (ent) { /* event requested */
-+                      struct io_event *evp =
-+                              aio_ring_event(info, head, KM_USER1);
-+                      *ent = *evp;
-+                      head = (head + 1) % info->nr;
-+                      /* finish reading the event before updatng the head */
-+                      smp_mb();
-+                      ring->head = head;
-+                      ret = 1;
-+                      put_aio_ring_event(evp, KM_USER1);
-+              } else /* only need to know availability */
-+                      ret = 1;
-       }
-       spin_unlock(&info->ring_lock);
-@@ -1236,9 +1252,78 @@
-       aio_cancel_all(ioctx);
-       wait_for_all_aios(ioctx);
-+#ifdef CONFIG_EPOLL
-+      /* forget the poll file, but it's up to the user to close it */
-+      if (ioctx->file) {
-+              ioctx->file->private_data = 0;
-+              ioctx->file = 0;
-+      }
-+#endif
-       put_ioctx(ioctx);       /* once for the lookup */
- }
-+#ifdef CONFIG_EPOLL
-+
-+static int aio_queue_fd_close(struct inode *inode, struct file *file)
-+{
-+      struct kioctx *ioctx = file->private_data;
-+      if (ioctx) {
-+              file->private_data = 0;
-+              spin_lock_irq(&ioctx->ctx_lock);
-+              ioctx->file = 0;
-+              spin_unlock_irq(&ioctx->ctx_lock);
-+      }
-+      return 0;
-+}
-+
-+static unsigned int aio_queue_fd_poll(struct file *file, poll_table *wait)
-+{     unsigned int pollflags = 0;
-+      struct kioctx *ioctx = file->private_data;
-+
-+      if (ioctx) {
-+
-+              spin_lock_irq(&ioctx->ctx_lock);
-+              /* Insert inside our poll wait queue */
-+              poll_wait(file, &ioctx->poll_wait, wait);
-+
-+              /* Check our condition */
-+              if (aio_read_evt(ioctx, 0))
-+                      pollflags = POLLIN | POLLRDNORM;
-+              spin_unlock_irq(&ioctx->ctx_lock);
-+      }
-+
-+      return pollflags;
-+}
-+
-+static struct file_operations aioq_fops = {
-+      .release        = aio_queue_fd_close,
-+      .poll           = aio_queue_fd_poll
-+};
-+
-+/* make_aio_fd:
-+ *  Create a file descriptor that can be used to poll the event queue.
-+ *  Based and piggybacked on the excellent epoll code.
-+ */
-+
-+static int make_aio_fd(struct kioctx *ioctx)
-+{
-+      int error, fd;
-+      struct inode *inode;
-+      struct file *file;
-+
-+      error = ep_getfd(&fd, &inode, &file, NULL, &aioq_fops);
-+      if (error)
-+              return error;
-+
-+      /* associate the file with the IO context */
-+      file->private_data = ioctx;
-+      ioctx->file = file;
-+      init_waitqueue_head(&ioctx->poll_wait);
-+      return fd;
-+}
-+#endif
-+
-+
- /* sys_io_setup:
-  *    Create an aio_context capable of receiving at least nr_events.
-  *    ctxp must not point to an aio_context that already exists, and
-@@ -1251,18 +1336,30 @@
-  *    resources are available.  May fail with -EFAULT if an invalid
-  *    pointer is passed for ctxp.  Will fail with -ENOSYS if not
-  *    implemented.
-+ *
-+ *    To request a selectable fd, the user context has to be initialized
-+ *    to 1, instead of 0, and the return value is the fd.
-+ *    This keeps the system call compatible, since a non-zero value
-+ *    was not allowed so far.
-  */
- asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
- {
-       struct kioctx *ioctx = NULL;
-       unsigned long ctx;
-       long ret;
-+      int make_fd = 0;
-       ret = get_user(ctx, ctxp);
-       if (unlikely(ret))
-               goto out;
-       ret = -EINVAL;
-+#ifdef CONFIG_EPOLL
-+      if (ctx == 1) {
-+              make_fd = 1;
-+              ctx = 0;
-+      }
-+#endif
-       if (unlikely(ctx || nr_events == 0)) {
-               pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
-                        ctx, nr_events);
-@@ -1273,8 +1370,12 @@
-       ret = PTR_ERR(ioctx);
-       if (!IS_ERR(ioctx)) {
-               ret = put_user(ioctx->user_id, ctxp);
--              if (!ret)
--                      return 0;
-+#ifdef CONFIG_EPOLL
-+              if (make_fd && ret >= 0)
-+                      ret = make_aio_fd(ioctx);
-+#endif
-+              if (ret >= 0)
-+                      return ret;
-               get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
-               io_destroy(ioctx);
-diff -Nur linux-2.6.16.33-noxen/fs/eventpoll.c linux-2.6.16.33/fs/eventpoll.c
---- linux-2.6.16.33-noxen/fs/eventpoll.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/fs/eventpoll.c     2007-05-23 21:00:01.000000000 +0000
-@@ -235,8 +235,6 @@
- static void ep_poll_safewake_init(struct poll_safewake *psw);
- static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
--static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
--                  struct eventpoll *ep);
- static int ep_alloc(struct eventpoll **pep);
- static void ep_free(struct eventpoll *ep);
- static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
-@@ -266,7 +264,7 @@
- static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
-                  int maxevents, long timeout);
- static int eventpollfs_delete_dentry(struct dentry *dentry);
--static struct inode *ep_eventpoll_inode(void);
-+static struct inode *ep_eventpoll_inode(struct file_operations *fops);
- static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
-                                             int flags, const char *dev_name,
-                                             void *data);
-@@ -525,7 +523,7 @@
-        * Creates all the items needed to setup an eventpoll file. That is,
-        * a file structure, and inode and a free file descriptor.
-        */
--      error = ep_getfd(&fd, &inode, &file, ep);
-+      error = ep_getfd(&fd, &inode, &file, ep, &eventpoll_fops);
-       if (error)
-               goto eexit_2;
-@@ -710,8 +708,8 @@
- /*
-  * Creates the file descriptor to be used by the epoll interface.
-  */
--static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
--                  struct eventpoll *ep)
-+int ep_getfd(int *efd, struct inode **einode, struct file **efile,
-+                  struct eventpoll *ep, struct file_operations *fops)
- {
-       struct qstr this;
-       char name[32];
-@@ -727,7 +725,7 @@
-               goto eexit_1;
-       /* Allocates an inode from the eventpoll file system */
--      inode = ep_eventpoll_inode();
-+      inode = ep_eventpoll_inode(fops);
-       error = PTR_ERR(inode);
-       if (IS_ERR(inode))
-               goto eexit_2;
-@@ -758,7 +756,7 @@
-       file->f_pos = 0;
-       file->f_flags = O_RDONLY;
--      file->f_op = &eventpoll_fops;
-+      file->f_op = fops;
-       file->f_mode = FMODE_READ;
-       file->f_version = 0;
-       file->private_data = ep;
-@@ -1574,7 +1572,7 @@
- }
--static struct inode *ep_eventpoll_inode(void)
-+static struct inode *ep_eventpoll_inode(struct file_operations *fops)
- {
-       int error = -ENOMEM;
-       struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
-@@ -1582,7 +1580,7 @@
-       if (!inode)
-               goto eexit_1;
--      inode->i_fop = &eventpoll_fops;
-+      inode->i_fop = fops;
-       /*
-        * Mark the inode dirty from the very beginning,
-diff -Nur linux-2.6.16.33-noxen/fs/proc/proc_misc.c linux-2.6.16.33/fs/proc/proc_misc.c
---- linux-2.6.16.33-noxen/fs/proc/proc_misc.c  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/fs/proc/proc_misc.c        2007-05-23 21:00:01.000000000 +0000
-@@ -433,7 +433,7 @@
-               (unsigned long long)cputime64_to_clock_t(irq),
-               (unsigned long long)cputime64_to_clock_t(softirq),
-               (unsigned long long)cputime64_to_clock_t(steal));
--      for_each_online_cpu(i) {
-+      for_each_cpu(i) {
-               /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
-               user = kstat_cpu(i).cpustat.user;
-diff -Nur linux-2.6.16.33-noxen/include/asm-generic/vmlinux.lds.h linux-2.6.16.33/include/asm-generic/vmlinux.lds.h
---- linux-2.6.16.33-noxen/include/asm-generic/vmlinux.lds.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-generic/vmlinux.lds.h  2007-05-23 21:00:01.000000000 +0000
-@@ -152,3 +152,6 @@
-               .stab.index 0 : { *(.stab.index) }                      \
-               .stab.indexstr 0 : { *(.stab.indexstr) }                \
-               .comment 0 : { *(.comment) }
-+
-+#define NOTES                                                         \
-+              .notes : { *(.note.*) } :note
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/a.out.h linux-2.6.16.33/include/asm-i386/a.out.h
---- linux-2.6.16.33-noxen/include/asm-i386/a.out.h     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/a.out.h   2007-01-08 15:00:45.000000000 +0000
-@@ -19,7 +19,7 @@
- #ifdef __KERNEL__
--#define STACK_TOP     TASK_SIZE
-+#define STACK_TOP     (TASK_SIZE - 3*PAGE_SIZE)
- #endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/apic.h linux-2.6.16.33/include/asm-i386/apic.h
---- linux-2.6.16.33-noxen/include/asm-i386/apic.h      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/apic.h    2007-01-08 15:00:45.000000000 +0000
-@@ -132,10 +132,12 @@
- extern int disable_timer_pin_1;
-+#ifndef CONFIG_XEN
- void smp_send_timer_broadcast_ipi(struct pt_regs *regs);
- void switch_APIC_timer_to_ipi(void *cpumask);
- void switch_ipi_to_APIC_timer(void *cpumask);
- #define ARCH_APICTIMER_STOPS_ON_C3    1
-+#endif
- extern int timer_over_8254;
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/atomic.h linux-2.6.16.33/include/asm-i386/atomic.h
---- linux-2.6.16.33-noxen/include/asm-i386/atomic.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/atomic.h  2007-01-08 15:00:45.000000000 +0000
-@@ -4,18 +4,13 @@
- #include <linux/config.h>
- #include <linux/compiler.h>
- #include <asm/processor.h>
-+#include <asm/smp_alt.h>
- /*
-  * Atomic operations that C can't guarantee us.  Useful for
-  * resource counting etc..
-  */
--#ifdef CONFIG_SMP
--#define LOCK "lock ; "
--#else
--#define LOCK ""
--#endif
--
- /*
-  * Make sure gcc doesn't try to be clever and move things around
-  * on us. We need to use _exactly_ the address the user gave us,
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/bitops.h linux-2.6.16.33/include/asm-i386/bitops.h
---- linux-2.6.16.33-noxen/include/asm-i386/bitops.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/bitops.h  2007-01-08 15:00:45.000000000 +0000
-@@ -7,6 +7,7 @@
- #include <linux/config.h>
- #include <linux/compiler.h>
-+#include <asm/smp_alt.h>
- /*
-  * These have to be done with inline assembly: that way the bit-setting
-@@ -16,12 +17,6 @@
-  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
-  */
--#ifdef CONFIG_SMP
--#define LOCK_PREFIX "lock ; "
--#else
--#define LOCK_PREFIX ""
--#endif
--
- #define ADDR (*(volatile long *) addr)
- /**
-@@ -41,7 +36,7 @@
-  */
- static inline void set_bit(int nr, volatile unsigned long * addr)
- {
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btsl %1,%0"
-               :"+m" (ADDR)
-               :"Ir" (nr));
-@@ -76,7 +71,7 @@
-  */
- static inline void clear_bit(int nr, volatile unsigned long * addr)
- {
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btrl %1,%0"
-               :"+m" (ADDR)
-               :"Ir" (nr));
-@@ -121,7 +116,7 @@
-  */
- static inline void change_bit(int nr, volatile unsigned long * addr)
- {
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btcl %1,%0"
-               :"+m" (ADDR)
-               :"Ir" (nr));
-@@ -140,7 +135,7 @@
- {
-       int oldbit;
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btsl %2,%1\n\tsbbl %0,%0"
-               :"=r" (oldbit),"+m" (ADDR)
-               :"Ir" (nr) : "memory");
-@@ -180,7 +175,7 @@
- {
-       int oldbit;
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btrl %2,%1\n\tsbbl %0,%0"
-               :"=r" (oldbit),"+m" (ADDR)
-               :"Ir" (nr) : "memory");
-@@ -231,7 +226,7 @@
- {
-       int oldbit;
--      __asm__ __volatile__( LOCK_PREFIX
-+      __asm__ __volatile__( LOCK
-               "btcl %2,%1\n\tsbbl %0,%0"
-               :"=r" (oldbit),"+m" (ADDR)
-               :"Ir" (nr) : "memory");
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/elf.h linux-2.6.16.33/include/asm-i386/elf.h
---- linux-2.6.16.33-noxen/include/asm-i386/elf.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/elf.h     2007-01-08 15:00:45.000000000 +0000
-@@ -129,11 +129,16 @@
- #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
- #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
--#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
-+#define VSYSCALL_BASE (PAGE_OFFSET - 2*PAGE_SIZE)
- #define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
- #define VSYSCALL_ENTRY        ((unsigned long) &__kernel_vsyscall)
- extern void __kernel_vsyscall;
-+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
-+struct linux_binprm;
-+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
-+                                       int executable_stack);
-+
- #define ARCH_DLINFO                                           \
- do {                                                          \
-               NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);        \
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/fixmap.h linux-2.6.16.33/include/asm-i386/fixmap.h
---- linux-2.6.16.33-noxen/include/asm-i386/fixmap.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/fixmap.h  2007-01-08 15:00:45.000000000 +0000
-@@ -20,7 +20,7 @@
-  * Leave one empty page between vmalloc'ed areas and
-  * the start of the fixmap.
-  */
--#define __FIXADDR_TOP 0xfffff000
-+extern unsigned long __FIXADDR_TOP;
- #ifndef __ASSEMBLY__
- #include <linux/kernel.h>
-@@ -52,7 +52,6 @@
-  */
- enum fixed_addresses {
-       FIX_HOLE,
--      FIX_VSYSCALL,
- #ifdef CONFIG_X86_LOCAL_APIC
-       FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
- #endif
-@@ -95,6 +94,8 @@
- extern void __set_fixmap (enum fixed_addresses idx,
-                                       unsigned long phys, pgprot_t flags);
-+extern void set_fixaddr_top(unsigned long top);
-+
- #define set_fixmap(idx, phys) \
-               __set_fixmap(idx, phys, PAGE_KERNEL)
- /*
-@@ -116,14 +117,6 @@
- #define __fix_to_virt(x)      (FIXADDR_TOP - ((x) << PAGE_SHIFT))
- #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
--/*
-- * This is the range that is readable by user mode, and things
-- * acting like user mode such as get_user_pages.
-- */
--#define FIXADDR_USER_START    (__fix_to_virt(FIX_VSYSCALL))
--#define FIXADDR_USER_END      (FIXADDR_USER_START + PAGE_SIZE)
--
--
- extern void __this_fixmap_does_not_exist(void);
- /*
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/futex.h linux-2.6.16.33/include/asm-i386/futex.h
---- linux-2.6.16.33-noxen/include/asm-i386/futex.h     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/futex.h   2007-01-08 15:00:45.000000000 +0000
-@@ -28,7 +28,7 @@
- "1:   movl    %2, %0\n\
-       movl    %0, %3\n"                                       \
-       insn "\n"                                               \
--"2:   " LOCK_PREFIX "cmpxchgl %3, %2\n\
-+"2:   " LOCK "cmpxchgl %3, %2\n\
-       jnz     1b\n\
- 3:    .section .fixup,\"ax\"\n\
- 4:    mov     %5, %1\n\
-@@ -68,7 +68,7 @@
- #endif
-               switch (op) {
-               case FUTEX_OP_ADD:
--                      __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
-+                      __futex_atomic_op1(LOCK "xaddl %0, %2", ret,
-                                          oldval, uaddr, oparg);
-                       break;
-               case FUTEX_OP_OR:
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/kexec.h linux-2.6.16.33/include/asm-i386/kexec.h
---- linux-2.6.16.33-noxen/include/asm-i386/kexec.h     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/kexec.h   2007-01-08 15:00:45.000000000 +0000
-@@ -1,6 +1,26 @@
- #ifndef _I386_KEXEC_H
- #define _I386_KEXEC_H
-+#define PA_CONTROL_PAGE  0
-+#define VA_CONTROL_PAGE  1
-+#define PA_PGD           2
-+#define VA_PGD           3
-+#define PA_PTE_0         4
-+#define VA_PTE_0         5
-+#define PA_PTE_1         6
-+#define VA_PTE_1         7
-+#ifdef CONFIG_X86_PAE
-+#define PA_PMD_0         8
-+#define VA_PMD_0         9
-+#define PA_PMD_1         10
-+#define VA_PMD_1         11
-+#define PAGES_NR         12
-+#else
-+#define PAGES_NR         8
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+
- #include <asm/fixmap.h>
- #include <asm/ptrace.h>
- #include <asm/string.h>
-@@ -72,5 +92,26 @@
-                newregs->eip = (unsigned long)current_text_addr();
-        }
- }
-+asmlinkage NORET_TYPE void
-+relocate_kernel(unsigned long indirection_page,
-+              unsigned long control_page,
-+              unsigned long start_address,
-+              unsigned int has_pae) ATTRIB_NORET;
-+
-+
-+/* Under Xen we need to work with machine addresses. These macros give the
-+ * machine address of a certain page to the generic kexec code instead of 
-+ * the pseudo physical address which would be given by the default macros.
-+ */
-+
-+#ifdef CONFIG_XEN
-+#define KEXEC_ARCH_HAS_PAGE_MACROS
-+#define kexec_page_to_pfn(page)  pfn_to_mfn(page_to_pfn(page))
-+#define kexec_pfn_to_page(pfn)   pfn_to_page(mfn_to_pfn(pfn))
-+#define kexec_virt_to_phys(addr) virt_to_machine(addr)
-+#define kexec_phys_to_virt(addr) phys_to_virt(machine_to_phys(addr))
-+#endif
-+
-+#endif /* __ASSEMBLY__ */
- #endif /* _I386_KEXEC_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-default/mach_traps.h linux-2.6.16.33/include/asm-i386/mach-default/mach_traps.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-default/mach_traps.h   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-default/mach_traps.h 2007-01-08 15:00:45.000000000 +0000
-@@ -15,6 +15,18 @@
-       outb(reason, 0x61);
- }
-+static inline void clear_io_check_error(unsigned char reason)
-+{
-+      unsigned long i;
-+
-+      reason = (reason & 0xf) | 8;
-+      outb(reason, 0x61);
-+      i = 2000;
-+      while (--i) udelay(1000);
-+      reason &= ~8;
-+      outb(reason, 0x61);
-+}
-+
- static inline unsigned char get_nmi_reason(void)
- {
-       return inb(0x61);
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/agp.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/agp.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/agp.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/agp.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,37 @@
-+#ifndef AGP_H
-+#define AGP_H 1
-+
-+#include <asm/pgtable.h>
-+#include <asm/cacheflush.h>
-+#include <asm/system.h>
-+
-+/* 
-+ * Functions to keep the agpgart mappings coherent with the MMU.
-+ * The GART gives the CPU a physical alias of pages in memory. The alias region is
-+ * mapped uncacheable. Make sure there are no conflicting mappings
-+ * with different cachability attributes for the same page. This avoids
-+ * data corruption on some CPUs.
-+ */
-+
-+int map_page_into_agp(struct page *page);
-+int unmap_page_from_agp(struct page *page);
-+#define flush_agp_mappings() global_flush_tlb()
-+
-+/* Could use CLFLUSH here if the cpu supports it. But then it would
-+   need to be called for each cacheline of the whole page so it may not be 
-+   worth it. Would need a page for it. */
-+#define flush_agp_cache() wbinvd()
-+
-+/* Convert a physical address to an address suitable for the GART. */
-+#define phys_to_gart(x) phys_to_machine(x)
-+#define gart_to_phys(x) machine_to_phys(x)
-+
-+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
-+#define alloc_gatt_pages(order)       ({                                          \
-+      char *_t; dma_addr_t _d;                                            \
-+      _t = dma_alloc_coherent(NULL,PAGE_SIZE<<(order),&_d,GFP_KERNEL);    \
-+      _t; })
-+#define free_gatt_pages(table, order) \
-+      dma_free_coherent(NULL,PAGE_SIZE<<(order),(table),virt_to_bus(table))
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/desc.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/desc.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/desc.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/desc.h       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,164 @@
-+#ifndef __ARCH_DESC_H
-+#define __ARCH_DESC_H
-+
-+#include <asm/ldt.h>
-+#include <asm/segment.h>
-+
-+#define CPU_16BIT_STACK_SIZE 1024
-+
-+#ifndef __ASSEMBLY__
-+
-+#include <linux/preempt.h>
-+#include <linux/smp.h>
-+
-+#include <asm/mmu.h>
-+
-+extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
-+
-+DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
-+
-+struct Xgt_desc_struct {
-+      unsigned short size;
-+      unsigned long address __attribute__((packed));
-+      unsigned short pad;
-+} __attribute__ ((packed));
-+
-+extern struct Xgt_desc_struct idt_descr;
-+DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
-+
-+
-+static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
-+{
-+      return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
-+}
-+
-+#define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
-+#define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8))
-+
-+#define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr))
-+#define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr))
-+#define load_tr(tr) __asm__ __volatile("ltr %0"::"mr" (tr))
-+#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"mr" (ldt))
-+
-+#define store_gdt(dtr) __asm__ ("sgdt %0":"=m" (*dtr))
-+#define store_idt(dtr) __asm__ ("sidt %0":"=m" (*dtr))
-+#define store_tr(tr) __asm__ ("str %0":"=mr" (tr))
-+#define store_ldt(ldt) __asm__ ("sldt %0":"=mr" (ldt))
-+
-+/*
-+ * This is the ldt that every process will get unless we need
-+ * something other than this.
-+ */
-+extern struct desc_struct default_ldt[];
-+extern void set_intr_gate(unsigned int irq, void * addr);
-+
-+#define _set_tssldt_desc(n,addr,limit,type) \
-+__asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
-+      "movw %w1,2(%2)\n\t" \
-+      "rorl $16,%1\n\t" \
-+      "movb %b1,4(%2)\n\t" \
-+      "movb %4,5(%2)\n\t" \
-+      "movb $0,6(%2)\n\t" \
-+      "movb %h1,7(%2)\n\t" \
-+      "rorl $16,%1" \
-+      : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type))
-+
-+#ifndef CONFIG_X86_NO_TSS
-+static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
-+{
-+      _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
-+              offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
-+}
-+
-+#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr)
-+#endif
-+
-+static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
-+{
-+      _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
-+}
-+
-+#define LDT_entry_a(info) \
-+      ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
-+
-+#define LDT_entry_b(info) \
-+      (((info)->base_addr & 0xff000000) | \
-+      (((info)->base_addr & 0x00ff0000) >> 16) | \
-+      ((info)->limit & 0xf0000) | \
-+      (((info)->read_exec_only ^ 1) << 9) | \
-+      ((info)->contents << 10) | \
-+      (((info)->seg_not_present ^ 1) << 15) | \
-+      ((info)->seg_32bit << 22) | \
-+      ((info)->limit_in_pages << 23) | \
-+      ((info)->useable << 20) | \
-+      0x7000)
-+
-+#define LDT_empty(info) (\
-+      (info)->base_addr       == 0    && \
-+      (info)->limit           == 0    && \
-+      (info)->contents        == 0    && \
-+      (info)->read_exec_only  == 1    && \
-+      (info)->seg_32bit       == 0    && \
-+      (info)->limit_in_pages  == 0    && \
-+      (info)->seg_not_present == 1    && \
-+      (info)->useable         == 0    )
-+
-+extern int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b);
-+
-+#if TLS_SIZE != 24
-+# error update this code.
-+#endif
-+
-+static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
-+{
-+#define C(i) HYPERVISOR_update_descriptor(virt_to_machine(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]), *(u64 *)&t->tls_array[i])
-+      C(0); C(1); C(2);
-+#undef C
-+}
-+
-+static inline void clear_LDT(void)
-+{
-+      int cpu = get_cpu();
-+
-+      /*
-+       * NB. We load the default_ldt for lcall7/27 handling on demand, as
-+       * it slows down context switching. Noone uses it anyway.
-+       */
-+      cpu = cpu;              /* XXX avoid compiler warning */
-+      xen_set_ldt(0UL, 0);
-+      put_cpu();
-+}
-+
-+/*
-+ * load one particular LDT into the current CPU
-+ */
-+static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
-+{
-+      void *segments = pc->ldt;
-+      int count = pc->size;
-+
-+      if (likely(!count))
-+              segments = NULL;
-+
-+      xen_set_ldt((unsigned long)segments, count);
-+}
-+
-+static inline void load_LDT(mm_context_t *pc)
-+{
-+      int cpu = get_cpu();
-+      load_LDT_nolock(pc, cpu);
-+      put_cpu();
-+}
-+
-+static inline unsigned long get_desc_base(unsigned long *desc)
-+{
-+      unsigned long base;
-+      base = ((desc[0] >> 16)  & 0x0000ffff) |
-+              ((desc[1] << 16) & 0x00ff0000) |
-+              (desc[1] & 0xff000000);
-+      return base;
-+}
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/dma-mapping.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/dma-mapping.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/dma-mapping.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/dma-mapping.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,152 @@
-+#ifndef _ASM_I386_DMA_MAPPING_H
-+#define _ASM_I386_DMA_MAPPING_H
-+
-+/*
-+ * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
-+ * documentation.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/mm.h>
-+#include <asm/cache.h>
-+#include <asm/io.h>
-+#include <asm/scatterlist.h>
-+#include <asm/swiotlb.h>
-+
-+static inline int
-+address_needs_mapping(struct device *hwdev, dma_addr_t addr)
-+{
-+      dma_addr_t mask = 0xffffffff;
-+      /* If the device has a mask, use it, otherwise default to 32 bits */
-+      if (hwdev && hwdev->dma_mask)
-+              mask = *hwdev->dma_mask;
-+      return (addr & ~mask) != 0;
-+}
-+
-+static inline int
-+range_straddles_page_boundary(void *p, size_t size)
-+{
-+      extern unsigned long *contiguous_bitmap;
-+      return (((((unsigned long)p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
-+              !test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap));
-+}
-+
-+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-+
-+void *dma_alloc_coherent(struct device *dev, size_t size,
-+                         dma_addr_t *dma_handle, gfp_t flag);
-+
-+void dma_free_coherent(struct device *dev, size_t size,
-+                       void *vaddr, dma_addr_t dma_handle);
-+
-+extern dma_addr_t
-+dma_map_single(struct device *dev, void *ptr, size_t size,
-+             enum dma_data_direction direction);
-+
-+extern void
-+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-+               enum dma_data_direction direction);
-+
-+extern int dma_map_sg(struct device *hwdev, struct scatterlist *sg,
-+                    int nents, enum dma_data_direction direction);
-+extern void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg,
-+                       int nents, enum dma_data_direction direction);
-+
-+extern dma_addr_t
-+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
-+           size_t size, enum dma_data_direction direction);
-+
-+extern void
-+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-+             enum dma_data_direction direction);
-+
-+extern void
-+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-+                      enum dma_data_direction direction);
-+
-+extern void
-+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-+                           enum dma_data_direction direction);
-+
-+static inline void
-+dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-+                            unsigned long offset, size_t size,
-+                            enum dma_data_direction direction)
-+{
-+      dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
-+}
-+
-+static inline void
-+dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-+                               unsigned long offset, size_t size,
-+                               enum dma_data_direction direction)
-+{
-+      dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
-+}
-+
-+static inline void
-+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-+                  enum dma_data_direction direction)
-+{
-+      if (swiotlb)
-+              swiotlb_sync_sg_for_cpu(dev,sg,nelems,direction);
-+      flush_write_buffers();
-+}
-+
-+static inline void
-+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-+                  enum dma_data_direction direction)
-+{
-+      if (swiotlb)
-+              swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
-+      flush_write_buffers();
-+}
-+
-+extern int
-+dma_mapping_error(dma_addr_t dma_addr);
-+
-+extern int
-+dma_supported(struct device *dev, u64 mask);
-+
-+static inline int
-+dma_set_mask(struct device *dev, u64 mask)
-+{
-+      if(!dev->dma_mask || !dma_supported(dev, mask))
-+              return -EIO;
-+
-+      *dev->dma_mask = mask;
-+
-+      return 0;
-+}
-+
-+static inline int
-+dma_get_cache_alignment(void)
-+{
-+      /* no easy way to get cache size on all x86, so return the
-+       * maximum possible, to be safe */
-+      return (1 << INTERNODE_CACHE_SHIFT);
-+}
-+
-+#define dma_is_consistent(d)  (1)
-+
-+static inline void
-+dma_cache_sync(void *vaddr, size_t size,
-+             enum dma_data_direction direction)
-+{
-+      flush_write_buffers();
-+}
-+
-+#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-+extern int
-+dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-+                          dma_addr_t device_addr, size_t size, int flags);
-+
-+extern void
-+dma_release_declared_memory(struct device *dev);
-+
-+extern void *
-+dma_mark_declared_memory_occupied(struct device *dev,
-+                                dma_addr_t device_addr, size_t size);
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/fixmap.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/fixmap.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/fixmap.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/fixmap.h     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,155 @@
-+/*
-+ * fixmap.h: compile-time virtual memory allocation
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License.  See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1998 Ingo Molnar
-+ *
-+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
-+ */
-+
-+#ifndef _ASM_FIXMAP_H
-+#define _ASM_FIXMAP_H
-+
-+#include <linux/config.h>
-+
-+/* used by vmalloc.c, vsyscall.lds.S.
-+ *
-+ * Leave one empty page between vmalloc'ed areas and
-+ * the start of the fixmap.
-+ */
-+extern unsigned long __FIXADDR_TOP;
-+
-+#ifndef __ASSEMBLY__
-+#include <linux/kernel.h>
-+#include <asm/acpi.h>
-+#include <asm/apicdef.h>
-+#include <asm/page.h>
-+#ifdef CONFIG_HIGHMEM
-+#include <linux/threads.h>
-+#include <asm/kmap_types.h>
-+#endif
-+
-+/*
-+ * Here we define all the compile-time 'special' virtual
-+ * addresses. The point is to have a constant address at
-+ * compile time, but to set the physical address only
-+ * in the boot process. We allocate these special addresses
-+ * from the end of virtual memory (0xfffff000) backwards.
-+ * Also this lets us do fail-safe vmalloc(), we
-+ * can guarantee that these special addresses and
-+ * vmalloc()-ed addresses never overlap.
-+ *
-+ * these 'compile-time allocated' memory buffers are
-+ * fixed-size 4k pages. (or larger if used with an increment
-+ * highger than 1) use fixmap_set(idx,phys) to associate
-+ * physical memory with fixmap indices.
-+ *
-+ * TLB entries of such buffers will not be flushed across
-+ * task switches.
-+ */
-+enum fixed_addresses {
-+      FIX_HOLE,
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
-+#endif
-+#ifdef CONFIG_X86_IO_APIC
-+      FIX_IO_APIC_BASE_0,
-+      FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
-+#endif
-+#ifdef CONFIG_X86_VISWS_APIC
-+      FIX_CO_CPU,     /* Cobalt timer */
-+      FIX_CO_APIC,    /* Cobalt APIC Redirection Table */ 
-+      FIX_LI_PCIA,    /* Lithium PCI Bridge A */
-+      FIX_LI_PCIB,    /* Lithium PCI Bridge B */
-+#endif
-+#ifdef CONFIG_X86_F00F_BUG
-+      FIX_F00F_IDT,   /* Virtual mapping for IDT */
-+#endif
-+#ifdef CONFIG_X86_CYCLONE_TIMER
-+      FIX_CYCLONE_TIMER, /*cyclone timer register*/
-+#endif 
-+#ifdef CONFIG_HIGHMEM
-+      FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
-+      FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
-+#endif
-+#ifdef CONFIG_ACPI
-+      FIX_ACPI_BEGIN,
-+      FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
-+#endif
-+#ifdef CONFIG_PCI_MMCONFIG
-+      FIX_PCIE_MCFG,
-+#endif
-+      FIX_SHARED_INFO,
-+#define NR_FIX_ISAMAPS        256
-+      FIX_ISAMAP_END,
-+      FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1,
-+      __end_of_permanent_fixed_addresses,
-+      /* temporary boot-time mappings, used before ioremap() is functional */
-+#define NR_FIX_BTMAPS 16
-+      FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
-+      FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
-+      FIX_WP_TEST,
-+      __end_of_fixed_addresses
-+};
-+
-+extern void __set_fixmap(enum fixed_addresses idx,
-+                                      maddr_t phys, pgprot_t flags);
-+
-+extern void set_fixaddr_top(void);
-+
-+#define set_fixmap(idx, phys) \
-+              __set_fixmap(idx, phys, PAGE_KERNEL)
-+/*
-+ * Some hardware wants to get fixmapped without caching.
-+ */
-+#define set_fixmap_nocache(idx, phys) \
-+              __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
-+
-+#define clear_fixmap(idx) \
-+              __set_fixmap(idx, 0, __pgprot(0))
-+
-+#define FIXADDR_TOP   ((unsigned long)__FIXADDR_TOP)
-+
-+#define __FIXADDR_SIZE        (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
-+#define __FIXADDR_BOOT_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
-+#define FIXADDR_START         (FIXADDR_TOP - __FIXADDR_SIZE)
-+#define FIXADDR_BOOT_START    (FIXADDR_TOP - __FIXADDR_BOOT_SIZE)
-+
-+#define __fix_to_virt(x)      (FIXADDR_TOP - ((x) << PAGE_SHIFT))
-+#define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
-+
-+extern void __this_fixmap_does_not_exist(void);
-+
-+/*
-+ * 'index to address' translation. If anyone tries to use the idx
-+ * directly without tranlation, we catch the bug with a NULL-deference
-+ * kernel oops. Illegal ranges of incoming indices are caught too.
-+ */
-+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
-+{
-+      /*
-+       * this branch gets completely eliminated after inlining,
-+       * except when someone tries to use fixaddr indices in an
-+       * illegal way. (such as mixing up address types or using
-+       * out-of-range indices).
-+       *
-+       * If it doesn't get removed, the linker will complain
-+       * loudly with a reasonably clear error message..
-+       */
-+      if (idx >= __end_of_fixed_addresses)
-+              __this_fixmap_does_not_exist();
-+
-+        return __fix_to_virt(idx);
-+}
-+
-+static inline unsigned long virt_to_fix(const unsigned long vaddr)
-+{
-+      BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
-+      return __virt_to_fix(vaddr);
-+}
-+
-+#endif /* !__ASSEMBLY__ */
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/floppy.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/floppy.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/floppy.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/floppy.h     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,147 @@
-+/*
-+ * Architecture specific parts of the Floppy driver
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License.  See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1995
-+ *
-+ * Modifications for Xen are Copyright (c) 2004, Keir Fraser.
-+ */
-+#ifndef __ASM_XEN_I386_FLOPPY_H
-+#define __ASM_XEN_I386_FLOPPY_H
-+
-+#include <linux/vmalloc.h>
-+
-+/* XEN: Hit DMA paths on the head. This trick from asm-m68k/floppy.h. */
-+#include <asm/dma.h>
-+#undef MAX_DMA_ADDRESS
-+#define MAX_DMA_ADDRESS 0
-+#define CROSS_64KB(a,s) (0)
-+
-+#define fd_inb(port)                  inb_p(port)
-+#define fd_outb(value,port)           outb_p(value,port)
-+
-+#define fd_request_dma()        (0)
-+#define fd_free_dma()           ((void)0)
-+#define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
-+#define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
-+#define fd_free_irq()         free_irq(FLOPPY_IRQ, NULL)
-+#define fd_get_dma_residue()    (virtual_dma_count + virtual_dma_residue)
-+#define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
-+/*
-+ * Do not use vmalloc/vfree: floppy_release_irq_and_dma() gets called from
-+ * softirq context via motor_off_callback. A generic bug we happen to trigger.
-+ */
-+#define fd_dma_mem_alloc(size)        __get_free_pages(GFP_KERNEL, get_order(size))
-+#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
-+
-+static int virtual_dma_count;
-+static int virtual_dma_residue;
-+static char *virtual_dma_addr;
-+static int virtual_dma_mode;
-+static int doing_pdma;
-+
-+static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
-+{
-+      register unsigned char st;
-+      register int lcount;
-+      register char *lptr;
-+
-+      if (!doing_pdma)
-+              return floppy_interrupt(irq, dev_id, regs);
-+
-+      st = 1;
-+      for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 
-+          lcount; lcount--, lptr++) {
-+              st=inb(virtual_dma_port+4) & 0xa0 ;
-+              if(st != 0xa0) 
-+                      break;
-+              if(virtual_dma_mode)
-+                      outb_p(*lptr, virtual_dma_port+5);
-+              else
-+                      *lptr = inb_p(virtual_dma_port+5);
-+      }
-+      virtual_dma_count = lcount;
-+      virtual_dma_addr = lptr;
-+      st = inb(virtual_dma_port+4);
-+
-+      if(st == 0x20)
-+              return IRQ_HANDLED;
-+      if(!(st & 0x20)) {
-+              virtual_dma_residue += virtual_dma_count;
-+              virtual_dma_count=0;
-+              doing_pdma = 0;
-+              floppy_interrupt(irq, dev_id, regs);
-+              return IRQ_HANDLED;
-+      }
-+      return IRQ_HANDLED;
-+}
-+
-+static void fd_disable_dma(void)
-+{
-+      doing_pdma = 0;
-+      virtual_dma_residue += virtual_dma_count;
-+      virtual_dma_count=0;
-+}
-+
-+static int fd_request_irq(void)
-+{
-+      return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
-+                                         "floppy", NULL);
-+}
-+
-+static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
-+{
-+      doing_pdma = 1;
-+      virtual_dma_port = io;
-+      virtual_dma_mode = (mode  == DMA_MODE_WRITE);
-+      virtual_dma_addr = addr;
-+      virtual_dma_count = size;
-+      virtual_dma_residue = 0;
-+      return 0;
-+}
-+
-+/* XEN: This trick to force 'virtual DMA' is from include/asm-m68k/floppy.h. */
-+#define FDC1 xen_floppy_init()
-+static int FDC2 = -1;
-+
-+static int xen_floppy_init(void)
-+{
-+      use_virtual_dma = 1;
-+      can_use_virtual_dma = 1;
-+      return 0x3f0;
-+}
-+
-+/*
-+ * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
-+ * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
-+ * coincides with another rtc CMOS user.              Paul G.
-+ */
-+#define FLOPPY0_TYPE  ({                              \
-+      unsigned long flags;                            \
-+      unsigned char val;                              \
-+      spin_lock_irqsave(&rtc_lock, flags);            \
-+      val = (CMOS_READ(0x10) >> 4) & 15;              \
-+      spin_unlock_irqrestore(&rtc_lock, flags);       \
-+      val;                                            \
-+})
-+
-+#define FLOPPY1_TYPE  ({                              \
-+      unsigned long flags;                            \
-+      unsigned char val;                              \
-+      spin_lock_irqsave(&rtc_lock, flags);            \
-+      val = CMOS_READ(0x10) & 15;                     \
-+      spin_unlock_irqrestore(&rtc_lock, flags);       \
-+      val;                                            \
-+})
-+
-+#define N_FDC 2
-+#define N_DRIVE 8
-+
-+#define FLOPPY_MOTOR_MASK 0xf0
-+
-+#define EXTRA_FLOPPY_PARAMS
-+
-+#endif /* __ASM_XEN_I386_FLOPPY_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/highmem.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/highmem.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/highmem.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/highmem.h    2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,81 @@
-+/*
-+ * highmem.h: virtual kernel memory mappings for high memory
-+ *
-+ * Used in CONFIG_HIGHMEM systems for memory pages which
-+ * are not addressable by direct kernel virtual addresses.
-+ *
-+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
-+ *                  Gerhard.Wichert@pdb.siemens.de
-+ *
-+ *
-+ * Redesigned the x86 32-bit VM architecture to deal with 
-+ * up to 16 Terabyte physical memory. With current x86 CPUs
-+ * we now support up to 64 Gigabytes physical RAM.
-+ *
-+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
-+ */
-+
-+#ifndef _ASM_HIGHMEM_H
-+#define _ASM_HIGHMEM_H
-+
-+#ifdef __KERNEL__
-+
-+#include <linux/config.h>
-+#include <linux/interrupt.h>
-+#include <linux/threads.h>
-+#include <asm/kmap_types.h>
-+#include <asm/tlbflush.h>
-+
-+/* declarations for highmem.c */
-+extern unsigned long highstart_pfn, highend_pfn;
-+
-+extern pte_t *kmap_pte;
-+extern pgprot_t kmap_prot;
-+extern pte_t *pkmap_page_table;
-+
-+/*
-+ * Right now we initialize only a single pte table. It can be extended
-+ * easily, subsequent pte tables have to be allocated in one physical
-+ * chunk of RAM.
-+ */
-+#ifdef CONFIG_X86_PAE
-+#define LAST_PKMAP 512
-+#else
-+#define LAST_PKMAP 1024
-+#endif
-+/*
-+ * Ordering is:
-+ *
-+ * FIXADDR_TOP
-+ *                    fixed_addresses
-+ * FIXADDR_START
-+ *                    temp fixed addresses
-+ * FIXADDR_BOOT_START
-+ *                    Persistent kmap area
-+ * PKMAP_BASE
-+ * VMALLOC_END
-+ *                    Vmalloc area
-+ * VMALLOC_START
-+ * high_memory
-+ */
-+#define PKMAP_BASE ( (FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK )
-+#define LAST_PKMAP_MASK (LAST_PKMAP-1)
-+#define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
-+#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
-+
-+extern void * FASTCALL(kmap_high(struct page *page));
-+extern void FASTCALL(kunmap_high(struct page *page));
-+
-+void *kmap(struct page *page);
-+void kunmap(struct page *page);
-+void *kmap_atomic(struct page *page, enum km_type type);
-+void *kmap_atomic_pte(struct page *page, enum km_type type);
-+void kunmap_atomic(void *kvaddr, enum km_type type);
-+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
-+struct page *kmap_atomic_to_page(void *ptr);
-+
-+#define flush_cache_kmaps()   do { } while (0)
-+
-+#endif /* __KERNEL__ */
-+
-+#endif /* _ASM_HIGHMEM_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/hw_irq.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/hw_irq.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/hw_irq.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/hw_irq.h     2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,77 @@
-+#ifndef _ASM_HW_IRQ_H
-+#define _ASM_HW_IRQ_H
-+
-+/*
-+ *    linux/include/asm/hw_irq.h
-+ *
-+ *    (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
-+ *
-+ *    moved some of the old arch/i386/kernel/irq.h to here. VY
-+ *
-+ *    IRQ/IPI changes taken from work by Thomas Radke
-+ *    <tomsoft@informatik.tu-chemnitz.de>
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/profile.h>
-+#include <asm/atomic.h>
-+#include <asm/irq.h>
-+#include <asm/sections.h>
-+
-+struct hw_interrupt_type;
-+
-+/*
-+ * Various low-level irq details needed by irq.c, process.c,
-+ * time.c, io_apic.c and smp.c
-+ *
-+ * Interrupt entry/exit code at both C and assembly level
-+ */
-+
-+extern u8 irq_vector[NR_IRQ_VECTORS];
-+#define IO_APIC_VECTOR(irq)   (irq_vector[irq])
-+#define AUTO_ASSIGN           -1
-+
-+extern void (*interrupt[NR_IRQS])(void);
-+
-+#ifdef CONFIG_SMP
-+fastcall void reschedule_interrupt(void);
-+fastcall void invalidate_interrupt(void);
-+fastcall void call_function_interrupt(void);
-+#endif
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+fastcall void apic_timer_interrupt(void);
-+fastcall void error_interrupt(void);
-+fastcall void spurious_interrupt(void);
-+fastcall void thermal_interrupt(struct pt_regs *);
-+#define platform_legacy_irq(irq)      ((irq) < 16)
-+#endif
-+
-+void disable_8259A_irq(unsigned int irq);
-+void enable_8259A_irq(unsigned int irq);
-+int i8259A_irq_pending(unsigned int irq);
-+void make_8259A_irq(unsigned int irq);
-+void init_8259A(int aeoi);
-+void FASTCALL(send_IPI_self(int vector));
-+void init_VISWS_APIC_irqs(void);
-+void setup_IO_APIC(void);
-+void disable_IO_APIC(void);
-+void print_IO_APIC(void);
-+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
-+void send_IPI(int dest, int vector);
-+void setup_ioapic_dest(void);
-+
-+extern unsigned long io_apic_irqs;
-+
-+extern atomic_t irq_err_count;
-+extern atomic_t irq_mis_count;
-+
-+#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
-+
-+extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i);
-+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
-+{
-+      resend_irq_on_evtchn(h, i);
-+}
-+
-+#endif /* _ASM_HW_IRQ_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/hypercall.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/hypercall.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/hypercall.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/hypercall.h  2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,407 @@
-+/******************************************************************************
-+ * hypercall.h
-+ * 
-+ * Linux-specific hypervisor handling.
-+ * 
-+ * Copyright (c) 2002-2004, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __HYPERCALL_H__
-+#define __HYPERCALL_H__
-+
-+#include <linux/string.h> /* memcpy() */
-+
-+#ifndef __HYPERVISOR_H__
-+# error "please don't include this file directly"
-+#endif
-+
-+#define __STR(x) #x
-+#define STR(x) __STR(x)
-+
-+#ifdef CONFIG_XEN
-+#define HYPERCALL_STR(name)                                   \
-+      "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
-+#else
-+#define HYPERCALL_STR(name)                                   \
-+      "mov hypercall_stubs,%%eax; "                           \
-+      "add $("STR(__HYPERVISOR_##name)" * 32),%%eax; "        \
-+      "call *%%eax"
-+#endif
-+
-+#define _hypercall0(type, name)                       \
-+({                                            \
-+      long __res;                             \
-+      asm volatile (                          \
-+              HYPERCALL_STR(name)             \
-+              : "=a" (__res)                  \
-+              :                               \
-+              : "memory" );                   \
-+      (type)__res;                            \
-+})
-+
-+#define _hypercall1(type, name, a1)                           \
-+({                                                            \
-+      long __res, __ign1;                                     \
-+      asm volatile (                                          \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=b" (__ign1)                   \
-+              : "1" ((long)(a1))                              \
-+              : "memory" );                                   \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall2(type, name, a1, a2)                               \
-+({                                                            \
-+      long __res, __ign1, __ign2;                             \
-+      asm volatile (                                          \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=b" (__ign1), "=c" (__ign2)    \
-+              : "1" ((long)(a1)), "2" ((long)(a2))            \
-+              : "memory" );                                   \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall3(type, name, a1, a2, a3)                   \
-+({                                                            \
-+      long __res, __ign1, __ign2, __ign3;                     \
-+      asm volatile (                                          \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
-+              "=d" (__ign3)                                   \
-+              : "1" ((long)(a1)), "2" ((long)(a2)),           \
-+              "3" ((long)(a3))                                \
-+              : "memory" );                                   \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall4(type, name, a1, a2, a3, a4)                       \
-+({                                                            \
-+      long __res, __ign1, __ign2, __ign3, __ign4;             \
-+      asm volatile (                                          \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
-+              "=d" (__ign3), "=S" (__ign4)                    \
-+              : "1" ((long)(a1)), "2" ((long)(a2)),           \
-+              "3" ((long)(a3)), "4" ((long)(a4))              \
-+              : "memory" );                                   \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall5(type, name, a1, a2, a3, a4, a5)           \
-+({                                                            \
-+      long __res, __ign1, __ign2, __ign3, __ign4, __ign5;     \
-+      asm volatile (                                          \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
-+              "=d" (__ign3), "=S" (__ign4), "=D" (__ign5)     \
-+              : "1" ((long)(a1)), "2" ((long)(a2)),           \
-+              "3" ((long)(a3)), "4" ((long)(a4)),             \
-+              "5" ((long)(a5))                                \
-+              : "memory" );                                   \
-+      (type)__res;                                            \
-+})
-+
-+static inline int
-+HYPERVISOR_set_trap_table(
-+      trap_info_t *table)
-+{
-+      return _hypercall1(int, set_trap_table, table);
-+}
-+
-+static inline int
-+HYPERVISOR_mmu_update(
-+      mmu_update_t *req, int count, int *success_count, domid_t domid)
-+{
-+      return _hypercall4(int, mmu_update, req, count, success_count, domid);
-+}
-+
-+static inline int
-+HYPERVISOR_mmuext_op(
-+      struct mmuext_op *op, int count, int *success_count, domid_t domid)
-+{
-+      return _hypercall4(int, mmuext_op, op, count, success_count, domid);
-+}
-+
-+static inline int
-+HYPERVISOR_set_gdt(
-+      unsigned long *frame_list, int entries)
-+{
-+      return _hypercall2(int, set_gdt, frame_list, entries);
-+}
-+
-+static inline int
-+HYPERVISOR_stack_switch(
-+      unsigned long ss, unsigned long esp)
-+{
-+      return _hypercall2(int, stack_switch, ss, esp);
-+}
-+
-+static inline int
-+HYPERVISOR_set_callbacks(
-+      unsigned long event_selector, unsigned long event_address,
-+      unsigned long failsafe_selector, unsigned long failsafe_address)
-+{
-+      return _hypercall4(int, set_callbacks,
-+                         event_selector, event_address,
-+                         failsafe_selector, failsafe_address);
-+}
-+
-+static inline int
-+HYPERVISOR_fpu_taskswitch(
-+      int set)
-+{
-+      return _hypercall1(int, fpu_taskswitch, set);
-+}
-+
-+static inline int
-+HYPERVISOR_sched_op_compat(
-+      int cmd, unsigned long arg)
-+{
-+      return _hypercall2(int, sched_op_compat, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_sched_op(
-+      int cmd, void *arg)
-+{
-+      return _hypercall2(int, sched_op, cmd, arg);
-+}
-+
-+static inline long
-+HYPERVISOR_set_timer_op(
-+      u64 timeout)
-+{
-+      unsigned long timeout_hi = (unsigned long)(timeout>>32);
-+      unsigned long timeout_lo = (unsigned long)timeout;
-+      return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
-+}
-+
-+static inline int
-+HYPERVISOR_dom0_op(
-+      dom0_op_t *dom0_op)
-+{
-+      dom0_op->interface_version = DOM0_INTERFACE_VERSION;
-+      return _hypercall1(int, dom0_op, dom0_op);
-+}
-+
-+static inline int
-+HYPERVISOR_set_debugreg(
-+      int reg, unsigned long value)
-+{
-+      return _hypercall2(int, set_debugreg, reg, value);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_get_debugreg(
-+      int reg)
-+{
-+      return _hypercall1(unsigned long, get_debugreg, reg);
-+}
-+
-+static inline int
-+HYPERVISOR_update_descriptor(
-+      u64 ma, u64 desc)
-+{
-+      return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
-+}
-+
-+static inline int
-+HYPERVISOR_memory_op(
-+      unsigned int cmd, void *arg)
-+{
-+      return _hypercall2(int, memory_op, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_multicall(
-+      void *call_list, int nr_calls)
-+{
-+      return _hypercall2(int, multicall, call_list, nr_calls);
-+}
-+
-+static inline int
-+HYPERVISOR_update_va_mapping(
-+      unsigned long va, pte_t new_val, unsigned long flags)
-+{
-+      unsigned long pte_hi = 0;
-+#ifdef CONFIG_X86_PAE
-+      pte_hi = new_val.pte_high;
-+#endif
-+      return _hypercall4(int, update_va_mapping, va,
-+                         new_val.pte_low, pte_hi, flags);
-+}
-+
-+static inline int
-+HYPERVISOR_event_channel_op(
-+      int cmd, void *arg)
-+{
-+      int rc = _hypercall2(int, event_channel_op, cmd, arg);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (unlikely(rc == -ENOSYS)) {
-+              struct evtchn_op op;
-+              op.cmd = cmd;
-+              memcpy(&op.u, arg, sizeof(op.u));
-+              rc = _hypercall1(int, event_channel_op_compat, &op);
-+              memcpy(arg, &op.u, sizeof(op.u));
-+      }
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_acm_op(
-+      int cmd, void *arg)
-+{
-+      return _hypercall2(int, acm_op, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_xen_version(
-+      int cmd, void *arg)
-+{
-+      return _hypercall2(int, xen_version, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_console_io(
-+      int cmd, int count, char *str)
-+{
-+      return _hypercall3(int, console_io, cmd, count, str);
-+}
-+
-+static inline int
-+HYPERVISOR_physdev_op(
-+      int cmd, void *arg)
-+{
-+      int rc = _hypercall2(int, physdev_op, cmd, arg);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (unlikely(rc == -ENOSYS)) {
-+              struct physdev_op op;
-+              op.cmd = cmd;
-+              memcpy(&op.u, arg, sizeof(op.u));
-+              rc = _hypercall1(int, physdev_op_compat, &op);
-+              memcpy(arg, &op.u, sizeof(op.u));
-+      }
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_grant_table_op(
-+      unsigned int cmd, void *uop, unsigned int count)
-+{
-+      return _hypercall3(int, grant_table_op, cmd, uop, count);
-+}
-+
-+static inline int
-+HYPERVISOR_update_va_mapping_otherdomain(
-+      unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
-+{
-+      unsigned long pte_hi = 0;
-+#ifdef CONFIG_X86_PAE
-+      pte_hi = new_val.pte_high;
-+#endif
-+      return _hypercall5(int, update_va_mapping_otherdomain, va,
-+                         new_val.pte_low, pte_hi, flags, domid);
-+}
-+
-+static inline int
-+HYPERVISOR_vm_assist(
-+      unsigned int cmd, unsigned int type)
-+{
-+      return _hypercall2(int, vm_assist, cmd, type);
-+}
-+
-+static inline int
-+HYPERVISOR_vcpu_op(
-+      int cmd, int vcpuid, void *extra_args)
-+{
-+      return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
-+}
-+
-+static inline int
-+HYPERVISOR_suspend(
-+      unsigned long srec)
-+{
-+      struct sched_shutdown sched_shutdown = {
-+              .reason = SHUTDOWN_suspend
-+      };
-+
-+      int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
-+                           &sched_shutdown, srec);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (rc == -ENOSYS)
-+              rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
-+                               SHUTDOWN_suspend, srec);
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_nmi_op(
-+      unsigned long op, void *arg)
-+{
-+      return _hypercall2(int, nmi_op, op, arg);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_hvm_op(
-+    int op, void *arg)
-+{
-+    return _hypercall2(unsigned long, hvm_op, op, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_callback_op(
-+      int cmd, void *arg)
-+{
-+      return _hypercall2(int, callback_op, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_xenoprof_op(
-+      int op, void *arg)
-+{
-+      return _hypercall2(int, xenoprof_op, op, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_kexec_op(
-+      unsigned long op, void *args)
-+{
-+      return _hypercall2(int, kexec_op, op, args);
-+}
-+
-+
-+
-+#endif /* __HYPERCALL_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/hypervisor.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/hypervisor.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/hypervisor.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/hypervisor.h 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,246 @@
-+/******************************************************************************
-+ * hypervisor.h
-+ * 
-+ * Linux-specific hypervisor handling.
-+ * 
-+ * Copyright (c) 2002-2004, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __HYPERVISOR_H__
-+#define __HYPERVISOR_H__
-+
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/version.h>
-+#include <linux/errno.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/dom0_ops.h>
-+#include <xen/interface/event_channel.h>
-+#include <xen/interface/physdev.h>
-+#include <xen/interface/sched.h>
-+#include <xen/interface/nmi.h>
-+#include <asm/ptrace.h>
-+#include <asm/page.h>
-+#if defined(__i386__)
-+#  ifdef CONFIG_X86_PAE
-+#   include <asm-generic/pgtable-nopud.h>
-+#  else
-+#   include <asm-generic/pgtable-nopmd.h>
-+#  endif
-+#endif
-+
-+extern shared_info_t *HYPERVISOR_shared_info;
-+
-+#ifdef CONFIG_X86_32
-+extern unsigned long hypervisor_virt_start;
-+#endif
-+
-+/* arch/xen/i386/kernel/setup.c */
-+extern start_info_t *xen_start_info;
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-+#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
-+#else
-+#define is_initial_xendomain() 0
-+#endif
-+
-+/* arch/xen/kernel/evtchn.c */
-+/* Force a proper event-channel callback from Xen. */
-+void force_evtchn_callback(void);
-+
-+/* arch/xen/kernel/process.c */
-+void xen_cpu_idle (void);
-+
-+/* arch/xen/i386/kernel/hypervisor.c */
-+void do_hypervisor_callback(struct pt_regs *regs);
-+
-+/* arch/xen/i386/mm/hypervisor.c */
-+/*
-+ * NB. ptr values should be PHYSICAL, not MACHINE. 'vals' should be already
-+ * be MACHINE addresses.
-+ */
-+
-+void xen_pt_switch(unsigned long ptr);
-+void xen_new_user_pt(unsigned long ptr); /* x86_64 only */
-+void xen_load_gs(unsigned int selector); /* x86_64 only */
-+void xen_tlb_flush(void);
-+void xen_invlpg(unsigned long ptr);
-+
-+void xen_l1_entry_update(pte_t *ptr, pte_t val);
-+void xen_l2_entry_update(pmd_t *ptr, pmd_t val);
-+void xen_l3_entry_update(pud_t *ptr, pud_t val); /* x86_64/PAE */
-+void xen_l4_entry_update(pgd_t *ptr, pgd_t val); /* x86_64 only */
-+void xen_pgd_pin(unsigned long ptr);
-+void xen_pgd_unpin(unsigned long ptr);
-+
-+void xen_set_ldt(unsigned long ptr, unsigned long bytes);
-+
-+#ifdef CONFIG_SMP
-+#include <linux/cpumask.h>
-+void xen_tlb_flush_all(void);
-+void xen_invlpg_all(unsigned long ptr);
-+void xen_tlb_flush_mask(cpumask_t *mask);
-+void xen_invlpg_mask(cpumask_t *mask, unsigned long ptr);
-+#endif
-+
-+/* Returns zero on success else negative errno. */
-+int xen_create_contiguous_region(
-+    unsigned long vstart, unsigned int order, unsigned int address_bits);
-+void xen_destroy_contiguous_region(
-+    unsigned long vstart, unsigned int order);
-+
-+/* Turn jiffies into Xen system time. */
-+u64 jiffies_to_st(unsigned long jiffies);
-+
-+#include <asm/hypercall.h>
-+
-+#if defined(CONFIG_X86_64)
-+#define MULTI_UVMFLAGS_INDEX 2
-+#define MULTI_UVMDOMID_INDEX 3
-+#else
-+#define MULTI_UVMFLAGS_INDEX 3
-+#define MULTI_UVMDOMID_INDEX 4
-+#endif
-+
-+#define is_running_on_xen() 1
-+
-+static inline int
-+HYPERVISOR_yield(
-+      void)
-+{
-+      int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (rc == -ENOSYS)
-+              rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_block(
-+      void)
-+{
-+      int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (rc == -ENOSYS)
-+              rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_shutdown(
-+      unsigned int reason)
-+{
-+      struct sched_shutdown sched_shutdown = {
-+              .reason = reason
-+      };
-+
-+      int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (rc == -ENOSYS)
-+              rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_poll(
-+      evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
-+{
-+      int rc;
-+      struct sched_poll sched_poll = {
-+              .nr_ports = nr_ports,
-+              .timeout = jiffies_to_st(timeout)
-+      };
-+      set_xen_guest_handle(sched_poll.ports, ports);
-+
-+      rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (rc == -ENOSYS)
-+              rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline void
-+MULTI_update_va_mapping(
-+    multicall_entry_t *mcl, unsigned long va,
-+    pte_t new_val, unsigned long flags)
-+{
-+    mcl->op = __HYPERVISOR_update_va_mapping;
-+    mcl->args[0] = va;
-+#if defined(CONFIG_X86_64)
-+    mcl->args[1] = new_val.pte;
-+#elif defined(CONFIG_X86_PAE)
-+    mcl->args[1] = new_val.pte_low;
-+    mcl->args[2] = new_val.pte_high;
-+#else
-+    mcl->args[1] = new_val.pte_low;
-+    mcl->args[2] = 0;
-+#endif
-+    mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
-+}
-+
-+static inline void
-+MULTI_grant_table_op(multicall_entry_t *mcl, unsigned int cmd,
-+                   void *uop, unsigned int count)
-+{
-+    mcl->op = __HYPERVISOR_grant_table_op;
-+    mcl->args[0] = cmd;
-+    mcl->args[1] = (unsigned long)uop;
-+    mcl->args[2] = count;
-+}
-+
-+static inline void
-+MULTI_update_va_mapping_otherdomain(
-+    multicall_entry_t *mcl, unsigned long va,
-+    pte_t new_val, unsigned long flags, domid_t domid)
-+{
-+    mcl->op = __HYPERVISOR_update_va_mapping_otherdomain;
-+    mcl->args[0] = va;
-+#if defined(CONFIG_X86_64)
-+    mcl->args[1] = new_val.pte;
-+#elif defined(CONFIG_X86_PAE)
-+    mcl->args[1] = new_val.pte_low;
-+    mcl->args[2] = new_val.pte_high;
-+#else
-+    mcl->args[1] = new_val.pte_low;
-+    mcl->args[2] = 0;
-+#endif
-+    mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
-+    mcl->args[MULTI_UVMDOMID_INDEX] = domid;
-+}
-+
-+#endif /* __HYPERVISOR_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/io.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/io.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/io.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/io.h 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,403 @@
-+#ifndef _ASM_IO_H
-+#define _ASM_IO_H
-+
-+#include <linux/config.h>
-+#include <linux/string.h>
-+#include <linux/compiler.h>
-+
-+/*
-+ * This file contains the definitions for the x86 IO instructions
-+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
-+ * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
-+ * versions of the single-IO instructions (inb_p/inw_p/..).
-+ *
-+ * This file is not meant to be obfuscating: it's just complicated
-+ * to (a) handle it all in a way that makes gcc able to optimize it
-+ * as well as possible and (b) trying to avoid writing the same thing
-+ * over and over again with slight variations and possibly making a
-+ * mistake somewhere.
-+ */
-+
-+/*
-+ * Thanks to James van Artsdalen for a better timing-fix than
-+ * the two short jumps: using outb's to a nonexistent port seems
-+ * to guarantee better timings even on fast machines.
-+ *
-+ * On the other hand, I'd like to be sure of a non-existent port:
-+ * I feel a bit unsafe about using 0x80 (should be safe, though)
-+ *
-+ *            Linus
-+ */
-+
-+ /*
-+  *  Bit simplified and optimized by Jan Hubicka
-+  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
-+  *
-+  *  isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added,
-+  *  isa_read[wl] and isa_write[wl] fixed
-+  *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-+  */
-+
-+#define IO_SPACE_LIMIT 0xffff
-+
-+#define XQUAD_PORTIO_BASE 0xfe400000
-+#define XQUAD_PORTIO_QUAD 0x40000  /* 256k per quad. */
-+
-+#ifdef __KERNEL__
-+
-+#include <asm-generic/iomap.h>
-+
-+#include <linux/vmalloc.h>
-+#include <asm/fixmap.h>
-+
-+/*
-+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
-+ * access
-+ */
-+#define xlate_dev_mem_ptr(p, sz)      ioremap(p, sz)
-+#define xlate_dev_mem_ptr_unmap(p)    iounmap(p)
-+
-+/*
-+ * Convert a virtual cached pointer to an uncached pointer
-+ */
-+#define xlate_dev_kmem_ptr(p) p
-+
-+/**
-+ *    virt_to_phys    -       map virtual addresses to physical
-+ *    @address: address to remap
-+ *
-+ *    The returned physical address is the physical (CPU) mapping for
-+ *    the memory address given. It is only valid to use this function on
-+ *    addresses directly mapped or allocated via kmalloc. 
-+ *
-+ *    This function does not give bus mappings for DMA transfers. In
-+ *    almost all conceivable cases a device driver should not be using
-+ *    this function
-+ */
-+ 
-+static inline unsigned long virt_to_phys(volatile void * address)
-+{
-+      return __pa(address);
-+}
-+
-+/**
-+ *    phys_to_virt    -       map physical address to virtual
-+ *    @address: address to remap
-+ *
-+ *    The returned virtual address is a current CPU mapping for
-+ *    the memory address given. It is only valid to use this function on
-+ *    addresses that have a kernel mapping
-+ *
-+ *    This function does not handle bus mappings for DMA transfers. In
-+ *    almost all conceivable cases a device driver should not be using
-+ *    this function
-+ */
-+
-+static inline void * phys_to_virt(unsigned long address)
-+{
-+      return __va(address);
-+}
-+
-+/*
-+ * Change "struct page" to physical address.
-+ */
-+#define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-+#define page_to_phys(page)     (phys_to_machine(page_to_pseudophys(page)))
-+#define page_to_bus(page)      (phys_to_machine(page_to_pseudophys(page)))
-+
-+#define bio_to_pseudophys(bio)         (page_to_pseudophys(bio_page((bio))) + \
-+                                (unsigned long) bio_offset((bio)))
-+#define bvec_to_pseudophys(bv)         (page_to_pseudophys((bv)->bv_page) + \
-+                                (unsigned long) (bv)->bv_offset)
-+
-+#define BIOVEC_PHYS_MERGEABLE(vec1, vec2)     \
-+      (((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) && \
-+       ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) == \
-+        bvec_to_pseudophys((vec2))))
-+
-+extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
-+
-+/**
-+ * ioremap     -   map bus memory into CPU space
-+ * @offset:    bus address of the memory
-+ * @size:      size of the resource to map
-+ *
-+ * ioremap performs a platform specific sequence of operations to
-+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
-+ * writew/writel functions and the other mmio helpers. The returned
-+ * address is not guaranteed to be usable directly as a virtual
-+ * address. 
-+ */
-+
-+static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
-+{
-+      return __ioremap(offset, size, 0);
-+}
-+
-+extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size);
-+extern void iounmap(volatile void __iomem *addr);
-+
-+/*
-+ * bt_ioremap() and bt_iounmap() are for temporary early boot-time
-+ * mappings, before the real ioremap() is functional.
-+ * A boot-time mapping is currently limited to at most 16 pages.
-+ */
-+extern void *bt_ioremap(unsigned long offset, unsigned long size);
-+extern void bt_iounmap(void *addr, unsigned long size);
-+
-+/* Use early IO mappings for DMI because it's initialized early */
-+#define dmi_ioremap bt_ioremap
-+#define dmi_iounmap bt_iounmap
-+#define dmi_alloc alloc_bootmem
-+
-+/*
-+ * ISA I/O bus memory addresses are 1:1 with the physical address.
-+ */
-+#define isa_virt_to_bus(_x) isa_virt_to_bus_is_UNSUPPORTED->x
-+#define isa_page_to_bus(_x) isa_page_to_bus_is_UNSUPPORTED->x
-+#define isa_bus_to_virt(_x) (void *)(__fix_to_virt(FIX_ISAMAP_BEGIN) + (_x))
-+
-+/*
-+ * However PCI ones are not necessarily 1:1 and therefore these interfaces
-+ * are forbidden in portable PCI drivers.
-+ *
-+ * Allow them on x86 for legacy drivers, though.
-+ */
-+#define virt_to_bus(_x) phys_to_machine(__pa(_x))
-+#define bus_to_virt(_x) __va(machine_to_phys(_x))
-+
-+/*
-+ * readX/writeX() are used to access memory mapped devices. On some
-+ * architectures the memory mapped IO stuff needs to be accessed
-+ * differently. On the x86 architecture, we just read/write the
-+ * memory location directly.
-+ */
-+
-+static inline unsigned char readb(const volatile void __iomem *addr)
-+{
-+      return *(volatile unsigned char __force *) addr;
-+}
-+static inline unsigned short readw(const volatile void __iomem *addr)
-+{
-+      return *(volatile unsigned short __force *) addr;
-+}
-+static inline unsigned int readl(const volatile void __iomem *addr)
-+{
-+      return *(volatile unsigned int __force *) addr;
-+}
-+#define readb_relaxed(addr) readb(addr)
-+#define readw_relaxed(addr) readw(addr)
-+#define readl_relaxed(addr) readl(addr)
-+#define __raw_readb readb
-+#define __raw_readw readw
-+#define __raw_readl readl
-+
-+static inline void writeb(unsigned char b, volatile void __iomem *addr)
-+{
-+      *(volatile unsigned char __force *) addr = b;
-+}
-+static inline void writew(unsigned short b, volatile void __iomem *addr)
-+{
-+      *(volatile unsigned short __force *) addr = b;
-+}
-+static inline void writel(unsigned int b, volatile void __iomem *addr)
-+{
-+      *(volatile unsigned int __force *) addr = b;
-+}
-+#define __raw_writeb writeb
-+#define __raw_writew writew
-+#define __raw_writel writel
-+
-+#define mmiowb()
-+
-+static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
-+{
-+      memset((void __force *) addr, val, count);
-+}
-+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
-+{
-+      __memcpy(dst, (void __force *) src, count);
-+}
-+static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
-+{
-+      __memcpy((void __force *) dst, src, count);
-+}
-+
-+/*
-+ * ISA space is 'always mapped' on a typical x86 system, no need to
-+ * explicitly ioremap() it. The fact that the ISA IO space is mapped
-+ * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
-+ * are physical addresses. The following constant pointer can be
-+ * used as the IO-area pointer (it can be iounmapped as well, so the
-+ * analogy with PCI is quite large):
-+ */
-+#define __ISA_IO_base ((char __iomem *)(fix_to_virt(FIX_ISAMAP_BEGIN)))
-+
-+#define isa_readb(a) readb(__ISA_IO_base + (a))
-+#define isa_readw(a) readw(__ISA_IO_base + (a))
-+#define isa_readl(a) readl(__ISA_IO_base + (a))
-+#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
-+#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
-+#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
-+#define isa_memset_io(a,b,c)          memset_io(__ISA_IO_base + (a),(b),(c))
-+#define isa_memcpy_fromio(a,b,c)      memcpy_fromio((a),__ISA_IO_base + (b),(c))
-+#define isa_memcpy_toio(a,b,c)                memcpy_toio(__ISA_IO_base + (a),(b),(c))
-+
-+
-+/*
-+ * Again, i386 does not require mem IO specific function.
-+ */
-+
-+#define eth_io_copy_and_sum(a,b,c,d)          eth_copy_and_sum((a),(void __force *)(b),(c),(d))
-+#define isa_eth_io_copy_and_sum(a,b,c,d)      eth_copy_and_sum((a),(void __force *)(__ISA_IO_base + (b)),(c),(d))
-+
-+/**
-+ *    check_signature         -       find BIOS signatures
-+ *    @io_addr: mmio address to check 
-+ *    @signature:  signature block
-+ *    @length: length of signature
-+ *
-+ *    Perform a signature comparison with the mmio address io_addr. This
-+ *    address should have been obtained by ioremap.
-+ *    Returns 1 on a match.
-+ */
-+ 
-+static inline int check_signature(volatile void __iomem * io_addr,
-+      const unsigned char *signature, int length)
-+{
-+      int retval = 0;
-+      do {
-+              if (readb(io_addr) != *signature)
-+                      goto out;
-+              io_addr++;
-+              signature++;
-+              length--;
-+      } while (length);
-+      retval = 1;
-+out:
-+      return retval;
-+}
-+
-+/*
-+ *    Cache management
-+ *
-+ *    This needed for two cases
-+ *    1. Out of order aware processors
-+ *    2. Accidentally out of order processors (PPro errata #51)
-+ */
-+ 
-+#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
-+
-+static inline void flush_write_buffers(void)
-+{
-+      __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
-+}
-+
-+#define dma_cache_inv(_start,_size)           flush_write_buffers()
-+#define dma_cache_wback(_start,_size)         flush_write_buffers()
-+#define dma_cache_wback_inv(_start,_size)     flush_write_buffers()
-+
-+#else
-+
-+/* Nothing to do */
-+
-+#define dma_cache_inv(_start,_size)           do { } while (0)
-+#define dma_cache_wback(_start,_size)         do { } while (0)
-+#define dma_cache_wback_inv(_start,_size)     do { } while (0)
-+#define flush_write_buffers()
-+
-+#endif
-+
-+#endif /* __KERNEL__ */
-+
-+#ifdef SLOW_IO_BY_JUMPING
-+#define __SLOW_DOWN_IO "jmp 1f; 1: jmp 1f; 1:"
-+#else
-+#define __SLOW_DOWN_IO "outb %%al,$0x80;"
-+#endif
-+
-+static inline void slow_down_io(void) {
-+      __asm__ __volatile__(
-+              __SLOW_DOWN_IO
-+#ifdef REALLY_SLOW_IO
-+              __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
-+#endif
-+              : : );
-+}
-+
-+#ifdef CONFIG_X86_NUMAQ
-+extern void *xquad_portio;    /* Where the IO area was mapped */
-+#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
-+#define __BUILDIO(bwl,bw,type) \
-+static inline void out##bwl##_quad(unsigned type value, int port, int quad) { \
-+      if (xquad_portio) \
-+              write##bwl(value, XQUAD_PORT_ADDR(port, quad)); \
-+      else \
-+              out##bwl##_local(value, port); \
-+} \
-+static inline void out##bwl(unsigned type value, int port) { \
-+      out##bwl##_quad(value, port, 0); \
-+} \
-+static inline unsigned type in##bwl##_quad(int port, int quad) { \
-+      if (xquad_portio) \
-+              return read##bwl(XQUAD_PORT_ADDR(port, quad)); \
-+      else \
-+              return in##bwl##_local(port); \
-+} \
-+static inline unsigned type in##bwl(int port) { \
-+      return in##bwl##_quad(port, 0); \
-+}
-+#else
-+#define __BUILDIO(bwl,bw,type) \
-+static inline void out##bwl(unsigned type value, int port) { \
-+      out##bwl##_local(value, port); \
-+} \
-+static inline unsigned type in##bwl(int port) { \
-+      return in##bwl##_local(port); \
-+}
-+#endif
-+
-+
-+#define BUILDIO(bwl,bw,type) \
-+static inline void out##bwl##_local(unsigned type value, int port) { \
-+      __asm__ __volatile__("out" #bwl " %" #bw "0, %w1" : : "a"(value), "Nd"(port)); \
-+} \
-+static inline unsigned type in##bwl##_local(int port) { \
-+      unsigned type value; \
-+      __asm__ __volatile__("in" #bwl " %w1, %" #bw "0" : "=a"(value) : "Nd"(port)); \
-+      return value; \
-+} \
-+static inline void out##bwl##_local_p(unsigned type value, int port) { \
-+      out##bwl##_local(value, port); \
-+      slow_down_io(); \
-+} \
-+static inline unsigned type in##bwl##_local_p(int port) { \
-+      unsigned type value = in##bwl##_local(port); \
-+      slow_down_io(); \
-+      return value; \
-+} \
-+__BUILDIO(bwl,bw,type) \
-+static inline void out##bwl##_p(unsigned type value, int port) { \
-+      out##bwl(value, port); \
-+      slow_down_io(); \
-+} \
-+static inline unsigned type in##bwl##_p(int port) { \
-+      unsigned type value = in##bwl(port); \
-+      slow_down_io(); \
-+      return value; \
-+} \
-+static inline void outs##bwl(int port, const void *addr, unsigned long count) { \
-+      __asm__ __volatile__("rep; outs" #bwl : "+S"(addr), "+c"(count) : "d"(port)); \
-+} \
-+static inline void ins##bwl(int port, void *addr, unsigned long count) { \
-+      __asm__ __volatile__("rep; ins" #bwl : "+D"(addr), "+c"(count) : "d"(port)); \
-+}
-+
-+BUILDIO(b,b,char)
-+BUILDIO(w,w,short)
-+BUILDIO(l,,int)
-+
-+/* We will be supplying our own /dev/mem implementation */
-+#define ARCH_HAS_DEV_MEM
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/kmap_types.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/kmap_types.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/kmap_types.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/kmap_types.h 2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,32 @@
-+#ifndef _ASM_KMAP_TYPES_H
-+#define _ASM_KMAP_TYPES_H
-+
-+#include <linux/config.h>
-+
-+#ifdef CONFIG_DEBUG_HIGHMEM
-+# define D(n) __KM_FENCE_##n ,
-+#else
-+# define D(n)
-+#endif
-+
-+enum km_type {
-+D(0)  KM_BOUNCE_READ,
-+D(1)  KM_SKB_SUNRPC_DATA,
-+D(2)  KM_SKB_DATA_SOFTIRQ,
-+D(3)  KM_USER0,
-+D(4)  KM_USER1,
-+D(5)  KM_BIO_SRC_IRQ,
-+D(6)  KM_BIO_DST_IRQ,
-+D(7)  KM_PTE0,
-+D(8)  KM_PTE1,
-+D(9)  KM_IRQ0,
-+D(10) KM_IRQ1,
-+D(11) KM_SOFTIRQ0,
-+D(12) KM_SOFTIRQ1,
-+D(13) KM_SWIOTLB,
-+D(14) KM_TYPE_NR
-+};
-+
-+#undef D
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/maddr.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/maddr.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/maddr.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/maddr.h      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,176 @@
-+#ifndef _I386_MADDR_H
-+#define _I386_MADDR_H
-+
-+#include <xen/features.h>
-+#include <xen/interface/xen.h>
-+
-+/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
-+#define INVALID_P2M_ENTRY     (~0UL)
-+#define FOREIGN_FRAME_BIT     (1UL<<31)
-+#define FOREIGN_FRAME(m)      ((m) | FOREIGN_FRAME_BIT)
-+
-+/* Definitions for machine and pseudophysical addresses. */
-+#ifdef CONFIG_X86_PAE
-+typedef unsigned long long paddr_t;
-+typedef unsigned long long maddr_t;
-+#else
-+typedef unsigned long paddr_t;
-+typedef unsigned long maddr_t;
-+#endif
-+
-+#ifdef CONFIG_XEN
-+
-+extern unsigned long *phys_to_machine_mapping;
-+
-+#undef machine_to_phys_mapping
-+extern unsigned long *machine_to_phys_mapping;
-+extern unsigned int   machine_to_phys_order;
-+
-+static inline unsigned long pfn_to_mfn(unsigned long pfn)
-+{
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return pfn;
-+      return phys_to_machine_mapping[(unsigned int)(pfn)] &
-+              ~FOREIGN_FRAME_BIT;
-+}
-+
-+static inline int phys_to_machine_mapping_valid(unsigned long pfn)
-+{
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return 1;
-+      return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
-+}
-+
-+static inline unsigned long mfn_to_pfn(unsigned long mfn)
-+{
-+      extern unsigned long max_mapnr;
-+      unsigned long pfn;
-+
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return mfn;
-+
-+      if (unlikely((mfn >> machine_to_phys_order) != 0))
-+              return max_mapnr;
-+
-+      /* The array access can fail (e.g., device space beyond end of RAM). */
-+      asm (
-+              "1:     movl %1,%0\n"
-+              "2:\n"
-+              ".section .fixup,\"ax\"\n"
-+              "3:     movl %2,%0\n"
-+              "       jmp  2b\n"
-+              ".previous\n"
-+              ".section __ex_table,\"a\"\n"
-+              "       .align 4\n"
-+              "       .long 1b,3b\n"
-+              ".previous"
-+              : "=r" (pfn)
-+              : "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) );
-+
-+      return pfn;
-+}
-+
-+/*
-+ * We detect special mappings in one of two ways:
-+ *  1. If the MFN is an I/O page then Xen will set the m2p entry
-+ *     to be outside our maximum possible pseudophys range.
-+ *  2. If the MFN belongs to a different domain then we will certainly
-+ *     not have MFN in our p2m table. Conversely, if the page is ours,
-+ *     then we'll have p2m(m2p(MFN))==MFN.
-+ * If we detect a special mapping then it doesn't have a 'struct page'.
-+ * We force !pfn_valid() by returning an out-of-range pointer.
-+ *
-+ * NB. These checks require that, for any MFN that is not in our reservation,
-+ * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
-+ * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
-+ * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
-+ *
-+ * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
-+ *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
-+ *      require. In all the cases we care about, the FOREIGN_FRAME bit is
-+ *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
-+ */
-+static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
-+{
-+      extern unsigned long max_mapnr;
-+      unsigned long pfn = mfn_to_pfn(mfn);
-+      if ((pfn < max_mapnr)
-+          && !xen_feature(XENFEAT_auto_translated_physmap)
-+          && (phys_to_machine_mapping[pfn] != mfn))
-+              return max_mapnr; /* force !pfn_valid() */
-+      return pfn;
-+}
-+
-+static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
-+{
-+      if (xen_feature(XENFEAT_auto_translated_physmap)) {
-+              BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
-+              return;
-+      }
-+      phys_to_machine_mapping[pfn] = mfn;
-+}
-+
-+static inline maddr_t phys_to_machine(paddr_t phys)
-+{
-+      maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
-+      machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
-+      return machine;
-+}
-+
-+static inline paddr_t machine_to_phys(maddr_t machine)
-+{
-+      paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
-+      phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
-+      return phys;
-+}
-+
-+static inline paddr_t pte_machine_to_phys(maddr_t machine)
-+{
-+      /*
-+       * In PAE mode, the NX bit needs to be dealt with in the value
-+       * passed to mfn_to_pfn(). On x86_64, we need to mask it off,
-+       * but for i386 the conversion to ulong for the argument will
-+       * clip it off.
-+       */
-+      paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
-+      phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
-+      return phys;
-+}
-+
-+#else /* !CONFIG_XEN */
-+
-+#define pfn_to_mfn(pfn) (pfn)
-+#define mfn_to_pfn(mfn) (mfn)
-+#define mfn_to_local_pfn(mfn) (mfn)
-+#define set_phys_to_machine(pfn, mfn) BUG_ON((pfn) != (mfn))
-+#define phys_to_machine_mapping_valid(pfn) (1)
-+#define phys_to_machine(phys) ((maddr_t)(phys))
-+#define machine_to_phys(mach) ((paddr_t)(mach))
-+#define pte_machine_to_phys(mach) ((paddr_t)(mach))
-+
-+#endif /* !CONFIG_XEN */
-+
-+/* VIRT <-> MACHINE conversion */
-+#define virt_to_machine(v)    (phys_to_machine(__pa(v)))
-+#define virt_to_mfn(v)                (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
-+#define mfn_to_virt(m)                (__va(mfn_to_pfn(m) << PAGE_SHIFT))
-+
-+#ifdef CONFIG_X86_PAE
-+static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot)
-+{
-+      pte_t pte;
-+
-+      pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \
-+                                      (pgprot_val(pgprot) >> 32);
-+      pte.pte_high &= (__supported_pte_mask >> 32);
-+      pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \
-+                                                      __supported_pte_mask;
-+      return pte;
-+}
-+#else
-+#define pfn_pte_ma(pfn, prot) __pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
-+#endif
-+
-+#define __pte_ma(x)   ((pte_t) { (x) } )
-+
-+#endif /* _I386_MADDR_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/mmu.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/mmu.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/mmu.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/mmu.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,28 @@
-+#ifndef __i386_MMU_H
-+#define __i386_MMU_H
-+
-+#include <asm/semaphore.h>
-+/*
-+ * The i386 doesn't have a mmu context, but
-+ * we put the segment information here.
-+ *
-+ * cpu_vm_mask is used to optimize ldt flushing.
-+ */
-+typedef struct { 
-+      int size;
-+      struct semaphore sem;
-+      void *ldt;
-+#ifdef CONFIG_XEN
-+      int has_foreign_mappings;
-+#endif
-+} mm_context_t;
-+
-+/* mm/memory.c:exit_mmap hook */
-+extern void _arch_exit_mmap(struct mm_struct *mm);
-+#define arch_exit_mmap(_mm) _arch_exit_mmap(_mm)
-+
-+/* kernel/fork.c:dup_mmap hook */
-+extern void _arch_dup_mmap(struct mm_struct *mm);
-+#define arch_dup_mmap(mm, oldmm) ((void)(oldmm), _arch_dup_mmap(mm))
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/mmu_context.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/mmu_context.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/mmu_context.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/mmu_context.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,109 @@
-+#ifndef __I386_SCHED_H
-+#define __I386_SCHED_H
-+
-+#include <linux/config.h>
-+#include <asm/desc.h>
-+#include <asm/atomic.h>
-+#include <asm/pgalloc.h>
-+#include <asm/tlbflush.h>
-+
-+/*
-+ * Used for LDT copy/destruction.
-+ */
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
-+void destroy_context(struct mm_struct *mm);
-+
-+
-+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-+{
-+#if 0 /* XEN: no lazy tlb */
-+      unsigned cpu = smp_processor_id();
-+      if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
-+              per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_LAZY;
-+#endif
-+}
-+
-+#define prepare_arch_switch(next)     __prepare_arch_switch()
-+
-+static inline void __prepare_arch_switch(void)
-+{
-+      /*
-+       * Save away %fs and %gs. No need to save %es and %ds, as those
-+       * are always kernel segments while inside the kernel. Must
-+       * happen before reload of cr3/ldt (i.e., not in __switch_to).
-+       */
-+      asm volatile ( "mov %%fs,%0 ; mov %%gs,%1"
-+              : "=m" (current->thread.fs),
-+                "=m" (current->thread.gs));
-+      asm volatile ( "movl %0,%%fs ; movl %0,%%gs"
-+              : : "r" (0) );
-+}
-+
-+extern void mm_pin(struct mm_struct *mm);
-+extern void mm_unpin(struct mm_struct *mm);
-+void mm_pin_all(void);
-+
-+static inline void switch_mm(struct mm_struct *prev,
-+                           struct mm_struct *next,
-+                           struct task_struct *tsk)
-+{
-+      int cpu = smp_processor_id();
-+      struct mmuext_op _op[2], *op = _op;
-+
-+      if (likely(prev != next)) {
-+              BUG_ON(!xen_feature(XENFEAT_writable_page_tables) &&
-+                     !test_bit(PG_pinned, &virt_to_page(next->pgd)->flags));
-+
-+              /* stop flush ipis for the previous mm */
-+              cpu_clear(cpu, prev->cpu_vm_mask);
-+#if 0 /* XEN: no lazy tlb */
-+              per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
-+              per_cpu(cpu_tlbstate, cpu).active_mm = next;
-+#endif
-+              cpu_set(cpu, next->cpu_vm_mask);
-+
-+              /* Re-load page tables: load_cr3(next->pgd) */
-+              op->cmd = MMUEXT_NEW_BASEPTR;
-+              op->arg1.mfn = pfn_to_mfn(__pa(next->pgd) >> PAGE_SHIFT);
-+              op++;
-+
-+              /*
-+               * load the LDT, if the LDT is different:
-+               */
-+              if (unlikely(prev->context.ldt != next->context.ldt)) {
-+                      /* load_LDT_nolock(&next->context, cpu) */
-+                      op->cmd = MMUEXT_SET_LDT;
-+                      op->arg1.linear_addr = (unsigned long)next->context.ldt;
-+                      op->arg2.nr_ents     = next->context.size;
-+                      op++;
-+              }
-+
-+              BUG_ON(HYPERVISOR_mmuext_op(_op, op-_op, NULL, DOMID_SELF));
-+      }
-+#if 0 /* XEN: no lazy tlb */
-+      else {
-+              per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
-+              BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
-+
-+              if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
-+                      /* We were in lazy tlb mode and leave_mm disabled 
-+                       * tlb flush IPI delivery. We must reload %cr3.
-+                       */
-+                      load_cr3(next->pgd);
-+                      load_LDT_nolock(&next->context, cpu);
-+              }
-+      }
-+#endif
-+}
-+
-+#define deactivate_mm(tsk, mm) \
-+      asm("movl %0,%%fs ; movl %0,%%gs": :"r" (0))
-+
-+static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
-+{
-+      if (!test_bit(PG_pinned, &virt_to_page(next->pgd)->flags))
-+              mm_pin(next);
-+      switch_mm(prev, next, NULL);
-+}
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/page.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/page.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/page.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/page.h       2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,227 @@
-+#ifndef _I386_PAGE_H
-+#define _I386_PAGE_H
-+
-+/* PAGE_SHIFT determines the page size */
-+#define PAGE_SHIFT    12
-+#define PAGE_SIZE     (1UL << PAGE_SHIFT)
-+#define PAGE_MASK     (~(PAGE_SIZE-1))
-+
-+#ifdef CONFIG_X86_PAE
-+#define __PHYSICAL_MASK_SHIFT 36
-+#define __PHYSICAL_MASK               ((1ULL << __PHYSICAL_MASK_SHIFT) - 1)
-+#define PHYSICAL_PAGE_MASK    (~((1ULL << PAGE_SHIFT) - 1) & __PHYSICAL_MASK)
-+#else
-+#define __PHYSICAL_MASK_SHIFT 32
-+#define __PHYSICAL_MASK               (~0UL)
-+#define PHYSICAL_PAGE_MASK    (PAGE_MASK & __PHYSICAL_MASK)
-+#endif
-+
-+#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
-+#define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
-+
-+#ifdef __KERNEL__
-+#ifndef __ASSEMBLY__
-+
-+#include <linux/config.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/bug.h>
-+#include <xen/interface/xen.h>
-+#include <xen/features.h>
-+#include <xen/foreign_page.h>
-+
-+#define arch_free_page(_page,_order)                  \
-+({    int foreign = PageForeign(_page);               \
-+      if (foreign)                                    \
-+              (PageForeignDestructor(_page))(_page);  \
-+      foreign;                                        \
-+})
-+#define HAVE_ARCH_FREE_PAGE
-+
-+#ifdef CONFIG_XEN_SCRUB_PAGES
-+#define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
-+#else
-+#define scrub_pages(_p,_n) ((void)0)
-+#endif
-+
-+#ifdef CONFIG_X86_USE_3DNOW
-+
-+#include <asm/mmx.h>
-+
-+#define clear_page(page)      mmx_clear_page((void *)(page))
-+#define copy_page(to,from)    mmx_copy_page(to,from)
-+
-+#else
-+
-+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
-+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
-+
-+/*
-+ *    On older X86 processors it's not a win to use MMX here it seems.
-+ *    Maybe the K6-III ?
-+ */
-+ 
-+#define clear_page(page)      memset((void *)(page), 0, PAGE_SIZE)
-+#define copy_page(to,from)    memcpy((void *)(to), (void *)(from), PAGE_SIZE)
-+
-+#endif
-+
-+#define clear_user_page(page, vaddr, pg)      clear_page(page)
-+#define copy_user_page(to, from, vaddr, pg)   copy_page(to, from)
-+
-+/*
-+ * These are used to make use of C type-checking..
-+ */
-+extern int nx_enabled;
-+#ifdef CONFIG_X86_PAE
-+extern unsigned long long __supported_pte_mask;
-+typedef struct { unsigned long pte_low, pte_high; } pte_t;
-+typedef struct { unsigned long long pmd; } pmd_t;
-+typedef struct { unsigned long long pgd; } pgd_t;
-+typedef struct { unsigned long long pgprot; } pgprot_t;
-+#define pgprot_val(x) ((x).pgprot)
-+#include <asm/maddr.h>
-+#define __pte(x) ({ unsigned long long _x = (x);        \
-+    if (_x & 1) _x = phys_to_machine(_x);               \
-+    ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); })
-+#define __pgd(x) ({ unsigned long long _x = (x); \
-+    (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
-+#define __pmd(x) ({ unsigned long long _x = (x); \
-+    (((_x)&1) ? ((pmd_t) {phys_to_machine(_x)}) : ((pmd_t) {(_x)})); })
-+static inline unsigned long long pte_val(pte_t x)
-+{
-+      unsigned long long ret;
-+
-+      if (x.pte_low) {
-+              ret = x.pte_low | (unsigned long long)x.pte_high << 32;
-+              ret = pte_machine_to_phys(ret) | 1;
-+      } else {
-+              ret = 0;
-+      }
-+      return ret;
-+}
-+static inline unsigned long long pmd_val(pmd_t x)
-+{
-+      unsigned long long ret = x.pmd;
-+      if (ret) ret = pte_machine_to_phys(ret) | 1;
-+      return ret;
-+}
-+static inline unsigned long long pgd_val(pgd_t x)
-+{
-+      unsigned long long ret = x.pgd;
-+      if (ret) ret = pte_machine_to_phys(ret) | 1;
-+      return ret;
-+}
-+static inline unsigned long long pte_val_ma(pte_t x)
-+{
-+      return (unsigned long long)x.pte_high << 32 | x.pte_low;
-+}
-+#define HPAGE_SHIFT   21
-+#else
-+typedef struct { unsigned long pte_low; } pte_t;
-+typedef struct { unsigned long pgd; } pgd_t;
-+typedef struct { unsigned long pgprot; } pgprot_t;
-+#define pgprot_val(x) ((x).pgprot)
-+#include <asm/maddr.h>
-+#define boot_pte_t pte_t /* or would you rather have a typedef */
-+#define pte_val(x)    (((x).pte_low & 1) ? \
-+                       pte_machine_to_phys((x).pte_low) : \
-+                       (x).pte_low)
-+#define pte_val_ma(x) ((x).pte_low)
-+#define __pte(x) ({ unsigned long _x = (x); \
-+    (((_x)&1) ? ((pte_t) {phys_to_machine(_x)}) : ((pte_t) {(_x)})); })
-+#define __pgd(x) ({ unsigned long _x = (x); \
-+    (((_x)&1) ? ((pgd_t) {phys_to_machine(_x)}) : ((pgd_t) {(_x)})); })
-+static inline unsigned long pgd_val(pgd_t x)
-+{
-+      unsigned long ret = x.pgd;
-+      if (ret) ret = pte_machine_to_phys(ret) | 1;
-+      return ret;
-+}
-+#define HPAGE_SHIFT   22
-+#endif
-+#define PTE_MASK      PAGE_MASK
-+
-+#ifdef CONFIG_HUGETLB_PAGE
-+#define HPAGE_SIZE    ((1UL) << HPAGE_SHIFT)
-+#define HPAGE_MASK    (~(HPAGE_SIZE - 1))
-+#define HUGETLB_PAGE_ORDER    (HPAGE_SHIFT - PAGE_SHIFT)
-+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-+#endif
-+
-+#define __pgprot(x)   ((pgprot_t) { (x) } )
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+/* to align the pointer to the (next) page boundary */
-+#define PAGE_ALIGN(addr)      (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-+
-+/*
-+ * This handles the memory map.. We could make this a config
-+ * option, but too many people screw it up, and too few need
-+ * it.
-+ *
-+ * A __PAGE_OFFSET of 0xC0000000 means that the kernel has
-+ * a virtual address space of one gigabyte, which limits the
-+ * amount of physical memory you can use to about 950MB. 
-+ *
-+ * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
-+ * and CONFIG_HIGHMEM64G options in the kernel configuration.
-+ */
-+
-+#ifndef __ASSEMBLY__
-+
-+/*
-+ * This much address space is reserved for vmalloc() and iomap()
-+ * as well as fixmap mappings.
-+ */
-+extern unsigned int __VMALLOC_RESERVE;
-+
-+extern int sysctl_legacy_va_layout;
-+
-+extern int page_is_ram(unsigned long pagenr);
-+
-+#endif /* __ASSEMBLY__ */
-+
-+#ifdef __ASSEMBLY__
-+#define __PAGE_OFFSET         CONFIG_PAGE_OFFSET
-+#define __PHYSICAL_START      CONFIG_PHYSICAL_START
-+#else
-+#define __PAGE_OFFSET         ((unsigned long)CONFIG_PAGE_OFFSET)
-+#define __PHYSICAL_START      ((unsigned long)CONFIG_PHYSICAL_START)
-+#endif
-+#define __KERNEL_START                (__PAGE_OFFSET + __PHYSICAL_START)
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+#undef LOAD_OFFSET
-+#define LOAD_OFFSET           0
-+#endif /* CONFIG_XEN_COMPAT_030002 */
-+
-+#define PAGE_OFFSET           ((unsigned long)__PAGE_OFFSET)
-+#define VMALLOC_RESERVE               ((unsigned long)__VMALLOC_RESERVE)
-+#define MAXMEM                        (__FIXADDR_TOP-__PAGE_OFFSET-__VMALLOC_RESERVE)
-+#define __pa(x)                       ((unsigned long)(x)-PAGE_OFFSET)
-+#define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
-+#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
-+#ifdef CONFIG_FLATMEM
-+#define pfn_to_page(pfn)      (mem_map + (pfn))
-+#define page_to_pfn(page)     ((unsigned long)((page) - mem_map))
-+#define pfn_valid(pfn)                ((pfn) < max_mapnr)
-+#endif /* CONFIG_FLATMEM */
-+#define virt_to_page(kaddr)   pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-+
-+#define virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-+
-+#define VM_DATA_DEFAULT_FLAGS \
-+      (VM_READ | VM_WRITE | \
-+      ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
-+               VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-+
-+#define __HAVE_ARCH_GATE_AREA 1
-+
-+#endif /* __KERNEL__ */
-+
-+#include <asm-generic/page.h>
-+
-+#endif /* _I386_PAGE_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/param.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/param.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/param.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/param.h      2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,24 @@
-+#ifndef _ASMi386_PARAM_H
-+#define _ASMi386_PARAM_H
-+
-+#ifdef __KERNEL__
-+# include <linux/config.h>
-+# define HZ           CONFIG_HZ       /* Internal kernel timer frequency */
-+# define USER_HZ      100             /* .. some user interfaces are in "ticks" */
-+# define CLOCKS_PER_SEC               (USER_HZ)       /* like times() */
-+#endif
-+
-+#ifndef HZ
-+#define HZ 100
-+#endif
-+
-+#define EXEC_PAGESIZE 4096
-+
-+#ifndef NOGROUP
-+#define NOGROUP               (-1)
-+#endif
-+
-+#define MAXHOSTNAMELEN        64      /* max length of hostname */
-+#define COMMAND_LINE_SIZE 256
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pci.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/pci.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pci.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/pci.h        2007-01-08 15:00:45.000000000 +0000
-@@ -0,0 +1,154 @@
-+#ifndef __i386_PCI_H
-+#define __i386_PCI_H
-+
-+#include <linux/config.h>
-+
-+#ifdef __KERNEL__
-+#include <linux/mm.h>         /* for struct page */
-+
-+/* Can be used to override the logic in pci_scan_bus for skipping
-+   already-configured bus numbers - to be used for buggy BIOSes
-+   or architectures with incomplete PCI setup by the loader */
-+
-+#ifdef CONFIG_PCI
-+extern unsigned int pcibios_assign_all_busses(void);
-+#else
-+#define pcibios_assign_all_busses()   0
-+#endif
-+#define pcibios_scan_all_fns(a, b)    0
-+
-+extern unsigned long pci_mem_start;
-+#define PCIBIOS_MIN_IO                0x1000
-+#define PCIBIOS_MIN_MEM               (pci_mem_start)
-+
-+#define PCIBIOS_MIN_CARDBUS_IO        0x4000
-+
-+void pcibios_config_init(void);
-+struct pci_bus * pcibios_scan_root(int bus);
-+
-+void pcibios_set_master(struct pci_dev *dev);
-+void pcibios_penalize_isa_irq(int irq, int active);
-+struct irq_routing_table *pcibios_get_irq_routing_table(void);
-+int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
-+
-+/* Dynamic DMA mapping stuff.
-+ * i386 has everything mapped statically.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <asm/scatterlist.h>
-+#include <linux/string.h>
-+#include <asm/io.h>
-+
-+struct pci_dev;
-+
-+#ifdef CONFIG_SWIOTLB
-+
-+
-+/* On Xen we use SWIOTLB instead of blk-specific bounce buffers. */
-+#define PCI_DMA_BUS_IS_PHYS   (0)
-+
-+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)     \
-+      dma_addr_t ADDR_NAME;
-+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)               \
-+      __u32 LEN_NAME;
-+#define pci_unmap_addr(PTR, ADDR_NAME)                        \
-+      ((PTR)->ADDR_NAME)
-+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)               \
-+      (((PTR)->ADDR_NAME) = (VAL))
-+#define pci_unmap_len(PTR, LEN_NAME)                  \
-+      ((PTR)->LEN_NAME)
-+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)         \
-+      (((PTR)->LEN_NAME) = (VAL))
-+
-+#else
-+
-+/* The PCI address space does equal the physical memory
-+ * address space.  The networking and block device layers use
-+ * this boolean for bounce buffer decisions.
-+ */
-+#define PCI_DMA_BUS_IS_PHYS   (1)
-+
-+/* pci_unmap_{page,single} is a nop so... */
-+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-+#define pci_unmap_addr(PTR, ADDR_NAME)                (0)
-+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)       do { } while (0)
-+#define pci_unmap_len(PTR, LEN_NAME)          (0)
-+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-+
-+#endif
-+
-+/* This is always fine. */
-+#define pci_dac_dma_supported(pci_dev, mask)  (1)
-+
-+static inline dma64_addr_t
-+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
-+{
-+      return ((dma64_addr_t) page_to_phys(page) +
-+              (dma64_addr_t) offset);
-+}
-+
-+static inline struct page *
-+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
-+{
-+      return pfn_to_page(dma_addr >> PAGE_SHIFT);
-+}
-+
-+static inline unsigned long
-+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
-+{
-+      return (dma_addr & ~PAGE_MASK);
-+}
-+
-+static inline void
-+pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-+{
-+}
-+
-+static inline void
-+pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-+{
-+      flush_write_buffers();
-+}
-+
-+#define HAVE_PCI_MMAP
-+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-+                             enum pci_mmap_state mmap_state, int write_combine);
-+
-+
-+static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-+{
-+}
-+
-+#ifdef CONFIG_PCI
-+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
-+                                      enum pci_dma_burst_strategy *strat,
-+                                      unsigned long *strategy_parameter)
-+{
-+      *strat = PCI_DMA_BURST_INFINITY;
-+      *strategy_parameter = ~0UL;
-+}
-+#endif
-+
-+#endif /* __KERNEL__ */
-+
-+#ifdef CONFIG_XEN_PCIDEV_FRONTEND
-+#include <xen/pcifront.h>
-+#endif /* CONFIG_XEN_PCIDEV_FRONTEND */
-+
-+/* implement the pci_ DMA API in terms of the generic device dma_ one */
-+#include <asm-generic/pci-dma-compat.h>
-+
-+/* generic pci stuff */
-+#include <asm-generic/pci.h>
-+
-+/* On Xen we have to scan all functions since Xen hides bridges from
-+ * us.  If a bridge is at fn=0 and that slot has a multifunction
-+ * device, we won't find the additional devices without scanning all
-+ * functions. */
-+#undef pcibios_scan_all_fns
-+#define pcibios_scan_all_fns(a, b)    1
-+
-+#endif /* __i386_PCI_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgalloc.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgalloc.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgalloc.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgalloc.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,64 @@
-+#ifndef _I386_PGALLOC_H
-+#define _I386_PGALLOC_H
-+
-+#include <linux/config.h>
-+#include <asm/fixmap.h>
-+#include <linux/threads.h>
-+#include <linux/mm.h>         /* for struct page */
-+#include <asm/io.h>           /* for phys_to_virt and page_to_pseudophys */
-+
-+/* Is this pagetable pinned? */
-+#define PG_pinned     PG_arch_1
-+
-+#define pmd_populate_kernel(mm, pmd, pte) \
-+              set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
-+
-+#define pmd_populate(mm, pmd, pte)                                    \
-+do {                                                                  \
-+      if (test_bit(PG_pinned, &virt_to_page((mm)->pgd)->flags)) {     \
-+              if (!PageHighMem(pte))                                  \
-+                      BUG_ON(HYPERVISOR_update_va_mapping(            \
-+                        (unsigned long)__va(page_to_pfn(pte)<<PAGE_SHIFT),\
-+                        pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));\
-+              set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
-+                      ((unsigned long long)page_to_pfn(pte) <<        \
-+                              (unsigned long long) PAGE_SHIFT)));     \
-+      } else {                                                        \
-+              *(pmd) = __pmd(_PAGE_TABLE +                            \
-+                      ((unsigned long long)page_to_pfn(pte) <<        \
-+                              (unsigned long long) PAGE_SHIFT));      \
-+      }                                                               \
-+} while (0)
-+
-+/*
-+ * Allocate and free page tables.
-+ */
-+extern pgd_t *pgd_alloc(struct mm_struct *);
-+extern void pgd_free(pgd_t *pgd);
-+
-+extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
-+extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
-+
-+static inline void pte_free_kernel(pte_t *pte)
-+{
-+      free_page((unsigned long)pte);
-+      make_page_writable(pte, XENFEAT_writable_page_tables);
-+}
-+
-+extern void pte_free(struct page *pte);
-+
-+#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
-+
-+#ifdef CONFIG_X86_PAE
-+/*
-+ * In the PAE case we free the pmds as part of the pgd.
-+ */
-+#define pmd_alloc_one(mm, addr)               ({ BUG(); ((pmd_t *)2); })
-+#define pmd_free(x)                   do { } while (0)
-+#define __pmd_free_tlb(tlb,x)         do { } while (0)
-+#define pud_populate(mm, pmd, pte)    BUG()
-+#endif
-+
-+#define check_pgt_cache()     do { } while (0)
-+
-+#endif /* _I386_PGALLOC_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,20 @@
-+#ifndef _I386_PGTABLE_2LEVEL_DEFS_H
-+#define _I386_PGTABLE_2LEVEL_DEFS_H
-+
-+#define HAVE_SHARED_KERNEL_PMD 0
-+
-+/*
-+ * traditional i386 two-level paging structure:
-+ */
-+
-+#define PGDIR_SHIFT   22
-+#define PTRS_PER_PGD  1024
-+
-+/*
-+ * the i386 is two-level, so we don't really have any
-+ * PMD directory physically.
-+ */
-+
-+#define PTRS_PER_PTE  1024
-+
-+#endif /* _I386_PGTABLE_2LEVEL_DEFS_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable-2level.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable-2level.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable-2level.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable-2level.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,85 @@
-+#ifndef _I386_PGTABLE_2LEVEL_H
-+#define _I386_PGTABLE_2LEVEL_H
-+
-+#include <asm-generic/pgtable-nopmd.h>
-+
-+#define pte_ERROR(e) \
-+      printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
-+#define pgd_ERROR(e) \
-+      printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
-+
-+/*
-+ * Certain architectures need to do special things when PTEs
-+ * within a page table are directly modified.  Thus, the following
-+ * hook is made available.
-+ */
-+#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
-+
-+#define set_pte_at(_mm,addr,ptep,pteval) do {                         \
-+      if (((_mm) != current->mm && (_mm) != &init_mm) ||              \
-+          HYPERVISOR_update_va_mapping((addr), (pteval), 0))          \
-+              set_pte((ptep), (pteval));                              \
-+} while (0)
-+
-+#define set_pte_at_sync(_mm,addr,ptep,pteval) do {                    \
-+      if (((_mm) != current->mm && (_mm) != &init_mm) ||              \
-+          HYPERVISOR_update_va_mapping((addr), (pteval), UVMF_INVLPG)) { \
-+              set_pte((ptep), (pteval));                              \
-+              xen_invlpg((addr));                                     \
-+      }                                                               \
-+} while (0)
-+
-+#define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval)
-+
-+#define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval))
-+
-+#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
-+#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
-+
-+#define ptep_get_and_clear(mm,addr,xp)        __pte_ma(xchg(&(xp)->pte_low, 0))
-+#define pte_same(a, b)                ((a).pte_low == (b).pte_low)
-+#define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
-+#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
-+
-+#define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
-+
-+#define pte_none(x)           (!(x).pte_low)
-+#define pfn_pte(pfn, prot)    __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
-+#define pfn_pmd(pfn, prot)    __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
-+
-+/*
-+ * All present user pages are user-executable:
-+ */
-+static inline int pte_exec(pte_t pte)
-+{
-+      return pte_user(pte);
-+}
-+
-+/*
-+ * All present pages are kernel-executable:
-+ */
-+static inline int pte_exec_kernel(pte_t pte)
-+{
-+      return 1;
-+}
-+
-+/*
-+ * Bits 0, 6 and 7 are taken, split up the 29 bits of offset
-+ * into this range:
-+ */
-+#define PTE_FILE_MAX_BITS     29
-+
-+#define pte_to_pgoff(pte) \
-+      ((((pte).pte_low >> 1) & 0x1f ) + (((pte).pte_low >> 8) << 5 ))
-+
-+#define pgoff_to_pte(off) \
-+      ((pte_t) { (((off) & 0x1f) << 1) + (((off) >> 5) << 8) + _PAGE_FILE })
-+
-+/* Encode and de-code a swap entry */
-+#define __swp_type(x)                 (((x).val >> 1) & 0x1f)
-+#define __swp_offset(x)                       ((x).val >> 8)
-+#define __swp_entry(type, offset)     ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
-+#define __pte_to_swp_entry(pte)               ((swp_entry_t) { (pte).pte_low })
-+#define __swp_entry_to_pte(x)         ((pte_t) { (x).val })
-+
-+#endif /* _I386_PGTABLE_2LEVEL_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,24 @@
-+#ifndef _I386_PGTABLE_3LEVEL_DEFS_H
-+#define _I386_PGTABLE_3LEVEL_DEFS_H
-+
-+#define HAVE_SHARED_KERNEL_PMD 0
-+
-+/*
-+ * PGDIR_SHIFT determines what a top-level page table entry can map
-+ */
-+#define PGDIR_SHIFT   30
-+#define PTRS_PER_PGD  4
-+
-+/*
-+ * PMD_SHIFT determines the size of the area a middle-level
-+ * page table can map
-+ */
-+#define PMD_SHIFT     21
-+#define PTRS_PER_PMD  512
-+
-+/*
-+ * entries per page directory level
-+ */
-+#define PTRS_PER_PTE  512
-+
-+#endif /* _I386_PGTABLE_3LEVEL_DEFS_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable-3level.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable-3level.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable-3level.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable-3level.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,183 @@
-+#ifndef _I386_PGTABLE_3LEVEL_H
-+#define _I386_PGTABLE_3LEVEL_H
-+
-+#include <asm-generic/pgtable-nopud.h>
-+
-+/*
-+ * Intel Physical Address Extension (PAE) Mode - three-level page
-+ * tables on PPro+ CPUs.
-+ *
-+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
-+ */
-+
-+#define pte_ERROR(e) \
-+      printk("%s:%d: bad pte %p(%08lx%08lx).\n", __FILE__, __LINE__, &(e), (e).pte_high, (e).pte_low)
-+#define pmd_ERROR(e) \
-+      printk("%s:%d: bad pmd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
-+#define pgd_ERROR(e) \
-+      printk("%s:%d: bad pgd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
-+
-+#define pud_none(pud)                         0
-+#define pud_bad(pud)                          0
-+#define pud_present(pud)                      1
-+
-+/*
-+ * Is the pte executable?
-+ */
-+static inline int pte_x(pte_t pte)
-+{
-+      return !(pte_val(pte) & _PAGE_NX);
-+}
-+
-+/*
-+ * All present user-pages with !NX bit are user-executable:
-+ */
-+static inline int pte_exec(pte_t pte)
-+{
-+      return pte_user(pte) && pte_x(pte);
-+}
-+/*
-+ * All present pages with !NX bit are kernel-executable:
-+ */
-+static inline int pte_exec_kernel(pte_t pte)
-+{
-+      return pte_x(pte);
-+}
-+
-+/* Rules for using set_pte: the pte being assigned *must* be
-+ * either not present or in a state where the hardware will
-+ * not attempt to update the pte.  In places where this is
-+ * not possible, use pte_get_and_clear to obtain the old pte
-+ * value and then use set_pte to update it.  -ben
-+ */
-+#define __HAVE_ARCH_SET_PTE_ATOMIC
-+
-+#if 1
-+/* use writable pagetables */
-+static inline void set_pte(pte_t *ptep, pte_t pte)
-+{
-+      ptep->pte_high = pte.pte_high;
-+      smp_wmb();
-+      ptep->pte_low = pte.pte_low;
-+}
-+# define set_pte_atomic(pteptr,pteval) \
-+              set_64bit((unsigned long long *)(pteptr),pte_val_ma(pteval))
-+#else
-+/* no writable pagetables */
-+# define set_pte(pteptr,pteval)                               \
-+              xen_l1_entry_update((pteptr), (pteval))
-+# define set_pte_atomic(pteptr,pteval) set_pte(pteptr,pteval)
-+#endif
-+
-+#define set_pte_at(_mm,addr,ptep,pteval) do {                         \
-+      if (((_mm) != current->mm && (_mm) != &init_mm) ||              \
-+          HYPERVISOR_update_va_mapping((addr), (pteval), 0))          \
-+              set_pte((ptep), (pteval));                              \
-+} while (0)
-+
-+#define set_pte_at_sync(_mm,addr,ptep,pteval) do {                    \
-+      if (((_mm) != current->mm && (_mm) != &init_mm) ||              \
-+          HYPERVISOR_update_va_mapping((addr), (pteval), UVMF_INVLPG)) { \
-+              set_pte((ptep), (pteval));                              \
-+              xen_invlpg((addr));                                     \
-+      }                                                               \
-+} while (0)
-+
-+#define set_pmd(pmdptr,pmdval)                                \
-+              xen_l2_entry_update((pmdptr), (pmdval))
-+#define set_pud(pudptr,pudval) \
-+              xen_l3_entry_update((pudptr), (pudval))
-+
-+/*
-+ * Pentium-II erratum A13: in PAE mode we explicitly have to flush
-+ * the TLB via cr3 if the top-level pgd is changed...
-+ * We do not let the generic code free and clear pgd entries due to
-+ * this erratum.
-+ */
-+static inline void pud_clear (pud_t * pud) { }
-+
-+#define pud_page(pud) \
-+((struct page *) __va(pud_val(pud) & PAGE_MASK))
-+
-+#define pud_page_kernel(pud) \
-+((unsigned long) __va(pud_val(pud) & PAGE_MASK))
-+
-+
-+/* Find an entry in the second-level page table.. */
-+#define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \
-+                      pmd_index(address))
-+
-+/*
-+ * For PTEs and PDEs, we must clear the P-bit first when clearing a page table
-+ * entry, so clear the bottom half first and enforce ordering with a compiler
-+ * barrier.
-+ */
-+static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-+{
-+      ptep->pte_low = 0;
-+      smp_wmb();
-+      ptep->pte_high = 0;
-+}
-+
-+#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
-+
-+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-+{
-+      pte_t res;
-+
-+      /* xchg acts as a barrier before the setting of the high bits */
-+      res.pte_low = xchg(&ptep->pte_low, 0);
-+      res.pte_high = ptep->pte_high;
-+      ptep->pte_high = 0;
-+
-+      return res;
-+}
-+
-+static inline int pte_same(pte_t a, pte_t b)
-+{
-+      return a.pte_low == b.pte_low && a.pte_high == b.pte_high;
-+}
-+
-+#define pte_page(x)   pfn_to_page(pte_pfn(x))
-+
-+static inline int pte_none(pte_t pte)
-+{
-+      return !pte.pte_low && !pte.pte_high;
-+}
-+
-+#define pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) |\
-+                     (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)))
-+#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
-+
-+extern unsigned long long __supported_pte_mask;
-+
-+static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
-+{
-+      return pfn_pte_ma(pfn_to_mfn(page_nr), pgprot);
-+}
-+
-+static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
-+{
-+      BUG(); panic("needs review");
-+      return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \
-+                      pgprot_val(pgprot)) & __supported_pte_mask);
-+}
-+
-+/*
-+ * Bits 0, 6 and 7 are taken in the low part of the pte,
-+ * put the 32 bits of offset into the high part.
-+ */
-+#define pte_to_pgoff(pte) ((pte).pte_high)
-+#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
-+#define PTE_FILE_MAX_BITS       32
-+
-+/* Encode and de-code a swap entry */
-+#define __swp_type(x)                 (((x).val) & 0x1f)
-+#define __swp_offset(x)                       ((x).val >> 5)
-+#define __swp_entry(type, offset)     ((swp_entry_t){(type) | (offset) << 5})
-+#define __pte_to_swp_entry(pte)               ((swp_entry_t){ (pte).pte_high })
-+#define __swp_entry_to_pte(x)         ((pte_t){ 0, (x).val })
-+
-+#define __pmd_free_tlb(tlb, x)                do { } while (0)
-+
-+#endif /* _I386_PGTABLE_3LEVEL_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/pgtable.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/pgtable.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,510 @@
-+#ifndef _I386_PGTABLE_H
-+#define _I386_PGTABLE_H
-+
-+#include <linux/config.h>
-+#include <asm/hypervisor.h>
-+
-+/*
-+ * The Linux memory management assumes a three-level page table setup. On
-+ * the i386, we use that, but "fold" the mid level into the top-level page
-+ * table, so that we physically have the same two-level page table as the
-+ * i386 mmu expects.
-+ *
-+ * This file contains the functions and defines necessary to modify and use
-+ * the i386 page table tree.
-+ */
-+#ifndef __ASSEMBLY__
-+#include <asm/processor.h>
-+#include <asm/fixmap.h>
-+#include <linux/threads.h>
-+
-+#ifndef _I386_BITOPS_H
-+#include <asm/bitops.h>
-+#endif
-+
-+#include <linux/slab.h>
-+#include <linux/list.h>
-+#include <linux/spinlock.h>
-+
-+struct mm_struct;
-+struct vm_area_struct;
-+
-+/*
-+ * ZERO_PAGE is a global shared page that is always zero: used
-+ * for zero-mapped memory areas etc..
-+ */
-+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
-+extern unsigned long empty_zero_page[1024];
-+extern pgd_t *swapper_pg_dir;
-+extern kmem_cache_t *pgd_cache;
-+extern kmem_cache_t *pmd_cache;
-+extern spinlock_t pgd_lock;
-+extern struct page *pgd_list;
-+
-+void pmd_ctor(void *, kmem_cache_t *, unsigned long);
-+void pgd_ctor(void *, kmem_cache_t *, unsigned long);
-+void pgd_dtor(void *, kmem_cache_t *, unsigned long);
-+void pgtable_cache_init(void);
-+void paging_init(void);
-+
-+/*
-+ * The Linux x86 paging architecture is 'compile-time dual-mode', it
-+ * implements both the traditional 2-level x86 page tables and the
-+ * newer 3-level PAE-mode page tables.
-+ */
-+#ifdef CONFIG_X86_PAE
-+# include <asm/pgtable-3level-defs.h>
-+# define PMD_SIZE     (1UL << PMD_SHIFT)
-+# define PMD_MASK     (~(PMD_SIZE-1))
-+#else
-+# include <asm/pgtable-2level-defs.h>
-+#endif
-+
-+#define PGDIR_SIZE    (1UL << PGDIR_SHIFT)
-+#define PGDIR_MASK    (~(PGDIR_SIZE-1))
-+
-+#define USER_PTRS_PER_PGD     (TASK_SIZE/PGDIR_SIZE)
-+#define FIRST_USER_ADDRESS    0
-+
-+#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
-+#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
-+
-+#define TWOLEVEL_PGDIR_SHIFT  22
-+#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
-+#define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
-+
-+/* Just any arbitrary offset to the start of the vmalloc VM area: the
-+ * current 8MB value just means that there will be a 8MB "hole" after the
-+ * physical memory until the kernel virtual memory starts.  That means that
-+ * any out-of-bounds memory accesses will hopefully be caught.
-+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
-+ * area for the same reason. ;)
-+ */
-+#define VMALLOC_OFFSET        (8*1024*1024)
-+#define VMALLOC_START (((unsigned long) high_memory + vmalloc_earlyreserve + \
-+                      2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1))
-+#ifdef CONFIG_HIGHMEM
-+# define VMALLOC_END  (PKMAP_BASE-2*PAGE_SIZE)
-+#else
-+# define VMALLOC_END  (FIXADDR_START-2*PAGE_SIZE)
-+#endif
-+
-+/*
-+ * _PAGE_PSE set in the page directory entry just means that
-+ * the page directory entry points directly to a 4MB-aligned block of
-+ * memory. 
-+ */
-+#define _PAGE_BIT_PRESENT     0
-+#define _PAGE_BIT_RW          1
-+#define _PAGE_BIT_USER                2
-+#define _PAGE_BIT_PWT         3
-+#define _PAGE_BIT_PCD         4
-+#define _PAGE_BIT_ACCESSED    5
-+#define _PAGE_BIT_DIRTY               6
-+#define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page, Pentium+, if present.. */
-+#define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
-+#define _PAGE_BIT_UNUSED1     9       /* available for programmer */
-+#define _PAGE_BIT_UNUSED2     10
-+#define _PAGE_BIT_UNUSED3     11
-+#define _PAGE_BIT_NX          63
-+
-+#define _PAGE_PRESENT 0x001
-+#define _PAGE_RW      0x002
-+#define _PAGE_USER    0x004
-+#define _PAGE_PWT     0x008
-+#define _PAGE_PCD     0x010
-+#define _PAGE_ACCESSED        0x020
-+#define _PAGE_DIRTY   0x040
-+#define _PAGE_PSE     0x080   /* 4 MB (or 2MB) page, Pentium+, if present.. */
-+#define _PAGE_GLOBAL  0x100   /* Global TLB entry PPro+ */
-+#define _PAGE_UNUSED1 0x200   /* available for programmer */
-+#define _PAGE_UNUSED2 0x400
-+#define _PAGE_UNUSED3 0x800
-+
-+/* If _PAGE_PRESENT is clear, we use these: */
-+#define _PAGE_FILE    0x040   /* nonlinear file mapping, saved PTE; unset:swap */
-+#define _PAGE_PROTNONE        0x080   /* if the user mapped it with PROT_NONE;
-+                                 pte_present gives true */
-+#ifdef CONFIG_X86_PAE
-+#define _PAGE_NX      (1ULL<<_PAGE_BIT_NX)
-+#else
-+#define _PAGE_NX      0
-+#endif
-+
-+#define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
-+#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
-+#define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
-+
-+#define PAGE_NONE \
-+      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
-+#define PAGE_SHARED \
-+      __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-+
-+#define PAGE_SHARED_EXEC \
-+      __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-+#define PAGE_COPY_NOEXEC \
-+      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-+#define PAGE_COPY_EXEC \
-+      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-+#define PAGE_COPY \
-+      PAGE_COPY_NOEXEC
-+#define PAGE_READONLY \
-+      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-+#define PAGE_READONLY_EXEC \
-+      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-+
-+#define _PAGE_KERNEL \
-+      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
-+#define _PAGE_KERNEL_EXEC \
-+      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
-+
-+extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
-+#define __PAGE_KERNEL_RO              (__PAGE_KERNEL & ~_PAGE_RW)
-+#define __PAGE_KERNEL_NOCACHE         (__PAGE_KERNEL | _PAGE_PCD)
-+#define __PAGE_KERNEL_LARGE           (__PAGE_KERNEL | _PAGE_PSE)
-+#define __PAGE_KERNEL_LARGE_EXEC      (__PAGE_KERNEL_EXEC | _PAGE_PSE)
-+
-+#define PAGE_KERNEL           __pgprot(__PAGE_KERNEL)
-+#define PAGE_KERNEL_RO                __pgprot(__PAGE_KERNEL_RO)
-+#define PAGE_KERNEL_EXEC      __pgprot(__PAGE_KERNEL_EXEC)
-+#define PAGE_KERNEL_NOCACHE   __pgprot(__PAGE_KERNEL_NOCACHE)
-+#define PAGE_KERNEL_LARGE     __pgprot(__PAGE_KERNEL_LARGE)
-+#define PAGE_KERNEL_LARGE_EXEC        __pgprot(__PAGE_KERNEL_LARGE_EXEC)
-+
-+/*
-+ * The i386 can't do page protection for execute, and considers that
-+ * the same are read. Also, write permissions imply read permissions.
-+ * This is the closest we can get..
-+ */
-+#define __P000        PAGE_NONE
-+#define __P001        PAGE_READONLY
-+#define __P010        PAGE_COPY
-+#define __P011        PAGE_COPY
-+#define __P100        PAGE_READONLY_EXEC
-+#define __P101        PAGE_READONLY_EXEC
-+#define __P110        PAGE_COPY_EXEC
-+#define __P111        PAGE_COPY_EXEC
-+
-+#define __S000        PAGE_NONE
-+#define __S001        PAGE_READONLY
-+#define __S010        PAGE_SHARED
-+#define __S011        PAGE_SHARED
-+#define __S100        PAGE_READONLY_EXEC
-+#define __S101        PAGE_READONLY_EXEC
-+#define __S110        PAGE_SHARED_EXEC
-+#define __S111        PAGE_SHARED_EXEC
-+
-+/*
-+ * Define this if things work differently on an i386 and an i486:
-+ * it will (on an i486) warn about kernel memory accesses that are
-+ * done without a 'access_ok(VERIFY_WRITE,..)'
-+ */
-+#undef TEST_ACCESS_OK
-+
-+/* The boot page tables (all created as a single array) */
-+extern unsigned long pg0[];
-+
-+#define pte_present(x)        ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
-+
-+/* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
-+#define pmd_none(x)   (!(unsigned long)pmd_val(x))
-+/* pmd_present doesn't just test the _PAGE_PRESENT bit since wr.p.t.
-+   can temporarily clear it. */
-+#define pmd_present(x)        (pmd_val(x))
-+#define pmd_bad(x)    ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
-+
-+
-+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
-+
-+/*
-+ * The following only work if pte_present() is true.
-+ * Undefined behaviour if not..
-+ */
-+#define __LARGE_PTE (_PAGE_PSE | _PAGE_PRESENT)
-+static inline int pte_user(pte_t pte)         { return (pte).pte_low & _PAGE_USER; }
-+static inline int pte_read(pte_t pte)         { return (pte).pte_low & _PAGE_USER; }
-+static inline int pte_dirty(pte_t pte)                { return (pte).pte_low & _PAGE_DIRTY; }
-+static inline int pte_young(pte_t pte)                { return (pte).pte_low & _PAGE_ACCESSED; }
-+static inline int pte_write(pte_t pte)                { return (pte).pte_low & _PAGE_RW; }
-+static inline int pte_huge(pte_t pte)         { return ((pte).pte_low & __LARGE_PTE) == __LARGE_PTE; }
-+
-+/*
-+ * The following only works if pte_present() is not true.
-+ */
-+static inline int pte_file(pte_t pte)         { return (pte).pte_low & _PAGE_FILE; }
-+
-+static inline pte_t pte_rdprotect(pte_t pte)  { (pte).pte_low &= ~_PAGE_USER; return pte; }
-+static inline pte_t pte_exprotect(pte_t pte)  { (pte).pte_low &= ~_PAGE_USER; return pte; }
-+static inline pte_t pte_mkclean(pte_t pte)    { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
-+static inline pte_t pte_mkold(pte_t pte)      { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
-+static inline pte_t pte_wrprotect(pte_t pte)  { (pte).pte_low &= ~_PAGE_RW; return pte; }
-+static inline pte_t pte_mkread(pte_t pte)     { (pte).pte_low |= _PAGE_USER; return pte; }
-+static inline pte_t pte_mkexec(pte_t pte)     { (pte).pte_low |= _PAGE_USER; return pte; }
-+static inline pte_t pte_mkdirty(pte_t pte)    { (pte).pte_low |= _PAGE_DIRTY; return pte; }
-+static inline pte_t pte_mkyoung(pte_t pte)    { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
-+static inline pte_t pte_mkwrite(pte_t pte)    { (pte).pte_low |= _PAGE_RW; return pte; }
-+static inline pte_t pte_mkhuge(pte_t pte)     { (pte).pte_low |= __LARGE_PTE; return pte; }
-+
-+#ifdef CONFIG_X86_PAE
-+# include <asm/pgtable-3level.h>
-+#else
-+# include <asm/pgtable-2level.h>
-+#endif
-+
-+static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
-+{
-+      if (!pte_dirty(*ptep))
-+              return 0;
-+      return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
-+}
-+
-+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
-+{
-+      if (!pte_young(*ptep))
-+              return 0;
-+      return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
-+}
-+
-+static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
-+{
-+      pte_t pte;
-+      if (full) {
-+              pte = *ptep;
-+              pte_clear(mm, addr, ptep);
-+      } else {
-+              pte = ptep_get_and_clear(mm, addr, ptep);
-+      }
-+      return pte;
-+}
-+
-+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-+{
-+      if (pte_write(*ptep))
-+              clear_bit(_PAGE_BIT_RW, &ptep->pte_low);
-+}
-+
-+/*
-+ * clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
-+ *
-+ *  dst - pointer to pgd range anwhere on a pgd page
-+ *  src - ""
-+ *  count - the number of pgds to copy.
-+ *
-+ * dst and src can be on the same page, but the range must not overlap,
-+ * and must not cross a page boundary.
-+ */
-+static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
-+{
-+       memcpy(dst, src, count * sizeof(pgd_t));
-+}
-+
-+/*
-+ * Macro to mark a page protection value as "uncacheable".  On processors which do not support
-+ * it, this is a no-op.
-+ */
-+#define pgprot_noncached(prot)        ((boot_cpu_data.x86 > 3)                                          \
-+                               ? (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT)) : (prot))
-+
-+/*
-+ * Conversion functions: convert a page and protection to a page entry,
-+ * and a page entry and page directory to the page they refer to.
-+ */
-+
-+#define mk_pte(page, pgprot)  pfn_pte(page_to_pfn(page), (pgprot))
-+
-+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-+{
-+      pte.pte_low &= _PAGE_CHG_MASK;
-+      pte.pte_low |= pgprot_val(newprot);
-+#ifdef CONFIG_X86_PAE
-+      /*
-+       * Chop off the NX bit (if present), and add the NX portion of
-+       * the newprot (if present):
-+       */
-+      pte.pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
-+      pte.pte_high |= (pgprot_val(newprot) >> 32) & \
-+                                      (__supported_pte_mask >> 32);
-+#endif
-+      return pte;
-+}
-+
-+#define pmd_large(pmd) \
-+((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
-+
-+/*
-+ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
-+ *
-+ * this macro returns the index of the entry in the pgd page which would
-+ * control the given virtual address
-+ */
-+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-+#define pgd_index_k(addr) pgd_index(addr)
-+
-+/*
-+ * pgd_offset() returns a (pgd_t *)
-+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
-+ */
-+#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
-+
-+/*
-+ * a shortcut which implies the use of the kernel's pgd, instead
-+ * of a process's
-+ */
-+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-+
-+/*
-+ * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
-+ *
-+ * this macro returns the index of the entry in the pmd page which would
-+ * control the given virtual address
-+ */
-+#define pmd_index(address) \
-+              (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
-+
-+/*
-+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
-+ *
-+ * this macro returns the index of the entry in the pte page which would
-+ * control the given virtual address
-+ */
-+#define pte_index(address) \
-+              (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-+#define pte_offset_kernel(dir, address) \
-+      ((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
-+
-+#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-+
-+#define pmd_page_kernel(pmd) \
-+              ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-+
-+/*
-+ * Helper function that returns the kernel pagetable entry controlling
-+ * the virtual address 'address'. NULL means no pagetable entry present.
-+ * NOTE: the return type is pte_t but if the pmd is PSE then we return it
-+ * as a pte too.
-+ */
-+extern pte_t *lookup_address(unsigned long address);
-+
-+/*
-+ * Make a given kernel text page executable/non-executable.
-+ * Returns the previous executability setting of that page (which
-+ * is used to restore the previous state). Used by the SMP bootup code.
-+ * NOTE: this is an __init function for security reasons.
-+ */
-+#ifdef CONFIG_X86_PAE
-+ extern int set_kernel_exec(unsigned long vaddr, int enable);
-+#else
-+ static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;}
-+#endif
-+
-+extern void noexec_setup(const char *str);
-+
-+#if defined(CONFIG_HIGHPTE)
-+#define pte_offset_map(dir, address) \
-+      ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + \
-+       pte_index(address))
-+#define pte_offset_map_nested(dir, address) \
-+      ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE1) + \
-+       pte_index(address))
-+#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
-+#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
-+#else
-+#define pte_offset_map(dir, address) \
-+      ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
-+#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
-+#define pte_unmap(pte) do { } while (0)
-+#define pte_unmap_nested(pte) do { } while (0)
-+#endif
-+
-+/*
-+ * The i386 doesn't have any external MMU info: the kernel page
-+ * tables contain all the necessary information.
-+ *
-+ * Also, we only update the dirty/accessed state if we set
-+ * the dirty bit by hand in the kernel, since the hardware
-+ * will do the accessed bit for us, and we don't want to
-+ * race with other CPU's that might be updating the dirty
-+ * bit at the same time.
-+ */
-+#define update_mmu_cache(vma,address,pte) do { } while (0)
-+#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-+      do {                                                              \
-+              if (__dirty) {                                            \
-+                      if ( likely((__vma)->vm_mm == current->mm) ) {    \
-+                          BUG_ON(HYPERVISOR_update_va_mapping((__address), (__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned long)((__vma)->vm_mm->cpu_vm_mask.bits))); \
-+                      } else {                                          \
-+                            xen_l1_entry_update((__ptep), (__entry)); \
-+                          flush_tlb_page((__vma), (__address));         \
-+                      }                                                 \
-+              }                                                         \
-+      } while (0)
-+
-+#define __HAVE_ARCH_PTEP_ESTABLISH
-+#define ptep_establish(__vma, __address, __ptep, __entry)             \
-+do {                                                                  \
-+      ptep_set_access_flags(__vma, __address, __ptep, __entry, 1);    \
-+} while (0)
-+
-+#include <xen/features.h>
-+void make_lowmem_page_readonly(void *va, unsigned int feature);
-+void make_lowmem_page_writable(void *va, unsigned int feature);
-+void make_page_readonly(void *va, unsigned int feature);
-+void make_page_writable(void *va, unsigned int feature);
-+void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
-+void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
-+
-+#define virt_to_ptep(__va)                                            \
-+({                                                                    \
-+      pgd_t *__pgd = pgd_offset_k((unsigned long)(__va));             \
-+      pud_t *__pud = pud_offset(__pgd, (unsigned long)(__va));        \
-+      pmd_t *__pmd = pmd_offset(__pud, (unsigned long)(__va));        \
-+      pte_offset_kernel(__pmd, (unsigned long)(__va));                \
-+})
-+
-+#define arbitrary_virt_to_machine(__va)                                       \
-+({                                                                    \
-+      maddr_t m = (maddr_t)pte_mfn(*virt_to_ptep(__va)) << PAGE_SHIFT;\
-+      m | ((unsigned long)(__va) & (PAGE_SIZE-1));                    \
-+})
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+#ifdef CONFIG_FLATMEM
-+#define kern_addr_valid(addr) (1)
-+#endif /* CONFIG_FLATMEM */
-+
-+int direct_remap_pfn_range(struct vm_area_struct *vma,
-+                           unsigned long address, 
-+                           unsigned long mfn,
-+                           unsigned long size, 
-+                           pgprot_t prot,
-+                           domid_t  domid);
-+int direct_kernel_remap_pfn_range(unsigned long address, 
-+                                unsigned long mfn,
-+                                unsigned long size, 
-+                                pgprot_t prot,
-+                                domid_t  domid);
-+int create_lookup_pte_addr(struct mm_struct *mm,
-+                           unsigned long address,
-+                           uint64_t *ptep);
-+int touch_pte_range(struct mm_struct *mm,
-+                    unsigned long address,
-+                    unsigned long size);
-+
-+#define io_remap_pfn_range(vma,from,pfn,size,prot) \
-+direct_remap_pfn_range(vma,from,pfn,size,prot,DOMID_IO)
-+
-+#define MK_IOSPACE_PFN(space, pfn)    (pfn)
-+#define GET_IOSPACE(pfn)              0
-+#define GET_PFN(pfn)                  (pfn)
-+
-+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
-+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
-+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-+#define __HAVE_ARCH_PTE_SAME
-+#include <asm-generic/pgtable.h>
-+
-+#endif /* _I386_PGTABLE_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/processor.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/processor.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/processor.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/processor.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,750 @@
-+/*
-+ * include/asm-i386/processor.h
-+ *
-+ * Copyright (C) 1994 Linus Torvalds
-+ */
-+
-+#ifndef __ASM_I386_PROCESSOR_H
-+#define __ASM_I386_PROCESSOR_H
-+
-+#include <asm/vm86.h>
-+#include <asm/math_emu.h>
-+#include <asm/segment.h>
-+#include <asm/page.h>
-+#include <asm/types.h>
-+#include <asm/sigcontext.h>
-+#include <asm/cpufeature.h>
-+#include <asm/msr.h>
-+#include <asm/system.h>
-+#include <linux/cache.h>
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <asm/percpu.h>
-+#include <xen/interface/physdev.h>
-+
-+/* flag for disabling the tsc */
-+extern int tsc_disable;
-+
-+struct desc_struct {
-+      unsigned long a,b;
-+};
-+
-+#define desc_empty(desc) \
-+              (!((desc)->a | (desc)->b))
-+
-+#define desc_equal(desc1, desc2) \
-+              (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
-+/*
-+ * Default implementation of macro that returns current
-+ * instruction pointer ("program counter").
-+ */
-+#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
-+
-+/*
-+ *  CPU type and hardware bug flags. Kept separately for each CPU.
-+ *  Members of this structure are referenced in head.S, so think twice
-+ *  before touching them. [mj]
-+ */
-+
-+struct cpuinfo_x86 {
-+      __u8    x86;            /* CPU family */
-+      __u8    x86_vendor;     /* CPU vendor */
-+      __u8    x86_model;
-+      __u8    x86_mask;
-+      char    wp_works_ok;    /* It doesn't on 386's */
-+      char    hlt_works_ok;   /* Problems on some 486Dx4's and old 386's */
-+      char    hard_math;
-+      char    rfu;
-+              int     cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
-+      unsigned long   x86_capability[NCAPINTS];
-+      char    x86_vendor_id[16];
-+      char    x86_model_id[64];
-+      int     x86_cache_size;  /* in KB - valid for CPUS which support this
-+                                  call  */
-+      int     x86_cache_alignment;    /* In bytes */
-+      char    fdiv_bug;
-+      char    f00f_bug;
-+      char    coma_bug;
-+      char    pad0;
-+      int     x86_power;
-+      unsigned long loops_per_jiffy;
-+      unsigned char x86_max_cores;    /* cpuid returned max cores value */
-+      unsigned char booted_cores;     /* number of cores as seen by OS */
-+      unsigned char apicid;
-+} __attribute__((__aligned__(SMP_CACHE_BYTES)));
-+
-+#define X86_VENDOR_INTEL 0
-+#define X86_VENDOR_CYRIX 1
-+#define X86_VENDOR_AMD 2
-+#define X86_VENDOR_UMC 3
-+#define X86_VENDOR_NEXGEN 4
-+#define X86_VENDOR_CENTAUR 5
-+#define X86_VENDOR_RISE 6
-+#define X86_VENDOR_TRANSMETA 7
-+#define X86_VENDOR_NSC 8
-+#define X86_VENDOR_NUM 9
-+#define X86_VENDOR_UNKNOWN 0xff
-+
-+/*
-+ * capabilities of CPUs
-+ */
-+
-+extern struct cpuinfo_x86 boot_cpu_data;
-+extern struct cpuinfo_x86 new_cpu_data;
-+#ifndef CONFIG_X86_NO_TSS
-+extern struct tss_struct doublefault_tss;
-+DECLARE_PER_CPU(struct tss_struct, init_tss);
-+#endif
-+
-+#ifdef CONFIG_SMP
-+extern struct cpuinfo_x86 cpu_data[];
-+#define current_cpu_data cpu_data[smp_processor_id()]
-+#else
-+#define cpu_data (&boot_cpu_data)
-+#define current_cpu_data boot_cpu_data
-+#endif
-+
-+extern        int phys_proc_id[NR_CPUS];
-+extern        int cpu_core_id[NR_CPUS];
-+extern char ignore_fpu_irq;
-+
-+extern void identify_cpu(struct cpuinfo_x86 *);
-+extern void print_cpu_info(struct cpuinfo_x86 *);
-+extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
-+
-+#ifdef CONFIG_X86_HT
-+extern void detect_ht(struct cpuinfo_x86 *c);
-+#else
-+static inline void detect_ht(struct cpuinfo_x86 *c) {}
-+#endif
-+
-+/*
-+ * EFLAGS bits
-+ */
-+#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
-+#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
-+#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
-+#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
-+#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
-+#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
-+#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
-+#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
-+#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
-+#define X86_EFLAGS_IOPL       0x00003000 /* IOPL mask */
-+#define X86_EFLAGS_NT 0x00004000 /* Nested Task */
-+#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
-+#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
-+#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
-+#define X86_EFLAGS_VIF        0x00080000 /* Virtual Interrupt Flag */
-+#define X86_EFLAGS_VIP        0x00100000 /* Virtual Interrupt Pending */
-+#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
-+
-+/*
-+ * Generic CPUID function
-+ * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
-+ * resulting in stale register contents being returned.
-+ */
-+static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
-+{
-+      __asm__(XEN_CPUID
-+              : "=a" (*eax),
-+                "=b" (*ebx),
-+                "=c" (*ecx),
-+                "=d" (*edx)
-+              : "0" (op), "c"(0));
-+}
-+
-+/* Some CPUID calls want 'count' to be placed in ecx */
-+static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
-+              int *edx)
-+{
-+      __asm__(XEN_CPUID
-+              : "=a" (*eax),
-+                "=b" (*ebx),
-+                "=c" (*ecx),
-+                "=d" (*edx)
-+              : "0" (op), "c" (count));
-+}
-+
-+/*
-+ * CPUID functions returning a single datum
-+ */
-+static inline unsigned int cpuid_eax(unsigned int op)
-+{
-+      unsigned int eax;
-+
-+      __asm__(XEN_CPUID
-+              : "=a" (eax)
-+              : "0" (op)
-+              : "bx", "cx", "dx");
-+      return eax;
-+}
-+static inline unsigned int cpuid_ebx(unsigned int op)
-+{
-+      unsigned int eax, ebx;
-+
-+      __asm__(XEN_CPUID
-+              : "=a" (eax), "=b" (ebx)
-+              : "0" (op)
-+              : "cx", "dx" );
-+      return ebx;
-+}
-+static inline unsigned int cpuid_ecx(unsigned int op)
-+{
-+      unsigned int eax, ecx;
-+
-+      __asm__(XEN_CPUID
-+              : "=a" (eax), "=c" (ecx)
-+              : "0" (op)
-+              : "bx", "dx" );
-+      return ecx;
-+}
-+static inline unsigned int cpuid_edx(unsigned int op)
-+{
-+      unsigned int eax, edx;
-+
-+      __asm__(XEN_CPUID
-+              : "=a" (eax), "=d" (edx)
-+              : "0" (op)
-+              : "bx", "cx");
-+      return edx;
-+}
-+
-+#define load_cr3(pgdir) write_cr3(__pa(pgdir))
-+
-+/*
-+ * Intel CPU features in CR4
-+ */
-+#define X86_CR4_VME           0x0001  /* enable vm86 extensions */
-+#define X86_CR4_PVI           0x0002  /* virtual interrupts flag enable */
-+#define X86_CR4_TSD           0x0004  /* disable time stamp at ipl 3 */
-+#define X86_CR4_DE            0x0008  /* enable debugging extensions */
-+#define X86_CR4_PSE           0x0010  /* enable page size extensions */
-+#define X86_CR4_PAE           0x0020  /* enable physical address extensions */
-+#define X86_CR4_MCE           0x0040  /* Machine check enable */
-+#define X86_CR4_PGE           0x0080  /* enable global pages */
-+#define X86_CR4_PCE           0x0100  /* enable performance counters at ipl 3 */
-+#define X86_CR4_OSFXSR                0x0200  /* enable fast FPU save and restore */
-+#define X86_CR4_OSXMMEXCPT    0x0400  /* enable unmasked SSE exceptions */
-+
-+/*
-+ * Save the cr4 feature set we're using (ie
-+ * Pentium 4MB enable and PPro Global page
-+ * enable), so that any CPU's that boot up
-+ * after us can get the correct flags.
-+ */
-+extern unsigned long mmu_cr4_features;
-+
-+static inline void set_in_cr4 (unsigned long mask)
-+{
-+      unsigned cr4;
-+      mmu_cr4_features |= mask;
-+      cr4 = read_cr4();
-+      cr4 |= mask;
-+      write_cr4(cr4);
-+}
-+
-+static inline void clear_in_cr4 (unsigned long mask)
-+{
-+      unsigned cr4;
-+      mmu_cr4_features &= ~mask;
-+      cr4 = read_cr4();
-+      cr4 &= ~mask;
-+      write_cr4(cr4);
-+}
-+
-+/*
-+ *      NSC/Cyrix CPU configuration register indexes
-+ */
-+
-+#define CX86_PCR0 0x20
-+#define CX86_GCR  0xb8
-+#define CX86_CCR0 0xc0
-+#define CX86_CCR1 0xc1
-+#define CX86_CCR2 0xc2
-+#define CX86_CCR3 0xc3
-+#define CX86_CCR4 0xe8
-+#define CX86_CCR5 0xe9
-+#define CX86_CCR6 0xea
-+#define CX86_CCR7 0xeb
-+#define CX86_PCR1 0xf0
-+#define CX86_DIR0 0xfe
-+#define CX86_DIR1 0xff
-+#define CX86_ARR_BASE 0xc4
-+#define CX86_RCR_BASE 0xdc
-+
-+/*
-+ *      NSC/Cyrix CPU indexed register access macros
-+ */
-+
-+#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
-+
-+#define setCx86(reg, data) do { \
-+      outb((reg), 0x22); \
-+      outb((data), 0x23); \
-+} while (0)
-+
-+/* Stop speculative execution */
-+static inline void sync_core(void)
-+{
-+      int tmp;
-+      asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
-+}
-+
-+static inline void __monitor(const void *eax, unsigned long ecx,
-+              unsigned long edx)
-+{
-+      /* "monitor %eax,%ecx,%edx;" */
-+      asm volatile(
-+              ".byte 0x0f,0x01,0xc8;"
-+              : :"a" (eax), "c" (ecx), "d"(edx));
-+}
-+
-+static inline void __mwait(unsigned long eax, unsigned long ecx)
-+{
-+      /* "mwait %eax,%ecx;" */
-+      asm volatile(
-+              ".byte 0x0f,0x01,0xc9;"
-+              : :"a" (eax), "c" (ecx));
-+}
-+
-+/* from system description table in BIOS.  Mostly for MCA use, but
-+others may find it useful. */
-+extern unsigned int machine_id;
-+extern unsigned int machine_submodel_id;
-+extern unsigned int BIOS_revision;
-+extern unsigned int mca_pentium_flag;
-+
-+/* Boot loader type from the setup header */
-+extern int bootloader_type;
-+
-+/*
-+ * User space process size: 3GB (default).
-+ */
-+#define TASK_SIZE     (PAGE_OFFSET)
-+
-+/* This decides where the kernel will search for a free chunk of vm
-+ * space during mmap's.
-+ */
-+#define TASK_UNMAPPED_BASE    (PAGE_ALIGN(TASK_SIZE / 3))
-+
-+#define HAVE_ARCH_PICK_MMAP_LAYOUT
-+
-+/*
-+ * Size of io_bitmap.
-+ */
-+#define IO_BITMAP_BITS  65536
-+#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
-+#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
-+#ifndef CONFIG_X86_NO_TSS
-+#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
-+#endif
-+#define INVALID_IO_BITMAP_OFFSET 0x8000
-+#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
-+
-+struct i387_fsave_struct {
-+      long    cwd;
-+      long    swd;
-+      long    twd;
-+      long    fip;
-+      long    fcs;
-+      long    foo;
-+      long    fos;
-+      long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
-+      long    status;         /* software status information */
-+};
-+
-+struct i387_fxsave_struct {
-+      unsigned short  cwd;
-+      unsigned short  swd;
-+      unsigned short  twd;
-+      unsigned short  fop;
-+      long    fip;
-+      long    fcs;
-+      long    foo;
-+      long    fos;
-+      long    mxcsr;
-+      long    mxcsr_mask;
-+      long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
-+      long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
-+      long    padding[56];
-+} __attribute__ ((aligned (16)));
-+
-+struct i387_soft_struct {
-+      long    cwd;
-+      long    swd;
-+      long    twd;
-+      long    fip;
-+      long    fcs;
-+      long    foo;
-+      long    fos;
-+      long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
-+      unsigned char   ftop, changed, lookahead, no_update, rm, alimit;
-+      struct info     *info;
-+      unsigned long   entry_eip;
-+};
-+
-+union i387_union {
-+      struct i387_fsave_struct        fsave;
-+      struct i387_fxsave_struct       fxsave;
-+      struct i387_soft_struct soft;
-+};
-+
-+typedef struct {
-+      unsigned long seg;
-+} mm_segment_t;
-+
-+struct thread_struct;
-+
-+#ifndef CONFIG_X86_NO_TSS
-+struct tss_struct {
-+      unsigned short  back_link,__blh;
-+      unsigned long   esp0;
-+      unsigned short  ss0,__ss0h;
-+      unsigned long   esp1;
-+      unsigned short  ss1,__ss1h;     /* ss1 is used to cache MSR_IA32_SYSENTER_CS */
-+      unsigned long   esp2;
-+      unsigned short  ss2,__ss2h;
-+      unsigned long   __cr3;
-+      unsigned long   eip;
-+      unsigned long   eflags;
-+      unsigned long   eax,ecx,edx,ebx;
-+      unsigned long   esp;
-+      unsigned long   ebp;
-+      unsigned long   esi;
-+      unsigned long   edi;
-+      unsigned short  es, __esh;
-+      unsigned short  cs, __csh;
-+      unsigned short  ss, __ssh;
-+      unsigned short  ds, __dsh;
-+      unsigned short  fs, __fsh;
-+      unsigned short  gs, __gsh;
-+      unsigned short  ldt, __ldth;
-+      unsigned short  trace, io_bitmap_base;
-+      /*
-+       * The extra 1 is there because the CPU will access an
-+       * additional byte beyond the end of the IO permission
-+       * bitmap. The extra byte must be all 1 bits, and must
-+       * be within the limit.
-+       */
-+      unsigned long   io_bitmap[IO_BITMAP_LONGS + 1];
-+      /*
-+       * Cache the current maximum and the last task that used the bitmap:
-+       */
-+      unsigned long io_bitmap_max;
-+      struct thread_struct *io_bitmap_owner;
-+      /*
-+       * pads the TSS to be cacheline-aligned (size is 0x100)
-+       */
-+      unsigned long __cacheline_filler[35];
-+      /*
-+       * .. and then another 0x100 bytes for emergency kernel stack
-+       */
-+      unsigned long stack[64];
-+} __attribute__((packed));
-+#endif
-+
-+#define ARCH_MIN_TASKALIGN    16
-+
-+struct thread_struct {
-+/* cached TLS descriptors. */
-+      struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
-+      unsigned long   esp0;
-+      unsigned long   sysenter_cs;
-+      unsigned long   eip;
-+      unsigned long   esp;
-+      unsigned long   fs;
-+      unsigned long   gs;
-+/* Hardware debugging registers */
-+      unsigned long   debugreg[8];  /* %%db0-7 debug registers */
-+/* fault info */
-+      unsigned long   cr2, trap_no, error_code;
-+/* floating point info */
-+      union i387_union        i387;
-+/* virtual 86 mode info */
-+      struct vm86_struct __user * vm86_info;
-+      unsigned long           screen_bitmap;
-+      unsigned long           v86flags, v86mask, saved_esp0;
-+      unsigned int            saved_fs, saved_gs;
-+/* IO permissions */
-+      unsigned long   *io_bitmap_ptr;
-+      unsigned long   iopl;
-+/* max allowed port in the bitmap, in bytes: */
-+      unsigned long   io_bitmap_max;
-+};
-+
-+#define INIT_THREAD  {                                                        \
-+      .vm86_info = NULL,                                              \
-+      .sysenter_cs = __KERNEL_CS,                                     \
-+      .io_bitmap_ptr = NULL,                                          \
-+}
-+
-+#ifndef CONFIG_X86_NO_TSS
-+/*
-+ * Note that the .io_bitmap member must be extra-big. This is because
-+ * the CPU will access an additional byte beyond the end of the IO
-+ * permission bitmap. The extra byte must be all 1 bits, and must
-+ * be within the limit.
-+ */
-+#define INIT_TSS  {                                                   \
-+      .esp0           = sizeof(init_stack) + (long)&init_stack,       \
-+      .ss0            = __KERNEL_DS,                                  \
-+      .ss1            = __KERNEL_CS,                                  \
-+      .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,                     \
-+      .io_bitmap      = { [ 0 ... IO_BITMAP_LONGS] = ~0 },            \
-+}
-+
-+static inline void __load_esp0(struct tss_struct *tss, struct thread_struct *thread)
-+{
-+      tss->esp0 = thread->esp0;
-+      /* This can only happen when SEP is enabled, no need to test "SEP"arately */
-+      if (unlikely(tss->ss1 != thread->sysenter_cs)) {
-+              tss->ss1 = thread->sysenter_cs;
-+              wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
-+      }
-+}
-+#define load_esp0(tss, thread) \
-+      __load_esp0(tss, thread)
-+#else
-+#define load_esp0(tss, thread) \
-+      HYPERVISOR_stack_switch(__KERNEL_DS, (thread)->esp0)
-+#endif
-+
-+#define start_thread(regs, new_eip, new_esp) do {             \
-+      __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0));       \
-+      set_fs(USER_DS);                                        \
-+      regs->xds = __USER_DS;                                  \
-+      regs->xes = __USER_DS;                                  \
-+      regs->xss = __USER_DS;                                  \
-+      regs->xcs = __USER_CS;                                  \
-+      regs->eip = new_eip;                                    \
-+      regs->esp = new_esp;                                    \
-+} while (0)
-+
-+/*
-+ * These special macros can be used to get or set a debugging register
-+ */
-+#define get_debugreg(var, register)                           \
-+              (var) = HYPERVISOR_get_debugreg((register))
-+#define set_debugreg(value, register)                 \
-+              HYPERVISOR_set_debugreg((register), (value))
-+
-+/*
-+ * Set IOPL bits in EFLAGS from given mask
-+ */
-+static inline void set_iopl_mask(unsigned mask)
-+{
-+      struct physdev_set_iopl set_iopl;
-+
-+      /* Force the change at ring 0. */
-+      set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
-+      HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
-+}
-+
-+/* Forward declaration, a strange C thing */
-+struct task_struct;
-+struct mm_struct;
-+
-+/* Free all resources held by a thread. */
-+extern void release_thread(struct task_struct *);
-+
-+/* Prepare to copy thread state - unlazy all lazy status */
-+extern void prepare_to_copy(struct task_struct *tsk);
-+
-+/*
-+ * create a kernel thread without removing it from tasklists
-+ */
-+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+
-+extern unsigned long thread_saved_pc(struct task_struct *tsk);
-+void show_trace(struct task_struct *task, unsigned long *stack);
-+
-+unsigned long get_wchan(struct task_struct *p);
-+
-+#define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
-+#define KSTK_TOP(info)                                                 \
-+({                                                                     \
-+       unsigned long *__ptr = (unsigned long *)(info);                 \
-+       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
-+})
-+
-+/*
-+ * The below -8 is to reserve 8 bytes on top of the ring0 stack.
-+ * This is necessary to guarantee that the entire "struct pt_regs"
-+ * is accessable even if the CPU haven't stored the SS/ESP registers
-+ * on the stack (interrupt gate does not save these registers
-+ * when switching to the same priv ring).
-+ * Therefore beware: accessing the xss/esp fields of the
-+ * "struct pt_regs" is possible, but they may contain the
-+ * completely wrong values.
-+ */
-+#define task_pt_regs(task)                                             \
-+({                                                                     \
-+       struct pt_regs *__regs__;                                       \
-+       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
-+       __regs__ - 1;                                                   \
-+})
-+
-+#define KSTK_EIP(task) (task_pt_regs(task)->eip)
-+#define KSTK_ESP(task) (task_pt_regs(task)->esp)
-+
-+
-+struct microcode_header {
-+      unsigned int hdrver;
-+      unsigned int rev;
-+      unsigned int date;
-+      unsigned int sig;
-+      unsigned int cksum;
-+      unsigned int ldrver;
-+      unsigned int pf;
-+      unsigned int datasize;
-+      unsigned int totalsize;
-+      unsigned int reserved[3];
-+};
-+
-+struct microcode {
-+      struct microcode_header hdr;
-+      unsigned int bits[0];
-+};
-+
-+typedef struct microcode microcode_t;
-+typedef struct microcode_header microcode_header_t;
-+
-+/* microcode format is extended from prescott processors */
-+struct extended_signature {
-+      unsigned int sig;
-+      unsigned int pf;
-+      unsigned int cksum;
-+};
-+
-+struct extended_sigtable {
-+      unsigned int count;
-+      unsigned int cksum;
-+      unsigned int reserved[3];
-+      struct extended_signature sigs[0];
-+};
-+/* '6' because it used to be for P6 only (but now covers Pentium 4 as well) */
-+#define MICROCODE_IOCFREE     _IO('6',0)
-+
-+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-+static inline void rep_nop(void)
-+{
-+      __asm__ __volatile__("rep;nop": : :"memory");
-+}
-+
-+#define cpu_relax()   rep_nop()
-+
-+/* generic versions from gas */
-+#define GENERIC_NOP1  ".byte 0x90\n"
-+#define GENERIC_NOP2          ".byte 0x89,0xf6\n"
-+#define GENERIC_NOP3        ".byte 0x8d,0x76,0x00\n"
-+#define GENERIC_NOP4        ".byte 0x8d,0x74,0x26,0x00\n"
-+#define GENERIC_NOP5        GENERIC_NOP1 GENERIC_NOP4
-+#define GENERIC_NOP6  ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
-+#define GENERIC_NOP7  ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
-+#define GENERIC_NOP8  GENERIC_NOP1 GENERIC_NOP7
-+
-+/* Opteron nops */
-+#define K8_NOP1 GENERIC_NOP1
-+#define K8_NOP2       ".byte 0x66,0x90\n" 
-+#define K8_NOP3       ".byte 0x66,0x66,0x90\n" 
-+#define K8_NOP4       ".byte 0x66,0x66,0x66,0x90\n" 
-+#define K8_NOP5       K8_NOP3 K8_NOP2 
-+#define K8_NOP6       K8_NOP3 K8_NOP3
-+#define K8_NOP7       K8_NOP4 K8_NOP3
-+#define K8_NOP8       K8_NOP4 K8_NOP4
-+
-+/* K7 nops */
-+/* uses eax dependencies (arbitary choice) */
-+#define K7_NOP1  GENERIC_NOP1
-+#define K7_NOP2       ".byte 0x8b,0xc0\n" 
-+#define K7_NOP3       ".byte 0x8d,0x04,0x20\n"
-+#define K7_NOP4       ".byte 0x8d,0x44,0x20,0x00\n"
-+#define K7_NOP5       K7_NOP4 ASM_NOP1
-+#define K7_NOP6       ".byte 0x8d,0x80,0,0,0,0\n"
-+#define K7_NOP7        ".byte 0x8D,0x04,0x05,0,0,0,0\n"
-+#define K7_NOP8        K7_NOP7 ASM_NOP1
-+
-+#ifdef CONFIG_MK8
-+#define ASM_NOP1 K8_NOP1
-+#define ASM_NOP2 K8_NOP2
-+#define ASM_NOP3 K8_NOP3
-+#define ASM_NOP4 K8_NOP4
-+#define ASM_NOP5 K8_NOP5
-+#define ASM_NOP6 K8_NOP6
-+#define ASM_NOP7 K8_NOP7
-+#define ASM_NOP8 K8_NOP8
-+#elif defined(CONFIG_MK7)
-+#define ASM_NOP1 K7_NOP1
-+#define ASM_NOP2 K7_NOP2
-+#define ASM_NOP3 K7_NOP3
-+#define ASM_NOP4 K7_NOP4
-+#define ASM_NOP5 K7_NOP5
-+#define ASM_NOP6 K7_NOP6
-+#define ASM_NOP7 K7_NOP7
-+#define ASM_NOP8 K7_NOP8
-+#else
-+#define ASM_NOP1 GENERIC_NOP1
-+#define ASM_NOP2 GENERIC_NOP2
-+#define ASM_NOP3 GENERIC_NOP3
-+#define ASM_NOP4 GENERIC_NOP4
-+#define ASM_NOP5 GENERIC_NOP5
-+#define ASM_NOP6 GENERIC_NOP6
-+#define ASM_NOP7 GENERIC_NOP7
-+#define ASM_NOP8 GENERIC_NOP8
-+#endif
-+
-+#define ASM_NOP_MAX 8
-+
-+/* Prefetch instructions for Pentium III and AMD Athlon */
-+/* It's not worth to care about 3dnow! prefetches for the K6
-+   because they are microcoded there and very slow.
-+   However we don't do prefetches for pre XP Athlons currently
-+   That should be fixed. */
-+#define ARCH_HAS_PREFETCH
-+static inline void prefetch(const void *x)
-+{
-+      alternative_input(ASM_NOP4,
-+                        "prefetchnta (%1)",
-+                        X86_FEATURE_XMM,
-+                        "r" (x));
-+}
-+
-+#define ARCH_HAS_PREFETCH
-+#define ARCH_HAS_PREFETCHW
-+#define ARCH_HAS_SPINLOCK_PREFETCH
-+
-+/* 3dnow! prefetch to get an exclusive cache line. Useful for 
-+   spinlocks to avoid one state transition in the cache coherency protocol. */
-+static inline void prefetchw(const void *x)
-+{
-+      alternative_input(ASM_NOP4,
-+                        "prefetchw (%1)",
-+                        X86_FEATURE_3DNOW,
-+                        "r" (x));
-+}
-+#define spin_lock_prefetch(x) prefetchw(x)
-+
-+extern void select_idle_routine(const struct cpuinfo_x86 *c);
-+
-+#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
-+
-+extern unsigned long boot_option_idle_override;
-+extern void enable_sep_cpu(void);
-+extern int sysenter_setup(void);
-+
-+#ifdef CONFIG_MTRR
-+extern void mtrr_ap_init(void);
-+extern void mtrr_bp_init(void);
-+#else
-+#define mtrr_ap_init() do {} while (0)
-+#define mtrr_bp_init() do {} while (0)
-+#endif
-+
-+#ifdef CONFIG_X86_MCE
-+extern void mcheck_init(struct cpuinfo_x86 *c);
-+#else
-+#define mcheck_init(c) do {} while(0)
-+#endif
-+
-+#endif /* __ASM_I386_PROCESSOR_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/ptrace.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/ptrace.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/ptrace.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/ptrace.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,90 @@
-+#ifndef _I386_PTRACE_H
-+#define _I386_PTRACE_H
-+
-+#define EBX 0
-+#define ECX 1
-+#define EDX 2
-+#define ESI 3
-+#define EDI 4
-+#define EBP 5
-+#define EAX 6
-+#define DS 7
-+#define ES 8
-+#define FS 9
-+#define GS 10
-+#define ORIG_EAX 11
-+#define EIP 12
-+#define CS  13
-+#define EFL 14
-+#define UESP 15
-+#define SS   16
-+#define FRAME_SIZE 17
-+
-+/* this struct defines the way the registers are stored on the 
-+   stack during a system call. */
-+
-+struct pt_regs {
-+      long ebx;
-+      long ecx;
-+      long edx;
-+      long esi;
-+      long edi;
-+      long ebp;
-+      long eax;
-+      int  xds;
-+      int  xes;
-+      long orig_eax;
-+      long eip;
-+      int  xcs;
-+      long eflags;
-+      long esp;
-+      int  xss;
-+};
-+
-+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-+#define PTRACE_GETREGS            12
-+#define PTRACE_SETREGS            13
-+#define PTRACE_GETFPREGS          14
-+#define PTRACE_SETFPREGS          15
-+#define PTRACE_GETFPXREGS         18
-+#define PTRACE_SETFPXREGS         19
-+
-+#define PTRACE_OLDSETOPTIONS         21
-+
-+#define PTRACE_GET_THREAD_AREA    25
-+#define PTRACE_SET_THREAD_AREA    26
-+
-+#define PTRACE_SYSEMU           31
-+#define PTRACE_SYSEMU_SINGLESTEP  32
-+
-+#ifdef __KERNEL__
-+
-+#include <asm/vm86.h>
-+
-+struct task_struct;
-+extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
-+
-+/*
-+ * user_mode_vm(regs) determines whether a register set came from user mode.
-+ * This is true if V8086 mode was enabled OR if the register set was from
-+ * protected mode with RPL-3 CS value.  This tricky test checks that with
-+ * one comparison.  Many places in the kernel can bypass this full check
-+ * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
-+ */
-+static inline int user_mode(struct pt_regs *regs)
-+{
-+      return (regs->xcs & 2) != 0;
-+}
-+static inline int user_mode_vm(struct pt_regs *regs)
-+{
-+      return ((regs->xcs & 2) | (regs->eflags & VM_MASK)) != 0;
-+}
-+#define instruction_pointer(regs) ((regs)->eip)
-+#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
-+extern unsigned long profile_pc(struct pt_regs *regs);
-+#else
-+#define profile_pc(regs) instruction_pointer(regs)
-+#endif
-+#endif /* __KERNEL__ */
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/scatterlist.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/scatterlist.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/scatterlist.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/scatterlist.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,22 @@
-+#ifndef _I386_SCATTERLIST_H
-+#define _I386_SCATTERLIST_H
-+
-+struct scatterlist {
-+    struct page               *page;
-+    unsigned int      offset;
-+    unsigned int      length;
-+    dma_addr_t                dma_address;
-+    unsigned int      dma_length;
-+};
-+
-+/* These macros should be used after a pci_map_sg call has been done
-+ * to get bus addresses of each of the SG entries and their lengths.
-+ * You should only work with the number of sg entries pci_map_sg
-+ * returns.
-+ */
-+#define sg_dma_address(sg)    ((sg)->dma_address)
-+#define sg_dma_len(sg)                ((sg)->dma_length)
-+
-+#define ISA_DMA_THRESHOLD (0x00ffffff)
-+
-+#endif /* !(_I386_SCATTERLIST_H) */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/segment.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/segment.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/segment.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/segment.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,117 @@
-+#ifndef _ASM_SEGMENT_H
-+#define _ASM_SEGMENT_H
-+
-+/*
-+ * The layout of the per-CPU GDT under Linux:
-+ *
-+ *   0 - null
-+ *   1 - reserved
-+ *   2 - reserved
-+ *   3 - reserved
-+ *
-+ *   4 - unused                       <==== new cacheline
-+ *   5 - unused
-+ *
-+ *  ------- start of TLS (Thread-Local Storage) segments:
-+ *
-+ *   6 - TLS segment #1                       [ glibc's TLS segment ]
-+ *   7 - TLS segment #2                       [ Wine's %fs Win32 segment ]
-+ *   8 - TLS segment #3
-+ *   9 - reserved
-+ *  10 - reserved
-+ *  11 - reserved
-+ *
-+ *  ------- start of kernel segments:
-+ *
-+ *  12 - kernel code segment          <==== new cacheline
-+ *  13 - kernel data segment
-+ *  14 - default user CS
-+ *  15 - default user DS
-+ *  16 - TSS
-+ *  17 - LDT
-+ *  18 - PNPBIOS support (16->32 gate)
-+ *  19 - PNPBIOS support
-+ *  20 - PNPBIOS support
-+ *  21 - PNPBIOS support
-+ *  22 - PNPBIOS support
-+ *  23 - APM BIOS support
-+ *  24 - APM BIOS support
-+ *  25 - APM BIOS support 
-+ *
-+ *  26 - ESPFIX small SS
-+ *  27 - unused
-+ *  28 - unused
-+ *  29 - unused
-+ *  30 - unused
-+ *  31 - TSS for double fault handler
-+ */
-+#define GDT_ENTRY_TLS_ENTRIES 3
-+#define GDT_ENTRY_TLS_MIN     6
-+#define GDT_ENTRY_TLS_MAX     (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
-+
-+#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8)
-+
-+#define GDT_ENTRY_DEFAULT_USER_CS     14
-+#define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS * 8 + 3)
-+
-+#define GDT_ENTRY_DEFAULT_USER_DS     15
-+#define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS * 8 + 3)
-+
-+#define GDT_ENTRY_KERNEL_BASE 12
-+
-+#define GDT_ENTRY_KERNEL_CS           (GDT_ENTRY_KERNEL_BASE + 0)
-+#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS * 8)
-+#define GET_KERNEL_CS() (__KERNEL_CS | (xen_feature(XENFEAT_supervisor_mode_kernel)?0:1) )
-+
-+#define GDT_ENTRY_KERNEL_DS           (GDT_ENTRY_KERNEL_BASE + 1)
-+#define __KERNEL_DS (GDT_ENTRY_KERNEL_DS * 8)
-+#define GET_KERNEL_DS() (__KERNEL_DS | (xen_feature(XENFEAT_supervisor_mode_kernel)?0:1) )
-+
-+#define GDT_ENTRY_TSS                 (GDT_ENTRY_KERNEL_BASE + 4)
-+#define GDT_ENTRY_LDT                 (GDT_ENTRY_KERNEL_BASE + 5)
-+
-+#define GDT_ENTRY_PNPBIOS_BASE                (GDT_ENTRY_KERNEL_BASE + 6)
-+#define GDT_ENTRY_APMBIOS_BASE                (GDT_ENTRY_KERNEL_BASE + 11)
-+
-+#define GDT_ENTRY_ESPFIX_SS           (GDT_ENTRY_KERNEL_BASE + 14)
-+#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
-+
-+#define GDT_ENTRY_DOUBLEFAULT_TSS     31
-+
-+/*
-+ * The GDT has 32 entries
-+ */
-+#define GDT_ENTRIES 32
-+
-+#define GDT_SIZE (GDT_ENTRIES * 8)
-+
-+/* Simple and small GDT entries for booting only */
-+
-+#define GDT_ENTRY_BOOT_CS             2
-+#define __BOOT_CS     (GDT_ENTRY_BOOT_CS * 8)
-+
-+#define GDT_ENTRY_BOOT_DS             (GDT_ENTRY_BOOT_CS + 1)
-+#define __BOOT_DS     (GDT_ENTRY_BOOT_DS * 8)
-+
-+/* The PnP BIOS entries in the GDT */
-+#define GDT_ENTRY_PNPBIOS_CS32                (GDT_ENTRY_PNPBIOS_BASE + 0)
-+#define GDT_ENTRY_PNPBIOS_CS16                (GDT_ENTRY_PNPBIOS_BASE + 1)
-+#define GDT_ENTRY_PNPBIOS_DS          (GDT_ENTRY_PNPBIOS_BASE + 2)
-+#define GDT_ENTRY_PNPBIOS_TS1         (GDT_ENTRY_PNPBIOS_BASE + 3)
-+#define GDT_ENTRY_PNPBIOS_TS2         (GDT_ENTRY_PNPBIOS_BASE + 4)
-+
-+/* The PnP BIOS selectors */
-+#define PNP_CS32   (GDT_ENTRY_PNPBIOS_CS32 * 8)       /* segment for calling fn */
-+#define PNP_CS16   (GDT_ENTRY_PNPBIOS_CS16 * 8)       /* code segment for BIOS */
-+#define PNP_DS     (GDT_ENTRY_PNPBIOS_DS * 8) /* data segment for BIOS */
-+#define PNP_TS1    (GDT_ENTRY_PNPBIOS_TS1 * 8)        /* transfer data segment */
-+#define PNP_TS2    (GDT_ENTRY_PNPBIOS_TS2 * 8)        /* another data segment */
-+
-+/*
-+ * The interrupt descriptor table has room for 256 idt's,
-+ * the global descriptor table is dependent on the number
-+ * of tasks we can have..
-+ */
-+#define IDT_ENTRIES 256
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/setup.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/setup.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/setup.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/setup.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,66 @@
-+/*
-+ *    Just a place holder. We don't want to have to test x86 before
-+ *    we include stuff
-+ */
-+
-+#ifndef _i386_SETUP_H
-+#define _i386_SETUP_H
-+
-+#define PFN_UP(x)     (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-+#define PFN_DOWN(x)   ((x) >> PAGE_SHIFT)
-+#define PFN_PHYS(x)   ((unsigned long long)(x) << PAGE_SHIFT)
-+
-+/*
-+ * Reserved space for vmalloc and iomap - defined in asm/page.h
-+ */
-+#define MAXMEM_PFN    PFN_DOWN(MAXMEM)
-+#define MAX_NONPAE_PFN        (1 << 20)
-+
-+#define PARAM_SIZE 4096
-+#define COMMAND_LINE_SIZE 256
-+
-+#define OLD_CL_MAGIC_ADDR     0x90020
-+#define OLD_CL_MAGIC          0xA33F
-+#define OLD_CL_BASE_ADDR      0x90000
-+#define OLD_CL_OFFSET         0x90022
-+#define NEW_CL_POINTER                0x228   /* Relative to real mode data */
-+
-+#ifndef __ASSEMBLY__
-+/*
-+ * This is set up by the setup-routine at boot-time
-+ */
-+extern unsigned char boot_params[PARAM_SIZE];
-+
-+#define PARAM (boot_params)
-+#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
-+#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
-+#define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
-+#define E820_MAP_NR (*(char*) (PARAM+E820NR))
-+#define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
-+#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
-+#define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
-+#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
-+#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
-+#define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
-+#define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
-+#define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
-+#define EFI_MEMMAP ((void *) *((unsigned long *)(PARAM+0x1d0)))
-+#define EFI_MEMMAP_SIZE (*((unsigned long *) (PARAM+0x1d4)))
-+#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
-+#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
-+#define VIDEO_MODE (*(unsigned short *) (PARAM+0x1FA))
-+#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
-+#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
-+#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
-+#define KERNEL_START (*(unsigned long *) (PARAM+0x214))
-+#define INITRD_START (__pa(xen_start_info->mod_start))
-+#define INITRD_SIZE (xen_start_info->mod_len)
-+#define EDID_INFO   (*(struct edid_info *) (PARAM+0x440))
-+#define EDD_NR     (*(unsigned char *) (PARAM+EDDNR))
-+#define EDD_MBR_SIG_NR (*(unsigned char *) (PARAM+EDD_MBR_SIG_NR_BUF))
-+#define EDD_MBR_SIGNATURE ((unsigned int *) (PARAM+EDD_MBR_SIG_BUF))
-+#define EDD_BUF     ((struct edd_info *) (PARAM+EDDBUF))
-+
-+#endif /* __ASSEMBLY__ */
-+
-+#endif /* _i386_SETUP_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/smp.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/smp.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/smp.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/smp.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,103 @@
-+#ifndef __ASM_SMP_H
-+#define __ASM_SMP_H
-+
-+/*
-+ * We need the APIC definitions automatically as part of 'smp.h'
-+ */
-+#ifndef __ASSEMBLY__
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/threads.h>
-+#include <linux/cpumask.h>
-+#endif
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+#ifndef __ASSEMBLY__
-+#include <asm/fixmap.h>
-+#include <asm/bitops.h>
-+#include <asm/mpspec.h>
-+#ifdef CONFIG_X86_IO_APIC
-+#include <asm/io_apic.h>
-+#endif
-+#include <asm/apic.h>
-+#endif
-+#endif
-+
-+#define BAD_APICID 0xFFu
-+#ifdef CONFIG_SMP
-+#ifndef __ASSEMBLY__
-+
-+/*
-+ * Private routines/data
-+ */
-+ 
-+extern void smp_alloc_memory(void);
-+extern int pic_mode;
-+extern int smp_num_siblings;
-+extern cpumask_t cpu_sibling_map[];
-+extern cpumask_t cpu_core_map[];
-+
-+extern void (*mtrr_hook) (void);
-+extern void zap_low_mappings (void);
-+extern void lock_ipi_call_lock(void);
-+extern void unlock_ipi_call_lock(void);
-+
-+#define MAX_APICID 256
-+extern u8 x86_cpu_to_apicid[];
-+
-+#define cpu_physical_id(cpu)  x86_cpu_to_apicid[cpu]
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+extern void cpu_exit_clear(void);
-+extern void cpu_uninit(void);
-+#endif
-+
-+/*
-+ * This function is needed by all SMP systems. It must _always_ be valid
-+ * from the initial startup. We map APIC_BASE very early in page_setup(),
-+ * so this is correct in the x86 case.
-+ */
-+#define raw_smp_processor_id() (current_thread_info()->cpu)
-+
-+extern cpumask_t cpu_possible_map;
-+#define cpu_callin_map cpu_possible_map
-+
-+/* We don't mark CPUs online until __cpu_up(), so we need another measure */
-+static inline int num_booting_cpus(void)
-+{
-+      return cpus_weight(cpu_possible_map);
-+}
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+
-+#ifdef APIC_DEFINITION
-+extern int hard_smp_processor_id(void);
-+#else
-+#include <mach_apicdef.h>
-+static inline int hard_smp_processor_id(void)
-+{
-+      /* we don't want to mark this access volatile - bad code generation */
-+      return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID));
-+}
-+#endif
-+
-+static __inline int logical_smp_processor_id(void)
-+{
-+      /* we don't want to mark this access volatile - bad code generation */
-+      return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR));
-+}
-+
-+#endif
-+
-+extern int __cpu_disable(void);
-+extern void __cpu_die(unsigned int cpu);
-+#endif /* !__ASSEMBLY__ */
-+
-+#else /* CONFIG_SMP */
-+
-+#define cpu_physical_id(cpu)          boot_cpu_physical_apicid
-+
-+#define NO_PROC_ID            0xFF            /* No processor magic marker */
-+
-+#endif
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/spinlock.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/spinlock.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/spinlock.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/spinlock.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,217 @@
-+#ifndef __ASM_SPINLOCK_H
-+#define __ASM_SPINLOCK_H
-+
-+#include <asm/atomic.h>
-+#include <asm/rwlock.h>
-+#include <asm/page.h>
-+#include <linux/config.h>
-+#include <linux/compiler.h>
-+#include <asm/smp_alt.h>
-+
-+/*
-+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
-+ *
-+ * Simple spin lock operations.  There are two variants, one clears IRQ's
-+ * on the local processor, one does not.
-+ *
-+ * We make no fairness assumptions. They have a cost.
-+ *
-+ * (the type definitions are in asm/spinlock_types.h)
-+ */
-+
-+#define __raw_spin_is_locked(x) \
-+              (*(volatile signed char *)(&(x)->slock) <= 0)
-+
-+#define __raw_spin_lock_string \
-+      "\n1:\n" \
-+      LOCK \
-+      "decb %0\n\t" \
-+      "jns 3f\n" \
-+      "2:\t" \
-+      "rep;nop\n\t" \
-+      "cmpb $0,%0\n\t" \
-+      "jle 2b\n\t" \
-+      "jmp 1b\n" \
-+      "3:\n\t"
-+
-+#define __raw_spin_lock_string_flags \
-+      "\n1:\n" \
-+      LOCK \
-+      "decb %0\n\t" \
-+      "jns 4f\n\t" \
-+      "2:\t" \
-+      "testl $0x200, %1\n\t" \
-+      "jz 3f\n\t" \
-+      "#sti\n\t" \
-+      "3:\t" \
-+      "rep;nop\n\t" \
-+      "cmpb $0, %0\n\t" \
-+      "jle 3b\n\t" \
-+      "#cli\n\t" \
-+      "jmp 1b\n" \
-+      "4:\n\t"
-+
-+static inline void __raw_spin_lock(raw_spinlock_t *lock)
-+{
-+      __asm__ __volatile__(
-+              __raw_spin_lock_string
-+              :"=m" (lock->slock) : : "memory");
-+}
-+
-+static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
-+{
-+      __asm__ __volatile__(
-+              __raw_spin_lock_string_flags
-+              :"=m" (lock->slock) : "r" (flags) : "memory");
-+}
-+
-+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
-+{
-+      char oldval;
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+      __asm__ __volatile__(
-+              "1:movb %1,%b0\n"
-+              "movb $0,%1\n"
-+              "2:"
-+              ".section __smp_alternatives,\"a\"\n"
-+              ".long 1b\n"
-+              ".long 3f\n"
-+              ".previous\n"
-+              ".section __smp_replacements,\"a\"\n"
-+              "3: .byte 2b - 1b\n"
-+              ".byte 5f-4f\n"
-+              ".byte 0\n"
-+              ".byte 6f-5f\n"
-+              ".byte -1\n"
-+              "4: xchgb %b0,%1\n"
-+              "5: movb %1,%b0\n"
-+              "movb $0,%1\n"
-+              "6:\n"
-+              ".previous\n"
-+              :"=q" (oldval), "=m" (lock->slock)
-+              :"0" (0) : "memory");
-+#else
-+      __asm__ __volatile__(
-+              "xchgb %b0,%1"
-+              :"=q" (oldval), "=m" (lock->slock)
-+              :"0" (0) : "memory");
-+#endif
-+      return oldval > 0;
-+}
-+
-+/*
-+ * __raw_spin_unlock based on writing $1 to the low byte.
-+ * This method works. Despite all the confusion.
-+ * (except on PPro SMP or if we are using OOSTORE, so we use xchgb there)
-+ * (PPro errata 66, 92)
-+ */
-+
-+#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)
-+
-+#define __raw_spin_unlock_string \
-+      "movb $1,%0" \
-+              :"=m" (lock->slock) : : "memory"
-+
-+
-+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
-+{
-+      __asm__ __volatile__(
-+              __raw_spin_unlock_string
-+      );
-+}
-+
-+#else
-+
-+#define __raw_spin_unlock_string \
-+      "xchgb %b0, %1" \
-+              :"=q" (oldval), "=m" (lock->slock) \
-+              :"0" (oldval) : "memory"
-+
-+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
-+{
-+      char oldval = 1;
-+
-+      __asm__ __volatile__(
-+              __raw_spin_unlock_string
-+      );
-+}
-+
-+#endif
-+
-+#define __raw_spin_unlock_wait(lock) \
-+      do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
-+
-+/*
-+ * Read-write spinlocks, allowing multiple readers
-+ * but only one writer.
-+ *
-+ * NOTE! it is quite common to have readers in interrupts
-+ * but no interrupt writers. For those circumstances we
-+ * can "mix" irq-safe locks - any writer needs to get a
-+ * irq-safe write-lock, but readers can get non-irqsafe
-+ * read-locks.
-+ *
-+ * On x86, we implement read-write locks as a 32-bit counter
-+ * with the high bit (sign) being the "contended" bit.
-+ *
-+ * The inline assembly is non-obvious. Think about it.
-+ *
-+ * Changed to use the same technique as rw semaphores.  See
-+ * semaphore.h for details.  -ben
-+ *
-+ * the helpers are in arch/i386/kernel/semaphore.c
-+ */
-+
-+/**
-+ * read_can_lock - would read_trylock() succeed?
-+ * @lock: the rwlock in question.
-+ */
-+#define __raw_read_can_lock(x)                ((int)(x)->lock > 0)
-+
-+/**
-+ * write_can_lock - would write_trylock() succeed?
-+ * @lock: the rwlock in question.
-+ */
-+#define __raw_write_can_lock(x)               ((x)->lock == RW_LOCK_BIAS)
-+
-+static inline void __raw_read_lock(raw_rwlock_t *rw)
-+{
-+      __build_read_lock(rw, "__read_lock_failed");
-+}
-+
-+static inline void __raw_write_lock(raw_rwlock_t *rw)
-+{
-+      __build_write_lock(rw, "__write_lock_failed");
-+}
-+
-+static inline int __raw_read_trylock(raw_rwlock_t *lock)
-+{
-+      atomic_t *count = (atomic_t *)lock;
-+      atomic_dec(count);
-+      if (atomic_read(count) >= 0)
-+              return 1;
-+      atomic_inc(count);
-+      return 0;
-+}
-+
-+static inline int __raw_write_trylock(raw_rwlock_t *lock)
-+{
-+      atomic_t *count = (atomic_t *)lock;
-+      if (atomic_sub_and_test(RW_LOCK_BIAS, count))
-+              return 1;
-+      atomic_add(RW_LOCK_BIAS, count);
-+      return 0;
-+}
-+
-+static inline void __raw_read_unlock(raw_rwlock_t *rw)
-+{
-+      asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
-+}
-+
-+static inline void __raw_write_unlock(raw_rwlock_t *rw)
-+{
-+      asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
-+                               : "=m" (rw->lock) : : "memory");
-+}
-+
-+#endif /* __ASM_SPINLOCK_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/swiotlb.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/swiotlb.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/swiotlb.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/swiotlb.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,45 @@
-+#ifndef _ASM_SWIOTLB_H
-+#define _ASM_SWIOTLB_H 1
-+
-+#include <linux/config.h>
-+
-+/* SWIOTLB interface */
-+
-+extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, size_t size,
-+                                    int dir);
-+extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
-+                                size_t size, int dir);
-+extern void swiotlb_sync_single_for_cpu(struct device *hwdev,
-+                                       dma_addr_t dev_addr,
-+                                       size_t size, int dir);
-+extern void swiotlb_sync_single_for_device(struct device *hwdev,
-+                                          dma_addr_t dev_addr,
-+                                          size_t size, int dir);
-+extern void swiotlb_sync_sg_for_cpu(struct device *hwdev,
-+                                   struct scatterlist *sg, int nelems,
-+                                   int dir);
-+extern void swiotlb_sync_sg_for_device(struct device *hwdev,
-+                                      struct scatterlist *sg, int nelems,
-+                                      int dir);
-+extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg,
-+                    int nents, int direction);
-+extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg,
-+                       int nents, int direction);
-+extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr);
-+extern dma_addr_t swiotlb_map_page(struct device *hwdev, struct page *page,
-+                                   unsigned long offset, size_t size,
-+                                   enum dma_data_direction direction);
-+extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dma_address,
-+                               size_t size, enum dma_data_direction direction);
-+extern int swiotlb_dma_supported(struct device *hwdev, u64 mask);
-+extern void swiotlb_init(void);
-+
-+extern unsigned int dma_bits;
-+
-+#ifdef CONFIG_SWIOTLB
-+extern int swiotlb;
-+#else
-+#define swiotlb 0
-+#endif
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/synch_bitops.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/synch_bitops.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/synch_bitops.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/synch_bitops.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,147 @@
-+#ifndef __XEN_SYNCH_BITOPS_H__
-+#define __XEN_SYNCH_BITOPS_H__
-+
-+/*
-+ * Copyright 1992, Linus Torvalds.
-+ * Heavily modified to provide guaranteed strong synchronisation
-+ * when communicating with Xen or other guest OSes running on other CPUs.
-+ */
-+
-+#include <linux/config.h>
-+
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+#define ADDR (*(volatile long *) addr)
-+
-+static __inline__ void synch_set_bit(int nr, volatile void * addr)
-+{
-+    __asm__ __volatile__ ( 
-+        "lock btsl %1,%0"
-+        : "+m" (ADDR) : "Ir" (nr) : "memory" );
-+}
-+
-+static __inline__ void synch_clear_bit(int nr, volatile void * addr)
-+{
-+    __asm__ __volatile__ (
-+        "lock btrl %1,%0"
-+        : "+m" (ADDR) : "Ir" (nr) : "memory" );
-+}
-+
-+static __inline__ void synch_change_bit(int nr, volatile void * addr)
-+{
-+    __asm__ __volatile__ (
-+        "lock btcl %1,%0"
-+        : "+m" (ADDR) : "Ir" (nr) : "memory" );
-+}
-+
-+static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr)
-+{
-+    int oldbit;
-+    __asm__ __volatile__ (
-+        "lock btsl %2,%1\n\tsbbl %0,%0"
-+        : "=r" (oldbit), "+m" (ADDR) : "Ir" (nr) : "memory");
-+    return oldbit;
-+}
-+
-+static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
-+{
-+    int oldbit;
-+    __asm__ __volatile__ (
-+        "lock btrl %2,%1\n\tsbbl %0,%0"
-+        : "=r" (oldbit), "+m" (ADDR) : "Ir" (nr) : "memory");
-+    return oldbit;
-+}
-+
-+static __inline__ int synch_test_and_change_bit(int nr, volatile void * addr)
-+{
-+    int oldbit;
-+
-+    __asm__ __volatile__ (
-+        "lock btcl %2,%1\n\tsbbl %0,%0"
-+        : "=r" (oldbit), "+m" (ADDR) : "Ir" (nr) : "memory");
-+    return oldbit;
-+}
-+
-+struct __synch_xchg_dummy { unsigned long a[100]; };
-+#define __synch_xg(x) ((struct __synch_xchg_dummy *)(x))
-+
-+#define synch_cmpxchg(ptr, old, new) \
-+((__typeof__(*(ptr)))__synch_cmpxchg((ptr),\
-+                                     (unsigned long)(old), \
-+                                     (unsigned long)(new), \
-+                                     sizeof(*(ptr))))
-+
-+static inline unsigned long __synch_cmpxchg(volatile void *ptr,
-+                                          unsigned long old,
-+                                          unsigned long new, int size)
-+{
-+      unsigned long prev;
-+      switch (size) {
-+      case 1:
-+              __asm__ __volatile__("lock; cmpxchgb %b1,%2"
-+                                   : "=a"(prev)
-+                                   : "q"(new), "m"(*__synch_xg(ptr)),
-+                                     "0"(old)
-+                                   : "memory");
-+              return prev;
-+      case 2:
-+              __asm__ __volatile__("lock; cmpxchgw %w1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__synch_xg(ptr)),
-+                                     "0"(old)
-+                                   : "memory");
-+              return prev;
-+#ifdef CONFIG_X86_64
-+      case 4:
-+              __asm__ __volatile__("lock; cmpxchgl %k1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__synch_xg(ptr)),
-+                                     "0"(old)
-+                                   : "memory");
-+              return prev;
-+      case 8:
-+              __asm__ __volatile__("lock; cmpxchgq %1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__synch_xg(ptr)),
-+                                     "0"(old)
-+                                   : "memory");
-+              return prev;
-+#else
-+      case 4:
-+              __asm__ __volatile__("lock; cmpxchgl %1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__synch_xg(ptr)),
-+                                     "0"(old)
-+                                   : "memory");
-+              return prev;
-+#endif
-+      }
-+      return old;
-+}
-+
-+static __always_inline int synch_const_test_bit(int nr,
-+                                              const volatile void * addr)
-+{
-+    return ((1UL << (nr & 31)) & 
-+            (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
-+}
-+
-+static __inline__ int synch_var_test_bit(int nr, volatile void * addr)
-+{
-+    int oldbit;
-+    __asm__ __volatile__ (
-+        "btl %2,%1\n\tsbbl %0,%0"
-+        : "=r" (oldbit) : "m" (ADDR), "Ir" (nr) );
-+    return oldbit;
-+}
-+
-+#define synch_test_bit(nr,addr) \
-+(__builtin_constant_p(nr) ? \
-+ synch_const_test_bit((nr),(addr)) : \
-+ synch_var_test_bit((nr),(addr)))
-+
-+#define synch_cmpxchg_subword synch_cmpxchg
-+
-+#endif /* __XEN_SYNCH_BITOPS_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/system.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/system.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/system.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/system.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,681 @@
-+#ifndef __ASM_SYSTEM_H
-+#define __ASM_SYSTEM_H
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <asm/synch_bitops.h>
-+#include <asm/segment.h>
-+#include <asm/cpufeature.h>
-+#include <asm/hypervisor.h>
-+#include <asm/smp_alt.h>
-+
-+#ifdef __KERNEL__
-+
-+#ifdef CONFIG_SMP
-+#define __vcpu_id smp_processor_id()
-+#else
-+#define __vcpu_id 0
-+#endif
-+
-+struct task_struct;   /* one of the stranger aspects of C forward declarations.. */
-+extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
-+
-+#define switch_to(prev,next,last) do {                                        \
-+      unsigned long esi,edi;                                          \
-+      asm volatile("pushl %%ebp\n\t"                                  \
-+                   "movl %%esp,%0\n\t"        /* save ESP */          \
-+                   "movl %5,%%esp\n\t"        /* restore ESP */       \
-+                   "movl $1f,%1\n\t"          /* save EIP */          \
-+                   "pushl %6\n\t"             /* restore EIP */       \
-+                   "jmp __switch_to\n"                                \
-+                   "1:\t"                                             \
-+                   "popl %%ebp\n\t"                                   \
-+                   :"=m" (prev->thread.esp),"=m" (prev->thread.eip),  \
-+                    "=a" (last),"=S" (esi),"=D" (edi)                 \
-+                   :"m" (next->thread.esp),"m" (next->thread.eip),    \
-+                    "2" (prev), "d" (next));                          \
-+} while (0)
-+
-+#define _set_base(addr,base) do { unsigned long __pr; \
-+__asm__ __volatile__ ("movw %%dx,%1\n\t" \
-+      "rorl $16,%%edx\n\t" \
-+      "movb %%dl,%2\n\t" \
-+      "movb %%dh,%3" \
-+      :"=&d" (__pr) \
-+      :"m" (*((addr)+2)), \
-+       "m" (*((addr)+4)), \
-+       "m" (*((addr)+7)), \
-+         "0" (base) \
-+        ); } while(0)
-+
-+#define _set_limit(addr,limit) do { unsigned long __lr; \
-+__asm__ __volatile__ ("movw %%dx,%1\n\t" \
-+      "rorl $16,%%edx\n\t" \
-+      "movb %2,%%dh\n\t" \
-+      "andb $0xf0,%%dh\n\t" \
-+      "orb %%dh,%%dl\n\t" \
-+      "movb %%dl,%2" \
-+      :"=&d" (__lr) \
-+      :"m" (*(addr)), \
-+       "m" (*((addr)+6)), \
-+       "0" (limit) \
-+        ); } while(0)
-+
-+#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
-+#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1) )
-+
-+/*
-+ * Load a segment. Fall back on loading the zero
-+ * segment if something goes wrong..
-+ */
-+#define loadsegment(seg,value)                        \
-+      asm volatile("\n"                       \
-+              "1:\t"                          \
-+              "mov %0,%%" #seg "\n"           \
-+              "2:\n"                          \
-+              ".section .fixup,\"ax\"\n"      \
-+              "3:\t"                          \
-+              "pushl $0\n\t"                  \
-+              "popl %%" #seg "\n\t"           \
-+              "jmp 2b\n"                      \
-+              ".previous\n"                   \
-+              ".section __ex_table,\"a\"\n\t" \
-+              ".align 4\n\t"                  \
-+              ".long 1b,3b\n"                 \
-+              ".previous"                     \
-+              : :"rm" (value))
-+
-+/*
-+ * Save a segment register away
-+ */
-+#define savesegment(seg, value) \
-+      asm volatile("mov %%" #seg ",%0":"=rm" (value))
-+
-+/*
-+ * Clear and set 'TS' bit respectively
-+ */
-+#define clts() (HYPERVISOR_fpu_taskswitch(0))
-+#define read_cr0() ({ \
-+      unsigned int __dummy; \
-+      __asm__ __volatile__( \
-+              "movl %%cr0,%0\n\t" \
-+              :"=r" (__dummy)); \
-+      __dummy; \
-+})
-+#define write_cr0(x) \
-+      __asm__ __volatile__("movl %0,%%cr0": :"r" (x));
-+
-+#define read_cr2() \
-+      (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
-+#define write_cr2(x) \
-+      __asm__ __volatile__("movl %0,%%cr2": :"r" (x));
-+
-+#define read_cr3() ({ \
-+      unsigned int __dummy; \
-+      __asm__ ( \
-+              "movl %%cr3,%0\n\t" \
-+              :"=r" (__dummy)); \
-+      __dummy = xen_cr3_to_pfn(__dummy); \
-+      mfn_to_pfn(__dummy) << PAGE_SHIFT; \
-+})
-+#define write_cr3(x) ({                                               \
-+      unsigned int __dummy = pfn_to_mfn((x) >> PAGE_SHIFT);   \
-+      __dummy = xen_pfn_to_cr3(__dummy);                      \
-+      __asm__ __volatile__("movl %0,%%cr3": :"r" (__dummy));  \
-+})
-+
-+#define read_cr4() ({ \
-+      unsigned int __dummy; \
-+      __asm__( \
-+              "movl %%cr4,%0\n\t" \
-+              :"=r" (__dummy)); \
-+      __dummy; \
-+})
-+
-+#define read_cr4_safe() ({                          \
-+      unsigned int __dummy;                         \
-+      /* This could fault if %cr4 does not exist */ \
-+      __asm__("1: movl %%cr4, %0              \n"   \
-+              "2:                             \n"   \
-+              ".section __ex_table,\"a\"      \n"   \
-+              ".long 1b,2b                    \n"   \
-+              ".previous                      \n"   \
-+              : "=r" (__dummy): "0" (0));           \
-+      __dummy;                                      \
-+})
-+
-+#define write_cr4(x) \
-+      __asm__ __volatile__("movl %0,%%cr4": :"r" (x));
-+#define stts() (HYPERVISOR_fpu_taskswitch(1))
-+
-+#endif        /* __KERNEL__ */
-+
-+#define wbinvd() \
-+      __asm__ __volatile__ ("wbinvd": : :"memory");
-+
-+static inline unsigned long get_limit(unsigned long segment)
-+{
-+      unsigned long __limit;
-+      __asm__("lsll %1,%0"
-+              :"=r" (__limit):"r" (segment));
-+      return __limit+1;
-+}
-+
-+#define nop() __asm__ __volatile__ ("nop")
-+
-+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
-+
-+#define tas(ptr) (xchg((ptr),1))
-+
-+struct __xchg_dummy { unsigned long a[100]; };
-+#define __xg(x) ((struct __xchg_dummy *)(x))
-+
-+
-+#ifdef CONFIG_X86_CMPXCHG64
-+
-+/*
-+ * The semantics of XCHGCMP8B are a bit strange, this is why
-+ * there is a loop and the loading of %%eax and %%edx has to
-+ * be inside. This inlines well in most cases, the cached
-+ * cost is around ~38 cycles. (in the future we might want
-+ * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
-+ * might have an implicit FPU-save as a cost, so it's not
-+ * clear which path to go.)
-+ *
-+ * cmpxchg8b must be used with the lock prefix here to allow
-+ * the instruction to be executed atomically, see page 3-102
-+ * of the instruction set reference 24319102.pdf. We need
-+ * the reader side to see the coherent 64bit value.
-+ */
-+static inline void __set_64bit (unsigned long long * ptr,
-+              unsigned int low, unsigned int high)
-+{
-+      __asm__ __volatile__ (
-+              "\n1:\t"
-+              "movl (%0), %%eax\n\t"
-+              "movl 4(%0), %%edx\n\t"
-+              "lock cmpxchg8b (%0)\n\t"
-+              "jnz 1b"
-+              : /* no outputs */
-+              :       "D"(ptr),
-+                      "b"(low),
-+                      "c"(high)
-+              :       "ax","dx","memory");
-+}
-+
-+static inline void __set_64bit_constant (unsigned long long *ptr,
-+                                               unsigned long long value)
-+{
-+      __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
-+}
-+#define ll_low(x)     *(((unsigned int*)&(x))+0)
-+#define ll_high(x)    *(((unsigned int*)&(x))+1)
-+
-+static inline void __set_64bit_var (unsigned long long *ptr,
-+                       unsigned long long value)
-+{
-+      __set_64bit(ptr,ll_low(value), ll_high(value));
-+}
-+
-+#define set_64bit(ptr,value) \
-+(__builtin_constant_p(value) ? \
-+ __set_64bit_constant(ptr, value) : \
-+ __set_64bit_var(ptr, value) )
-+
-+#define _set_64bit(ptr,value) \
-+(__builtin_constant_p(value) ? \
-+ __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
-+ __set_64bit(ptr, ll_low(value), ll_high(value)) )
-+
-+#endif
-+
-+/*
-+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
-+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
-+ *      but generally the primitive is invalid, *ptr is output argument. --ANK
-+ */
-+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-+{
-+      switch (size) {
-+              case 1:
-+                      __asm__ __volatile__("xchgb %b0,%1"
-+                              :"=q" (x)
-+                              :"m" (*__xg(ptr)), "0" (x)
-+                              :"memory");
-+                      break;
-+              case 2:
-+                      __asm__ __volatile__("xchgw %w0,%1"
-+                              :"=r" (x)
-+                              :"m" (*__xg(ptr)), "0" (x)
-+                              :"memory");
-+                      break;
-+              case 4:
-+                      __asm__ __volatile__("xchgl %0,%1"
-+                              :"=r" (x)
-+                              :"m" (*__xg(ptr)), "0" (x)
-+                              :"memory");
-+                      break;
-+      }
-+      return x;
-+}
-+
-+/*
-+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
-+ * store NEW in MEM.  Return the initial value in MEM.  Success is
-+ * indicated by comparing RETURN with OLD.
-+ */
-+
-+#ifdef CONFIG_X86_CMPXCHG
-+#define __HAVE_ARCH_CMPXCHG 1
-+#define cmpxchg(ptr,o,n)\
-+      ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
-+                                      (unsigned long)(n),sizeof(*(ptr))))
-+#endif
-+
-+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
-+                                    unsigned long new, int size)
-+{
-+      unsigned long prev;
-+      switch (size) {
-+      case 1:
-+              __asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
-+                                   : "=a"(prev)
-+                                   : "q"(new), "m"(*__xg(ptr)), "0"(old)
-+                                   : "memory");
-+              return prev;
-+      case 2:
-+              __asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__xg(ptr)), "0"(old)
-+                                   : "memory");
-+              return prev;
-+      case 4:
-+              __asm__ __volatile__(LOCK "cmpxchgl %1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__xg(ptr)), "0"(old)
-+                                   : "memory");
-+              return prev;
-+      }
-+      return old;
-+}
-+
-+#ifndef CONFIG_X86_CMPXCHG
-+/*
-+ * Building a kernel capable running on 80386. It may be necessary to
-+ * simulate the cmpxchg on the 80386 CPU. For that purpose we define
-+ * a function for each of the sizes we support.
-+ */
-+
-+extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
-+extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
-+extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
-+
-+static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
-+                                    unsigned long new, int size)
-+{
-+      switch (size) {
-+      case 1:
-+              return cmpxchg_386_u8(ptr, old, new);
-+      case 2:
-+              return cmpxchg_386_u16(ptr, old, new);
-+      case 4:
-+              return cmpxchg_386_u32(ptr, old, new);
-+      }
-+      return old;
-+}
-+
-+#define cmpxchg(ptr,o,n)                                              \
-+({                                                                    \
-+      __typeof__(*(ptr)) __ret;                                       \
-+      if (likely(boot_cpu_data.x86 > 3))                              \
-+              __ret = __cmpxchg((ptr), (unsigned long)(o),            \
-+                                      (unsigned long)(n), sizeof(*(ptr))); \
-+      else                                                            \
-+              __ret = cmpxchg_386((ptr), (unsigned long)(o),          \
-+                                      (unsigned long)(n), sizeof(*(ptr))); \
-+      __ret;                                                          \
-+})
-+#endif
-+
-+#ifdef CONFIG_X86_CMPXCHG64
-+
-+static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
-+                                    unsigned long long new)
-+{
-+      unsigned long long prev;
-+      __asm__ __volatile__(LOCK "cmpxchg8b %3"
-+                           : "=A"(prev)
-+                           : "b"((unsigned long)new),
-+                             "c"((unsigned long)(new >> 32)),
-+                             "m"(*__xg(ptr)),
-+                             "0"(old)
-+                           : "memory");
-+      return prev;
-+}
-+
-+#define cmpxchg64(ptr,o,n)\
-+      ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
-+                                      (unsigned long long)(n)))
-+
-+#endif
-+    
-+#ifdef __KERNEL__
-+struct alt_instr { 
-+      __u8 *instr;            /* original instruction */
-+      __u8 *replacement;
-+      __u8  cpuid;            /* cpuid bit set for replacement */
-+      __u8  instrlen;         /* length of original instruction */
-+      __u8  replacementlen;   /* length of new instruction, <= instrlen */ 
-+      __u8  pad;
-+}; 
-+#endif
-+
-+/* 
-+ * Alternative instructions for different CPU types or capabilities.
-+ * 
-+ * This allows to use optimized instructions even on generic binary
-+ * kernels.
-+ * 
-+ * length of oldinstr must be longer or equal the length of newinstr
-+ * It can be padded with nops as needed.
-+ * 
-+ * For non barrier like inlines please define new variants
-+ * without volatile and memory clobber.
-+ */
-+#define alternative(oldinstr, newinstr, feature)      \
-+      asm volatile ("661:\n\t" oldinstr "\n662:\n"                 \
-+                    ".section .altinstructions,\"a\"\n"            \
-+                    "  .align 4\n"                                   \
-+                    "  .long 661b\n"            /* label */          \
-+                    "  .long 663f\n"            /* new instruction */         \
-+                    "  .byte %c0\n"             /* feature bit */    \
-+                    "  .byte 662b-661b\n"       /* sourcelen */      \
-+                    "  .byte 664f-663f\n"       /* replacementlen */ \
-+                    ".previous\n"                                             \
-+                    ".section .altinstr_replacement,\"ax\"\n"                 \
-+                    "663:\n\t" newinstr "\n664:\n"   /* replacement */    \
-+                    ".previous" :: "i" (feature) : "memory")  
-+
-+/*
-+ * Alternative inline assembly with input.
-+ * 
-+ * Pecularities:
-+ * No memory clobber here. 
-+ * Argument numbers start with 1.
-+ * Best is to use constraints that are fixed size (like (%1) ... "r")
-+ * If you use variable sized constraints like "m" or "g" in the 
-+ * replacement maake sure to pad to the worst case length.
-+ */
-+#define alternative_input(oldinstr, newinstr, feature, input...)              \
-+      asm volatile ("661:\n\t" oldinstr "\n662:\n"                            \
-+                    ".section .altinstructions,\"a\"\n"                       \
-+                    "  .align 4\n"                                            \
-+                    "  .long 661b\n"            /* label */                   \
-+                    "  .long 663f\n"            /* new instruction */         \
-+                    "  .byte %c0\n"             /* feature bit */             \
-+                    "  .byte 662b-661b\n"       /* sourcelen */               \
-+                    "  .byte 664f-663f\n"       /* replacementlen */          \
-+                    ".previous\n"                                             \
-+                    ".section .altinstr_replacement,\"ax\"\n"                 \
-+                    "663:\n\t" newinstr "\n664:\n"   /* replacement */        \
-+                    ".previous" :: "i" (feature), ##input)
-+
-+/*
-+ * Force strict CPU ordering.
-+ * And yes, this is required on UP too when we're talking
-+ * to devices.
-+ *
-+ * For now, "wmb()" doesn't actually do anything, as all
-+ * Intel CPU's follow what Intel calls a *Processor Order*,
-+ * in which all writes are seen in the program order even
-+ * outside the CPU.
-+ *
-+ * I expect future Intel CPU's to have a weaker ordering,
-+ * but I'd also expect them to finally get their act together
-+ * and add some real memory barriers if so.
-+ *
-+ * Some non intel clones support out of order store. wmb() ceases to be a
-+ * nop for these.
-+ */
-+ 
-+
-+/* 
-+ * Actually only lfence would be needed for mb() because all stores done 
-+ * by the kernel should be already ordered. But keep a full barrier for now. 
-+ */
-+
-+#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
-+#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
-+
-+/**
-+ * read_barrier_depends - Flush all pending reads that subsequents reads
-+ * depend on.
-+ *
-+ * No data-dependent reads from memory-like regions are ever reordered
-+ * over this barrier.  All reads preceding this primitive are guaranteed
-+ * to access memory (but not necessarily other CPUs' caches) before any
-+ * reads following this primitive that depend on the data return by
-+ * any of the preceding reads.  This primitive is much lighter weight than
-+ * rmb() on most CPUs, and is never heavier weight than is
-+ * rmb().
-+ *
-+ * These ordering constraints are respected by both the local CPU
-+ * and the compiler.
-+ *
-+ * Ordering is not guaranteed by anything other than these primitives,
-+ * not even by data dependencies.  See the documentation for
-+ * memory_barrier() for examples and URLs to more information.
-+ *
-+ * For example, the following code would force ordering (the initial
-+ * value of "a" is zero, "b" is one, and "p" is "&a"):
-+ *
-+ * <programlisting>
-+ *    CPU 0                           CPU 1
-+ *
-+ *    b = 2;
-+ *    memory_barrier();
-+ *    p = &b;                         q = p;
-+ *                                    read_barrier_depends();
-+ *                                    d = *q;
-+ * </programlisting>
-+ *
-+ * because the read of "*q" depends on the read of "p" and these
-+ * two reads are separated by a read_barrier_depends().  However,
-+ * the following code, with the same initial values for "a" and "b":
-+ *
-+ * <programlisting>
-+ *    CPU 0                           CPU 1
-+ *
-+ *    a = 2;
-+ *    memory_barrier();
-+ *    b = 3;                          y = b;
-+ *                                    read_barrier_depends();
-+ *                                    x = a;
-+ * </programlisting>
-+ *
-+ * does not enforce ordering, since there is no data dependency between
-+ * the read of "a" and the read of "b".  Therefore, on some CPUs, such
-+ * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
-+ * in cases like thiswhere there are no data dependencies.
-+ **/
-+
-+#define read_barrier_depends()        do { } while(0)
-+
-+#ifdef CONFIG_X86_OOSTORE
-+/* Actually there are no OOO store capable CPUs for now that do SSE, 
-+   but make it already an possibility. */
-+#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
-+#else
-+#define wmb() __asm__ __volatile__ ("": : :"memory")
-+#endif
-+
-+#ifdef CONFIG_SMP
-+#define smp_wmb()     wmb()
-+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
-+#define smp_alt_mb(instr)                                           \
-+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
-+                   ".section __smp_alternatives,\"a\"\n"          \
-+                   ".long 6667b\n"                                \
-+                     ".long 6673f\n"                                \
-+                   ".previous\n"                                  \
-+                   ".section __smp_replacements,\"a\"\n"          \
-+                   "6673:.byte 6668b-6667b\n"                     \
-+                   ".byte 6670f-6669f\n"                          \
-+                   ".byte 6671f-6670f\n"                          \
-+                     ".byte 0\n"                                    \
-+                   ".byte %c0\n"                                  \
-+                   "6669:lock;addl $0,0(%%esp)\n"                 \
-+                   "6670:" instr "\n"                             \
-+                   "6671:\n"                                      \
-+                   ".previous\n"                                  \
-+                   :                                              \
-+                   : "i" (X86_FEATURE_XMM2)                       \
-+                   : "memory")
-+#define smp_rmb() smp_alt_mb("lfence")
-+#define smp_mb()  smp_alt_mb("mfence")
-+#define set_mb(var, value) do {                                     \
-+unsigned long __set_mb_temp;                                        \
-+__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
-+                   ".section __smp_alternatives,\"a\"\n"          \
-+                   ".long 6667b\n"                                \
-+                   ".long 6673f\n"                                \
-+                   ".previous\n"                                  \
-+                   ".section __smp_replacements,\"a\"\n"          \
-+                   "6673: .byte 6668b-6667b\n"                    \
-+                   ".byte 6670f-6669f\n"                          \
-+                   ".byte 0\n"                                    \
-+                   ".byte 6671f-6670f\n"                          \
-+                   ".byte -1\n"                                   \
-+                   "6669: xchg %1, %0\n"                          \
-+                   "6670:movl %1, %0\n"                           \
-+                   "6671:\n"                                      \
-+                   ".previous\n"                                  \
-+                   : "=m" (var), "=r" (__set_mb_temp)             \
-+                   : "1" (value)                                  \
-+                   : "memory"); } while (0)
-+#else
-+#define smp_rmb()     rmb()
-+#define smp_mb()      mb()
-+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
-+#endif
-+#define smp_read_barrier_depends()    read_barrier_depends()
-+#else
-+#define smp_mb()      barrier()
-+#define smp_rmb()     barrier()
-+#define smp_wmb()     barrier()
-+#define smp_read_barrier_depends()    do { } while(0)
-+#define set_mb(var, value) do { var = value; barrier(); } while (0)
-+#endif
-+
-+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
-+
-+/* interrupt control.. */
-+
-+/* 
-+ * The use of 'barrier' in the following reflects their use as local-lock
-+ * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
-+ * critical operations are executed. All critical operations must complete
-+ * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
-+ * includes these barriers, for example.
-+ */
-+
-+#define __cli()                                                               \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      _vcpu->evtchn_upcall_mask = 1;                                  \
-+      preempt_enable_no_resched();                                    \
-+      barrier();                                                      \
-+} while (0)
-+
-+#define __sti()                                                               \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      barrier();                                                      \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      _vcpu->evtchn_upcall_mask = 0;                                  \
-+      barrier(); /* unmask then check (avoid races) */                \
-+      if (unlikely(_vcpu->evtchn_upcall_pending))                     \
-+              force_evtchn_callback();                                \
-+      preempt_enable();                                               \
-+} while (0)
-+
-+#define __save_flags(x)                                                       \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      (x) = _vcpu->evtchn_upcall_mask;                                \
-+      preempt_enable();                                               \
-+} while (0)
-+
-+#define __restore_flags(x)                                            \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      barrier();                                                      \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
-+              barrier(); /* unmask then check (avoid races) */        \
-+              if (unlikely(_vcpu->evtchn_upcall_pending))             \
-+                      force_evtchn_callback();                        \
-+              preempt_enable();                                       \
-+      } else                                                          \
-+              preempt_enable_no_resched();                            \
-+} while (0)
-+
-+void safe_halt(void);
-+void halt(void);
-+
-+#define __save_and_cli(x)                                             \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      (x) = _vcpu->evtchn_upcall_mask;                                \
-+      _vcpu->evtchn_upcall_mask = 1;                                  \
-+      preempt_enable_no_resched();                                    \
-+      barrier();                                                      \
-+} while (0)
-+
-+#define local_irq_save(x)     __save_and_cli(x)
-+#define local_irq_restore(x)  __restore_flags(x)
-+#define local_save_flags(x)   __save_flags(x)
-+#define local_irq_disable()   __cli()
-+#define local_irq_enable()    __sti()
-+
-+/* Cannot use preempt_enable() here as we would recurse in preempt_sched(). */
-+#define irqs_disabled()                                                       \
-+({    int ___x;                                                       \
-+      vcpu_info_t *_vcpu;                                             \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      ___x = (_vcpu->evtchn_upcall_mask != 0);                        \
-+      preempt_enable_no_resched();                                    \
-+      ___x; })
-+
-+/*
-+ * disable hlt during certain critical i/o operations
-+ */
-+#define HAVE_DISABLE_HLT
-+void disable_hlt(void);
-+void enable_hlt(void);
-+
-+extern int es7000_plat;
-+void cpu_idle_wait(void);
-+
-+/*
-+ * On SMP systems, when the scheduler does migration-cost autodetection,
-+ * it needs a way to flush as much of the CPU's caches as possible:
-+ */
-+static inline void sched_cacheflush(void)
-+{
-+      wbinvd();
-+}
-+
-+extern unsigned long arch_align_stack(unsigned long sp);
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/tlbflush.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/tlbflush.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/tlbflush.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/tlbflush.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,102 @@
-+#ifndef _I386_TLBFLUSH_H
-+#define _I386_TLBFLUSH_H
-+
-+#include <linux/config.h>
-+#include <linux/mm.h>
-+#include <asm/processor.h>
-+
-+#define __flush_tlb() xen_tlb_flush()
-+#define __flush_tlb_global() xen_tlb_flush()
-+#define __flush_tlb_all() xen_tlb_flush()
-+
-+extern unsigned long pgkern_mask;
-+
-+#define cpu_has_invlpg        (boot_cpu_data.x86 > 3)
-+
-+#define __flush_tlb_single(addr) xen_invlpg(addr)
-+
-+#define __flush_tlb_one(addr) __flush_tlb_single(addr)
-+
-+/*
-+ * TLB flushing:
-+ *
-+ *  - flush_tlb() flushes the current mm struct TLBs
-+ *  - flush_tlb_all() flushes all processes TLBs
-+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
-+ *  - flush_tlb_page(vma, vmaddr) flushes one page
-+ *  - flush_tlb_range(vma, start, end) flushes a range of pages
-+ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
-+ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
-+ *
-+ * ..but the i386 has somewhat limited tlb flushing capabilities,
-+ * and page-granular flushes are available only on i486 and up.
-+ */
-+
-+#ifndef CONFIG_SMP
-+
-+#define flush_tlb() __flush_tlb()
-+#define flush_tlb_all() __flush_tlb_all()
-+#define local_flush_tlb() __flush_tlb()
-+
-+static inline void flush_tlb_mm(struct mm_struct *mm)
-+{
-+      if (mm == current->active_mm)
-+              __flush_tlb();
-+}
-+
-+static inline void flush_tlb_page(struct vm_area_struct *vma,
-+      unsigned long addr)
-+{
-+      if (vma->vm_mm == current->active_mm)
-+              __flush_tlb_one(addr);
-+}
-+
-+static inline void flush_tlb_range(struct vm_area_struct *vma,
-+      unsigned long start, unsigned long end)
-+{
-+      if (vma->vm_mm == current->active_mm)
-+              __flush_tlb();
-+}
-+
-+#else
-+
-+#include <asm/smp.h>
-+
-+#define local_flush_tlb() \
-+      __flush_tlb()
-+
-+extern void flush_tlb_all(void);
-+extern void flush_tlb_current_task(void);
-+extern void flush_tlb_mm(struct mm_struct *);
-+extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
-+
-+#define flush_tlb()   flush_tlb_current_task()
-+
-+static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
-+{
-+      flush_tlb_mm(vma->vm_mm);
-+}
-+
-+#define TLBSTATE_OK   1
-+#define TLBSTATE_LAZY 2
-+
-+struct tlb_state
-+{
-+      struct mm_struct *active_mm;
-+      int state;
-+      char __cacheline_padding[L1_CACHE_BYTES-8];
-+};
-+DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
-+
-+
-+#endif
-+
-+#define flush_tlb_kernel_range(start, end) flush_tlb_all()
-+
-+static inline void flush_tlb_pgtables(struct mm_struct *mm,
-+                                    unsigned long start, unsigned long end)
-+{
-+      /* i386 does not keep any page table caches in TLB */
-+}
-+
-+#endif /* _I386_TLBFLUSH_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/vga.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/vga.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/vga.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/vga.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,20 @@
-+/*
-+ *    Access to VGA videoram
-+ *
-+ *    (c) 1998 Martin Mares <mj@ucw.cz>
-+ */
-+
-+#ifndef _LINUX_ASM_VGA_H_
-+#define _LINUX_ASM_VGA_H_
-+
-+/*
-+ *    On the PC, we can just recalculate addresses and then
-+ *    access the videoram directly without any black magic.
-+ */
-+
-+#define VGA_MAP_MEM(x) (unsigned long)isa_bus_to_virt(x)
-+
-+#define vga_readb(x) (*(x))
-+#define vga_writeb(x,y) (*(y) = (x))
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/xenoprof.h linux-2.6.16.33/include/asm-i386/mach-xen/asm/xenoprof.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/asm/xenoprof.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/asm/xenoprof.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,48 @@
-+/******************************************************************************
-+ * asm-i386/mach-xen/asm/xenoprof.h
-+ *
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+#ifndef __ASM_XENOPROF_H__
-+#define __ASM_XENOPROF_H__
-+#ifdef CONFIG_XEN
-+
-+struct super_block;
-+struct dentry;
-+int xenoprof_create_files(struct super_block * sb, struct dentry * root);
-+#define HAVE_XENOPROF_CREATE_FILES
-+
-+struct xenoprof_init;
-+void xenoprof_arch_init_counter(struct xenoprof_init *init);
-+void xenoprof_arch_counter(void);
-+void xenoprof_arch_start(void);
-+void xenoprof_arch_stop(void);
-+
-+struct xenoprof_arch_shared_buffer {
-+      /* nothing */
-+};
-+struct xenoprof_shared_buffer;
-+void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer* sbuf);
-+struct xenoprof_get_buffer;
-+int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer* get_buffer, struct xenoprof_shared_buffer* sbuf);
-+struct xenoprof_passive;
-+int xenoprof_arch_set_passive(struct xenoprof_passive* pdomain, struct xenoprof_shared_buffer* sbuf);
-+
-+#endif /* CONFIG_XEN */
-+#endif /* __ASM_XENOPROF_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/irq_vectors.h linux-2.6.16.33/include/asm-i386/mach-xen/irq_vectors.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/irq_vectors.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/irq_vectors.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,125 @@
-+/*
-+ * This file should contain #defines for all of the interrupt vector
-+ * numbers used by this architecture.
-+ *
-+ * In addition, there are some standard defines:
-+ *
-+ *    FIRST_EXTERNAL_VECTOR:
-+ *            The first free place for external interrupts
-+ *
-+ *    SYSCALL_VECTOR:
-+ *            The IRQ vector a syscall makes the user to kernel transition
-+ *            under.
-+ *
-+ *    TIMER_IRQ:
-+ *            The IRQ number the timer interrupt comes in at.
-+ *
-+ *    NR_IRQS:
-+ *            The total number of interrupt vectors (including all the
-+ *            architecture specific interrupts) needed.
-+ *
-+ */                   
-+#ifndef _ASM_IRQ_VECTORS_H
-+#define _ASM_IRQ_VECTORS_H
-+
-+/*
-+ * IDT vectors usable for external interrupt sources start
-+ * at 0x20:
-+ */
-+#define FIRST_EXTERNAL_VECTOR 0x20
-+
-+#define SYSCALL_VECTOR                0x80
-+
-+/*
-+ * Vectors 0x20-0x2f are used for ISA interrupts.
-+ */
-+
-+#if 0
-+/*
-+ * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
-+ *
-+ *  some of the following vectors are 'rare', they are merged
-+ *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
-+ *  TLB, reschedule and local APIC vectors are performance-critical.
-+ *
-+ *  Vectors 0xf0-0xfa are free (reserved for future Linux use).
-+ */
-+#define SPURIOUS_APIC_VECTOR  0xff
-+#define ERROR_APIC_VECTOR     0xfe
-+#define INVALIDATE_TLB_VECTOR 0xfd
-+#define RESCHEDULE_VECTOR     0xfc
-+#define CALL_FUNCTION_VECTOR  0xfb
-+
-+#define THERMAL_APIC_VECTOR   0xf0
-+/*
-+ * Local APIC timer IRQ vector is on a different priority level,
-+ * to work around the 'lost local interrupt if more than 2 IRQ
-+ * sources per level' errata.
-+ */
-+#define LOCAL_TIMER_VECTOR    0xef
-+#endif
-+
-+#define SPURIOUS_APIC_VECTOR  0xff
-+#define ERROR_APIC_VECTOR     0xfe
-+
-+/*
-+ * First APIC vector available to drivers: (vectors 0x30-0xee)
-+ * we start at 0x31 to spread out vectors evenly between priority
-+ * levels. (0x80 is the syscall vector)
-+ */
-+#define FIRST_DEVICE_VECTOR   0x31
-+#define FIRST_SYSTEM_VECTOR   0xef
-+
-+/*
-+ * 16 8259A IRQ's, 208 potential APIC interrupt sources.
-+ * Right now the APIC is mostly only used for SMP.
-+ * 256 vectors is an architectural limit. (we can have
-+ * more than 256 devices theoretically, but they will
-+ * have to use shared interrupts)
-+ * Since vectors 0x00-0x1f are used/reserved for the CPU,
-+ * the usable vector space is 0x20-0xff (224 vectors)
-+ */
-+
-+#define RESCHEDULE_VECTOR     0
-+#define CALL_FUNCTION_VECTOR  1
-+#define NR_IPIS                       2
-+
-+/*
-+ * The maximum number of vectors supported by i386 processors
-+ * is limited to 256. For processors other than i386, NR_VECTORS
-+ * should be changed accordingly.
-+ */
-+#define NR_VECTORS 256
-+
-+#define FPU_IRQ                       13
-+
-+#define       FIRST_VM86_IRQ          3
-+#define LAST_VM86_IRQ         15
-+#define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15)
-+
-+/*
-+ * The flat IRQ space is divided into two regions:
-+ *  1. A one-to-one mapping of real physical IRQs. This space is only used
-+ *     if we have physical device-access privilege. This region is at the 
-+ *     start of the IRQ space so that existing device drivers do not need
-+ *     to be modified to translate physical IRQ numbers into our IRQ space.
-+ *  3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
-+ *     are bound using the provided bind/unbind functions.
-+ */
-+
-+#define PIRQ_BASE             0
-+#define NR_PIRQS              256
-+
-+#define DYNIRQ_BASE           (PIRQ_BASE + NR_PIRQS)
-+#define NR_DYNIRQS            256
-+
-+#define NR_IRQS                       (NR_PIRQS + NR_DYNIRQS)
-+#define NR_IRQ_VECTORS                NR_IRQS
-+
-+#define pirq_to_irq(_x)               ((_x) + PIRQ_BASE)
-+#define irq_to_pirq(_x)               ((_x) - PIRQ_BASE)
-+
-+#define dynirq_to_irq(_x)     ((_x) + DYNIRQ_BASE)
-+#define irq_to_dynirq(_x)     ((_x) - DYNIRQ_BASE)
-+
-+#endif /* _ASM_IRQ_VECTORS_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/mach_traps.h linux-2.6.16.33/include/asm-i386/mach-xen/mach_traps.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/mach_traps.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/mach_traps.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,33 @@
-+/*
-+ *  include/asm-xen/asm-i386/mach-xen/mach_traps.h
-+ *
-+ *  Machine specific NMI handling for Xen
-+ */
-+#ifndef _MACH_TRAPS_H
-+#define _MACH_TRAPS_H
-+
-+#include <linux/bitops.h>
-+#include <xen/interface/nmi.h>
-+
-+static inline void clear_mem_error(unsigned char reason) {}
-+static inline void clear_io_check_error(unsigned char reason) {}
-+
-+static inline unsigned char get_nmi_reason(void)
-+{
-+      shared_info_t *s = HYPERVISOR_shared_info;
-+      unsigned char reason = 0;
-+
-+      /* construct a value which looks like it came from
-+       * port 0x61.
-+       */
-+      if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
-+              reason |= 0x40;
-+      if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
-+              reason |= 0x80;
-+
-+        return reason;
-+}
-+
-+static inline void reassert_nmi(void) {}
-+
-+#endif /* !_MACH_TRAPS_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/setup_arch_post.h linux-2.6.16.33/include/asm-i386/mach-xen/setup_arch_post.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/setup_arch_post.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/setup_arch_post.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,108 @@
-+/**
-+ * machine_specific_memory_setup - Hook for machine specific memory setup.
-+ *
-+ * Description:
-+ *    This is included late in kernel/setup.c so that it can make
-+ *    use of all of the static functions.
-+ **/
-+
-+#include <xen/interface/callback.h>
-+#include <xen/interface/memory.h>
-+
-+static char * __init machine_specific_memory_setup(void)
-+{
-+      int rc;
-+      struct xen_memory_map memmap;
-+      /*
-+       * This is rather large for a stack variable but this early in
-+       * the boot process we know we have plenty slack space.
-+       */
-+      struct e820entry map[E820MAX];
-+
-+      memmap.nr_entries = E820MAX;
-+      set_xen_guest_handle(memmap.buffer, map);
-+
-+      rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
-+      if ( rc == -ENOSYS ) {
-+              memmap.nr_entries = 1;
-+              map[0].addr = 0ULL;
-+              map[0].size = PFN_PHYS(xen_start_info->nr_pages);
-+              /* 8MB slack (to balance backend allocations). */
-+              map[0].size += 8ULL << 20;
-+              map[0].type = E820_RAM;
-+              rc = 0;
-+      }
-+      BUG_ON(rc);
-+
-+      sanitize_e820_map(map, (char *)&memmap.nr_entries);
-+
-+      BUG_ON(copy_e820_map(map, (char)memmap.nr_entries) < 0);
-+
-+      return "Xen";
-+}
-+
-+extern void hypervisor_callback(void);
-+extern void failsafe_callback(void);
-+extern void nmi(void);
-+
-+unsigned long *machine_to_phys_mapping;
-+EXPORT_SYMBOL(machine_to_phys_mapping);
-+unsigned int machine_to_phys_order;
-+EXPORT_SYMBOL(machine_to_phys_order);
-+
-+static void __init machine_specific_arch_setup(void)
-+{
-+      int ret;
-+      struct xen_machphys_mapping mapping;
-+      unsigned long machine_to_phys_nr_ents;
-+      struct xen_platform_parameters pp;
-+      static struct callback_register __initdata event = {
-+              .type = CALLBACKTYPE_event,
-+              .address = { __KERNEL_CS, (unsigned long)hypervisor_callback },
-+      };
-+      static struct callback_register __initdata failsafe = {
-+              .type = CALLBACKTYPE_failsafe,
-+              .address = { __KERNEL_CS, (unsigned long)failsafe_callback },
-+      };
-+      static struct callback_register __initdata nmi_cb = {
-+              .type = CALLBACKTYPE_nmi,
-+              .address = { __KERNEL_CS, (unsigned long)nmi },
-+      };
-+
-+      ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
-+      if (ret == 0)
-+              ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (ret == -ENOSYS)
-+              ret = HYPERVISOR_set_callbacks(
-+                      event.address.cs, event.address.eip,
-+                      failsafe.address.cs, failsafe.address.eip);
-+#endif
-+      BUG_ON(ret);
-+
-+      ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (ret == -ENOSYS) {
-+              static struct xennmi_callback __initdata cb = {
-+                      .handler_address = (unsigned long)nmi
-+              };
-+
-+              HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
-+      }
-+#endif
-+
-+      if (HYPERVISOR_xen_version(XENVER_platform_parameters,
-+                                 &pp) == 0) {
-+              hypervisor_virt_start = pp.virt_start;
-+              set_fixaddr_top();
-+      }
-+
-+      machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
-+      machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
-+      if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
-+              machine_to_phys_mapping = (unsigned long *)mapping.v_start;
-+              machine_to_phys_nr_ents = mapping.max_mfn + 1;
-+      }
-+      while ((1UL << machine_to_phys_order) < machine_to_phys_nr_ents )
-+              machine_to_phys_order++;
-+}
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/mach-xen/setup_arch_pre.h linux-2.6.16.33/include/asm-i386/mach-xen/setup_arch_pre.h
---- linux-2.6.16.33-noxen/include/asm-i386/mach-xen/setup_arch_pre.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/mach-xen/setup_arch_pre.h 2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,5 @@
-+/* Hook to call BIOS initialisation function */
-+
-+#define ARCH_SETUP machine_specific_arch_setup();
-+
-+static void __init machine_specific_arch_setup(void);
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/page.h linux-2.6.16.33/include/asm-i386/page.h
---- linux-2.6.16.33-noxen/include/asm-i386/page.h      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/page.h    2007-01-08 15:00:46.000000000 +0000
-@@ -121,7 +121,7 @@
- #define PAGE_OFFSET           ((unsigned long)__PAGE_OFFSET)
- #define VMALLOC_RESERVE               ((unsigned long)__VMALLOC_RESERVE)
--#define MAXMEM                        (-__PAGE_OFFSET-__VMALLOC_RESERVE)
-+#define MAXMEM                        (__FIXADDR_TOP-__PAGE_OFFSET-__VMALLOC_RESERVE)
- #define __pa(x)                       ((unsigned long)(x)-PAGE_OFFSET)
- #define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
- #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
-@@ -139,6 +139,8 @@
-       ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
-                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-+#define __HAVE_ARCH_GATE_AREA 1
-+
- #endif /* __KERNEL__ */
- #include <asm-generic/page.h>
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/pgtable-2level-defs.h linux-2.6.16.33/include/asm-i386/pgtable-2level-defs.h
---- linux-2.6.16.33-noxen/include/asm-i386/pgtable-2level-defs.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/pgtable-2level-defs.h     2007-05-23 21:00:01.000000000 +0000
-@@ -1,6 +1,8 @@
- #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
- #define _I386_PGTABLE_2LEVEL_DEFS_H
-+#define HAVE_SHARED_KERNEL_PMD 0
-+
- /*
-  * traditional i386 two-level paging structure:
-  */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/pgtable-3level-defs.h linux-2.6.16.33/include/asm-i386/pgtable-3level-defs.h
---- linux-2.6.16.33-noxen/include/asm-i386/pgtable-3level-defs.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/pgtable-3level-defs.h     2007-05-23 21:00:01.000000000 +0000
-@@ -1,6 +1,8 @@
- #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
- #define _I386_PGTABLE_3LEVEL_DEFS_H
-+#define HAVE_SHARED_KERNEL_PMD 1
-+
- /*
-  * PGDIR_SHIFT determines what a top-level page table entry can map
-  */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/rwsem.h linux-2.6.16.33/include/asm-i386/rwsem.h
---- linux-2.6.16.33-noxen/include/asm-i386/rwsem.h     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/rwsem.h   2007-01-08 15:00:46.000000000 +0000
-@@ -40,6 +40,7 @@
- #include <linux/list.h>
- #include <linux/spinlock.h>
-+#include <asm/smp_alt.h>
- struct rwsem_waiter;
-@@ -99,7 +100,7 @@
- {
-       __asm__ __volatile__(
-               "# beginning down_read\n\t"
--LOCK_PREFIX   "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
-+LOCK          "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
-               "  js        2f\n\t" /* jump if we weren't granted the lock */
-               "1:\n\t"
-               LOCK_SECTION_START("")
-@@ -130,7 +131,7 @@
-               "  movl      %1,%2\n\t"
-               "  addl      %3,%2\n\t"
-               "  jle       2f\n\t"
--LOCK_PREFIX   "  cmpxchgl  %2,%0\n\t"
-+LOCK          "  cmpxchgl  %2,%0\n\t"
-               "  jnz       1b\n\t"
-               "2:\n\t"
-               "# ending __down_read_trylock\n\t"
-@@ -150,7 +151,7 @@
-       tmp = RWSEM_ACTIVE_WRITE_BIAS;
-       __asm__ __volatile__(
-               "# beginning down_write\n\t"
--LOCK_PREFIX   "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
-+LOCK          "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
-               "  testl     %%edx,%%edx\n\t" /* was the count 0 before? */
-               "  jnz       2f\n\t" /* jump if we weren't granted the lock */
-               "1:\n\t"
-@@ -188,7 +189,7 @@
-       __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
-       __asm__ __volatile__(
-               "# beginning __up_read\n\t"
--LOCK_PREFIX   "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
-+LOCK          "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
-               "  js        2f\n\t" /* jump if the lock is being waited upon */
-               "1:\n\t"
-               LOCK_SECTION_START("")
-@@ -214,7 +215,7 @@
-       __asm__ __volatile__(
-               "# beginning __up_write\n\t"
-               "  movl      %2,%%edx\n\t"
--LOCK_PREFIX   "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
-+LOCK          "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
-               "  jnz       2f\n\t" /* jump if the lock is being waited upon */
-               "1:\n\t"
-               LOCK_SECTION_START("")
-@@ -239,7 +240,7 @@
- {
-       __asm__ __volatile__(
-               "# beginning __downgrade_write\n\t"
--LOCK_PREFIX   "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
-+LOCK          "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
-               "  js        2f\n\t" /* jump if the lock is being waited upon */
-               "1:\n\t"
-               LOCK_SECTION_START("")
-@@ -263,7 +264,7 @@
- static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
- {
-       __asm__ __volatile__(
--LOCK_PREFIX   "addl %1,%0"
-+LOCK            "addl %1,%0"
-               : "=m"(sem->count)
-               : "ir"(delta), "m"(sem->count));
- }
-@@ -276,7 +277,7 @@
-       int tmp = delta;
-       __asm__ __volatile__(
--LOCK_PREFIX   "xadd %0,(%2)"
-+LOCK                    "xadd %0,(%2)"
-               : "+r"(tmp), "=m"(sem->count)
-               : "r"(sem), "m"(sem->count)
-               : "memory");
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/smp_alt.h linux-2.6.16.33/include/asm-i386/smp_alt.h
---- linux-2.6.16.33-noxen/include/asm-i386/smp_alt.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/smp_alt.h 2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,32 @@
-+#ifndef __ASM_SMP_ALT_H__
-+#define __ASM_SMP_ALT_H__
-+
-+#include <linux/config.h>
-+
-+#ifdef CONFIG_SMP
-+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
-+#define LOCK \
-+        "6677: nop\n" \
-+      ".section __smp_alternatives,\"a\"\n" \
-+      ".long 6677b\n" \
-+      ".long 6678f\n" \
-+      ".previous\n" \
-+      ".section __smp_replacements,\"a\"\n" \
-+      "6678: .byte 1\n" \
-+      ".byte 1\n" \
-+      ".byte 0\n" \
-+        ".byte 1\n" \
-+      ".byte -1\n" \
-+      "lock\n" \
-+      "nop\n" \
-+      ".previous\n"
-+void prepare_for_smp(void);
-+void unprepare_for_smp(void);
-+#else
-+#define LOCK "lock ; "
-+#endif
-+#else
-+#define LOCK ""
-+#endif
-+
-+#endif /* __ASM_SMP_ALT_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/spinlock.h linux-2.6.16.33/include/asm-i386/spinlock.h
---- linux-2.6.16.33-noxen/include/asm-i386/spinlock.h  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/spinlock.h        2007-01-08 15:00:46.000000000 +0000
-@@ -6,6 +6,7 @@
- #include <asm/page.h>
- #include <linux/config.h>
- #include <linux/compiler.h>
-+#include <asm/smp_alt.h>
- /*
-  * Your basic SMP spinlocks, allowing only a single CPU anywhere
-@@ -23,7 +24,8 @@
- #define __raw_spin_lock_string \
-       "\n1:\t" \
--      "lock ; decb %0\n\t" \
-+      LOCK \
-+      "decb %0\n\t" \
-       "jns 3f\n" \
-       "2:\t" \
-       "rep;nop\n\t" \
-@@ -34,7 +36,8 @@
- #define __raw_spin_lock_string_flags \
-       "\n1:\t" \
--      "lock ; decb %0\n\t" \
-+      LOCK \
-+      "decb %0\n\t" \
-       "jns 4f\n\t" \
-       "2:\t" \
-       "testl $0x200, %1\n\t" \
-@@ -65,10 +68,34 @@
- static inline int __raw_spin_trylock(raw_spinlock_t *lock)
- {
-       char oldval;
-+#ifdef CONFIG_SMP_ALTERNATIVES
-+      __asm__ __volatile__(
-+              "1:movb %1,%b0\n"
-+              "movb $0,%1\n"
-+              "2:"
-+              ".section __smp_alternatives,\"a\"\n"
-+              ".long 1b\n"
-+              ".long 3f\n"
-+              ".previous\n"
-+              ".section __smp_replacements,\"a\"\n"
-+              "3: .byte 2b - 1b\n"
-+              ".byte 5f-4f\n"
-+              ".byte 0\n"
-+              ".byte 6f-5f\n"
-+              ".byte -1\n"
-+              "4: xchgb %b0,%1\n"
-+              "5: movb %1,%b0\n"
-+              "movb $0,%1\n"
-+              "6:\n"
-+              ".previous\n"
-+              :"=q" (oldval), "=m" (lock->slock)
-+              :"0" (0) : "memory");
-+#else
-       __asm__ __volatile__(
-               "xchgb %b0,%1"
-               :"=q" (oldval), "=m" (lock->slock)
-               :"0" (0) : "memory");
-+#endif
-       return oldval > 0;
- }
-@@ -178,12 +205,12 @@
- static inline void __raw_read_unlock(raw_rwlock_t *rw)
- {
--      asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
-+      asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
- }
- static inline void __raw_write_unlock(raw_rwlock_t *rw)
- {
--      asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
-+      asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
-                                : "=m" (rw->lock) : : "memory");
- }
-diff -Nur linux-2.6.16.33-noxen/include/asm-i386/system.h linux-2.6.16.33/include/asm-i386/system.h
---- linux-2.6.16.33-noxen/include/asm-i386/system.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-i386/system.h  2007-01-08 15:00:46.000000000 +0000
-@@ -5,7 +5,7 @@
- #include <linux/kernel.h>
- #include <asm/segment.h>
- #include <asm/cpufeature.h>
--#include <linux/bitops.h> /* for LOCK_PREFIX */
-+#include <asm/smp_alt.h>
- #ifdef __KERNEL__
-@@ -271,19 +271,19 @@
-       unsigned long prev;
-       switch (size) {
-       case 1:
--              __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
-+              __asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
-                                    : "=a"(prev)
-                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
-                                    : "memory");
-               return prev;
-       case 2:
--              __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
-+              __asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
-                                    : "=a"(prev)
-                                    : "r"(new), "m"(*__xg(ptr)), "0"(old)
-                                    : "memory");
-               return prev;
-       case 4:
--              __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
-+              __asm__ __volatile__(LOCK "cmpxchgl %1,%2"
-                                    : "=a"(prev)
-                                    : "r"(new), "m"(*__xg(ptr)), "0"(old)
-                                    : "memory");
-@@ -336,7 +336,7 @@
-                                     unsigned long long new)
- {
-       unsigned long long prev;
--      __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
-+      __asm__ __volatile__(LOCK "cmpxchg8b %3"
-                            : "=A"(prev)
-                            : "b"((unsigned long)new),
-                              "c"((unsigned long)(new >> 32)),
-@@ -503,11 +503,55 @@
- #endif
- #ifdef CONFIG_SMP
-+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
-+#define smp_alt_mb(instr)                                           \
-+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
-+                   ".section __smp_alternatives,\"a\"\n"          \
-+                   ".long 6667b\n"                                \
-+                     ".long 6673f\n"                                \
-+                   ".previous\n"                                  \
-+                   ".section __smp_replacements,\"a\"\n"          \
-+                   "6673:.byte 6668b-6667b\n"                     \
-+                   ".byte 6670f-6669f\n"                          \
-+                   ".byte 6671f-6670f\n"                          \
-+                     ".byte 0\n"                                    \
-+                   ".byte %c0\n"                                  \
-+                   "6669:lock;addl $0,0(%%esp)\n"                 \
-+                   "6670:" instr "\n"                             \
-+                   "6671:\n"                                      \
-+                   ".previous\n"                                  \
-+                   :                                              \
-+                   : "i" (X86_FEATURE_XMM2)                       \
-+                   : "memory")
-+#define smp_mb()  smp_alt_mb("mfence")
-+#define smp_rmb() smp_alt_mb("lfence")
-+#define set_mb(var, value) do {                                     \
-+unsigned long __set_mb_temp;                                        \
-+__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
-+                   ".section __smp_alternatives,\"a\"\n"          \
-+                   ".long 6667b\n"                                \
-+                   ".long 6673f\n"                                \
-+                   ".previous\n"                                  \
-+                   ".section __smp_replacements,\"a\"\n"          \
-+                   "6673: .byte 6668b-6667b\n"                    \
-+                   ".byte 6670f-6669f\n"                          \
-+                   ".byte 0\n"                                    \
-+                   ".byte 6671f-6670f\n"                          \
-+                   ".byte -1\n"                                   \
-+                   "6669: xchg %1, %0\n"                          \
-+                   "6670:movl %1, %0\n"                           \
-+                   "6671:\n"                                      \
-+                   ".previous\n"                                  \
-+                   : "=m" (var), "=r" (__set_mb_temp)             \
-+                   : "1" (value)                                  \
-+                   : "memory"); } while (0)
-+#else
- #define smp_mb()      mb()
- #define smp_rmb()     rmb()
-+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
-+#endif
- #define smp_wmb()     wmb()
- #define smp_read_barrier_depends()    read_barrier_depends()
--#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
- #else
- #define smp_mb()      barrier()
- #define smp_rmb()     barrier()
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/agp.h linux-2.6.16.33/include/asm-ia64/agp.h
---- linux-2.6.16.33-noxen/include/asm-ia64/agp.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/agp.h     2007-01-08 15:00:46.000000000 +0000
-@@ -19,13 +19,44 @@
- #define flush_agp_cache()             mb()
- /* Convert a physical address to an address suitable for the GART. */
-+#ifndef CONFIG_XEN
- #define phys_to_gart(x) (x)
- #define gart_to_phys(x) (x)
-+#else
-+#define phys_to_gart(x) phys_to_machine_for_dma(x)
-+#define gart_to_phys(x) machine_to_phys_for_dma(x)
-+#endif
- /* GATT allocation. Returns/accepts GATT kernel virtual address. */
-+#ifndef CONFIG_XEN
- #define alloc_gatt_pages(order)               \
-       ((char *)__get_free_pages(GFP_KERNEL, (order)))
- #define free_gatt_pages(table, order) \
-       free_pages((unsigned long)(table), (order))
-+#else
-+#include <asm/hypervisor.h>
-+static inline char*
-+alloc_gatt_pages(unsigned int order)
-+{
-+      unsigned long error;
-+      unsigned long ret = __get_free_pages(GFP_KERNEL, (order));
-+      if (ret == 0) {
-+              goto out;
-+      }
-+      error = xen_create_contiguous_region(ret, order, 0);
-+      if (error) {
-+              free_pages(ret, order);
-+              ret = 0;
-+      }
-+out:
-+      return (char*)ret;
-+}
-+static inline void
-+free_gatt_pages(void* table, unsigned int order)
-+{
-+      xen_destroy_contiguous_region((unsigned long)table, order);
-+      free_pages((unsigned long)table, order);
-+}
-+#endif /* CONFIG_XEN */
- #endif /* _ASM_IA64_AGP_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/dma-mapping.h linux-2.6.16.33/include/asm-ia64/dma-mapping.h
---- linux-2.6.16.33-noxen/include/asm-ia64/dma-mapping.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/dma-mapping.h     2007-01-08 15:00:46.000000000 +0000
-@@ -7,7 +7,14 @@
-  */
- #include <linux/config.h>
- #include <asm/machvec.h>
-+#ifdef CONFIG_XEN
-+/* Needed for arch/i386/kernel/swiotlb.c and arch/i386/kernel/pci-dma-xen.c */
-+#include <asm/hypervisor.h>
-+/* Needed for arch/i386/kernel/swiotlb.c */
-+#include <asm-i386/mach-xen/asm/swiotlb.h>
-+#endif
-+#ifndef CONFIG_XEN
- #define dma_alloc_coherent    platform_dma_alloc_coherent
- #define dma_alloc_noncoherent platform_dma_alloc_coherent     /* coherent mem. is cheap */
- #define dma_free_coherent     platform_dma_free_coherent
-@@ -21,6 +28,46 @@
- #define dma_sync_single_for_device platform_dma_sync_single_for_device
- #define dma_sync_sg_for_device        platform_dma_sync_sg_for_device
- #define dma_mapping_error     platform_dma_mapping_error
-+#else
-+int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-+               enum dma_data_direction direction);
-+void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-+                  enum dma_data_direction direction);
-+int dma_supported(struct device *dev, u64 mask);
-+void *dma_alloc_coherent(struct device *dev, size_t size,
-+                         dma_addr_t *dma_handle, gfp_t gfp);
-+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-+                       dma_addr_t dma_handle);
-+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-+                          enum dma_data_direction direction);
-+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-+                      enum dma_data_direction direction);
-+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-+                             size_t size, enum dma_data_direction direction);
-+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-+                                size_t size,
-+                                enum dma_data_direction direction);
-+int dma_mapping_error(dma_addr_t dma_addr);
-+
-+#define flush_write_buffers() do { } while (0)
-+static inline void
-+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-+                    enum dma_data_direction direction)
-+{
-+      if (swiotlb)
-+              swiotlb_sync_sg_for_cpu(dev,sg,nelems,direction);
-+      flush_write_buffers();
-+}
-+
-+static inline void
-+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-+                       enum dma_data_direction direction)
-+{
-+      if (swiotlb)
-+              swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
-+      flush_write_buffers();
-+}
-+#endif
- #define dma_map_page(dev, pg, off, size, dir)                         \
-       dma_map_single(dev, page_address(pg) + (off), (size), (dir))
-@@ -37,7 +84,9 @@
- #define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir)  \
-       dma_sync_single_for_device(dev, dma_handle, size, dir)
-+#ifndef CONFIG_XEN
- #define dma_supported         platform_dma_supported
-+#endif
- static inline int
- dma_set_mask (struct device *dev, u64 mask)
-@@ -62,4 +111,27 @@
- #define dma_is_consistent(dma_handle) (1)     /* all we do is coherent memory... */
-+#ifdef CONFIG_XEN
-+/* arch/i386/kernel/swiotlb.o requires */
-+void contiguous_bitmap_init(unsigned long end_pfn);
-+
-+static inline int
-+address_needs_mapping(struct device *hwdev, dma_addr_t addr)
-+{
-+      dma_addr_t mask = DMA_64BIT_MASK;
-+      /* If the device has a mask, use it, otherwise default to 64 bits */
-+      if (hwdev && hwdev->dma_mask)
-+              mask = *hwdev->dma_mask;
-+      return (addr & ~mask) != 0;
-+}
-+
-+static inline int
-+range_straddles_page_boundary(void *p, size_t size)
-+{
-+      extern unsigned long *contiguous_bitmap;
-+      return (((((unsigned long)p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
-+              !test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap));
-+}
-+#endif
-+
- #endif /* _ASM_IA64_DMA_MAPPING_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/fixmap.h linux-2.6.16.33/include/asm-ia64/fixmap.h
---- linux-2.6.16.33-noxen/include/asm-ia64/fixmap.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/fixmap.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,2 @@
-+#define clear_fixmap(x)       do {} while (0)
-+#define       set_fixmap(x,y) do {} while (0)
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/gcc_intrin.h linux-2.6.16.33/include/asm-ia64/gcc_intrin.h
---- linux-2.6.16.33-noxen/include/asm-ia64/gcc_intrin.h        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/gcc_intrin.h      2007-01-08 15:00:46.000000000 +0000
-@@ -26,7 +26,7 @@
- register unsigned long ia64_r13 asm ("r13") __attribute_used__;
--#define ia64_setreg(regnum, val)                                              \
-+#define __ia64_setreg(regnum, val)                                            \
- ({                                                                            \
-       switch (regnum) {                                                       \
-           case _IA64_REG_PSR_L:                                               \
-@@ -55,7 +55,7 @@
-       }                                                                       \
- })
--#define ia64_getreg(regnum)                                                   \
-+#define __ia64_getreg(regnum)                                                 \
- ({                                                                            \
-       __u64 ia64_intri_res;                                                   \
-                                                                               \
-@@ -92,7 +92,7 @@
- #define ia64_hint_pause 0
--#define ia64_hint(mode)                                               \
-+#define __ia64_hint(mode)                                             \
- ({                                                            \
-       switch (mode) {                                         \
-       case ia64_hint_pause:                                   \
-@@ -374,7 +374,7 @@
- #define ia64_invala() asm volatile ("invala" ::: "memory")
--#define ia64_thash(addr)                                                      \
-+#define __ia64_thash(addr)                                                    \
- ({                                                                            \
-       __u64 ia64_intri_res;                                                   \
-       asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr));       \
-@@ -394,18 +394,18 @@
- #define ia64_nop(x)   asm volatile ("nop %0"::"i"(x));
--#define ia64_itci(addr)       asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
-+#define __ia64_itci(addr)     asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
--#define ia64_itcd(addr)       asm volatile ("itc.d %0;;" :: "r"(addr) : "memory")
-+#define __ia64_itcd(addr)     asm volatile ("itc.d %0;;" :: "r"(addr) : "memory")
--#define ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1"                               \
-+#define __ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1"                     \
-                                            :: "r"(trnum), "r"(addr) : "memory")
--#define ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1"                               \
-+#define __ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1"                     \
-                                            :: "r"(trnum), "r"(addr) : "memory")
--#define ia64_tpa(addr)                                                                \
-+#define __ia64_tpa(addr)                                                      \
- ({                                                                            \
-       __u64 ia64_pa;                                                          \
-       asm volatile ("tpa %0 = %1" : "=r"(ia64_pa) : "r"(addr) : "memory");    \
-@@ -415,22 +415,22 @@
- #define __ia64_set_dbr(index, val)                                            \
-       asm volatile ("mov dbr[%0]=%1" :: "r"(index), "r"(val) : "memory")
--#define ia64_set_ibr(index, val)                                              \
-+#define __ia64_set_ibr(index, val)                                            \
-       asm volatile ("mov ibr[%0]=%1" :: "r"(index), "r"(val) : "memory")
--#define ia64_set_pkr(index, val)                                              \
-+#define __ia64_set_pkr(index, val)                                            \
-       asm volatile ("mov pkr[%0]=%1" :: "r"(index), "r"(val) : "memory")
--#define ia64_set_pmc(index, val)                                              \
-+#define __ia64_set_pmc(index, val)                                            \
-       asm volatile ("mov pmc[%0]=%1" :: "r"(index), "r"(val) : "memory")
--#define ia64_set_pmd(index, val)                                              \
-+#define __ia64_set_pmd(index, val)                                            \
-       asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
--#define ia64_set_rr(index, val)                                                       \
-+#define __ia64_set_rr(index, val)                                                     \
-       asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
--#define ia64_get_cpuid(index)                                                         \
-+#define __ia64_get_cpuid(index)                                                               \
- ({                                                                                    \
-       __u64 ia64_intri_res;                                                           \
-       asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index));        \
-@@ -444,21 +444,21 @@
-       ia64_intri_res;                                                         \
- })
--#define ia64_get_ibr(index)                                                   \
-+#define __ia64_get_ibr(index)                                                 \
- ({                                                                            \
-       __u64 ia64_intri_res;                                                   \
-       asm volatile ("mov %0=ibr[%1]" : "=r"(ia64_intri_res) : "r"(index));    \
-       ia64_intri_res;                                                         \
- })
--#define ia64_get_pkr(index)                                                   \
-+#define __ia64_get_pkr(index)                                                 \
- ({                                                                            \
-       __u64 ia64_intri_res;                                                   \
-       asm volatile ("mov %0=pkr[%1]" : "=r"(ia64_intri_res) : "r"(index));    \
-       ia64_intri_res;                                                         \
- })
--#define ia64_get_pmc(index)                                                   \
-+#define __ia64_get_pmc(index)                                                 \
- ({                                                                            \
-       __u64 ia64_intri_res;                                                   \
-       asm volatile ("mov %0=pmc[%1]" : "=r"(ia64_intri_res) : "r"(index));    \
-@@ -466,48 +466,48 @@
- })
--#define ia64_get_pmd(index)                                                   \
-+#define __ia64_get_pmd(index)                                                 \
- ({                                                                            \
-       __u64 ia64_intri_res;                                                   \
-       asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index));    \
-       ia64_intri_res;                                                         \
- })
--#define ia64_get_rr(index)                                                    \
-+#define __ia64_get_rr(index)                                                  \
- ({                                                                            \
-       __u64 ia64_intri_res;                                                   \
-       asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index));    \
-       ia64_intri_res;                                                         \
- })
--#define ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
-+#define __ia64_fc(addr)       asm volatile ("fc %0" :: "r"(addr) : "memory")
- #define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
--#define ia64_ssm(mask)        asm volatile ("ssm %0":: "i"((mask)) : "memory")
--#define ia64_rsm(mask)        asm volatile ("rsm %0":: "i"((mask)) : "memory")
-+#define __ia64_ssm(mask)      asm volatile ("ssm %0":: "i"((mask)) : "memory")
-+#define __ia64_rsm(mask)      asm volatile ("rsm %0":: "i"((mask)) : "memory")
- #define ia64_sum(mask)        asm volatile ("sum %0":: "i"((mask)) : "memory")
- #define ia64_rum(mask)        asm volatile ("rum %0":: "i"((mask)) : "memory")
--#define ia64_ptce(addr)       asm volatile ("ptc.e %0" :: "r"(addr))
-+#define __ia64_ptce(addr)     asm volatile ("ptc.e %0" :: "r"(addr))
--#define ia64_ptcga(addr, size)                                                        \
-+#define __ia64_ptcga(addr, size)                                                      \
- do {                                                                          \
-       asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory");       \
-       ia64_dv_serialize_data();                                               \
- } while (0)
--#define ia64_ptcl(addr, size)                                                 \
-+#define __ia64_ptcl(addr, size)                                                       \
- do {                                                                          \
-       asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(size) : "memory");        \
-       ia64_dv_serialize_data();                                               \
- } while (0)
--#define ia64_ptri(addr, size)                                         \
-+#define __ia64_ptri(addr, size)                                               \
-       asm volatile ("ptr.i %0,%1" :: "r"(addr), "r"(size) : "memory")
--#define ia64_ptrd(addr, size)                                         \
-+#define __ia64_ptrd(addr, size)                                               \
-       asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory")
- /* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */
-@@ -589,7 +589,7 @@
-         }                                                             \
- })
--#define ia64_intrin_local_irq_restore(x)                      \
-+#define __ia64_intrin_local_irq_restore(x)                    \
- do {                                                          \
-       asm volatile (";;   cmp.ne p6,p7=%0,r0;;"               \
-                     "(p6) ssm psr.i;"                         \
-@@ -598,4 +598,6 @@
-                     :: "r"((x)) : "p6", "p7", "memory");      \
- } while (0)
-+#define __ia64_get_psr_i()    (__ia64_getreg(_IA64_REG_PSR) & 0x4000UL)
-+
- #endif /* _ASM_IA64_GCC_INTRIN_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/hw_irq.h linux-2.6.16.33/include/asm-ia64/hw_irq.h
---- linux-2.6.16.33-noxen/include/asm-ia64/hw_irq.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/hw_irq.h  2007-01-08 15:00:46.000000000 +0000
-@@ -15,7 +15,11 @@
- #include <asm/ptrace.h>
- #include <asm/smp.h>
-+#ifndef CONFIG_XEN
- typedef u8 ia64_vector;
-+#else
-+typedef u16 ia64_vector;
-+#endif
- /*
-  * 0 special
-@@ -89,6 +93,13 @@
- static inline void
- hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
- {
-+#ifdef CONFIG_XEN
-+      extern void resend_irq_on_evtchn(struct hw_interrupt_type *h,
-+                                       unsigned int i);
-+      if (is_running_on_xen())
-+              resend_irq_on_evtchn(h, vector);
-+      else
-+#endif /* CONFIG_XEN */
-       platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
- }
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/hypercall.h linux-2.6.16.33/include/asm-ia64/hypercall.h
---- linux-2.6.16.33-noxen/include/asm-ia64/hypercall.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/hypercall.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,463 @@
-+/******************************************************************************
-+ * hypercall.h
-+ * 
-+ * Linux-specific hypervisor handling.
-+ * 
-+ * Copyright (c) 2002-2004, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __HYPERCALL_H__
-+#define __HYPERCALL_H__
-+
-+#ifndef __HYPERVISOR_H__
-+# error "please don't include this file directly"
-+#endif
-+
-+#include <asm/xen/xcom_hcall.h>
-+struct xencomm_handle;
-+
-+/*
-+ * Assembler stubs for hyper-calls.
-+ */
-+
-+#define _hypercall0(type, name)                                       \
-+({                                                            \
-+      long __res;                                             \
-+      __asm__ __volatile__ (";;\n"                            \
-+                            "mov r2=%1\n"                     \
-+                            "break 0x1000 ;;\n"               \
-+                            "mov %0=r8 ;;\n"                  \
-+                            : "=r" (__res)                    \
-+                            : "J" (__HYPERVISOR_##name)       \
-+                            : "r2","r8",                      \
-+                              "memory" );                     \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall1(type, name, a1)                           \
-+({                                                            \
-+      long __res;                                             \
-+      __asm__ __volatile__ (";;\n"                            \
-+                            "mov r14=%2\n"                    \
-+                            "mov r2=%1\n"                     \
-+                            "break 0x1000 ;;\n"               \
-+                            "mov %0=r8 ;;\n"                  \
-+                            : "=r" (__res)                    \
-+                            : "J" (__HYPERVISOR_##name),      \
-+                              "rI" ((unsigned long)(a1))      \
-+                            : "r14","r2","r8",                \
-+                              "memory" );                     \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall2(type, name, a1, a2)                               \
-+({                                                            \
-+      long __res;                                             \
-+      __asm__ __volatile__ (";;\n"                            \
-+                            "mov r14=%2\n"                    \
-+                            "mov r15=%3\n"                    \
-+                            "mov r2=%1\n"                     \
-+                            "break 0x1000 ;;\n"               \
-+                            "mov %0=r8 ;;\n"                  \
-+                            : "=r" (__res)                    \
-+                            : "J" (__HYPERVISOR_##name),      \
-+                              "rI" ((unsigned long)(a1)),     \
-+                              "rI" ((unsigned long)(a2))      \
-+                            : "r14","r15","r2","r8",          \
-+                              "memory" );                     \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall3(type, name, a1, a2, a3)                   \
-+({                                                            \
-+      long __res;                                             \
-+      __asm__ __volatile__ (";;\n"                            \
-+                            "mov r14=%2\n"                    \
-+                            "mov r15=%3\n"                    \
-+                            "mov r16=%4\n"                    \
-+                            "mov r2=%1\n"                     \
-+                            "break 0x1000 ;;\n"               \
-+                            "mov %0=r8 ;;\n"                  \
-+                            : "=r" (__res)                    \
-+                            : "J" (__HYPERVISOR_##name),      \
-+                              "rI" ((unsigned long)(a1)),     \
-+                              "rI" ((unsigned long)(a2)),     \
-+                              "rI" ((unsigned long)(a3))      \
-+                            : "r14","r15","r16","r2","r8",    \
-+                              "memory" );                     \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall4(type, name, a1, a2, a3, a4)                       \
-+({                                                            \
-+      long __res;                                             \
-+      __asm__ __volatile__ (";;\n"                            \
-+                            "mov r14=%2\n"                    \
-+                            "mov r15=%3\n"                    \
-+                            "mov r16=%4\n"                    \
-+                            "mov r17=%5\n"                    \
-+                            "mov r2=%1\n"                     \
-+                            "break 0x1000 ;;\n"               \
-+                            "mov %0=r8 ;;\n"                  \
-+                            : "=r" (__res)                    \
-+                            : "J" (__HYPERVISOR_##name),      \
-+                              "rI" ((unsigned long)(a1)),     \
-+                              "rI" ((unsigned long)(a2)),     \
-+                              "rI" ((unsigned long)(a3)),     \
-+                              "rI" ((unsigned long)(a4))      \
-+                            : "r14","r15","r16","r2","r8",    \
-+                              "r17","memory" );               \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall5(type, name, a1, a2, a3, a4, a5)           \
-+({                                                            \
-+      long __res;                                             \
-+      __asm__ __volatile__ (";;\n"                            \
-+                            "mov r14=%2\n"                    \
-+                            "mov r15=%3\n"                    \
-+                            "mov r16=%4\n"                    \
-+                            "mov r17=%5\n"                    \
-+                            "mov r18=%6\n"                    \
-+                            "mov r2=%1\n"                     \
-+                            "break 0x1000 ;;\n"               \
-+                            "mov %0=r8 ;;\n"                  \
-+                            : "=r" (__res)                    \
-+                            : "J" (__HYPERVISOR_##name),      \
-+                              "rI" ((unsigned long)(a1)),     \
-+                              "rI" ((unsigned long)(a2)),     \
-+                              "rI" ((unsigned long)(a3)),     \
-+                              "rI" ((unsigned long)(a4)),     \
-+                              "rI" ((unsigned long)(a5))      \
-+                            : "r14","r15","r16","r2","r8",    \
-+                              "r17","r18","memory" );         \
-+      (type)__res;                                            \
-+})
-+
-+
-+static inline int
-+xencomm_arch_hypercall_sched_op(int cmd, struct xencomm_handle *arg)
-+{
-+      return _hypercall2(int, sched_op, cmd, arg);
-+}
-+
-+static inline long
-+HYPERVISOR_set_timer_op(u64 timeout)
-+{
-+      unsigned long timeout_hi = (unsigned long)(timeout >> 32);
-+      unsigned long timeout_lo = (unsigned long)timeout;
-+      return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_dom0_op(struct xencomm_handle *op)
-+{
-+      return _hypercall1(int, dom0_op, op);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_sysctl(struct xencomm_handle *op)
-+{
-+      return _hypercall1(int, sysctl, op);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_domctl(struct xencomm_handle *op)
-+{
-+      return _hypercall1(int, domctl, op);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_multicall(struct xencomm_handle *call_list,
-+                               int nr_calls)
-+{
-+      return _hypercall2(int, multicall, call_list, nr_calls);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_memory_op(unsigned int cmd, struct xencomm_handle *arg)
-+{
-+      return _hypercall2(int, memory_op, cmd, arg);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_event_channel_op(int cmd, struct xencomm_handle *arg)
-+{
-+      return _hypercall2(int, event_channel_op, cmd, arg);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_acm_op(unsigned int cmd, struct xencomm_handle *arg)
-+{
-+      return _hypercall2(int, acm_op, cmd, arg);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_xen_version(int cmd, struct xencomm_handle *arg)
-+{
-+      return _hypercall2(int, xen_version, cmd, arg);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_console_io(int cmd, int count,
-+                                  struct xencomm_handle *str)
-+{
-+      return _hypercall3(int, console_io, cmd, count, str);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_physdev_op(int cmd, struct xencomm_handle *arg)
-+{
-+      return _hypercall2(int, physdev_op, cmd, arg);
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_grant_table_op(unsigned int cmd,
-+                                      struct xencomm_handle *uop,
-+                                      unsigned int count)
-+{
-+      return _hypercall3(int, grant_table_op, cmd, uop, count);
-+}
-+
-+int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
-+
-+extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg);
-+
-+static inline int
-+xencomm_arch_hypercall_callback_op(int cmd, struct xencomm_handle *arg)
-+{
-+      return _hypercall2(int, callback_op, cmd, arg);
-+}
-+
-+static inline unsigned long
-+xencomm_arch_hypercall_hvm_op(int cmd, void *arg)
-+{
-+      return _hypercall2(unsigned long, hvm_op, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_physdev_op(int cmd, void *arg)
-+{
-+      switch (cmd) {
-+      case PHYSDEVOP_eoi:
-+              return _hypercall1(int, ia64_fast_eoi,
-+                                 ((struct physdev_eoi *)arg)->irq);
-+      default:
-+              return xencomm_hypercall_physdev_op(cmd, arg);
-+      }
-+}
-+
-+static inline int
-+xencomm_arch_hypercall_xenoprof_op(int op, struct xencomm_handle *arg)
-+{
-+      return _hypercall2(int, xenoprof_op, op, arg);
-+}
-+
-+extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
-+static inline void exit_idle(void) {}
-+#define do_IRQ(irq, regs) ({                  \
-+      irq_enter();                            \
-+      __do_IRQ((irq), (regs));                \
-+      irq_exit();                             \
-+})
-+
-+#include <linux/err.h>
-+#ifdef CONFIG_XEN
-+#include <asm/xen/privop.h>
-+#endif /* CONFIG_XEN */
-+#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-+#include <xen/platform-compat.h>
-+#endif
-+
-+static inline unsigned long
-+__HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
-+{
-+      return _hypercall3(unsigned long, ia64_dom0vp_op,
-+                         IA64_DOM0VP_ioremap, ioaddr, size);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
-+{
-+      unsigned long ret = ioaddr;
-+      if (is_running_on_xen()) {
-+              ret = __HYPERVISOR_ioremap(ioaddr, size);
-+              if (unlikely(ret == -ENOSYS))
-+                      panic("hypercall %s failed with %ld. "
-+                            "Please check Xen and Linux config mismatch\n",
-+                            __func__, -ret);
-+              else if (unlikely(IS_ERR_VALUE(ret)))
-+                      ret = ioaddr;
-+      }
-+      return ret;
-+}
-+
-+static inline unsigned long
-+__HYPERVISOR_phystomach(unsigned long gpfn)
-+{
-+      return _hypercall2(unsigned long, ia64_dom0vp_op,
-+                         IA64_DOM0VP_phystomach, gpfn);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_phystomach(unsigned long gpfn)
-+{
-+      unsigned long ret = gpfn;
-+      if (is_running_on_xen()) {
-+              ret = __HYPERVISOR_phystomach(gpfn);
-+      }
-+      return ret;
-+}
-+
-+static inline unsigned long
-+__HYPERVISOR_machtophys(unsigned long mfn)
-+{
-+      return _hypercall2(unsigned long, ia64_dom0vp_op,
-+                         IA64_DOM0VP_machtophys, mfn);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_machtophys(unsigned long mfn)
-+{
-+      unsigned long ret = mfn;
-+      if (is_running_on_xen()) {
-+              ret = __HYPERVISOR_machtophys(mfn);
-+      }
-+      return ret;
-+}
-+
-+static inline unsigned long
-+__HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
-+{
-+      return _hypercall3(unsigned long, ia64_dom0vp_op,
-+                         IA64_DOM0VP_zap_physmap, gpfn, extent_order);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
-+{
-+      unsigned long ret = 0;
-+      if (is_running_on_xen()) {
-+              ret = __HYPERVISOR_zap_physmap(gpfn, extent_order);
-+      }
-+      return ret;
-+}
-+
-+static inline unsigned long
-+__HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
-+                       unsigned long flags, domid_t domid)
-+{
-+      return _hypercall5(unsigned long, ia64_dom0vp_op,
-+                         IA64_DOM0VP_add_physmap, gpfn, mfn, flags, domid);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
-+                     unsigned long flags, domid_t domid)
-+{
-+      unsigned long ret = 0;
-+      BUG_ON(!is_running_on_xen());//XXX
-+      if (is_running_on_xen()) {
-+              ret = __HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
-+      }
-+      return ret;
-+}
-+
-+static inline unsigned long
-+__HYPERVISOR_add_physmap_with_gmfn(unsigned long gpfn, unsigned long gmfn,
-+                                   unsigned long flags, domid_t domid)
-+{
-+      return _hypercall5(unsigned long, ia64_dom0vp_op,
-+                         IA64_DOM0VP_add_physmap_with_gmfn,
-+                         gpfn, gmfn, flags, domid);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_add_physmap_with_gmfn(unsigned long gpfn, unsigned long gmfn,
-+                               unsigned long flags, domid_t domid)
-+{
-+      unsigned long ret = 0;
-+      BUG_ON(!is_running_on_xen());//XXX
-+      if (is_running_on_xen()) {
-+              ret = __HYPERVISOR_add_physmap_with_gmfn(gpfn, gmfn,
-+                                                       flags, domid);
-+      }
-+      return ret;
-+}
-+
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
-+static inline unsigned long
-+HYPERVISOR_expose_p2m(unsigned long conv_start_gpfn,
-+                      unsigned long assign_start_gpfn,
-+                      unsigned long expose_size, unsigned long granule_pfn)
-+{
-+      return _hypercall5(unsigned long, ia64_dom0vp_op,
-+                         IA64_DOM0VP_expose_p2m, conv_start_gpfn,
-+                         assign_start_gpfn, expose_size, granule_pfn);
-+}
-+#endif
-+
-+static inline int
-+xencomm_arch_hypercall_perfmon_op(unsigned long cmd,
-+                                  struct xencomm_handle *arg,
-+                                  unsigned long count)
-+{
-+      return _hypercall4(int, ia64_dom0vp_op,
-+                         IA64_DOM0VP_perfmon, cmd, arg, count);
-+}
-+
-+// for balloon driver
-+#define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
-+
-+/* Use xencomm to do hypercalls.  */
-+#ifdef MODULE
-+#define HYPERVISOR_sched_op xencomm_mini_hypercall_sched_op
-+#define HYPERVISOR_event_channel_op xencomm_mini_hypercall_event_channel_op
-+#define HYPERVISOR_callback_op xencomm_mini_hypercall_callback_op
-+#define HYPERVISOR_multicall xencomm_mini_hypercall_multicall
-+#define HYPERVISOR_xen_version xencomm_mini_hypercall_xen_version
-+#define HYPERVISOR_console_io xencomm_mini_hypercall_console_io
-+#define HYPERVISOR_hvm_op xencomm_mini_hypercall_hvm_op
-+#define HYPERVISOR_memory_op xencomm_mini_hypercall_memory_op
-+#define HYPERVISOR_xenoprof_op xencomm_mini_hypercall_xenoprof_op
-+#define HYPERVISOR_perfmon_op xencomm_mini_hypercall_perfmon_op
-+#else
-+#define HYPERVISOR_sched_op xencomm_hypercall_sched_op
-+#define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op
-+#define HYPERVISOR_callback_op xencomm_hypercall_callback_op
-+#define HYPERVISOR_multicall xencomm_hypercall_multicall
-+#define HYPERVISOR_xen_version xencomm_hypercall_xen_version
-+#define HYPERVISOR_console_io xencomm_hypercall_console_io
-+#define HYPERVISOR_hvm_op xencomm_hypercall_hvm_op
-+#define HYPERVISOR_memory_op xencomm_hypercall_memory_op
-+#define HYPERVISOR_xenoprof_op xencomm_hypercall_xenoprof_op
-+#define HYPERVISOR_perfmon_op xencomm_hypercall_perfmon_op
-+#endif
-+
-+#define HYPERVISOR_suspend xencomm_hypercall_suspend
-+
-+#endif /* __HYPERCALL_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/hypervisor.h linux-2.6.16.33/include/asm-ia64/hypervisor.h
---- linux-2.6.16.33-noxen/include/asm-ia64/hypervisor.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/hypervisor.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,223 @@
-+/******************************************************************************
-+ * hypervisor.h
-+ * 
-+ * Linux-specific hypervisor handling.
-+ * 
-+ * Copyright (c) 2002-2004, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __HYPERVISOR_H__
-+#define __HYPERVISOR_H__
-+
-+#ifdef CONFIG_XEN
-+extern int running_on_xen;
-+#define is_running_on_xen()                   (running_on_xen)
-+#else /* CONFIG_XEN */
-+# ifdef CONFIG_VMX_GUEST
-+#  define is_running_on_xen()                 (1)
-+# else /* CONFIG_VMX_GUEST */
-+#  define is_running_on_xen()                 (0)
-+#  define HYPERVISOR_ioremap(offset, size)    (offset)
-+# endif /* CONFIG_VMX_GUEST */
-+#endif /* CONFIG_XEN */
-+
-+#if defined(CONFIG_XEN) || defined(CONFIG_VMX_GUEST)
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/version.h>
-+#include <linux/errno.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/dom0_ops.h>
-+#include <xen/interface/event_channel.h>
-+#include <xen/interface/physdev.h>
-+#include <xen/interface/sched.h>
-+#include <asm/hypercall.h>
-+#include <asm/ptrace.h>
-+#include <asm/page.h>
-+
-+extern shared_info_t *HYPERVISOR_shared_info;
-+extern start_info_t *xen_start_info;
-+
-+void force_evtchn_callback(void);
-+
-+#ifndef CONFIG_VMX_GUEST
-+/* Turn jiffies into Xen system time. XXX Implement me. */
-+#define jiffies_to_st(j)      0
-+
-+static inline int
-+HYPERVISOR_yield(
-+      void)
-+{
-+      int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_block(
-+      void)
-+{
-+      int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_shutdown(
-+      unsigned int reason)
-+{
-+      struct sched_shutdown sched_shutdown = {
-+              .reason = reason
-+      };
-+
-+      int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_poll(
-+      evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
-+{
-+      struct sched_poll sched_poll = {
-+              .nr_ports = nr_ports,
-+              .timeout = jiffies_to_st(timeout)
-+      };
-+
-+      int rc;
-+
-+      set_xen_guest_handle(sched_poll.ports, ports);
-+      rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
-+
-+      return rc;
-+}
-+
-+// for drivers/xen/privcmd/privcmd.c
-+#define machine_to_phys_mapping 0
-+struct vm_area_struct;
-+int direct_remap_pfn_range(struct vm_area_struct *vma,
-+                         unsigned long address,
-+                         unsigned long mfn,
-+                         unsigned long size,
-+                         pgprot_t prot,
-+                         domid_t  domid);
-+struct file;
-+int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
-+int privcmd_mmap(struct file * file, struct vm_area_struct * vma);
-+#define HAVE_ARCH_PRIVCMD_MMAP
-+
-+// for drivers/xen/balloon/balloon.c
-+#ifdef CONFIG_XEN_SCRUB_PAGES
-+#define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
-+#else
-+#define scrub_pages(_p,_n) ((void)0)
-+#endif
-+#define       pte_mfn(_x)     pte_pfn(_x)
-+#define phys_to_machine_mapping_valid(_x)     (1)
-+
-+#endif /* !CONFIG_VMX_GUEST */
-+
-+#define __pte_ma(_x)  ((pte_t) {(_x)})        /* unmodified use */
-+#define pfn_pte_ma(_x,_y)     __pte_ma(0)     /* unmodified use */
-+
-+#ifndef CONFIG_VMX_GUEST
-+int __xen_create_contiguous_region(unsigned long vstart, unsigned int order, unsigned int address_bits);
-+static inline int
-+xen_create_contiguous_region(unsigned long vstart,
-+                             unsigned int order, unsigned int address_bits)
-+{
-+      int ret = 0;
-+      if (is_running_on_xen()) {
-+              ret = __xen_create_contiguous_region(vstart, order,
-+                                                   address_bits);
-+      }
-+      return ret;
-+}
-+
-+void __xen_destroy_contiguous_region(unsigned long vstart, unsigned int order);
-+static inline void
-+xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
-+{
-+      if (is_running_on_xen())
-+              __xen_destroy_contiguous_region(vstart, order);
-+}
-+
-+#endif /* !CONFIG_VMX_GUEST */
-+
-+// for netfront.c, netback.c
-+#define MULTI_UVMFLAGS_INDEX 0 //XXX any value
-+
-+static inline void
-+MULTI_update_va_mapping(
-+      multicall_entry_t *mcl, unsigned long va,
-+      pte_t new_val, unsigned long flags)
-+{
-+      mcl->op = __HYPERVISOR_update_va_mapping;
-+      mcl->result = 0;
-+}
-+
-+static inline void
-+MULTI_grant_table_op(multicall_entry_t *mcl, unsigned int cmd,
-+      void *uop, unsigned int count)
-+{
-+      mcl->op = __HYPERVISOR_grant_table_op;
-+      mcl->args[0] = cmd;
-+      mcl->args[1] = (unsigned long)uop;
-+      mcl->args[2] = count;
-+}
-+
-+/*
-+ * for blktap.c
-+ * int create_lookup_pte_addr(struct mm_struct *mm, 
-+ *                            unsigned long address,
-+ *                            uint64_t *ptep);
-+ */
-+#define create_lookup_pte_addr(mm, address, ptep)                     \
-+      ({                                                              \
-+              printk(KERN_EMERG                                       \
-+                     "%s:%d "                                         \
-+                     "create_lookup_pte_addr() isn't supported.\n",   \
-+                     __func__, __LINE__);                             \
-+              BUG();                                                  \
-+              (-ENOSYS);                                              \
-+      })
-+
-+// for debug
-+asmlinkage int xprintk(const char *fmt, ...);
-+#define xprintd(fmt, ...)     xprintk("%s:%d " fmt, __func__, __LINE__, \
-+                                      ##__VA_ARGS__)
-+
-+#endif /* CONFIG_XEN || CONFIG_VMX_GUEST */
-+
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-+#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
-+#else
-+#define is_initial_xendomain() 0
-+#endif
-+
-+#endif /* __HYPERVISOR_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/intel_intrin.h linux-2.6.16.33/include/asm-ia64/intel_intrin.h
---- linux-2.6.16.33-noxen/include/asm-ia64/intel_intrin.h      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/intel_intrin.h    2007-01-08 15:00:46.000000000 +0000
-@@ -119,10 +119,10 @@
-                        * intrinsic
-                        */
--#define ia64_getreg           __getReg
--#define ia64_setreg           __setReg
-+#define __ia64_getreg         __getReg
-+#define __ia64_setreg         __setReg
--#define ia64_hint(x)
-+#define __ia64_hint(x)
- #define ia64_mux1_brcst        0
- #define ia64_mux1_mix          8
-@@ -135,16 +135,16 @@
- #define ia64_getf_exp         __getf_exp
- #define ia64_shrp             _m64_shrp
--#define ia64_tpa              __tpa
-+#define __ia64_tpa            __tpa
- #define ia64_invala           __invala
- #define ia64_invala_gr                __invala_gr
- #define ia64_invala_fr                __invala_fr
- #define ia64_nop              __nop
- #define ia64_sum              __sum
--#define ia64_ssm              __ssm
-+#define __ia64_ssm            __ssm
- #define ia64_rum              __rum
--#define ia64_rsm              __rsm
--#define ia64_fc               __fc
-+#define __ia64_rsm            __rsm
-+#define __ia64_fc             __fc
- #define ia64_ldfs             __ldfs
- #define ia64_ldfd             __ldfd
-@@ -182,24 +182,24 @@
- #define __ia64_set_dbr(index, val)    \
-               __setIndReg(_IA64_REG_INDR_DBR, index, val)
--#define ia64_set_ibr(index, val)      \
-+#define __ia64_set_ibr(index, val)    \
-               __setIndReg(_IA64_REG_INDR_IBR, index, val)
--#define ia64_set_pkr(index, val)      \
-+#define __ia64_set_pkr(index, val)    \
-               __setIndReg(_IA64_REG_INDR_PKR, index, val)
--#define ia64_set_pmc(index, val)      \
-+#define __ia64_set_pmc(index, val)    \
-               __setIndReg(_IA64_REG_INDR_PMC, index, val)
--#define ia64_set_pmd(index, val)      \
-+#define __ia64_set_pmd(index, val)    \
-               __setIndReg(_IA64_REG_INDR_PMD, index, val)
--#define ia64_set_rr(index, val)       \
-+#define __ia64_set_rr(index, val)     \
-               __setIndReg(_IA64_REG_INDR_RR, index, val)
--#define ia64_get_cpuid(index)         __getIndReg(_IA64_REG_INDR_CPUID, index)
-+#define __ia64_get_cpuid(index)       __getIndReg(_IA64_REG_INDR_CPUID, index)
- #define __ia64_get_dbr(index)         __getIndReg(_IA64_REG_INDR_DBR, index)
--#define ia64_get_ibr(index)   __getIndReg(_IA64_REG_INDR_IBR, index)
--#define ia64_get_pkr(index)   __getIndReg(_IA64_REG_INDR_PKR, index)
--#define ia64_get_pmc(index)   __getIndReg(_IA64_REG_INDR_PMC, index)
--#define ia64_get_pmd(index)   __getIndReg(_IA64_REG_INDR_PMD, index)
--#define ia64_get_rr(index)    __getIndReg(_IA64_REG_INDR_RR, index)
-+#define __ia64_get_ibr(index)         __getIndReg(_IA64_REG_INDR_IBR, index)
-+#define __ia64_get_pkr(index)         __getIndReg(_IA64_REG_INDR_PKR, index)
-+#define __ia64_get_pmc(index)         __getIndReg(_IA64_REG_INDR_PMC, index)
-+#define __ia64_get_pmd(index)         __getIndReg(_IA64_REG_INDR_PMD, index)
-+#define __ia64_get_rr(index)  __getIndReg(_IA64_REG_INDR_RR, index)
- #define ia64_srlz_d           __dsrlz
- #define ia64_srlz_i           __isrlz
-@@ -218,18 +218,18 @@
- #define ia64_ld8_acq          __ld8_acq
- #define ia64_sync_i           __synci
--#define ia64_thash            __thash
--#define ia64_ttag             __ttag
--#define ia64_itcd             __itcd
--#define ia64_itci             __itci
--#define ia64_itrd             __itrd
--#define ia64_itri             __itri
--#define ia64_ptce             __ptce
--#define ia64_ptcl             __ptcl
--#define ia64_ptcg             __ptcg
--#define ia64_ptcga            __ptcga
--#define ia64_ptri             __ptri
--#define ia64_ptrd             __ptrd
-+#define __ia64_thash          __thash
-+#define __ia64_ttag           __ttag
-+#define __ia64_itcd           __itcd
-+#define __ia64_itci           __itci
-+#define __ia64_itrd           __itrd
-+#define __ia64_itri           __itri
-+#define __ia64_ptce           __ptce
-+#define __ia64_ptcl           __ptcl
-+#define __ia64_ptcg           __ptcg
-+#define __ia64_ptcga          __ptcga
-+#define __ia64_ptri           __ptri
-+#define __ia64_ptrd           __ptrd
- #define ia64_dep_mi           _m64_dep_mi
- /* Values for lfhint in __lfetch and __lfetch_fault */
-@@ -244,14 +244,16 @@
- #define ia64_lfetch_fault     __lfetch_fault
- #define ia64_lfetch_fault_excl        __lfetch_fault_excl
--#define ia64_intrin_local_irq_restore(x)              \
-+#define __ia64_intrin_local_irq_restore(x)            \
- do {                                                  \
-       if ((x) != 0) {                                 \
--              ia64_ssm(IA64_PSR_I);                   \
-+              __ia64_ssm(IA64_PSR_I);                 \
-               ia64_srlz_d();                          \
-       } else {                                        \
--              ia64_rsm(IA64_PSR_I);                   \
-+              __ia64_rsm(IA64_PSR_I);                 \
-       }                                               \
- } while (0)
-+#define __ia64_get_psr_i()    (__ia64_getreg(_IA64_REG_PSR) & 0x4000UL)
-+
- #endif /* _ASM_IA64_INTEL_INTRIN_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/io.h linux-2.6.16.33/include/asm-ia64/io.h
---- linux-2.6.16.33-noxen/include/asm-ia64/io.h        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/io.h      2007-01-08 15:00:46.000000000 +0000
-@@ -66,9 +66,11 @@
- #define PIO_RESERVED          __IA64_UNCACHED_OFFSET
- #define HAVE_ARCH_PIO_SIZE
-+#include <asm/hypervisor.h>
- #include <asm/intrinsics.h>
- #include <asm/machvec.h>
- #include <asm/page.h>
-+#include <asm/privop.h>
- #include <asm/system.h>
- #include <asm-generic/iomap.h>
-@@ -95,9 +97,44 @@
-  * The following two macros are deprecated and scheduled for removal.
-  * Please use the PCI-DMA interface defined in <asm/pci.h> instead.
-  */
-+#ifndef CONFIG_XEN
- #define bus_to_virt   phys_to_virt
- #define virt_to_bus   virt_to_phys
- #define page_to_bus   page_to_phys
-+#else
-+#define bus_to_virt(bus)      \
-+      phys_to_virt(machine_to_phys_for_dma(bus))
-+#define virt_to_bus(virt)     \
-+      phys_to_machine_for_dma(virt_to_phys(virt))
-+#define page_to_bus(page)     \
-+      phys_to_machine_for_dma(page_to_pseudophys(page))
-+
-+#define page_to_pseudophys(page) \
-+      ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-+
-+/*
-+ * Drivers that use page_to_phys() for bus addresses are broken.
-+ * This includes:
-+ * drivers/ide/cris/ide-cris.c
-+ * drivers/scsi/dec_esp.c
-+ */
-+#define page_to_phys(page)    (page_to_pseudophys(page))
-+#define bvec_to_bus(bv)               (page_to_bus((bv)->bv_page) + \
-+                              (unsigned long) (bv)->bv_offset)
-+#define bio_to_pseudophys(bio)        (page_to_pseudophys(bio_page((bio))) +  \
-+                               (unsigned long) bio_offset((bio)))
-+#define bvec_to_pseudophys(bv)  (page_to_pseudophys((bv)->bv_page) +  \
-+                               (unsigned long) (bv)->bv_offset)
-+#define BIOVEC_PHYS_MERGEABLE(vec1, vec2)                             \
-+      (((bvec_to_bus((vec1)) + (vec1)->bv_len) == bvec_to_bus((vec2))) && \
-+       ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) ==              \
-+        bvec_to_pseudophys((vec2))))
-+
-+/* We will be supplying our own /dev/mem implementation */
-+#define ARCH_HAS_DEV_MEM
-+#define ARCH_HAS_DEV_MEM_MMAP_MEM
-+int xen_mmap_mem(struct file * file, struct vm_area_struct * vma);
-+#endif /* CONFIG_XEN */
- # endif /* KERNEL */
-@@ -425,6 +462,9 @@
- static inline void __iomem *
- ioremap (unsigned long offset, unsigned long size)
- {
-+      offset = HYPERVISOR_ioremap(offset, size);
-+      if (IS_ERR_VALUE(offset))
-+              return (void __iomem*)offset;
-       return (void __iomem *) (__IA64_UNCACHED_OFFSET | (offset));
- }
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/iosapic.h linux-2.6.16.33/include/asm-ia64/iosapic.h
---- linux-2.6.16.33-noxen/include/asm-ia64/iosapic.h   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/iosapic.h 2007-01-08 15:00:46.000000000 +0000
-@@ -53,6 +53,7 @@
- #define NR_IOSAPICS                   256
-+#ifndef CONFIG_XEN
- static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int reg)
- {
-       writel(reg, iosapic + IOSAPIC_REG_SELECT);
-@@ -64,6 +65,7 @@
-       writel(reg, iosapic + IOSAPIC_REG_SELECT);
-       writel(val, iosapic + IOSAPIC_WINDOW);
- }
-+#endif
- static inline void iosapic_eoi(char __iomem *iosapic, u32 vector)
- {
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/irq.h linux-2.6.16.33/include/asm-ia64/irq.h
---- linux-2.6.16.33-noxen/include/asm-ia64/irq.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/irq.h     2007-01-08 15:00:46.000000000 +0000
-@@ -11,8 +11,41 @@
-  * 02/29/00     D.Mosberger   moved most things into hw_irq.h
-  */
-+#ifndef CONFIG_XEN
- #define NR_IRQS               256
- #define NR_IRQ_VECTORS        NR_IRQS
-+#else
-+/*
-+ * The flat IRQ space is divided into two regions:
-+ *  1. A one-to-one mapping of real physical IRQs. This space is only used
-+ *     if we have physical device-access privilege. This region is at the 
-+ *     start of the IRQ space so that existing device drivers do not need
-+ *     to be modified to translate physical IRQ numbers into our IRQ space.
-+ *  3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
-+ *     are bound using the provided bind/unbind functions.
-+ */
-+
-+#define PIRQ_BASE             0
-+#define NR_PIRQS              256
-+
-+#define DYNIRQ_BASE           (PIRQ_BASE + NR_PIRQS)
-+#define NR_DYNIRQS            256
-+
-+#define NR_IRQS                       (NR_PIRQS + NR_DYNIRQS)
-+#define NR_IRQ_VECTORS                NR_IRQS
-+
-+#define pirq_to_irq(_x)               ((_x) + PIRQ_BASE)
-+#define irq_to_pirq(_x)               ((_x) - PIRQ_BASE)
-+
-+#define dynirq_to_irq(_x)     ((_x) + DYNIRQ_BASE)
-+#define irq_to_dynirq(_x)     ((_x) - DYNIRQ_BASE)
-+
-+#define RESCHEDULE_VECTOR     0
-+#define IPI_VECTOR            1
-+#define CMCP_VECTOR           2
-+#define CPEP_VECTOR           3
-+#define NR_IPIS                       4
-+#endif /* CONFIG_XEN */
- /*
-  * IRQ line status macro IRQ_PER_CPU is used
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/machvec_dig.h linux-2.6.16.33/include/asm-ia64/machvec_dig.h
---- linux-2.6.16.33-noxen/include/asm-ia64/machvec_dig.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/machvec_dig.h     2007-01-08 15:00:46.000000000 +0000
-@@ -15,4 +15,19 @@
- #define platform_setup                dig_setup
- #define platform_irq_init     dig_irq_init
-+#ifdef CONFIG_XEN
-+# define platform_dma_map_sg          dma_map_sg
-+# define platform_dma_unmap_sg                dma_unmap_sg
-+# define platform_dma_mapping_error   dma_mapping_error
-+# define platform_dma_supported               dma_supported
-+# define platform_dma_alloc_coherent  dma_alloc_coherent
-+# define platform_dma_free_coherent   dma_free_coherent
-+# define platform_dma_map_single      dma_map_single
-+# define platform_dma_unmap_single    dma_unmap_single
-+# define platform_dma_sync_single_for_cpu \
-+                                      dma_sync_single_for_cpu
-+# define platform_dma_sync_single_for_device \
-+                                      dma_sync_single_for_device
-+#endif
-+
- #endif /* _ASM_IA64_MACHVEC_DIG_h */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/maddr.h linux-2.6.16.33/include/asm-ia64/maddr.h
---- linux-2.6.16.33-noxen/include/asm-ia64/maddr.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/maddr.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,102 @@
-+#ifndef _ASM_IA64_MADDR_H
-+#define _ASM_IA64_MADDR_H
-+
-+#include <linux/kernel.h>
-+#include <asm/hypervisor.h>
-+#include <xen/features.h>
-+#include <xen/interface/xen.h>
-+
-+#ifdef CONFIG_XEN
-+
-+#define INVALID_P2M_ENTRY       (~0UL)
-+
-+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
-+extern int p2m_initialized;
-+extern unsigned long p2m_min_low_pfn;
-+extern unsigned long p2m_max_low_pfn;
-+extern unsigned long p2m_convert_min_pfn;
-+extern unsigned long p2m_convert_max_pfn;
-+extern volatile const pte_t* p2m_pte;
-+unsigned long p2m_phystomach(unsigned long gpfn);
-+#else
-+#define p2m_initialized               (0)
-+#define p2m_phystomach(gpfn)  INVALID_MFN
-+#endif
-+
-+/* XXX xen page size != page size */
-+static inline unsigned long
-+pfn_to_mfn_for_dma(unsigned long pfn)
-+{
-+      unsigned long mfn;
-+      if (p2m_initialized)
-+              return p2m_phystomach(pfn);
-+      mfn = HYPERVISOR_phystomach(pfn);
-+      BUG_ON(mfn == 0); // XXX
-+      BUG_ON(mfn == INVALID_P2M_ENTRY); // XXX
-+      BUG_ON(mfn == INVALID_MFN);
-+      return mfn;
-+}
-+
-+static inline unsigned long
-+phys_to_machine_for_dma(unsigned long phys)
-+{
-+      unsigned long machine =
-+                    pfn_to_mfn_for_dma(phys >> PAGE_SHIFT) << PAGE_SHIFT;
-+      machine |= (phys & ~PAGE_MASK);
-+      return machine;
-+}
-+
-+static inline unsigned long
-+mfn_to_pfn_for_dma(unsigned long mfn)
-+{
-+      unsigned long pfn;
-+      pfn = HYPERVISOR_machtophys(mfn);
-+      BUG_ON(pfn == 0);
-+      //BUG_ON(pfn == INVALID_M2P_ENTRY);
-+      return pfn;
-+}
-+
-+static inline unsigned long
-+machine_to_phys_for_dma(unsigned long machine)
-+{
-+      unsigned long phys =
-+                    mfn_to_pfn_for_dma(machine >> PAGE_SHIFT) << PAGE_SHIFT;
-+      phys |= (machine & ~PAGE_MASK);
-+      return phys;
-+}
-+
-+static inline unsigned long
-+mfn_to_local_pfn(unsigned long mfn)
-+{
-+      extern unsigned long max_mapnr;
-+      unsigned long pfn = mfn_to_pfn_for_dma(mfn);
-+      if (!pfn_valid(pfn))
-+              return INVALID_P2M_ENTRY;
-+      return pfn;
-+}
-+
-+#else /* !CONFIG_XEN */
-+
-+#define pfn_to_mfn_for_dma(pfn) (pfn)
-+#define mfn_to_pfn_for_dma(mfn) (mfn)
-+#define phys_to_machine_for_dma(phys) (phys)
-+#define machine_to_phys_for_dma(machine) (machine)
-+#define mfn_to_local_pfn(mfn) (mfn)
-+
-+#endif /* !CONFIG_XEN */
-+
-+/* XXX to compile set_phys_to_machine(vaddr, FOREIGN_FRAME(m)) */
-+#define FOREIGN_FRAME(m)        (INVALID_P2M_ENTRY)
-+
-+#define mfn_to_pfn(mfn) (mfn)
-+#define pfn_to_mfn(pfn) (pfn)
-+
-+#define mfn_to_virt(mfn) (__va((mfn) << PAGE_SHIFT))
-+#define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT)
-+#define virt_to_machine(virt) __pa(virt) // for tpmfront.c
-+
-+#define set_phys_to_machine(pfn, mfn) do { } while (0)
-+
-+typedef unsigned long maddr_t;        // to compile netback, netfront
-+
-+#endif /* _ASM_IA64_MADDR_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/meminit.h linux-2.6.16.33/include/asm-ia64/meminit.h
---- linux-2.6.16.33-noxen/include/asm-ia64/meminit.h   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/meminit.h 2007-01-08 15:00:46.000000000 +0000
-@@ -17,10 +17,15 @@
-  *    - command line string
-  *    - kernel code & data
-  *    - Kernel memory map built from EFI memory map
-+ *    - xen start info
-  *
-  * More could be added if necessary
-  */
-+#ifndef CONFIG_XEN
- #define IA64_MAX_RSVD_REGIONS 6
-+#else
-+#define IA64_MAX_RSVD_REGIONS 7
-+#endif
- struct rsvd_region {
-       unsigned long start;    /* virtual address of beginning of element */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/page.h linux-2.6.16.33/include/asm-ia64/page.h
---- linux-2.6.16.33-noxen/include/asm-ia64/page.h      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/page.h    2007-01-08 15:00:46.000000000 +0000
-@@ -117,7 +117,9 @@
- # define pfn_to_page(pfn)     (vmem_map + (pfn))
- #endif
-+#ifndef CONFIG_XEN
- #define page_to_phys(page)    (page_to_pfn(page) << PAGE_SHIFT)
-+#endif
- #define virt_to_page(kaddr)   pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
- #define pfn_to_kaddr(pfn)     __va((pfn) << PAGE_SHIFT)
-@@ -219,4 +221,53 @@
-                                        (((current->personality & READ_IMPLIES_EXEC) != 0)     \
-                                         ? VM_EXEC : 0))
-+#ifndef __ASSEMBLY__
-+#ifdef CONFIG_XEN
-+
-+#include <linux/kernel.h>
-+#include <asm/hypervisor.h>
-+#include <xen/features.h>     // to compile netback, netfront
-+
-+/*
-+ * XXX hack!
-+ * Linux/IA64 uses PG_arch_1.
-+ * This hack will be removed once PG_foreign bit is taken.
-+ * #include <xen/foreign_page.h>
-+ */
-+#ifdef __ASM_XEN_FOREIGN_PAGE_H__
-+# error "don't include include/xen/foreign_page.h!"
-+#endif
-+
-+extern struct address_space xen_ia64_foreign_dummy_mapping;
-+#define PageForeign(page)     \
-+      ((page)->mapping == &xen_ia64_foreign_dummy_mapping)
-+
-+#define SetPageForeign(page, dtor) do {                               \
-+      set_page_private((page), (unsigned long)(dtor));        \
-+      (page)->mapping = &xen_ia64_foreign_dummy_mapping;      \
-+      smp_rmb();                                              \
-+} while (0)
-+
-+#define ClearPageForeign(page) do {   \
-+      (page)->mapping = NULL;         \
-+      smp_rmb();                      \
-+      set_page_private((page), 0);    \
-+} while (0)
-+
-+#define PageForeignDestructor(page)   \
-+      ( (void (*) (struct page *)) page_private(page) )
-+
-+#define arch_free_page(_page,_order)                  \
-+({      int foreign = PageForeign(_page);               \
-+      if (foreign)                                    \
-+              (PageForeignDestructor(_page))(_page);  \
-+      foreign;                                        \
-+})
-+#define HAVE_ARCH_FREE_PAGE
-+
-+#include <asm/maddr.h>
-+
-+#endif /* CONFIG_XEN */
-+#endif /* __ASSEMBLY__ */
-+
- #endif /* _ASM_IA64_PAGE_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/pal.h linux-2.6.16.33/include/asm-ia64/pal.h
---- linux-2.6.16.33-noxen/include/asm-ia64/pal.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/pal.h     2007-01-08 15:00:46.000000000 +0000
-@@ -81,6 +81,7 @@
- #ifndef __ASSEMBLY__
- #include <linux/types.h>
-+#include <asm/processor.h>
- #include <asm/fpu.h>
- /*
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/pgalloc.h linux-2.6.16.33/include/asm-ia64/pgalloc.h
---- linux-2.6.16.33-noxen/include/asm-ia64/pgalloc.h   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/pgalloc.h 2007-01-08 15:00:46.000000000 +0000
-@@ -126,7 +126,11 @@
- static inline void
- pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, struct page *pte)
- {
-+#ifndef CONFIG_XEN
-       pmd_val(*pmd_entry) = page_to_phys(pte);
-+#else
-+      pmd_val(*pmd_entry) = page_to_pseudophys(pte);
-+#endif
- }
- static inline void
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/privop.h linux-2.6.16.33/include/asm-ia64/privop.h
---- linux-2.6.16.33-noxen/include/asm-ia64/privop.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/privop.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,60 @@
-+#ifndef _ASM_IA64_PRIVOP_H
-+#define _ASM_IA64_PRIVOP_H
-+
-+/*
-+ * Copyright (C) 2005 Hewlett-Packard Co
-+ *    Dan Magenheimer <dan.magenheimer@hp.com>
-+ *
-+ */
-+
-+#ifdef CONFIG_XEN
-+#include <asm/xen/privop.h>
-+#endif
-+
-+#ifndef __ASSEMBLY
-+
-+#ifndef IA64_PARAVIRTUALIZED
-+
-+#define ia64_getreg                   __ia64_getreg
-+#define ia64_setreg                   __ia64_setreg
-+#define ia64_hint                     __ia64_hint
-+#define ia64_thash                    __ia64_thash
-+#define ia64_itci                     __ia64_itci
-+#define ia64_itcd                     __ia64_itcd
-+#define ia64_itri                     __ia64_itri
-+#define ia64_itrd                     __ia64_itrd
-+#define ia64_tpa                      __ia64_tpa
-+#define ia64_set_ibr                  __ia64_set_ibr
-+#define ia64_set_pkr                  __ia64_set_pkr
-+#define ia64_set_pmc                  __ia64_set_pmc
-+#define ia64_set_pmd                  __ia64_set_pmd
-+#define ia64_set_rr                   __ia64_set_rr
-+#define ia64_get_cpuid                        __ia64_get_cpuid
-+#define ia64_get_ibr                  __ia64_get_ibr
-+#define ia64_get_pkr                  __ia64_get_pkr
-+#define ia64_get_pmc                  __ia64_get_pmc
-+#define ia64_get_pmd                  __ia64_get_pmd
-+#define ia64_get_rr                   __ia64_get_rr
-+#define ia64_fc                               __ia64_fc
-+#define ia64_ssm                      __ia64_ssm
-+#define ia64_rsm                      __ia64_rsm
-+#define ia64_ptce                     __ia64_ptce
-+#define ia64_ptcga                    __ia64_ptcga
-+#define ia64_ptcl                     __ia64_ptcl
-+#define ia64_ptri                     __ia64_ptri
-+#define ia64_ptrd                     __ia64_ptrd
-+#define ia64_get_psr_i                        __ia64_get_psr_i
-+#define ia64_intrin_local_irq_restore __ia64_intrin_local_irq_restore
-+#define ia64_pal_halt_light           __ia64_pal_halt_light
-+#define ia64_leave_kernel             __ia64_leave_kernel
-+#define ia64_leave_syscall            __ia64_leave_syscall
-+#define ia64_trace_syscall            __ia64_trace_syscall
-+#define ia64_ret_from_clone           __ia64_ret_from_clone
-+#define ia64_switch_to                        __ia64_switch_to
-+#define ia64_pal_call_static          __ia64_pal_call_static
-+
-+#endif /* !IA64_PARAVIRTUALIZED */
-+
-+#endif /* !__ASSEMBLY */
-+
-+#endif /* _ASM_IA64_PRIVOP_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/processor.h linux-2.6.16.33/include/asm-ia64/processor.h
---- linux-2.6.16.33-noxen/include/asm-ia64/processor.h 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/processor.h       2007-01-08 15:00:46.000000000 +0000
-@@ -19,6 +19,7 @@
- #include <asm/kregs.h>
- #include <asm/ptrace.h>
- #include <asm/ustack.h>
-+#include <asm/privop.h>
- #define IA64_NUM_DBG_REGS     8
- /*
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/sal.h linux-2.6.16.33/include/asm-ia64/sal.h
---- linux-2.6.16.33-noxen/include/asm-ia64/sal.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/sal.h     2007-01-08 15:00:46.000000000 +0000
-@@ -42,6 +42,9 @@
- #include <asm/pal.h>
- #include <asm/system.h>
- #include <asm/fpu.h>
-+#ifdef CONFIG_XEN
-+#include <asm/xen/xencomm.h>
-+#endif
- extern spinlock_t sal_lock;
-@@ -686,10 +689,28 @@
- /* Get the processor and platform information logged by SAL with respect to the machine
-  * state at the time of the MCAs, INITs, CMCs, or CPEs.
-  */
-+#ifdef CONFIG_XEN
-+static inline u64 ia64_sal_get_state_info_size (u64 sal_info_type);
-+#endif
-+
- static inline u64
- ia64_sal_get_state_info (u64 sal_info_type, u64 *sal_info)
- {
-       struct ia64_sal_retval isrv;
-+#ifdef CONFIG_XEN
-+      if (is_running_on_xen()) {
-+              struct xencomm_handle *desc;
-+
-+              if (xencomm_create(sal_info,
-+                                 ia64_sal_get_state_info_size(sal_info_type),
-+                                 &desc, GFP_KERNEL))
-+                      return 0;
-+
-+              SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO, sal_info_type, 0,
-+                                 desc, 0, 0, 0, 0);
-+              xencomm_free(desc);
-+      } else
-+#endif
-       SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO, sal_info_type, 0,
-                     sal_info, 0, 0, 0, 0);
-       if (isrv.status)
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/synch_bitops.h linux-2.6.16.33/include/asm-ia64/synch_bitops.h
---- linux-2.6.16.33-noxen/include/asm-ia64/synch_bitops.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/synch_bitops.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,63 @@
-+#ifndef __XEN_SYNCH_BITOPS_H__
-+#define __XEN_SYNCH_BITOPS_H__
-+
-+/*
-+ * Copyright 1992, Linus Torvalds.
-+ * Heavily modified to provide guaranteed strong synchronisation
-+ * when communicating with Xen or other guest OSes running on other CPUs.
-+ */
-+
-+#include <linux/config.h>
-+
-+#define ADDR (*(volatile long *) addr)
-+
-+static __inline__ void synch_set_bit(int nr, volatile void * addr)
-+{
-+      set_bit(nr, addr);
-+}
-+
-+static __inline__ void synch_clear_bit(int nr, volatile void * addr)
-+{
-+      clear_bit(nr, addr);
-+}
-+
-+static __inline__ void synch_change_bit(int nr, volatile void * addr)
-+{
-+      change_bit(nr, addr);
-+}
-+
-+static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr)
-+{
-+    return test_and_set_bit(nr, addr);
-+}
-+
-+static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
-+{
-+    return test_and_clear_bit(nr, addr);
-+}
-+
-+static __inline__ int synch_test_and_change_bit(int nr, volatile void * addr)
-+{
-+    return test_and_change_bit(nr, addr);
-+}
-+
-+static __inline__ int synch_const_test_bit(int nr, const volatile void * addr)
-+{
-+    return test_bit(nr, addr);
-+}
-+
-+static __inline__ int synch_var_test_bit(int nr, volatile void * addr)
-+{
-+    return test_bit(nr, addr);
-+}
-+
-+#define synch_cmpxchg ia64_cmpxchg4_acq
-+
-+#define synch_test_bit(nr,addr) \
-+(__builtin_constant_p(nr) ? \
-+ synch_const_test_bit((nr),(addr)) : \
-+ synch_var_test_bit((nr),(addr)))
-+
-+#define synch_cmpxchg_subword synch_cmpxchg
-+
-+#endif /* __XEN_SYNCH_BITOPS_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/system.h linux-2.6.16.33/include/asm-ia64/system.h
---- linux-2.6.16.33-noxen/include/asm-ia64/system.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/system.h  2007-01-08 15:00:46.000000000 +0000
-@@ -125,7 +125,7 @@
- #define __local_irq_save(x)                   \
- do {                                          \
-       ia64_stop();                            \
--      (x) = ia64_getreg(_IA64_REG_PSR);       \
-+      (x) = ia64_get_psr_i();                 \
-       ia64_stop();                            \
-       ia64_rsm(IA64_PSR_I);                   \
- } while (0)
-@@ -173,7 +173,7 @@
- #endif /* !CONFIG_IA64_DEBUG_IRQ */
- #define local_irq_enable()    ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
--#define local_save_flags(flags)       ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); })
-+#define local_save_flags(flags)       ({ ia64_stop(); (flags) = ia64_get_psr_i(); })
- #define irqs_disabled()                               \
- ({                                            \
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/uaccess.h linux-2.6.16.33/include/asm-ia64/uaccess.h
---- linux-2.6.16.33-noxen/include/asm-ia64/uaccess.h   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/uaccess.h 2007-01-08 15:00:46.000000000 +0000
-@@ -365,6 +365,7 @@
- }
- #define ARCH_HAS_TRANSLATE_MEM_PTR    1
-+#ifndef CONFIG_XEN
- static __inline__ char *
- xlate_dev_mem_ptr (unsigned long p)
- {
-@@ -379,6 +380,25 @@
-       return ptr;
- }
-+#else
-+static __inline__ char *
-+xlate_dev_mem_ptr (unsigned long p, ssize_t sz)
-+{
-+      unsigned long pfn = p >> PAGE_SHIFT;
-+
-+      if (pfn_valid(pfn) && !PageUncached(pfn_to_page(pfn)))
-+              return __va(p);
-+
-+      return ioremap(p, sz);
-+}
-+
-+static __inline__ void
-+xlate_dev_mem_ptr_unmap (char* v)
-+{
-+      if (REGION_NUMBER(v) == RGN_UNCACHED)
-+              iounmap(v);
-+}
-+#endif
- /*
-  * Convert a virtual cached kernel memory pointer to an uncached pointer
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/xen/privop.h linux-2.6.16.33/include/asm-ia64/xen/privop.h
---- linux-2.6.16.33-noxen/include/asm-ia64/xen/privop.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/xen/privop.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,303 @@
-+#ifndef _ASM_IA64_XEN_PRIVOP_H
-+#define _ASM_IA64_XEN_PRIVOP_H
-+
-+/*
-+ * Copyright (C) 2005 Hewlett-Packard Co
-+ *    Dan Magenheimer <dan.magenheimer@hp.com>
-+ *
-+ * Paravirtualizations of privileged operations for Xen/ia64
-+ *
-+ */
-+
-+
-+#include <xen/interface/arch-ia64.h>
-+
-+#define IA64_PARAVIRTUALIZED
-+
-+/* At 1 MB, before per-cpu space but still addressable using addl instead
-+   of movl. */
-+#define XSI_BASE                              0xfffffffffff00000
-+
-+/* Address of mapped regs.  */
-+#define XMAPPEDREGS_BASE              (XSI_BASE + XSI_SIZE)
-+
-+#ifdef __ASSEMBLY__
-+#define       XEN_HYPER_RFI                   break HYPERPRIVOP_RFI
-+#define       XEN_HYPER_RSM_PSR_DT            break HYPERPRIVOP_RSM_DT
-+#define       XEN_HYPER_SSM_PSR_DT            break HYPERPRIVOP_SSM_DT
-+#define       XEN_HYPER_COVER                 break HYPERPRIVOP_COVER
-+#define       XEN_HYPER_ITC_D                 break HYPERPRIVOP_ITC_D
-+#define       XEN_HYPER_ITC_I                 break HYPERPRIVOP_ITC_I
-+#define       XEN_HYPER_SSM_I                 break HYPERPRIVOP_SSM_I
-+#define       XEN_HYPER_GET_IVR               break HYPERPRIVOP_GET_IVR
-+#define       XEN_HYPER_GET_TPR               break HYPERPRIVOP_GET_TPR
-+#define       XEN_HYPER_SET_TPR               break HYPERPRIVOP_SET_TPR
-+#define       XEN_HYPER_EOI                   break HYPERPRIVOP_EOI
-+#define       XEN_HYPER_SET_ITM               break HYPERPRIVOP_SET_ITM
-+#define       XEN_HYPER_THASH                 break HYPERPRIVOP_THASH
-+#define       XEN_HYPER_PTC_GA                break HYPERPRIVOP_PTC_GA
-+#define       XEN_HYPER_ITR_D                 break HYPERPRIVOP_ITR_D
-+#define       XEN_HYPER_GET_RR                break HYPERPRIVOP_GET_RR
-+#define       XEN_HYPER_SET_RR                break HYPERPRIVOP_SET_RR
-+#define       XEN_HYPER_SET_KR                break HYPERPRIVOP_SET_KR
-+#define       XEN_HYPER_FC                    break HYPERPRIVOP_FC
-+#define       XEN_HYPER_GET_CPUID             break HYPERPRIVOP_GET_CPUID
-+#define       XEN_HYPER_GET_PMD               break HYPERPRIVOP_GET_PMD
-+#define       XEN_HYPER_GET_EFLAG             break HYPERPRIVOP_GET_EFLAG
-+#define       XEN_HYPER_SET_EFLAG             break HYPERPRIVOP_SET_EFLAG
-+#define       XEN_HYPER_RSM_BE                break HYPERPRIVOP_RSM_BE
-+#define       XEN_HYPER_GET_PSR               break HYPERPRIVOP_GET_PSR
-+
-+#define XSI_IFS                       (XSI_BASE + XSI_IFS_OFS)
-+#define XSI_PRECOVER_IFS      (XSI_BASE + XSI_PRECOVER_IFS_OFS)
-+#define XSI_INCOMPL_REGFR     (XSI_BASE + XSI_INCOMPL_REGFR_OFS)
-+#define XSI_IFA                       (XSI_BASE + XSI_IFA_OFS)
-+#define XSI_ISR                       (XSI_BASE + XSI_ISR_OFS)
-+#define XSI_IIM                       (XSI_BASE + XSI_IIM_OFS)
-+#define XSI_ITIR              (XSI_BASE + XSI_ITIR_OFS)
-+#define XSI_PSR_I_ADDR                (XSI_BASE + XSI_PSR_I_ADDR_OFS)
-+#define XSI_PSR_IC            (XSI_BASE + XSI_PSR_IC_OFS)
-+#define XSI_IPSR              (XSI_BASE + XSI_IPSR_OFS)
-+#define XSI_IIP                       (XSI_BASE + XSI_IIP_OFS)
-+#define XSI_BANK1_R16         (XSI_BASE + XSI_BANK1_R16_OFS)
-+#define XSI_BANKNUM           (XSI_BASE + XSI_BANKNUM_OFS)
-+#define XSI_IHA                       (XSI_BASE + XSI_IHA_OFS)
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+#define       XEN_HYPER_SSM_I         asm("break %0" : : "i" (HYPERPRIVOP_SSM_I))
-+#define       XEN_HYPER_GET_IVR       asm("break %0" : : "i" (HYPERPRIVOP_GET_IVR))
-+
-+/************************************************/
-+/* Instructions paravirtualized for correctness */
-+/************************************************/
-+
-+/* "fc" and "thash" are privilege-sensitive instructions, meaning they
-+ *  may have different semantics depending on whether they are executed
-+ *  at PL0 vs PL!=0.  When paravirtualized, these instructions mustn't
-+ *  be allowed to execute directly, lest incorrect semantics result. */
-+extern unsigned long xen_fc(unsigned long addr);
-+#define ia64_fc(addr)                 xen_fc((unsigned long)(addr))
-+extern unsigned long xen_thash(unsigned long addr);
-+#define ia64_thash(addr)              xen_thash((unsigned long)(addr))
-+/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
-+ * is not currently used (though it may be in a long-format VHPT system!)
-+ * and the semantics of cover only change if psr.ic is off which is very
-+ * rare (and currently non-existent outside of assembly code */
-+
-+/* There are also privilege-sensitive registers.  These registers are
-+ * readable at any privilege level but only writable at PL0. */
-+extern unsigned long xen_get_cpuid(int index);
-+#define       ia64_get_cpuid(i)               xen_get_cpuid(i)
-+extern unsigned long xen_get_pmd(int index);
-+#define       ia64_get_pmd(i)                 xen_get_pmd(i)
-+extern unsigned long xen_get_eflag(void);     /* see xen_ia64_getreg */
-+extern void xen_set_eflag(unsigned long);     /* see xen_ia64_setreg */
-+
-+/************************************************/
-+/* Instructions paravirtualized for performance */
-+/************************************************/
-+
-+/* Xen uses memory-mapped virtual privileged registers for access to many
-+ * performance-sensitive privileged registers.  Some, like the processor
-+ * status register (psr), are broken up into multiple memory locations.
-+ * Others, like "pend", are abstractions based on privileged registers.
-+ * "Pend" is guaranteed to be set if reading cr.ivr would return a
-+ * (non-spurious) interrupt. */
-+#define XEN_MAPPEDREGS ((struct mapped_regs *)XMAPPEDREGS_BASE)
-+#define XSI_PSR_I                     \
-+      (*XEN_MAPPEDREGS->interrupt_mask_addr)
-+#define xen_get_virtual_psr_i()               \
-+      (!XSI_PSR_I)
-+#define xen_set_virtual_psr_i(_val)   \
-+      ({ XSI_PSR_I = (uint8_t)(_val) ? 0 : 1; })
-+#define xen_set_virtual_psr_ic(_val)  \
-+      ({ XEN_MAPPEDREGS->interrupt_collection_enabled = _val ? 1 : 0; })
-+#define xen_get_virtual_pend()                \
-+      (*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1))
-+
-+/* Hyperprivops are "break" instructions with a well-defined API.
-+ * In particular, the virtual psr.ic bit must be off; in this way
-+ * it is guaranteed to never conflict with a linux break instruction.
-+ * Normally, this is done in a xen stub but this one is frequent enough
-+ * that we inline it */
-+#define xen_hyper_ssm_i()                                             \
-+({                                                                    \
-+      xen_set_virtual_psr_i(0);                                       \
-+      xen_set_virtual_psr_ic(0);                                      \
-+      XEN_HYPER_SSM_I;                                                \
-+})
-+
-+/* turning off interrupts can be paravirtualized simply by writing
-+ * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */
-+#define xen_rsm_i()   xen_set_virtual_psr_i(0)
-+
-+/* turning on interrupts is a bit more complicated.. write to the
-+ * memory-mapped virtual psr.i bit first (to avoid race condition),
-+ * then if any interrupts were pending, we have to execute a hyperprivop
-+ * to ensure the pending interrupt gets delivered; else we're done! */
-+#define xen_ssm_i()                                                   \
-+({                                                                    \
-+      int old = xen_get_virtual_psr_i();                              \
-+      xen_set_virtual_psr_i(1);                                       \
-+      if (!old && xen_get_virtual_pend()) xen_hyper_ssm_i();          \
-+})
-+
-+#define xen_ia64_intrin_local_irq_restore(x)                          \
-+{                                                                     \
-+     if (is_running_on_xen()) {                                               \
-+      if ((x) & IA64_PSR_I) { xen_ssm_i(); }                          \
-+      else { xen_rsm_i(); }                                           \
-+    }                                                                 \
-+    else __ia64_intrin_local_irq_restore((x));                                \
-+}
-+
-+#define       xen_get_psr_i()                                                 \
-+(                                                                     \
-+      (is_running_on_xen()) ?                                         \
-+              (xen_get_virtual_psr_i() ? IA64_PSR_I : 0)              \
-+              : __ia64_get_psr_i()                                    \
-+)
-+
-+#define xen_ia64_ssm(mask)                                            \
-+{                                                                     \
-+      if ((mask)==IA64_PSR_I) {                                       \
-+              if (is_running_on_xen()) { xen_ssm_i(); }                       \
-+              else { __ia64_ssm(mask); }                              \
-+      }                                                               \
-+      else { __ia64_ssm(mask); }                                      \
-+}
-+
-+#define xen_ia64_rsm(mask)                                            \
-+{                                                                     \
-+      if ((mask)==IA64_PSR_I) {                                       \
-+              if (is_running_on_xen()) { xen_rsm_i(); }                       \
-+              else { __ia64_rsm(mask); }                              \
-+      }                                                               \
-+      else { __ia64_rsm(mask); }                                      \
-+}
-+
-+
-+/* Although all privileged operations can be left to trap and will
-+ * be properly handled by Xen, some are frequent enough that we use
-+ * hyperprivops for performance. */
-+
-+extern unsigned long xen_get_ivr(void);
-+extern unsigned long xen_get_tpr(void);
-+extern void xen_set_itm(unsigned long);
-+extern void xen_set_tpr(unsigned long);
-+extern void xen_eoi(void);
-+extern void xen_set_rr(unsigned long index, unsigned long val);
-+extern unsigned long xen_get_rr(unsigned long index);
-+extern void xen_set_kr(unsigned long index, unsigned long val);
-+extern void xen_ptcga(unsigned long addr, unsigned long size);
-+
-+/* Note: It may look wrong to test for is_running_on_xen() in each case.
-+ * However regnum is always a constant so, as written, the compiler
-+ * eliminates the switch statement, whereas is_running_on_xen() must be
-+ * tested dynamically. */
-+#define xen_ia64_getreg(regnum)                                               \
-+({                                                                    \
-+      __u64 ia64_intri_res;                                           \
-+                                                                      \
-+      switch(regnum) {                                                \
-+      case _IA64_REG_CR_IVR:                                          \
-+              ia64_intri_res = (is_running_on_xen()) ?                        \
-+                      xen_get_ivr() :                                 \
-+                      __ia64_getreg(regnum);                          \
-+              break;                                                  \
-+      case _IA64_REG_CR_TPR:                                          \
-+              ia64_intri_res = (is_running_on_xen()) ?                        \
-+                      xen_get_tpr() :                                 \
-+                      __ia64_getreg(regnum);                          \
-+              break;                                                  \
-+      case _IA64_REG_AR_EFLAG:                                        \
-+              ia64_intri_res = (is_running_on_xen()) ?                        \
-+                      xen_get_eflag() :                               \
-+                      __ia64_getreg(regnum);                          \
-+              break;                                                  \
-+      default:                                                        \
-+              ia64_intri_res = __ia64_getreg(regnum);                 \
-+              break;                                                  \
-+      }                                                               \
-+      ia64_intri_res;                                                 \
-+})
-+
-+#define xen_ia64_setreg(regnum,val)                                   \
-+({                                                                    \
-+      switch(regnum) {                                                \
-+      case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:                     \
-+              (is_running_on_xen()) ?                                 \
-+                      xen_set_kr((regnum-_IA64_REG_AR_KR0), val) :    \
-+                      __ia64_setreg(regnum,val);                      \
-+              break;                                                  \
-+      case _IA64_REG_CR_ITM:                                          \
-+              (is_running_on_xen()) ?                                 \
-+                      xen_set_itm(val) :                              \
-+                      __ia64_setreg(regnum,val);                      \
-+              break;                                                  \
-+      case _IA64_REG_CR_TPR:                                          \
-+              (is_running_on_xen()) ?                                 \
-+                      xen_set_tpr(val) :                              \
-+                      __ia64_setreg(regnum,val);                      \
-+              break;                                                  \
-+      case _IA64_REG_CR_EOI:                                          \
-+              (is_running_on_xen()) ?                                 \
-+                      xen_eoi() :                                     \
-+                      __ia64_setreg(regnum,val);                      \
-+              break;                                                  \
-+      case _IA64_REG_AR_EFLAG:                                        \
-+              (is_running_on_xen()) ?                                 \
-+                      xen_set_eflag(val) :                            \
-+                      __ia64_setreg(regnum,val);                      \
-+              break;                                                  \
-+      default:                                                        \
-+              __ia64_setreg(regnum,val);                              \
-+              break;                                                  \
-+      }                                                               \
-+})
-+
-+#define ia64_ssm                      xen_ia64_ssm
-+#define ia64_rsm                      xen_ia64_rsm
-+#define ia64_intrin_local_irq_restore xen_ia64_intrin_local_irq_restore
-+#define       ia64_ptcga                      xen_ptcga
-+#define       ia64_set_rr(index,val)          xen_set_rr(index,val)
-+#define       ia64_get_rr(index)              xen_get_rr(index)
-+#define ia64_getreg                   xen_ia64_getreg
-+#define ia64_setreg                   xen_ia64_setreg
-+#define       ia64_get_psr_i                  xen_get_psr_i
-+
-+/* the remainder of these are not performance-sensitive so its
-+ * OK to not paravirtualize and just take a privop trap and emulate */
-+#define ia64_hint                     __ia64_hint
-+#define ia64_set_pmd                  __ia64_set_pmd
-+#define ia64_itci                     __ia64_itci
-+#define ia64_itcd                     __ia64_itcd
-+#define ia64_itri                     __ia64_itri
-+#define ia64_itrd                     __ia64_itrd
-+#define ia64_tpa                      __ia64_tpa
-+#define ia64_set_ibr                  __ia64_set_ibr
-+#define ia64_set_pkr                  __ia64_set_pkr
-+#define ia64_set_pmc                  __ia64_set_pmc
-+#define ia64_get_ibr                  __ia64_get_ibr
-+#define ia64_get_pkr                  __ia64_get_pkr
-+#define ia64_get_pmc                  __ia64_get_pmc
-+#define ia64_ptce                     __ia64_ptce
-+#define ia64_ptcl                     __ia64_ptcl
-+#define ia64_ptri                     __ia64_ptri
-+#define ia64_ptrd                     __ia64_ptrd
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+/* these routines utilize privilege-sensitive or performance-sensitive
-+ * privileged instructions so the code must be replaced with
-+ * paravirtualized versions */
-+#define ia64_pal_halt_light           xen_pal_halt_light
-+#define       ia64_leave_kernel               xen_leave_kernel
-+#define       ia64_leave_syscall              xen_leave_syscall
-+#define       ia64_trace_syscall              xen_trace_syscall
-+#define       ia64_ret_from_clone             xen_ret_from_clone
-+#define       ia64_switch_to                  xen_switch_to
-+#define       ia64_pal_call_static            xen_pal_call_static
-+
-+#endif /* _ASM_IA64_XEN_PRIVOP_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/xen/xcom_hcall.h linux-2.6.16.33/include/asm-ia64/xen/xcom_hcall.h
---- linux-2.6.16.33-noxen/include/asm-ia64/xen/xcom_hcall.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/xen/xcom_hcall.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,86 @@
-+/*
-+ * Copyright (C) 2006 Tristan Gingold <tristan.gingold@bull.net>, Bull SAS
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ * 
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ * 
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-+ */
-+
-+#ifndef _LINUX_XENCOMM_HCALL_H_
-+#define _LINUX_XENCOMM_HCALL_H_
-+
-+/* These function creates inline descriptor for the parameters and
-+   calls the corresponding xencomm_arch_hypercall_X.
-+   Architectures should defines HYPERVISOR_xxx as xencomm_hypercall_xxx unless
-+   they want to use their own wrapper.  */
-+extern int xencomm_hypercall_console_io(int cmd, int count, char *str);
-+
-+extern int xencomm_hypercall_event_channel_op(int cmd, void *op);
-+
-+extern int xencomm_hypercall_xen_version(int cmd, void *arg);
-+
-+extern int xencomm_hypercall_physdev_op(int cmd, void *op);
-+
-+extern int xencomm_hypercall_grant_table_op(unsigned int cmd, void *op,
-+                                            unsigned int count);
-+
-+extern int xencomm_hypercall_sched_op(int cmd, void *arg);
-+
-+extern int xencomm_hypercall_multicall(void *call_list, int nr_calls);
-+
-+extern int xencomm_hypercall_callback_op(int cmd, void *arg);
-+
-+extern int xencomm_hypercall_memory_op(unsigned int cmd, void *arg);
-+
-+extern unsigned long xencomm_hypercall_hvm_op(int cmd, void *arg);
-+
-+extern int xencomm_hypercall_suspend(unsigned long srec);
-+
-+extern int xencomm_hypercall_xenoprof_op(int op, void *arg);
-+
-+extern int xencomm_hypercall_perfmon_op(unsigned long cmd, void* arg,
-+                                        unsigned long count);
-+
-+/* Using mini xencomm.  */
-+extern int xencomm_mini_hypercall_console_io(int cmd, int count, char *str);
-+
-+extern int xencomm_mini_hypercall_event_channel_op(int cmd, void *op);
-+
-+extern int xencomm_mini_hypercall_xen_version(int cmd, void *arg);
-+
-+extern int xencomm_mini_hypercall_physdev_op(int cmd, void *op);
-+
-+extern int xencomm_mini_hypercall_grant_table_op(unsigned int cmd, void *op,
-+                                                 unsigned int count);
-+
-+extern int xencomm_mini_hypercall_sched_op(int cmd, void *arg);
-+
-+extern int xencomm_mini_hypercall_multicall(void *call_list, int nr_calls);
-+
-+extern int xencomm_mini_hypercall_callback_op(int cmd, void *arg);
-+
-+extern int xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg);
-+
-+extern unsigned long xencomm_mini_hypercall_hvm_op(int cmd, void *arg);
-+
-+extern int xencomm_mini_hypercall_xenoprof_op(int op, void *arg);
-+
-+extern int xencomm_mini_hypercall_perfmon_op(unsigned long cmd, void* arg,
-+                                             unsigned long count);
-+
-+/* For privcmd.  Locally declare argument type to avoid include storm.
-+   Type coherency will be checked within privcmd.c  */
-+struct privcmd_hypercall;
-+extern int privcmd_hypercall(struct privcmd_hypercall *hypercall);
-+
-+#endif /* _LINUX_XENCOMM_HCALL_H_ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/xen/xencomm.h linux-2.6.16.33/include/asm-ia64/xen/xencomm.h
---- linux-2.6.16.33-noxen/include/asm-ia64/xen/xencomm.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/xen/xencomm.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright (C) 2006 Hollis Blanchard <hollisb@us.ibm.com>, IBM Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ * 
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ * 
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-+ */
-+
-+#ifndef _LINUX_XENCOMM_H_
-+#define _LINUX_XENCOMM_H_
-+
-+#include <xen/interface/xencomm.h>
-+
-+#define XENCOMM_MINI_ADDRS 3
-+struct xencomm_mini {
-+      struct xencomm_desc _desc;
-+      uint64_t address[XENCOMM_MINI_ADDRS];
-+};
-+
-+/* Must be called before any hypercall.  */
-+extern void xencomm_init (void);
-+
-+/* To avoid additionnal virt to phys conversion, an opaque structure is
-+   presented.  */
-+struct xencomm_handle;
-+
-+extern int xencomm_create(void *buffer, unsigned long bytes,
-+                          struct xencomm_handle **desc, gfp_t type);
-+extern void xencomm_free(struct xencomm_handle *desc);
-+
-+extern int xencomm_create_mini(struct xencomm_mini *area, int *nbr_area,
-+                               void *buffer, unsigned long bytes,
-+                               struct xencomm_handle **ret);
-+
-+/* Translate virtual address to physical address.  */
-+extern unsigned long xencomm_vaddr_to_paddr(unsigned long vaddr);
-+
-+/* Inline version.  To be used only on linear space (kernel space).  */
-+static inline struct xencomm_handle *
-+xencomm_create_inline(void *buffer)
-+{
-+      unsigned long paddr;
-+
-+      paddr = xencomm_vaddr_to_paddr((unsigned long)buffer);
-+      return (struct xencomm_handle *)(paddr | XENCOMM_INLINE_FLAG);
-+}
-+
-+#define xen_guest_handle(hnd)  ((hnd).p)
-+
-+#endif /* _LINUX_XENCOMM_H_ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-ia64/xenoprof.h linux-2.6.16.33/include/asm-ia64/xenoprof.h
---- linux-2.6.16.33-noxen/include/asm-ia64/xenoprof.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-ia64/xenoprof.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,48 @@
-+/******************************************************************************
-+ * asm-ia64/xenoprof.h
-+ *
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+#ifndef __ASM_XENOPROF_H__
-+#define __ASM_XENOPROF_H__
-+#ifdef CONFIG_XEN
-+
-+#undef HAVE_XENOPROF_CREATE_FILES
-+
-+struct xenoprof_init;
-+void xenoprof_arch_init_counter(struct xenoprof_init *init);
-+void xenoprof_arch_counter(void);
-+void xenoprof_arch_start(void);
-+void xenoprof_arch_stop(void);
-+
-+struct xenoprof_arch_shared_buffer {
-+      struct resource*        res;
-+};
-+
-+struct xenoprof_shared_buffer;
-+void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer* sbuf);
-+struct xenoprof_get_buffer;
-+int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer* get_buffer,
-+                                    struct xenoprof_shared_buffer* sbuf);
-+struct xenoprof_passive;
-+int xenoprof_arch_set_passive(struct xenoprof_passive* pdomain,
-+                              struct xenoprof_shared_buffer* sbuf);
-+
-+#endif /* CONFIG_XEN */
-+#endif /* __ASM_XENOPROF_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-um/page.h linux-2.6.16.33/include/asm-um/page.h
---- linux-2.6.16.33-noxen/include/asm-um/page.h        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-um/page.h      2007-01-08 15:00:46.000000000 +0000
-@@ -118,7 +118,7 @@
- extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
- #define HAVE_ARCH_VALIDATE
--extern void arch_free_page(struct page *page, int order);
-+extern int arch_free_page(struct page *page, int order);
- #define HAVE_ARCH_FREE_PAGE
- #include <asm-generic/page.h>
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/apic.h linux-2.6.16.33/include/asm-x86_64/apic.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/apic.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/apic.h  2007-01-08 15:00:46.000000000 +0000
-@@ -105,11 +105,13 @@
- extern void setup_threshold_lvt(unsigned long lvt_off);
-+#ifndef CONFIG_XEN
- void smp_send_timer_broadcast_ipi(void);
- void switch_APIC_timer_to_ipi(void *cpumask);
- void switch_ipi_to_APIC_timer(void *cpumask);
- #define ARCH_APICTIMER_STOPS_ON_C3    1
-+#endif
- #endif /* CONFIG_X86_LOCAL_APIC */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/hw_irq.h linux-2.6.16.33/include/asm-x86_64/hw_irq.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/hw_irq.h  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/hw_irq.h        2007-05-23 21:00:01.000000000 +0000
-@@ -127,7 +127,7 @@
- __asm__( \
- "\n.p2align\n" \
- "IRQ" #nr "_interrupt:\n\t" \
--      "push $" #nr "-256 ; " \
-+      "push $~(" #nr ") ; " \
-       "jmp common_interrupt");
- #if defined(CONFIG_X86_IO_APIC)
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/kexec.h linux-2.6.16.33/include/asm-x86_64/kexec.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/kexec.h   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/kexec.h 2007-01-08 15:00:46.000000000 +0000
-@@ -1,6 +1,27 @@
- #ifndef _X86_64_KEXEC_H
- #define _X86_64_KEXEC_H
-+#define PA_CONTROL_PAGE  0
-+#define VA_CONTROL_PAGE  1
-+#define PA_PGD           2
-+#define VA_PGD           3
-+#define PA_PUD_0         4
-+#define VA_PUD_0         5
-+#define PA_PMD_0         6
-+#define VA_PMD_0         7
-+#define PA_PTE_0         8
-+#define VA_PTE_0         9
-+#define PA_PUD_1         10
-+#define VA_PUD_1         11
-+#define PA_PMD_1         12
-+#define VA_PMD_1         13
-+#define PA_PTE_1         14
-+#define VA_PTE_1         15
-+#define PA_TABLE_PAGE    16
-+#define PAGES_NR         17
-+
-+#ifndef __ASSEMBLY__
-+
- #include <linux/string.h>
- #include <asm/page.h>
-@@ -64,4 +85,25 @@
-               newregs->rip = (unsigned long)current_text_addr();
-       }
- }
-+
-+NORET_TYPE void
-+relocate_kernel(unsigned long indirection_page,
-+              unsigned long page_list,
-+              unsigned long start_address) ATTRIB_NORET;
-+
-+/* Under Xen we need to work with machine addresses. These macros give the
-+ * machine address of a certain page to the generic kexec code instead of 
-+ * the pseudo physical address which would be given by the default macros.
-+ */
-+
-+#ifdef CONFIG_XEN
-+#define KEXEC_ARCH_HAS_PAGE_MACROS
-+#define kexec_page_to_pfn(page)  pfn_to_mfn(page_to_pfn(page))
-+#define kexec_pfn_to_page(pfn)   pfn_to_page(mfn_to_pfn(pfn))
-+#define kexec_virt_to_phys(addr) virt_to_machine(addr)
-+#define kexec_phys_to_virt(addr) phys_to_virt(machine_to_phys(addr))
-+#endif
-+
-+#endif /* __ASSEMBLY__ */
-+
- #endif /* _X86_64_KEXEC_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/agp.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/agp.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/agp.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/agp.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,35 @@
-+#ifndef AGP_H
-+#define AGP_H 1
-+
-+#include <asm/cacheflush.h>
-+#include <asm/system.h>
-+
-+/*
-+ * Functions to keep the agpgart mappings coherent.
-+ * The GART gives the CPU a physical alias of memory. The alias is
-+ * mapped uncacheable. Make sure there are no conflicting mappings
-+ * with different cachability attributes for the same page.
-+ */
-+
-+int map_page_into_agp(struct page *page);
-+int unmap_page_from_agp(struct page *page);
-+#define flush_agp_mappings() global_flush_tlb()
-+
-+/* Could use CLFLUSH here if the cpu supports it. But then it would
-+   need to be called for each cacheline of the whole page so it may not be
-+   worth it. Would need a page for it. */
-+#define flush_agp_cache() wbinvd()
-+
-+/* Convert a physical address to an address suitable for the GART. */
-+#define phys_to_gart(x) phys_to_machine(x)
-+#define gart_to_phys(x) machine_to_phys(x)
-+
-+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
-+#define alloc_gatt_pages(order)       ({                                          \
-+      char *_t; dma_addr_t _d;                                            \
-+      _t = dma_alloc_coherent(NULL,PAGE_SIZE<<(order),&_d,GFP_KERNEL);    \
-+      _t; })
-+#define free_gatt_pages(table, order) \
-+      dma_free_coherent(NULL,PAGE_SIZE<<(order),(table),virt_to_bus(table))
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/arch_hooks.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/arch_hooks.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/arch_hooks.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/arch_hooks.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,27 @@
-+#ifndef _ASM_ARCH_HOOKS_H
-+#define _ASM_ARCH_HOOKS_H
-+
-+#include <linux/interrupt.h>
-+
-+/*
-+ *    linux/include/asm/arch_hooks.h
-+ *
-+ *    define the architecture specific hooks 
-+ */
-+
-+/* these aren't arch hooks, they are generic routines
-+ * that can be used by the hooks */
-+extern void init_ISA_irqs(void);
-+extern void apic_intr_init(void);
-+extern void smp_intr_init(void);
-+extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-+
-+/* these are the defined hooks */
-+extern void intr_init_hook(void);
-+extern void pre_intr_init_hook(void);
-+extern void pre_setup_arch_hook(void);
-+extern void trap_init_hook(void);
-+extern void time_init_hook(void);
-+extern void mca_nmi_hook(void);
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/bootsetup.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/bootsetup.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/bootsetup.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/bootsetup.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,42 @@
-+
-+#ifndef _X86_64_BOOTSETUP_H
-+#define _X86_64_BOOTSETUP_H 1
-+
-+#define BOOT_PARAM_SIZE               4096
-+extern char x86_boot_params[BOOT_PARAM_SIZE];
-+
-+/*
-+ * This is set up by the setup-routine at boot-time
-+ */
-+#define PARAM ((unsigned char *)x86_boot_params)
-+#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
-+#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
-+#define ALT_MEM_K (*(unsigned int *) (PARAM+0x1e0))
-+#define E820_MAP_NR (*(char*) (PARAM+E820NR))
-+#define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
-+#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
-+#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
-+#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
-+#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
-+#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
-+#define SAVED_VIDEO_MODE (*(unsigned short *) (PARAM+0x1FA))
-+#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
-+#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
-+#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
-+#define KERNEL_START (*(unsigned int *) (PARAM+0x214))
-+
-+#define INITRD_START (__pa(xen_start_info->mod_start))
-+#define INITRD_SIZE (xen_start_info->mod_len)
-+#define EDID_INFO   (*(struct edid_info *) (PARAM+0x440))
-+
-+#define EDD_NR     (*(unsigned char *) (PARAM+EDDNR))
-+#define EDD_MBR_SIG_NR (*(unsigned char *) (PARAM+EDD_MBR_SIG_NR_BUF))
-+#define EDD_MBR_SIGNATURE ((unsigned int *) (PARAM+EDD_MBR_SIG_BUF))
-+#define EDD_BUF     ((struct edd_info *) (PARAM+EDDBUF))
-+#define COMMAND_LINE saved_command_line
-+
-+#define RAMDISK_IMAGE_START_MASK      0x07FF
-+#define RAMDISK_PROMPT_FLAG           0x8000
-+#define RAMDISK_LOAD_FLAG             0x4000  
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/desc.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/desc.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/desc.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/desc.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,263 @@
-+/* Written 2000 by Andi Kleen */ 
-+#ifndef __ARCH_DESC_H
-+#define __ARCH_DESC_H
-+
-+#include <linux/threads.h>
-+#include <asm/ldt.h>
-+
-+#ifndef __ASSEMBLY__
-+
-+#include <linux/string.h>
-+#include <linux/smp.h>
-+
-+#include <asm/segment.h>
-+#include <asm/mmu.h>
-+
-+// 8 byte segment descriptor
-+struct desc_struct { 
-+      u16 limit0;
-+      u16 base0;
-+      unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1;
-+      unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 : 8;
-+} __attribute__((packed)); 
-+
-+struct n_desc_struct { 
-+      unsigned int a,b;
-+};    
-+
-+enum { 
-+      GATE_INTERRUPT = 0xE, 
-+      GATE_TRAP = 0xF,        
-+      GATE_CALL = 0xC,
-+};    
-+
-+// 16byte gate
-+struct gate_struct {          
-+      u16 offset_low;
-+      u16 segment; 
-+      unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
-+      u16 offset_middle;
-+      u32 offset_high;
-+      u32 zero1; 
-+} __attribute__((packed));
-+
-+#define PTR_LOW(x) ((unsigned long)(x) & 0xFFFF) 
-+#define PTR_MIDDLE(x) (((unsigned long)(x) >> 16) & 0xFFFF)
-+#define PTR_HIGH(x) ((unsigned long)(x) >> 32)
-+
-+enum { 
-+      DESC_TSS = 0x9,
-+      DESC_LDT = 0x2,
-+}; 
-+
-+// LDT or TSS descriptor in the GDT. 16 bytes.
-+struct ldttss_desc { 
-+      u16 limit0;
-+      u16 base0;
-+      unsigned base1 : 8, type : 5, dpl : 2, p : 1;
-+      unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8;
-+      u32 base3;
-+      u32 zero1; 
-+} __attribute__((packed)); 
-+
-+struct desc_ptr {
-+      unsigned short size;
-+      unsigned long address;
-+} __attribute__((packed)) ;
-+
-+extern struct desc_ptr idt_descr, cpu_gdt_descr[NR_CPUS];
-+
-+extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
-+
-+#define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8))
-+#define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
-+
-+static inline void clear_LDT(void)
-+{
-+      int cpu = get_cpu();
-+
-+      /*
-+       * NB. We load the default_ldt for lcall7/27 handling on demand, as
-+       * it slows down context switching. Noone uses it anyway.
-+       */
-+      cpu = cpu;              /* XXX avoid compiler warning */
-+      xen_set_ldt(0UL, 0);
-+      put_cpu();
-+}
-+
-+/*
-+ * This is the ldt that every process will get unless we need
-+ * something other than this.
-+ */
-+extern struct desc_struct default_ldt[];
-+#ifndef CONFIG_X86_NO_IDT
-+extern struct gate_struct idt_table[]; 
-+#endif
-+extern struct desc_ptr cpu_gdt_descr[];
-+
-+/* the cpu gdt accessor */
-+#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
-+
-+static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
-+{
-+      struct gate_struct s;   
-+      s.offset_low = PTR_LOW(func); 
-+      s.segment = __KERNEL_CS;
-+      s.ist = ist; 
-+      s.p = 1;
-+      s.dpl = dpl; 
-+      s.zero0 = 0;
-+      s.zero1 = 0; 
-+      s.type = type; 
-+      s.offset_middle = PTR_MIDDLE(func); 
-+      s.offset_high = PTR_HIGH(func); 
-+      /* does not need to be atomic because it is only done once at setup time */ 
-+      memcpy(adr, &s, 16); 
-+} 
-+
-+#ifndef CONFIG_X86_NO_IDT
-+static inline void set_intr_gate(int nr, void *func) 
-+{ 
-+      BUG_ON((unsigned)nr > 0xFF);
-+      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, 0); 
-+} 
-+
-+static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) 
-+{ 
-+      BUG_ON((unsigned)nr > 0xFF);
-+      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, ist); 
-+} 
-+
-+static inline void set_system_gate(int nr, void *func) 
-+{ 
-+      BUG_ON((unsigned)nr > 0xFF);
-+      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); 
-+} 
-+
-+static inline void set_system_gate_ist(int nr, void *func, unsigned ist)
-+{
-+      _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
-+}
-+#endif
-+
-+static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, 
-+                                       unsigned size) 
-+{ 
-+      struct ldttss_desc d;
-+      memset(&d,0,sizeof(d)); 
-+      d.limit0 = size & 0xFFFF;
-+      d.base0 = PTR_LOW(tss); 
-+      d.base1 = PTR_MIDDLE(tss) & 0xFF; 
-+      d.type = type;
-+      d.p = 1; 
-+      d.limit1 = (size >> 16) & 0xF;
-+      d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; 
-+      d.base3 = PTR_HIGH(tss); 
-+      memcpy(ptr, &d, 16); 
-+}
-+
-+#ifndef CONFIG_X86_NO_TSS
-+static inline void set_tss_desc(unsigned cpu, void *addr)
-+{ 
-+      /*
-+       * sizeof(unsigned long) coming from an extra "long" at the end
-+       * of the iobitmap. See tss_struct definition in processor.h
-+       *
-+       * -1? seg base+limit should be pointing to the address of the
-+       * last valid byte
-+       */
-+      set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_TSS], 
-+              (unsigned long)addr, DESC_TSS,
-+              IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1);
-+} 
-+#endif
-+
-+static inline void set_ldt_desc(unsigned cpu, void *addr, int size)
-+{ 
-+      set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_LDT], (unsigned long)addr,
-+                            DESC_LDT, size * 8 - 1);
-+}
-+
-+static inline void set_seg_base(unsigned cpu, int entry, void *base)
-+{ 
-+      struct desc_struct *d = &cpu_gdt(cpu)[entry];
-+      u32 addr = (u32)(u64)base;
-+      BUG_ON((u64)base >> 32); 
-+      d->base0 = addr & 0xffff;
-+      d->base1 = (addr >> 16) & 0xff;
-+      d->base2 = (addr >> 24) & 0xff;
-+} 
-+
-+#define LDT_entry_a(info) \
-+      ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
-+/* Don't allow setting of the lm bit. It is useless anyways because 
-+   64bit system calls require __USER_CS. */ 
-+#define LDT_entry_b(info) \
-+      (((info)->base_addr & 0xff000000) | \
-+      (((info)->base_addr & 0x00ff0000) >> 16) | \
-+      ((info)->limit & 0xf0000) | \
-+      (((info)->read_exec_only ^ 1) << 9) | \
-+      ((info)->contents << 10) | \
-+      (((info)->seg_not_present ^ 1) << 15) | \
-+      ((info)->seg_32bit << 22) | \
-+      ((info)->limit_in_pages << 23) | \
-+      ((info)->useable << 20) | \
-+      /* ((info)->lm << 21) | */ \
-+      0x7000)
-+
-+#define LDT_empty(info) (\
-+      (info)->base_addr       == 0    && \
-+      (info)->limit           == 0    && \
-+      (info)->contents        == 0    && \
-+      (info)->read_exec_only  == 1    && \
-+      (info)->seg_32bit       == 0    && \
-+      (info)->limit_in_pages  == 0    && \
-+      (info)->seg_not_present == 1    && \
-+      (info)->useable         == 0    && \
-+      (info)->lm              == 0)
-+
-+#if TLS_SIZE != 24
-+# error update this code.
-+#endif
-+
-+static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
-+{
-+#if 0
-+      u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN);
-+      gdt[0] = t->tls_array[0];
-+      gdt[1] = t->tls_array[1];
-+      gdt[2] = t->tls_array[2];
-+#endif
-+#define C(i) \
-+      HYPERVISOR_update_descriptor(virt_to_machine(&cpu_gdt(cpu)[GDT_ENTRY_TLS_MIN + i]), t->tls_array[i])
-+
-+      C(0); C(1); C(2);
-+#undef C
-+} 
-+
-+/*
-+ * load one particular LDT into the current CPU
-+ */
-+static inline void load_LDT_nolock (mm_context_t *pc, int cpu)
-+{
-+      void *segments = pc->ldt;
-+      int count = pc->size;
-+
-+      if (likely(!count))
-+              segments = NULL;
-+
-+      xen_set_ldt((unsigned long)segments, count);
-+}
-+
-+static inline void load_LDT(mm_context_t *pc)
-+{
-+      int cpu = get_cpu();
-+      load_LDT_nolock(pc, cpu);
-+      put_cpu();
-+}
-+
-+extern struct desc_ptr idt_descr;
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/dma-mapping.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/dma-mapping.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/dma-mapping.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/dma-mapping.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,191 @@
-+#ifndef _X8664_DMA_MAPPING_H
-+#define _X8664_DMA_MAPPING_H 1
-+
-+/*
-+ * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
-+ * documentation.
-+ */
-+
-+#include <linux/config.h>
-+
-+#include <asm/scatterlist.h>
-+#include <asm/io.h>
-+#include <asm/swiotlb.h>
-+
-+struct dma_mapping_ops {
-+      int             (*mapping_error)(dma_addr_t dma_addr);
-+      void*           (*alloc_coherent)(struct device *dev, size_t size,
-+                                dma_addr_t *dma_handle, gfp_t gfp);
-+      void            (*free_coherent)(struct device *dev, size_t size,
-+                                void *vaddr, dma_addr_t dma_handle);
-+      dma_addr_t      (*map_single)(struct device *hwdev, void *ptr,
-+                                size_t size, int direction);
-+      /* like map_single, but doesn't check the device mask */
-+      dma_addr_t      (*map_simple)(struct device *hwdev, char *ptr,
-+                                size_t size, int direction);
-+      void            (*unmap_single)(struct device *dev, dma_addr_t addr,
-+                              size_t size, int direction);
-+      void            (*sync_single_for_cpu)(struct device *hwdev,
-+                              dma_addr_t dma_handle, size_t size,
-+                              int direction);
-+      void            (*sync_single_for_device)(struct device *hwdev,
-+                                dma_addr_t dma_handle, size_t size,
-+                              int direction);
-+      void            (*sync_single_range_for_cpu)(struct device *hwdev,
-+                                dma_addr_t dma_handle, unsigned long offset,
-+                              size_t size, int direction);
-+      void            (*sync_single_range_for_device)(struct device *hwdev,
-+                              dma_addr_t dma_handle, unsigned long offset,
-+                              size_t size, int direction);
-+      void            (*sync_sg_for_cpu)(struct device *hwdev,
-+                                struct scatterlist *sg, int nelems,
-+                              int direction);
-+      void            (*sync_sg_for_device)(struct device *hwdev,
-+                              struct scatterlist *sg, int nelems,
-+                              int direction);
-+      int             (*map_sg)(struct device *hwdev, struct scatterlist *sg,
-+                              int nents, int direction);
-+      void            (*unmap_sg)(struct device *hwdev,
-+                              struct scatterlist *sg, int nents,
-+                              int direction);
-+      int             (*dma_supported)(struct device *hwdev, u64 mask);
-+      int             is_phys;
-+};
-+
-+extern dma_addr_t bad_dma_address;
-+extern struct dma_mapping_ops* dma_ops;
-+extern int iommu_merge;
-+
-+#if 0
-+static inline int dma_mapping_error(dma_addr_t dma_addr)
-+{
-+      if (dma_ops->mapping_error)
-+              return dma_ops->mapping_error(dma_addr);
-+
-+      return (dma_addr == bad_dma_address);
-+}
-+
-+extern void *dma_alloc_coherent(struct device *dev, size_t size,
-+                              dma_addr_t *dma_handle, gfp_t gfp);
-+extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-+                            dma_addr_t dma_handle);
-+
-+static inline dma_addr_t
-+dma_map_single(struct device *hwdev, void *ptr, size_t size,
-+             int direction)
-+{
-+      return dma_ops->map_single(hwdev, ptr, size, direction);
-+}
-+
-+static inline void
-+dma_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
-+               int direction)
-+{
-+      dma_ops->unmap_single(dev, addr, size, direction);
-+}
-+
-+#define dma_map_page(dev,page,offset,size,dir) \
-+      dma_map_single((dev), page_address(page)+(offset), (size), (dir))
-+
-+#define dma_unmap_page dma_unmap_single
-+
-+static inline void
-+dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
-+                      size_t size, int direction)
-+{
-+      if (dma_ops->sync_single_for_cpu)
-+              dma_ops->sync_single_for_cpu(hwdev, dma_handle, size,
-+                                           direction);
-+      flush_write_buffers();
-+}
-+
-+static inline void
-+dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
-+                         size_t size, int direction)
-+{
-+      if (dma_ops->sync_single_for_device)
-+              dma_ops->sync_single_for_device(hwdev, dma_handle, size,
-+                                              direction);
-+      flush_write_buffers();
-+}
-+
-+static inline void
-+dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
-+                            unsigned long offset, size_t size, int direction)
-+{
-+      if (dma_ops->sync_single_range_for_cpu) {
-+              dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, size, direction);
-+      }
-+
-+      flush_write_buffers();
-+}
-+
-+static inline void
-+dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
-+                               unsigned long offset, size_t size, int direction)
-+{
-+      if (dma_ops->sync_single_range_for_device)
-+              dma_ops->sync_single_range_for_device(hwdev, dma_handle,
-+                                                    offset, size, direction);
-+
-+      flush_write_buffers();
-+}
-+
-+static inline void
-+dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
-+                  int nelems, int direction)
-+{
-+      if (dma_ops->sync_sg_for_cpu)
-+              dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction);
-+      flush_write_buffers();
-+}
-+
-+static inline void
-+dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
-+                     int nelems, int direction)
-+{
-+      if (dma_ops->sync_sg_for_device) {
-+              dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction);
-+      }
-+
-+      flush_write_buffers();
-+}
-+
-+static inline int
-+dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction)
-+{
-+      return dma_ops->map_sg(hwdev, sg, nents, direction);
-+}
-+
-+static inline void
-+dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
-+           int direction)
-+{
-+      dma_ops->unmap_sg(hwdev, sg, nents, direction);
-+}
-+
-+extern int dma_supported(struct device *hwdev, u64 mask);
-+
-+/* same for gart, swiotlb, and nommu */
-+static inline int dma_get_cache_alignment(void)
-+{
-+      return boot_cpu_data.x86_clflush_size;
-+}
-+
-+#define dma_is_consistent(h) 1
-+
-+extern int dma_set_mask(struct device *dev, u64 mask);
-+
-+static inline void
-+dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction dir)
-+{
-+      flush_write_buffers();
-+}
-+
-+extern struct device fallback_dev;
-+extern int panic_on_overflow;
-+#endif
-+
-+#endif /* _X8664_DMA_MAPPING_H */
-+
-+#include <asm-i386/mach-xen/asm/dma-mapping.h>
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/e820.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/e820.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/e820.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/e820.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,63 @@
-+/*
-+ * structures and definitions for the int 15, ax=e820 memory map
-+ * scheme.
-+ *
-+ * In a nutshell, setup.S populates a scratch table in the
-+ * empty_zero_block that contains a list of usable address/size
-+ * duples.  setup.c, this information is transferred into the e820map,
-+ * and in init.c/numa.c, that new information is used to mark pages
-+ * reserved or not.
-+ */
-+#ifndef __E820_HEADER
-+#define __E820_HEADER
-+
-+#include <linux/mmzone.h>
-+
-+#define E820MAP       0x2d0           /* our map */
-+#define E820MAX       128             /* number of entries in E820MAP */
-+#define E820NR        0x1e8           /* # entries in E820MAP */
-+
-+#define E820_RAM      1
-+#define E820_RESERVED 2
-+#define E820_ACPI     3 /* usable as RAM once ACPI tables have been read */
-+#define E820_NVS      4
-+
-+#define HIGH_MEMORY   (1024*1024)
-+
-+#define LOWMEMSIZE()  (0x9f000)
-+
-+#ifndef __ASSEMBLY__
-+struct e820entry {
-+      u64 addr;       /* start of memory segment */
-+      u64 size;       /* size of memory segment */
-+      u32 type;       /* type of memory segment */
-+} __attribute__((packed));
-+
-+struct e820map {
-+    int nr_map;
-+      struct e820entry map[E820MAX];
-+};
-+
-+extern unsigned long find_e820_area(unsigned long start, unsigned long end, 
-+                                  unsigned size);
-+extern void add_memory_region(unsigned long start, unsigned long size, 
-+                            int type);
-+extern void setup_memory_region(void);
-+extern void contig_e820_setup(void); 
-+extern unsigned long e820_end_of_ram(void);
-+extern void e820_reserve_resources(struct e820entry *e820, int nr_map);
-+extern void e820_print_map(char *who);
-+extern int e820_mapped(unsigned long start, unsigned long end, unsigned type);
-+
-+extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
-+extern void e820_setup_gap(struct e820entry *e820, int nr_map);
-+extern unsigned long e820_hole_size(unsigned long start_pfn,
-+                                  unsigned long end_pfn);
-+
-+extern void __init parse_memopt(char *p, char **end);
-+extern void __init parse_memmapopt(char *p, char **end);
-+
-+extern struct e820map e820;
-+#endif/*!__ASSEMBLY__*/
-+
-+#endif/*__E820_HEADER*/
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/fixmap.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/fixmap.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/fixmap.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/fixmap.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,108 @@
-+/*
-+ * fixmap.h: compile-time virtual memory allocation
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License.  See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1998 Ingo Molnar
-+ */
-+
-+#ifndef _ASM_FIXMAP_H
-+#define _ASM_FIXMAP_H
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <asm/apicdef.h>
-+#include <asm/page.h>
-+#include <asm/vsyscall.h>
-+#include <asm/vsyscall32.h>
-+#include <asm/acpi.h>
-+
-+/*
-+ * Here we define all the compile-time 'special' virtual
-+ * addresses. The point is to have a constant address at
-+ * compile time, but to set the physical address only
-+ * in the boot process.
-+ *
-+ * these 'compile-time allocated' memory buffers are
-+ * fixed-size 4k pages. (or larger if used with an increment
-+ * highger than 1) use fixmap_set(idx,phys) to associate
-+ * physical memory with fixmap indices.
-+ *
-+ * TLB entries of such buffers will not be flushed across
-+ * task switches.
-+ */
-+
-+enum fixed_addresses {
-+      VSYSCALL_LAST_PAGE,
-+      VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
-+      VSYSCALL_HPET,
-+      FIX_HPET_BASE,
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
-+#endif
-+#ifdef CONFIG_X86_IO_APIC
-+      FIX_IO_APIC_BASE_0,
-+      FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
-+#endif
-+#ifdef CONFIG_ACPI
-+      FIX_ACPI_BEGIN,
-+      FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
-+#endif
-+      FIX_SHARED_INFO,
-+#define NR_FIX_ISAMAPS        256
-+      FIX_ISAMAP_END,
-+      FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1,
-+      __end_of_fixed_addresses
-+};
-+
-+extern void __set_fixmap (enum fixed_addresses idx,
-+                                      unsigned long phys, pgprot_t flags);
-+
-+#define set_fixmap(idx, phys) \
-+              __set_fixmap(idx, phys, PAGE_KERNEL)
-+/*
-+ * Some hardware wants to get fixmapped without caching.
-+ */
-+#define set_fixmap_nocache(idx, phys) \
-+              __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
-+
-+#define clear_fixmap(idx) \
-+                __set_fixmap(idx, 0, __pgprot(0))
-+
-+#define FIXADDR_TOP   (VSYSCALL_END-PAGE_SIZE)
-+#define FIXADDR_SIZE  (__end_of_fixed_addresses << PAGE_SHIFT)
-+#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
-+
-+/* Only covers 32bit vsyscalls currently. Need another set for 64bit. */
-+#define FIXADDR_USER_START    ((unsigned long)VSYSCALL32_VSYSCALL)
-+#define FIXADDR_USER_END      (FIXADDR_USER_START + PAGE_SIZE)
-+
-+#define __fix_to_virt(x)      (FIXADDR_TOP - ((x) << PAGE_SHIFT))
-+
-+extern void __this_fixmap_does_not_exist(void);
-+
-+/*
-+ * 'index to address' translation. If anyone tries to use the idx
-+ * directly without translation, we catch the bug with a NULL-deference
-+ * kernel oops. Illegal ranges of incoming indices are caught too.
-+ */
-+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
-+{
-+      /*
-+       * this branch gets completely eliminated after inlining,
-+       * except when someone tries to use fixaddr indices in an
-+       * illegal way. (such as mixing up address types or using
-+       * out-of-range indices).
-+       *
-+       * If it doesn't get removed, the linker will complain
-+       * loudly with a reasonably clear error message..
-+       */
-+      if (idx >= __end_of_fixed_addresses)
-+              __this_fixmap_does_not_exist();
-+
-+        return __fix_to_virt(idx);
-+}
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/floppy.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/floppy.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/floppy.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/floppy.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,206 @@
-+/*
-+ * Architecture specific parts of the Floppy driver
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License.  See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1995
-+ *
-+ * Modifications for Xen are Copyright (c) 2004, Keir Fraser.
-+ */
-+#ifndef __ASM_XEN_X86_64_FLOPPY_H
-+#define __ASM_XEN_X86_64_FLOPPY_H
-+
-+#include <linux/vmalloc.h>
-+
-+/*
-+ * The DMA channel used by the floppy controller cannot access data at
-+ * addresses >= 16MB
-+ *
-+ * Went back to the 1MB limit, as some people had problems with the floppy
-+ * driver otherwise. It doesn't matter much for performance anyway, as most
-+ * floppy accesses go through the track buffer.
-+ */
-+#define _CROSS_64KB(a,s,vdma) \
-+(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
-+
-+/* XEN: Hit DMA paths on the head. This trick from asm-m68k/floppy.h. */
-+#include <asm/dma.h>
-+#undef MAX_DMA_ADDRESS
-+#define MAX_DMA_ADDRESS 0
-+#define CROSS_64KB(a,s) (0)
-+
-+#define fd_inb(port)                  inb_p(port)
-+#define fd_outb(value,port)           outb_p(value,port)
-+
-+#define fd_request_dma()        (0)
-+#define fd_free_dma()           ((void)0)
-+#define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
-+#define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
-+#define fd_free_irq()         free_irq(FLOPPY_IRQ, NULL)
-+#define fd_get_dma_residue()    vdma_get_dma_residue(FLOPPY_DMA)
-+/*
-+ * Do not use vmalloc/vfree: floppy_release_irq_and_dma() gets called from
-+ * softirq context via motor_off_callback. A generic bug we happen to trigger.
-+ */
-+#define fd_dma_mem_alloc(size)        __get_free_pages(GFP_KERNEL, get_order(size))
-+#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
-+#define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
-+
-+static int virtual_dma_count;
-+static int virtual_dma_residue;
-+static char *virtual_dma_addr;
-+static int virtual_dma_mode;
-+static int doing_pdma;
-+
-+static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
-+{
-+      register unsigned char st;
-+
-+#undef TRACE_FLPY_INT
-+
-+#ifdef TRACE_FLPY_INT
-+      static int calls=0;
-+      static int bytes=0;
-+      static int dma_wait=0;
-+#endif
-+      if (!doing_pdma)
-+              return floppy_interrupt(irq, dev_id, regs);
-+
-+#ifdef TRACE_FLPY_INT
-+      if(!calls)
-+              bytes = virtual_dma_count;
-+#endif
-+
-+      {
-+              register int lcount;
-+              register char *lptr;
-+
-+              st = 1;
-+              for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 
-+                  lcount; lcount--, lptr++) {
-+                      st=inb(virtual_dma_port+4) & 0xa0 ;
-+                      if(st != 0xa0) 
-+                              break;
-+                      if(virtual_dma_mode)
-+                              outb_p(*lptr, virtual_dma_port+5);
-+                      else
-+                              *lptr = inb_p(virtual_dma_port+5);
-+              }
-+              virtual_dma_count = lcount;
-+              virtual_dma_addr = lptr;
-+              st = inb(virtual_dma_port+4);
-+      }
-+
-+#ifdef TRACE_FLPY_INT
-+      calls++;
-+#endif
-+      if(st == 0x20)
-+              return IRQ_HANDLED;
-+      if(!(st & 0x20)) {
-+              virtual_dma_residue += virtual_dma_count;
-+              virtual_dma_count=0;
-+#ifdef TRACE_FLPY_INT
-+              printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", 
-+                     virtual_dma_count, virtual_dma_residue, calls, bytes,
-+                     dma_wait);
-+              calls = 0;
-+              dma_wait=0;
-+#endif
-+              doing_pdma = 0;
-+              floppy_interrupt(irq, dev_id, regs);
-+              return IRQ_HANDLED;
-+      }
-+#ifdef TRACE_FLPY_INT
-+      if(!virtual_dma_count)
-+              dma_wait++;
-+#endif
-+      return IRQ_HANDLED;
-+}
-+
-+static void fd_disable_dma(void)
-+{
-+      doing_pdma = 0;
-+      virtual_dma_residue += virtual_dma_count;
-+      virtual_dma_count=0;
-+}
-+
-+static int vdma_get_dma_residue(unsigned int dummy)
-+{
-+      return virtual_dma_count + virtual_dma_residue;
-+}
-+
-+
-+static int fd_request_irq(void)
-+{
-+      return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
-+                                         "floppy", NULL);
-+}
-+
-+#if 0
-+static unsigned long vdma_mem_alloc(unsigned long size)
-+{
-+      return (unsigned long) vmalloc(size);
-+
-+}
-+
-+static void vdma_mem_free(unsigned long addr, unsigned long size)
-+{
-+      vfree((void *)addr);
-+}
-+#endif
-+
-+static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
-+{
-+      doing_pdma = 1;
-+      virtual_dma_port = io;
-+      virtual_dma_mode = (mode  == DMA_MODE_WRITE);
-+      virtual_dma_addr = addr;
-+      virtual_dma_count = size;
-+      virtual_dma_residue = 0;
-+      return 0;
-+}
-+
-+/* XEN: This trick to force 'virtual DMA' is from include/asm-m68k/floppy.h. */
-+#define FDC1 xen_floppy_init()
-+static int FDC2 = -1;
-+
-+static int xen_floppy_init(void)
-+{
-+      use_virtual_dma = 1;
-+      can_use_virtual_dma = 1;
-+      return 0x3f0;
-+}
-+
-+/*
-+ * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
-+ * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
-+ * coincides with another rtc CMOS user.              Paul G.
-+ */
-+#define FLOPPY0_TYPE  ({                              \
-+      unsigned long flags;                            \
-+      unsigned char val;                              \
-+      spin_lock_irqsave(&rtc_lock, flags);            \
-+      val = (CMOS_READ(0x10) >> 4) & 15;              \
-+      spin_unlock_irqrestore(&rtc_lock, flags);       \
-+      val;                                            \
-+})
-+
-+#define FLOPPY1_TYPE  ({                              \
-+      unsigned long flags;                            \
-+      unsigned char val;                              \
-+      spin_lock_irqsave(&rtc_lock, flags);            \
-+      val = CMOS_READ(0x10) & 15;                     \
-+      spin_unlock_irqrestore(&rtc_lock, flags);       \
-+      val;                                            \
-+})
-+
-+#define N_FDC 2
-+#define N_DRIVE 8
-+
-+#define FLOPPY_MOTOR_MASK 0xf0
-+
-+#define EXTRA_FLOPPY_PARAMS
-+
-+#endif /* __ASM_XEN_X86_64_FLOPPY_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/hw_irq.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/hw_irq.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/hw_irq.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/hw_irq.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,145 @@
-+#ifndef _ASM_HW_IRQ_H
-+#define _ASM_HW_IRQ_H
-+
-+/*
-+ *    linux/include/asm/hw_irq.h
-+ *
-+ *    (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
-+ *
-+ *    moved some of the old arch/i386/kernel/irq.h to here. VY
-+ *
-+ *    IRQ/IPI changes taken from work by Thomas Radke
-+ *    <tomsoft@informatik.tu-chemnitz.de>
-+ *
-+ *    hacked by Andi Kleen for x86-64.
-+ * 
-+ *  $Id: hw_irq.h,v 1.24 2001/09/14 20:55:03 vojtech Exp $
-+ */
-+
-+#ifndef __ASSEMBLY__
-+#include <linux/config.h>
-+#include <asm/atomic.h>
-+#include <asm/irq.h>
-+#include <linux/profile.h>
-+#include <linux/smp.h>
-+
-+struct hw_interrupt_type;
-+#endif
-+
-+#define NMI_VECTOR            0x02
-+/*
-+ * IDT vectors usable for external interrupt sources start
-+ * at 0x20:
-+ */
-+#define FIRST_EXTERNAL_VECTOR 0x20
-+
-+#define IA32_SYSCALL_VECTOR   0x80
-+
-+
-+/*
-+ * Vectors 0x20-0x2f are used for ISA interrupts.
-+ */
-+
-+/*
-+ * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
-+ *
-+ *  some of the following vectors are 'rare', they are merged
-+ *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
-+ *  TLB, reschedule and local APIC vectors are performance-critical.
-+ */
-+#ifndef CONFIG_XEN
-+#define SPURIOUS_APIC_VECTOR  0xff
-+#define ERROR_APIC_VECTOR     0xfe
-+#define RESCHEDULE_VECTOR     0xfd
-+#define CALL_FUNCTION_VECTOR  0xfc
-+/* fb free - please don't readd KDB here because it's useless
-+   (hint - think what a NMI bit does to a vector) */
-+#define THERMAL_APIC_VECTOR   0xfa
-+#define THRESHOLD_APIC_VECTOR   0xf9
-+/* f8 free */
-+#define INVALIDATE_TLB_VECTOR_END     0xf7
-+#define INVALIDATE_TLB_VECTOR_START   0xf0    /* f0-f7 used for TLB flush */
-+
-+#define NUM_INVALIDATE_TLB_VECTORS    8
-+#endif
-+
-+/*
-+ * Local APIC timer IRQ vector is on a different priority level,
-+ * to work around the 'lost local interrupt if more than 2 IRQ
-+ * sources per level' errata.
-+ */
-+#define LOCAL_TIMER_VECTOR    0xef
-+
-+/*
-+ * First APIC vector available to drivers: (vectors 0x30-0xee)
-+ * we start at 0x31 to spread out vectors evenly between priority
-+ * levels. (0x80 is the syscall vector)
-+ */
-+#define FIRST_DEVICE_VECTOR   0x31
-+#define FIRST_SYSTEM_VECTOR   0xef   /* duplicated in irq.h */
-+
-+
-+#ifndef __ASSEMBLY__
-+extern u8 irq_vector[NR_IRQ_VECTORS];
-+#define IO_APIC_VECTOR(irq)   (irq_vector[irq])
-+#define AUTO_ASSIGN           -1
-+
-+/*
-+ * Various low-level irq details needed by irq.c, process.c,
-+ * time.c, io_apic.c and smp.c
-+ *
-+ * Interrupt entry/exit code at both C and assembly level
-+ */
-+
-+extern void disable_8259A_irq(unsigned int irq);
-+extern void enable_8259A_irq(unsigned int irq);
-+extern int i8259A_irq_pending(unsigned int irq);
-+extern void make_8259A_irq(unsigned int irq);
-+extern void init_8259A(int aeoi);
-+extern void FASTCALL(send_IPI_self(int vector));
-+extern void init_VISWS_APIC_irqs(void);
-+extern void setup_IO_APIC(void);
-+extern void disable_IO_APIC(void);
-+extern void print_IO_APIC(void);
-+extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
-+extern void send_IPI(int dest, int vector);
-+extern void setup_ioapic_dest(void);
-+
-+extern unsigned long io_apic_irqs;
-+
-+extern atomic_t irq_err_count;
-+extern atomic_t irq_mis_count;
-+
-+#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
-+
-+#define __STR(x) #x
-+#define STR(x) __STR(x)
-+
-+#include <asm/ptrace.h>
-+
-+#define IRQ_NAME2(nr) nr##_interrupt(void)
-+#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
-+
-+/*
-+ *    SMP has a few special interrupts for IPI messages
-+ */
-+
-+#define BUILD_IRQ(nr) \
-+asmlinkage void IRQ_NAME(nr); \
-+__asm__( \
-+"\n.p2align\n" \
-+"IRQ" #nr "_interrupt:\n\t" \
-+      "push $" #nr "-256 ; " \
-+      "jmp common_interrupt");
-+
-+extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i);
-+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
-+{
-+      resend_irq_on_evtchn(h, i);
-+}
-+
-+#define platform_legacy_irq(irq)      ((irq) < 16)
-+
-+#endif
-+
-+#endif /* _ASM_HW_IRQ_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/hypercall.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/hypercall.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/hypercall.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/hypercall.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,406 @@
-+/******************************************************************************
-+ * hypercall.h
-+ * 
-+ * Linux-specific hypervisor handling.
-+ * 
-+ * Copyright (c) 2002-2004, K A Fraser
-+ * 
-+ * 64-bit updates:
-+ *   Benjamin Liu <benjamin.liu@intel.com>
-+ *   Jun Nakajima <jun.nakajima@intel.com>
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __HYPERCALL_H__
-+#define __HYPERCALL_H__
-+
-+#include <linux/string.h> /* memcpy() */
-+
-+#ifndef __HYPERVISOR_H__
-+# error "please don't include this file directly"
-+#endif
-+
-+#define __STR(x) #x
-+#define STR(x) __STR(x)
-+
-+#ifdef CONFIG_XEN
-+#define HYPERCALL_STR(name)                                   \
-+      "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
-+#else
-+#define HYPERCALL_STR(name)                                   \
-+      "mov hypercall_stubs,%%rax; "                           \
-+      "add $("STR(__HYPERVISOR_##name)" * 32),%%rax; "        \
-+      "call *%%rax"
-+#endif
-+
-+#define _hypercall0(type, name)                       \
-+({                                            \
-+      long __res;                             \
-+      asm volatile (                          \
-+              HYPERCALL_STR(name)             \
-+              : "=a" (__res)                  \
-+              :                               \
-+              : "memory" );                   \
-+      (type)__res;                            \
-+})
-+
-+#define _hypercall1(type, name, a1)                           \
-+({                                                            \
-+      long __res, __ign1;                                     \
-+      asm volatile (                                          \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=D" (__ign1)                   \
-+              : "1" ((long)(a1))                              \
-+              : "memory" );                                   \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall2(type, name, a1, a2)                               \
-+({                                                            \
-+      long __res, __ign1, __ign2;                             \
-+      asm volatile (                                          \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=D" (__ign1), "=S" (__ign2)    \
-+              : "1" ((long)(a1)), "2" ((long)(a2))            \
-+              : "memory" );                                   \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall3(type, name, a1, a2, a3)                   \
-+({                                                            \
-+      long __res, __ign1, __ign2, __ign3;                     \
-+      asm volatile (                                          \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
-+              "=d" (__ign3)                                   \
-+              : "1" ((long)(a1)), "2" ((long)(a2)),           \
-+              "3" ((long)(a3))                                \
-+              : "memory" );                                   \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall4(type, name, a1, a2, a3, a4)                       \
-+({                                                            \
-+      long __res, __ign1, __ign2, __ign3;                     \
-+      asm volatile (                                          \
-+              "movq %7,%%r10; "                               \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
-+              "=d" (__ign3)                                   \
-+              : "1" ((long)(a1)), "2" ((long)(a2)),           \
-+              "3" ((long)(a3)), "g" ((long)(a4))              \
-+              : "memory", "r10" );                            \
-+      (type)__res;                                            \
-+})
-+
-+#define _hypercall5(type, name, a1, a2, a3, a4, a5)           \
-+({                                                            \
-+      long __res, __ign1, __ign2, __ign3;                     \
-+      asm volatile (                                          \
-+              "movq %7,%%r10; movq %8,%%r8; "                 \
-+              HYPERCALL_STR(name)                             \
-+              : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
-+              "=d" (__ign3)                                   \
-+              : "1" ((long)(a1)), "2" ((long)(a2)),           \
-+              "3" ((long)(a3)), "g" ((long)(a4)),             \
-+              "g" ((long)(a5))                                \
-+              : "memory", "r10", "r8" );                      \
-+      (type)__res;                                            \
-+})
-+
-+static inline int
-+HYPERVISOR_set_trap_table(
-+      trap_info_t *table)
-+{
-+      return _hypercall1(int, set_trap_table, table);
-+}
-+
-+static inline int
-+HYPERVISOR_mmu_update(
-+      mmu_update_t *req, int count, int *success_count, domid_t domid)
-+{
-+      return _hypercall4(int, mmu_update, req, count, success_count, domid);
-+}
-+
-+static inline int
-+HYPERVISOR_mmuext_op(
-+      struct mmuext_op *op, int count, int *success_count, domid_t domid)
-+{
-+      return _hypercall4(int, mmuext_op, op, count, success_count, domid);
-+}
-+
-+static inline int
-+HYPERVISOR_set_gdt(
-+      unsigned long *frame_list, int entries)
-+{
-+      return _hypercall2(int, set_gdt, frame_list, entries);
-+}
-+
-+static inline int
-+HYPERVISOR_stack_switch(
-+      unsigned long ss, unsigned long esp)
-+{
-+      return _hypercall2(int, stack_switch, ss, esp);
-+}
-+
-+static inline int
-+HYPERVISOR_set_callbacks(
-+      unsigned long event_address, unsigned long failsafe_address, 
-+      unsigned long syscall_address)
-+{
-+      return _hypercall3(int, set_callbacks,
-+                         event_address, failsafe_address, syscall_address);
-+}
-+
-+static inline int
-+HYPERVISOR_fpu_taskswitch(
-+      int set)
-+{
-+      return _hypercall1(int, fpu_taskswitch, set);
-+}
-+
-+static inline int
-+HYPERVISOR_sched_op_compat(
-+      int cmd, unsigned long arg)
-+{
-+      return _hypercall2(int, sched_op_compat, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_sched_op(
-+      int cmd, void *arg)
-+{
-+      return _hypercall2(int, sched_op, cmd, arg);
-+}
-+
-+static inline long
-+HYPERVISOR_set_timer_op(
-+      u64 timeout)
-+{
-+      return _hypercall1(long, set_timer_op, timeout);
-+}
-+
-+static inline int
-+HYPERVISOR_dom0_op(
-+      dom0_op_t *dom0_op)
-+{
-+      dom0_op->interface_version = DOM0_INTERFACE_VERSION;
-+      return _hypercall1(int, dom0_op, dom0_op);
-+}
-+
-+static inline int
-+HYPERVISOR_set_debugreg(
-+      int reg, unsigned long value)
-+{
-+      return _hypercall2(int, set_debugreg, reg, value);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_get_debugreg(
-+      int reg)
-+{
-+      return _hypercall1(unsigned long, get_debugreg, reg);
-+}
-+
-+static inline int
-+HYPERVISOR_update_descriptor(
-+      unsigned long ma, unsigned long word)
-+{
-+      return _hypercall2(int, update_descriptor, ma, word);
-+}
-+
-+static inline int
-+HYPERVISOR_memory_op(
-+      unsigned int cmd, void *arg)
-+{
-+      return _hypercall2(int, memory_op, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_multicall(
-+      void *call_list, int nr_calls)
-+{
-+      return _hypercall2(int, multicall, call_list, nr_calls);
-+}
-+
-+static inline int
-+HYPERVISOR_update_va_mapping(
-+      unsigned long va, pte_t new_val, unsigned long flags)
-+{
-+      return _hypercall3(int, update_va_mapping, va, new_val.pte, flags);
-+}
-+
-+static inline int
-+HYPERVISOR_event_channel_op(
-+      int cmd, void *arg)
-+{
-+      int rc = _hypercall2(int, event_channel_op, cmd, arg);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (unlikely(rc == -ENOSYS)) {
-+              struct evtchn_op op;
-+              op.cmd = cmd;
-+              memcpy(&op.u, arg, sizeof(op.u));
-+              rc = _hypercall1(int, event_channel_op_compat, &op);
-+              memcpy(arg, &op.u, sizeof(op.u));
-+      }
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_acm_op(
-+      int cmd, void *arg)
-+{
-+      return _hypercall2(int, acm_op, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_xen_version(
-+      int cmd, void *arg)
-+{
-+      return _hypercall2(int, xen_version, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_console_io(
-+      int cmd, int count, char *str)
-+{
-+      return _hypercall3(int, console_io, cmd, count, str);
-+}
-+
-+static inline int
-+HYPERVISOR_physdev_op(
-+      int cmd, void *arg)
-+{
-+      int rc = _hypercall2(int, physdev_op, cmd, arg);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (unlikely(rc == -ENOSYS)) {
-+              struct physdev_op op;
-+              op.cmd = cmd;
-+              memcpy(&op.u, arg, sizeof(op.u));
-+              rc = _hypercall1(int, physdev_op_compat, &op);
-+              memcpy(arg, &op.u, sizeof(op.u));
-+      }
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_grant_table_op(
-+      unsigned int cmd, void *uop, unsigned int count)
-+{
-+      return _hypercall3(int, grant_table_op, cmd, uop, count);
-+}
-+
-+static inline int
-+HYPERVISOR_update_va_mapping_otherdomain(
-+      unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
-+{
-+      return _hypercall4(int, update_va_mapping_otherdomain, va,
-+                         new_val.pte, flags, domid);
-+}
-+
-+static inline int
-+HYPERVISOR_vm_assist(
-+      unsigned int cmd, unsigned int type)
-+{
-+      return _hypercall2(int, vm_assist, cmd, type);
-+}
-+
-+static inline int
-+HYPERVISOR_vcpu_op(
-+      int cmd, int vcpuid, void *extra_args)
-+{
-+      return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
-+}
-+
-+static inline int
-+HYPERVISOR_set_segment_base(
-+      int reg, unsigned long value)
-+{
-+      return _hypercall2(int, set_segment_base, reg, value);
-+}
-+
-+static inline int
-+HYPERVISOR_suspend(
-+      unsigned long srec)
-+{
-+      struct sched_shutdown sched_shutdown = {
-+              .reason = SHUTDOWN_suspend
-+      };
-+
-+      int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
-+                           &sched_shutdown, srec);
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (rc == -ENOSYS)
-+              rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
-+                               SHUTDOWN_suspend, srec);
-+#endif
-+
-+      return rc;
-+}
-+
-+static inline int
-+HYPERVISOR_nmi_op(
-+      unsigned long op, void *arg)
-+{
-+      return _hypercall2(int, nmi_op, op, arg);
-+}
-+
-+static inline unsigned long
-+HYPERVISOR_hvm_op(
-+    int op, void *arg)
-+{
-+    return _hypercall2(unsigned long, hvm_op, op, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_callback_op(
-+      int cmd, void *arg)
-+{
-+      return _hypercall2(int, callback_op, cmd, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_xenoprof_op(
-+      int op, void *arg)
-+{
-+      return _hypercall2(int, xenoprof_op, op, arg);
-+}
-+
-+static inline int
-+HYPERVISOR_kexec_op(
-+      unsigned long op, void *args)
-+{
-+      return _hypercall2(int, kexec_op, op, args);
-+}
-+
-+#endif /* __HYPERCALL_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/hypervisor.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/hypervisor.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/hypervisor.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/hypervisor.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,2 @@
-+
-+#include <asm-i386/mach-xen/asm/hypervisor.h>
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/io.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/io.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/io.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/io.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,361 @@
-+#ifndef _ASM_IO_H
-+#define _ASM_IO_H
-+
-+#include <linux/config.h>
-+#include <asm/fixmap.h>
-+
-+/*
-+ * This file contains the definitions for the x86 IO instructions
-+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
-+ * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
-+ * versions of the single-IO instructions (inb_p/inw_p/..).
-+ *
-+ * This file is not meant to be obfuscating: it's just complicated
-+ * to (a) handle it all in a way that makes gcc able to optimize it
-+ * as well as possible and (b) trying to avoid writing the same thing
-+ * over and over again with slight variations and possibly making a
-+ * mistake somewhere.
-+ */
-+
-+/*
-+ * Thanks to James van Artsdalen for a better timing-fix than
-+ * the two short jumps: using outb's to a nonexistent port seems
-+ * to guarantee better timings even on fast machines.
-+ *
-+ * On the other hand, I'd like to be sure of a non-existent port:
-+ * I feel a bit unsafe about using 0x80 (should be safe, though)
-+ *
-+ *            Linus
-+ */
-+
-+ /*
-+  *  Bit simplified and optimized by Jan Hubicka
-+  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
-+  *
-+  *  isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added,
-+  *  isa_read[wl] and isa_write[wl] fixed
-+  *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-+  */
-+
-+#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
-+
-+#ifdef REALLY_SLOW_IO
-+#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
-+#else
-+#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
-+#endif
-+
-+/*
-+ * Talk about misusing macros..
-+ */
-+#define __OUT1(s,x) \
-+static inline void out##s(unsigned x value, unsigned short port) {
-+
-+#define __OUT2(s,s1,s2) \
-+__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
-+
-+#define __OUT(s,s1,x) \
-+__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
-+__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
-+
-+#define __IN1(s) \
-+static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
-+
-+#define __IN2(s,s1,s2) \
-+__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
-+
-+#define __IN(s,s1,i...) \
-+__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-+__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
-+
-+#define __INS(s) \
-+static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
-+{ __asm__ __volatile__ ("rep ; ins" #s \
-+: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
-+
-+#define __OUTS(s) \
-+static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
-+{ __asm__ __volatile__ ("rep ; outs" #s \
-+: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
-+
-+#define RETURN_TYPE unsigned char
-+__IN(b,"")
-+#undef RETURN_TYPE
-+#define RETURN_TYPE unsigned short
-+__IN(w,"")
-+#undef RETURN_TYPE
-+#define RETURN_TYPE unsigned int
-+__IN(l,"")
-+#undef RETURN_TYPE
-+
-+__OUT(b,"b",char)
-+__OUT(w,"w",short)
-+__OUT(l,,int)
-+
-+__INS(b)
-+__INS(w)
-+__INS(l)
-+
-+__OUTS(b)
-+__OUTS(w)
-+__OUTS(l)
-+
-+#define IO_SPACE_LIMIT 0xffff
-+
-+#if defined(__KERNEL__) && __x86_64__
-+
-+#include <linux/vmalloc.h>
-+
-+#ifndef __i386__
-+/*
-+ * Change virtual addresses to physical addresses and vv.
-+ * These are pretty trivial
-+ */
-+static inline unsigned long virt_to_phys(volatile void * address)
-+{
-+      return __pa(address);
-+}
-+
-+static inline void * phys_to_virt(unsigned long address)
-+{
-+      return __va(address);
-+}
-+
-+#define virt_to_bus(_x) phys_to_machine(__pa(_x))
-+#define bus_to_virt(_x) __va(machine_to_phys(_x))
-+#endif
-+
-+/*
-+ * Change "struct page" to physical address.
-+ */
-+#define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-+#define page_to_phys(page)     (phys_to_machine(page_to_pseudophys(page)))
-+#define page_to_bus(page)      (phys_to_machine(page_to_pseudophys(page)))
-+
-+#define bio_to_pseudophys(bio)         (page_to_pseudophys(bio_page((bio))) + \
-+                                (unsigned long) bio_offset((bio)))
-+#define bvec_to_pseudophys(bv)         (page_to_pseudophys((bv)->bv_page) + \
-+                                (unsigned long) (bv)->bv_offset)
-+
-+#define BIOVEC_PHYS_MERGEABLE(vec1, vec2)     \
-+      (((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) && \
-+       ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) == \
-+        bvec_to_pseudophys((vec2))))
-+
-+#include <asm-generic/iomap.h>
-+
-+extern void __iomem *__ioremap(unsigned long offset, unsigned long size, unsigned long flags);
-+
-+static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
-+{
-+      return __ioremap(offset, size, 0);
-+}
-+
-+/*
-+ * This one maps high address device memory and turns off caching for that area.
-+ * it's useful if some control registers are in such an area and write combining
-+ * or read caching is not desirable:
-+ */
-+extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
-+extern void iounmap(volatile void __iomem *addr);
-+
-+/* Use normal IO mappings for DMI */
-+#define dmi_ioremap ioremap
-+#define dmi_iounmap(x,l) iounmap(x)
-+#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
-+
-+/*
-+ * ISA I/O bus memory addresses are 1:1 with the physical address.
-+ */
-+
-+#define isa_virt_to_bus(_x) isa_virt_to_bus_is_UNSUPPORTED->x
-+#define isa_page_to_bus(_x) isa_page_to_bus_is_UNSUPPORTED->x
-+#define isa_bus_to_virt(_x) (void *)(__fix_to_virt(FIX_ISAMAP_BEGIN) + (_x))
-+
-+/*
-+ * However PCI ones are not necessarily 1:1 and therefore these interfaces
-+ * are forbidden in portable PCI drivers.
-+ *
-+ * Allow them on x86 for legacy drivers, though.
-+ */
-+#define virt_to_bus(_x) phys_to_machine(__pa(_x))
-+#define bus_to_virt(_x) __va(machine_to_phys(_x))
-+
-+/*
-+ * readX/writeX() are used to access memory mapped devices. On some
-+ * architectures the memory mapped IO stuff needs to be accessed
-+ * differently. On the x86 architecture, we just read/write the
-+ * memory location directly.
-+ */
-+
-+static inline __u8 __readb(const volatile void __iomem *addr)
-+{
-+      return *(__force volatile __u8 *)addr;
-+}
-+static inline __u16 __readw(const volatile void __iomem *addr)
-+{
-+      return *(__force volatile __u16 *)addr;
-+}
-+static inline __u32 __readl(const volatile void __iomem *addr)
-+{
-+      return *(__force volatile __u32 *)addr;
-+}
-+static inline __u64 __readq(const volatile void __iomem *addr)
-+{
-+      return *(__force volatile __u64 *)addr;
-+}
-+#define readb(x) __readb(x)
-+#define readw(x) __readw(x)
-+#define readl(x) __readl(x)
-+#define readq(x) __readq(x)
-+#define readb_relaxed(a) readb(a)
-+#define readw_relaxed(a) readw(a)
-+#define readl_relaxed(a) readl(a)
-+#define readq_relaxed(a) readq(a)
-+#define __raw_readb readb
-+#define __raw_readw readw
-+#define __raw_readl readl
-+#define __raw_readq readq
-+
-+#define mmiowb()
-+
-+#ifdef CONFIG_UNORDERED_IO
-+static inline void __writel(__u32 val, volatile void __iomem *addr)
-+{
-+      volatile __u32 __iomem *target = addr;
-+      asm volatile("movnti %1,%0"
-+                   : "=m" (*target)
-+                   : "r" (val) : "memory");
-+}
-+
-+static inline void __writeq(__u64 val, volatile void __iomem *addr)
-+{
-+      volatile __u64 __iomem *target = addr;
-+      asm volatile("movnti %1,%0"
-+                   : "=m" (*target)
-+                   : "r" (val) : "memory");
-+}
-+#else
-+static inline void __writel(__u32 b, volatile void __iomem *addr)
-+{
-+      *(__force volatile __u32 *)addr = b;
-+}
-+static inline void __writeq(__u64 b, volatile void __iomem *addr)
-+{
-+      *(__force volatile __u64 *)addr = b;
-+}
-+#endif
-+static inline void __writeb(__u8 b, volatile void __iomem *addr)
-+{
-+      *(__force volatile __u8 *)addr = b;
-+}
-+static inline void __writew(__u16 b, volatile void __iomem *addr)
-+{
-+      *(__force volatile __u16 *)addr = b;
-+}
-+#define writeq(val,addr) __writeq((val),(addr))
-+#define writel(val,addr) __writel((val),(addr))
-+#define writew(val,addr) __writew((val),(addr))
-+#define writeb(val,addr) __writeb((val),(addr))
-+#define __raw_writeb writeb
-+#define __raw_writew writew
-+#define __raw_writel writel
-+#define __raw_writeq writeq
-+
-+void __memcpy_fromio(void*,unsigned long,unsigned);
-+void __memcpy_toio(unsigned long,const void*,unsigned);
-+
-+static inline void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len)
-+{
-+      __memcpy_fromio(to,(unsigned long)from,len);
-+}
-+static inline void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len)
-+{
-+      __memcpy_toio((unsigned long)to,from,len);
-+}
-+
-+void memset_io(volatile void __iomem *a, int b, size_t c);
-+
-+/*
-+ * ISA space is 'always mapped' on a typical x86 system, no need to
-+ * explicitly ioremap() it. The fact that the ISA IO space is mapped
-+ * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
-+ * are physical addresses. The following constant pointer can be
-+ * used as the IO-area pointer (it can be iounmapped as well, so the
-+ * analogy with PCI is quite large):
-+ */
-+#define __ISA_IO_base ((char __iomem *)(fix_to_virt(FIX_ISAMAP_BEGIN)))
-+
-+#define isa_readb(a) readb(__ISA_IO_base + (a))
-+#define isa_readw(a) readw(__ISA_IO_base + (a))
-+#define isa_readl(a) readl(__ISA_IO_base + (a))
-+#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
-+#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
-+#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
-+#define isa_memset_io(a,b,c)          memset_io(__ISA_IO_base + (a),(b),(c))
-+#define isa_memcpy_fromio(a,b,c)      memcpy_fromio((a),__ISA_IO_base + (b),(c))
-+#define isa_memcpy_toio(a,b,c)                memcpy_toio(__ISA_IO_base + (a),(b),(c))
-+
-+
-+/*
-+ * Again, x86-64 does not require mem IO specific function.
-+ */
-+
-+#define eth_io_copy_and_sum(a,b,c,d)          eth_copy_and_sum((a),(void *)(b),(c),(d))
-+#define isa_eth_io_copy_and_sum(a,b,c,d)      eth_copy_and_sum((a),(void *)(__ISA_IO_base + (b)),(c),(d))
-+
-+/**
-+ *    check_signature         -       find BIOS signatures
-+ *    @io_addr: mmio address to check 
-+ *    @signature:  signature block
-+ *    @length: length of signature
-+ *
-+ *    Perform a signature comparison with the mmio address io_addr. This
-+ *    address should have been obtained by ioremap.
-+ *    Returns 1 on a match.
-+ */
-+ 
-+static inline int check_signature(void __iomem *io_addr,
-+      const unsigned char *signature, int length)
-+{
-+      int retval = 0;
-+      do {
-+              if (readb(io_addr) != *signature)
-+                      goto out;
-+              io_addr++;
-+              signature++;
-+              length--;
-+      } while (length);
-+      retval = 1;
-+out:
-+      return retval;
-+}
-+
-+/* Nothing to do */
-+
-+#define dma_cache_inv(_start,_size)           do { } while (0)
-+#define dma_cache_wback(_start,_size)         do { } while (0)
-+#define dma_cache_wback_inv(_start,_size)     do { } while (0)
-+
-+#define flush_write_buffers() 
-+
-+extern int iommu_bio_merge;
-+#define BIO_VMERGE_BOUNDARY iommu_bio_merge
-+
-+/*
-+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
-+ * access
-+ */
-+#define xlate_dev_mem_ptr(p, sz)      ioremap(p, sz)
-+#define xlate_dev_mem_ptr_unmap(p)    iounmap(p)
-+
-+/*
-+ * Convert a virtual cached pointer to an uncached pointer
-+ */
-+#define xlate_dev_kmem_ptr(p) p
-+
-+#endif /* __KERNEL__ */
-+
-+#define ARCH_HAS_DEV_MEM
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/irq.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/irq.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/irq.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/irq.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,39 @@
-+#ifndef _ASM_IRQ_H
-+#define _ASM_IRQ_H
-+
-+/*
-+ *    linux/include/asm/irq.h
-+ *
-+ *    (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
-+ *
-+ *    IRQ/IPI changes taken from work by Thomas Radke
-+ *    <tomsoft@informatik.tu-chemnitz.de>
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+/* include comes from machine specific directory */
-+#include "irq_vectors.h"
-+#include <asm/thread_info.h>
-+
-+static __inline__ int irq_canonicalize(int irq)
-+{
-+      return ((irq == 2) ? 9 : irq);
-+}
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+#define ARCH_HAS_NMI_WATCHDOG         /* See include/linux/nmi.h */
-+#endif
-+
-+#define KDB_VECTOR    0xf9
-+
-+# define irq_ctx_init(cpu) do { } while (0)
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+#include <linux/cpumask.h>
-+extern void fixup_irqs(cpumask_t map);
-+#endif
-+
-+#define __ARCH_HAS_DO_SOFTIRQ 1
-+
-+#endif /* _ASM_IRQ_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/maddr.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/maddr.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/maddr.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/maddr.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,150 @@
-+#ifndef _X86_64_MADDR_H
-+#define _X86_64_MADDR_H
-+
-+#include <xen/features.h>
-+#include <xen/interface/xen.h>
-+
-+/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
-+#define INVALID_P2M_ENTRY     (~0UL)
-+#define FOREIGN_FRAME_BIT     (1UL<<63)
-+#define FOREIGN_FRAME(m)      ((m) | FOREIGN_FRAME_BIT)
-+
-+/* Definitions for machine and pseudophysical addresses. */
-+typedef unsigned long paddr_t;
-+typedef unsigned long maddr_t;
-+
-+#ifdef CONFIG_XEN
-+
-+extern unsigned long *phys_to_machine_mapping;
-+
-+#undef machine_to_phys_mapping
-+extern unsigned long *machine_to_phys_mapping;
-+extern unsigned int   machine_to_phys_order;
-+
-+static inline unsigned long pfn_to_mfn(unsigned long pfn)
-+{
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return pfn;
-+      return phys_to_machine_mapping[(unsigned int)(pfn)] &
-+              ~FOREIGN_FRAME_BIT;
-+}
-+
-+static inline int phys_to_machine_mapping_valid(unsigned long pfn)
-+{
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return 1;
-+      return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
-+}
-+
-+static inline unsigned long mfn_to_pfn(unsigned long mfn)
-+{
-+      unsigned long pfn;
-+
-+      if (xen_feature(XENFEAT_auto_translated_physmap))
-+              return mfn;
-+
-+      if (unlikely((mfn >> machine_to_phys_order) != 0))
-+              return end_pfn;
-+
-+      /* The array access can fail (e.g., device space beyond end of RAM). */
-+      asm (
-+              "1:     movq %1,%0\n"
-+              "2:\n"
-+              ".section .fixup,\"ax\"\n"
-+              "3:     movq %2,%0\n"
-+              "       jmp  2b\n"
-+              ".previous\n"
-+              ".section __ex_table,\"a\"\n"
-+              "       .align 8\n"
-+              "       .quad 1b,3b\n"
-+              ".previous"
-+              : "=r" (pfn)
-+              : "m" (machine_to_phys_mapping[mfn]), "m" (end_pfn) );
-+
-+      return pfn;
-+}
-+
-+/*
-+ * We detect special mappings in one of two ways:
-+ *  1. If the MFN is an I/O page then Xen will set the m2p entry
-+ *     to be outside our maximum possible pseudophys range.
-+ *  2. If the MFN belongs to a different domain then we will certainly
-+ *     not have MFN in our p2m table. Conversely, if the page is ours,
-+ *     then we'll have p2m(m2p(MFN))==MFN.
-+ * If we detect a special mapping then it doesn't have a 'struct page'.
-+ * We force !pfn_valid() by returning an out-of-range pointer.
-+ *
-+ * NB. These checks require that, for any MFN that is not in our reservation,
-+ * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
-+ * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
-+ * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
-+ *
-+ * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
-+ *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
-+ *      require. In all the cases we care about, the FOREIGN_FRAME bit is
-+ *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
-+ */
-+static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
-+{
-+      unsigned long pfn = mfn_to_pfn(mfn);
-+      if ((pfn < end_pfn)
-+          && !xen_feature(XENFEAT_auto_translated_physmap)
-+          && (phys_to_machine_mapping[pfn] != mfn))
-+              return end_pfn; /* force !pfn_valid() */
-+      return pfn;
-+}
-+
-+static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
-+{
-+      if (xen_feature(XENFEAT_auto_translated_physmap)) {
-+              BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
-+              return;
-+      }
-+      phys_to_machine_mapping[pfn] = mfn;
-+}
-+
-+static inline maddr_t phys_to_machine(paddr_t phys)
-+{
-+      maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
-+      machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
-+      return machine;
-+}
-+
-+static inline paddr_t machine_to_phys(maddr_t machine)
-+{
-+      paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
-+      phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
-+      return phys;
-+}
-+
-+static inline paddr_t pte_machine_to_phys(maddr_t machine)
-+{
-+      paddr_t phys;
-+      phys = mfn_to_pfn((machine & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT);
-+      phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
-+      return phys;
-+}
-+
-+#else /* !CONFIG_XEN */
-+
-+#define pfn_to_mfn(pfn) (pfn)
-+#define mfn_to_pfn(mfn) (mfn)
-+#define mfn_to_local_pfn(mfn) (mfn)
-+#define set_phys_to_machine(pfn, mfn) BUG_ON((pfn) != (mfn))
-+#define phys_to_machine_mapping_valid(pfn) (1)
-+#define phys_to_machine(phys) ((maddr_t)(phys))
-+#define machine_to_phys(mach) ((paddr_t)(mach))
-+#define pte_machine_to_phys(mach) ((paddr_t)(mach))
-+
-+#endif /* !CONFIG_XEN */
-+
-+/* VIRT <-> MACHINE conversion */
-+#define virt_to_machine(v)    (phys_to_machine(__pa(v)))
-+#define virt_to_mfn(v)                (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
-+#define mfn_to_virt(m)                (__va(mfn_to_pfn(m) << PAGE_SHIFT))
-+
-+#define __pte_ma(x)     ((pte_t) { (x) } )
-+#define pfn_pte_ma(pfn, prot) __pte_ma((((pfn) << PAGE_SHIFT) | pgprot_val(prot)) & __supported_pte_mask)
-+
-+#endif /* _X86_64_MADDR_H */
-+
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/mmu.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/mmu.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/mmu.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/mmu.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,38 @@
-+#ifndef __x86_64_MMU_H
-+#define __x86_64_MMU_H
-+
-+#include <linux/spinlock.h>
-+#include <asm/semaphore.h>
-+
-+/*
-+ * The x86_64 doesn't have a mmu context, but
-+ * we put the segment information here.
-+ *
-+ * cpu_vm_mask is used to optimize ldt flushing.
-+ */
-+typedef struct { 
-+      void *ldt;
-+      rwlock_t ldtlock; 
-+      int size;
-+      struct semaphore sem; 
-+#ifdef CONFIG_XEN
-+      unsigned pinned:1;
-+      unsigned has_foreign_mappings:1;
-+      struct list_head unpinned;
-+#endif
-+} mm_context_t;
-+
-+#ifdef CONFIG_XEN
-+extern struct list_head mm_unpinned;
-+extern spinlock_t mm_unpinned_lock;
-+
-+/* mm/memory.c:exit_mmap hook */
-+extern void _arch_exit_mmap(struct mm_struct *mm);
-+#define arch_exit_mmap(_mm) _arch_exit_mmap(_mm)
-+
-+/* kernel/fork.c:dup_mmap hook */
-+extern void _arch_dup_mmap(struct mm_struct *mm);
-+#define arch_dup_mmap(mm, oldmm) ((void)(oldmm), _arch_dup_mmap(mm))
-+#endif
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/mmu_context.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/mmu_context.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/mmu_context.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/mmu_context.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,136 @@
-+#ifndef __X86_64_MMU_CONTEXT_H
-+#define __X86_64_MMU_CONTEXT_H
-+
-+#include <linux/config.h>
-+#include <asm/desc.h>
-+#include <asm/atomic.h>
-+#include <asm/pgalloc.h>
-+#include <asm/page.h>
-+#include <asm/pda.h>
-+#include <asm/pgtable.h>
-+#include <asm/tlbflush.h>
-+
-+/*
-+ * possibly do the LDT unload here?
-+ */
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
-+void destroy_context(struct mm_struct *mm);
-+
-+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-+{
-+#if defined(CONFIG_SMP) && !defined(CONFIG_XEN)
-+      if (read_pda(mmu_state) == TLBSTATE_OK) 
-+              write_pda(mmu_state, TLBSTATE_LAZY);
-+#endif
-+}
-+
-+#define prepare_arch_switch(next)     __prepare_arch_switch()
-+
-+static inline void __prepare_arch_switch(void)
-+{
-+      /*
-+       * Save away %es, %ds, %fs and %gs. Must happen before reload
-+       * of cr3/ldt (i.e., not in __switch_to).
-+       */
-+      __asm__ __volatile__ (
-+              "mov %%es,%0 ; mov %%ds,%1 ; mov %%fs,%2 ; mov %%gs,%3"
-+              : "=m" (current->thread.es),
-+                "=m" (current->thread.ds),
-+                "=m" (current->thread.fsindex),
-+                "=m" (current->thread.gsindex) );
-+
-+      if (current->thread.ds)
-+              __asm__ __volatile__ ( "movl %0,%%ds" : : "r" (0) );
-+
-+      if (current->thread.es)
-+              __asm__ __volatile__ ( "movl %0,%%es" : : "r" (0) );
-+
-+      if (current->thread.fsindex) {
-+              __asm__ __volatile__ ( "movl %0,%%fs" : : "r" (0) );
-+              current->thread.fs = 0;
-+      }
-+
-+      if (current->thread.gsindex) {
-+              load_gs_index(0);
-+              current->thread.gs = 0;
-+      }
-+}
-+
-+extern void mm_pin(struct mm_struct *mm);
-+extern void mm_unpin(struct mm_struct *mm);
-+void mm_pin_all(void);
-+
-+static inline void load_cr3(pgd_t *pgd)
-+{
-+      asm volatile("movq %0,%%cr3" :: "r" (phys_to_machine(__pa(pgd))) :
-+                   "memory");
-+}
-+
-+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
-+                           struct task_struct *tsk)
-+{
-+      unsigned cpu = smp_processor_id();
-+      struct mmuext_op _op[3], *op = _op;
-+
-+      if (likely(prev != next)) {
-+              BUG_ON(!next->context.pinned);
-+
-+              /* stop flush ipis for the previous mm */
-+              clear_bit(cpu, &prev->cpu_vm_mask);
-+#if defined(CONFIG_SMP) && !defined(CONFIG_XEN)
-+              write_pda(mmu_state, TLBSTATE_OK);
-+              write_pda(active_mm, next);
-+#endif
-+              set_bit(cpu, &next->cpu_vm_mask);
-+
-+              /* load_cr3(next->pgd) */
-+              op->cmd = MMUEXT_NEW_BASEPTR;
-+              op->arg1.mfn = pfn_to_mfn(__pa(next->pgd) >> PAGE_SHIFT);
-+              op++;
-+
-+              /* xen_new_user_pt(__pa(__user_pgd(next->pgd))) */
-+              op->cmd = MMUEXT_NEW_USER_BASEPTR;
-+              op->arg1.mfn = pfn_to_mfn(__pa(__user_pgd(next->pgd)) >> PAGE_SHIFT);
-+              op++;
-+              
-+              if (unlikely(next->context.ldt != prev->context.ldt)) {
-+                      /* load_LDT_nolock(&next->context, cpu) */
-+                      op->cmd = MMUEXT_SET_LDT;
-+                      op->arg1.linear_addr = (unsigned long)next->context.ldt;
-+                      op->arg2.nr_ents     = next->context.size;
-+                      op++;
-+              }
-+
-+              BUG_ON(HYPERVISOR_mmuext_op(_op, op-_op, NULL, DOMID_SELF));
-+      }
-+#if defined(CONFIG_SMP) && !defined(CONFIG_XEN)
-+      else {
-+              write_pda(mmu_state, TLBSTATE_OK);
-+              if (read_pda(active_mm) != next)
-+                      out_of_line_bug();
-+              if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
-+                      /* We were in lazy tlb mode and leave_mm disabled 
-+                       * tlb flush IPI delivery. We must reload CR3
-+                       * to make sure to use no freed page tables.
-+                       */
-+                        load_cr3(next->pgd);
-+                        xen_new_user_pt(__pa(__user_pgd(next->pgd)));         
-+                      load_LDT_nolock(&next->context, cpu);
-+              }
-+      }
-+#endif
-+}
-+
-+#define deactivate_mm(tsk,mm) do { \
-+      load_gs_index(0); \
-+      asm volatile("movl %0,%%fs"::"r"(0));  \
-+} while(0)
-+
-+static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
-+{
-+      if (!next->context.pinned)
-+              mm_pin(next);
-+      switch_mm(prev, next, NULL);
-+}
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/msr.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/msr.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/msr.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/msr.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,399 @@
-+#ifndef X86_64_MSR_H
-+#define X86_64_MSR_H 1
-+
-+#ifndef __ASSEMBLY__
-+/*
-+ * Access to machine-specific registers (available on 586 and better only)
-+ * Note: the rd* operations modify the parameters directly (without using
-+ * pointer indirection), this allows gcc to optimize better
-+ */
-+
-+#define rdmsr(msr,val1,val2) \
-+       __asm__ __volatile__("rdmsr" \
-+                          : "=a" (val1), "=d" (val2) \
-+                          : "c" (msr))
-+
-+
-+#define rdmsrl(msr,val) do { unsigned long a__,b__; \
-+       __asm__ __volatile__("rdmsr" \
-+                          : "=a" (a__), "=d" (b__) \
-+                          : "c" (msr)); \
-+       val = a__ | (b__<<32); \
-+} while(0)
-+
-+#define wrmsr(msr,val1,val2) \
-+     __asm__ __volatile__("wrmsr" \
-+                        : /* no outputs */ \
-+                        : "c" (msr), "a" (val1), "d" (val2))
-+
-+#define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32) 
-+
-+/* wrmsr with exception handling */
-+#define wrmsr_safe(msr,a,b) ({ int ret__;                     \
-+      asm volatile("2: wrmsr ; xorl %0,%0\n"                  \
-+                   "1:\n\t"                                   \
-+                   ".section .fixup,\"ax\"\n\t"               \
-+                   "3:  movl %4,%0 ; jmp 1b\n\t"              \
-+                   ".previous\n\t"                            \
-+                   ".section __ex_table,\"a\"\n"              \
-+                   "   .align 8\n\t"                          \
-+                   "   .quad  2b,3b\n\t"                      \
-+                   ".previous"                                \
-+                   : "=a" (ret__)                             \
-+                   : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \
-+      ret__; })
-+
-+#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32))
-+
-+#define rdmsr_safe(msr,a,b) \
-+      ({ int ret__;                                           \
-+        asm volatile ("1:       rdmsr\n"                      \
-+                      "2:\n"                                  \
-+                      ".section .fixup,\"ax\"\n"              \
-+                      "3:       movl %4,%0\n"                 \
-+                      " jmp 2b\n"                             \
-+                      ".previous\n"                           \
-+                      ".section __ex_table,\"a\"\n"           \
-+                      " .align 8\n"                           \
-+                      " .quad 1b,3b\n"                                \
-+                      ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b))\
-+                      :"c"(msr), "i"(-EIO), "0"(0));          \
-+        ret__; })             
-+
-+#define rdtsc(low,high) \
-+     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
-+
-+#define rdtscl(low) \
-+     __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
-+
-+#define rdtscll(val) do { \
-+     unsigned int __a,__d; \
-+     asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
-+     (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
-+} while(0)
-+
-+#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
-+
-+#define rdpmc(counter,low,high) \
-+     __asm__ __volatile__("rdpmc" \
-+                        : "=a" (low), "=d" (high) \
-+                        : "c" (counter))
-+
-+static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx,
-+                       unsigned int *ecx, unsigned int *edx)
-+{
-+      __asm__(XEN_CPUID
-+              : "=a" (*eax),
-+                "=b" (*ebx),
-+                "=c" (*ecx),
-+                "=d" (*edx)
-+              : "0" (op));
-+}
-+
-+/* Some CPUID calls want 'count' to be placed in ecx */
-+static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
-+              int *edx)
-+{
-+      __asm__(XEN_CPUID
-+              : "=a" (*eax),
-+                "=b" (*ebx),
-+                "=c" (*ecx),
-+                "=d" (*edx)
-+              : "0" (op), "c" (count));
-+}
-+
-+/*
-+ * CPUID functions returning a single datum
-+ */
-+static inline unsigned int cpuid_eax(unsigned int op)
-+{
-+      unsigned int eax;
-+
-+      __asm__(XEN_CPUID
-+              : "=a" (eax)
-+              : "0" (op)
-+              : "bx", "cx", "dx");
-+      return eax;
-+}
-+static inline unsigned int cpuid_ebx(unsigned int op)
-+{
-+      unsigned int eax, ebx;
-+
-+      __asm__(XEN_CPUID
-+              : "=a" (eax), "=b" (ebx)
-+              : "0" (op)
-+              : "cx", "dx" );
-+      return ebx;
-+}
-+static inline unsigned int cpuid_ecx(unsigned int op)
-+{
-+      unsigned int eax, ecx;
-+
-+      __asm__(XEN_CPUID
-+              : "=a" (eax), "=c" (ecx)
-+              : "0" (op)
-+              : "bx", "dx" );
-+      return ecx;
-+}
-+static inline unsigned int cpuid_edx(unsigned int op)
-+{
-+      unsigned int eax, edx;
-+
-+      __asm__(XEN_CPUID
-+              : "=a" (eax), "=d" (edx)
-+              : "0" (op)
-+              : "bx", "cx");
-+      return edx;
-+}
-+
-+#define MSR_IA32_UCODE_WRITE          0x79
-+#define MSR_IA32_UCODE_REV            0x8b
-+
-+
-+#endif
-+
-+/* AMD/K8 specific MSRs */ 
-+#define MSR_EFER 0xc0000080           /* extended feature register */
-+#define MSR_STAR 0xc0000081           /* legacy mode SYSCALL target */
-+#define MSR_LSTAR 0xc0000082          /* long mode SYSCALL target */
-+#define MSR_CSTAR 0xc0000083          /* compatibility mode SYSCALL target */
-+#define MSR_SYSCALL_MASK 0xc0000084   /* EFLAGS mask for syscall */
-+#define MSR_FS_BASE 0xc0000100                /* 64bit GS base */
-+#define MSR_GS_BASE 0xc0000101                /* 64bit FS base */
-+#define MSR_KERNEL_GS_BASE  0xc0000102        /* SwapGS GS shadow (or USER_GS from kernel) */ 
-+/* EFER bits: */ 
-+#define _EFER_SCE 0  /* SYSCALL/SYSRET */
-+#define _EFER_LME 8  /* Long mode enable */
-+#define _EFER_LMA 10 /* Long mode active (read-only) */
-+#define _EFER_NX 11  /* No execute enable */
-+
-+#define EFER_SCE (1<<_EFER_SCE)
-+#define EFER_LME (1<<_EFER_LME)
-+#define EFER_LMA (1<<_EFER_LMA)
-+#define EFER_NX (1<<_EFER_NX)
-+
-+/* Intel MSRs. Some also available on other CPUs */
-+#define MSR_IA32_TSC          0x10
-+#define MSR_IA32_PLATFORM_ID  0x17
-+
-+#define MSR_IA32_PERFCTR0      0xc1
-+#define MSR_IA32_PERFCTR1      0xc2
-+
-+#define MSR_MTRRcap           0x0fe
-+#define MSR_IA32_BBL_CR_CTL        0x119
-+
-+#define MSR_IA32_SYSENTER_CS  0x174
-+#define MSR_IA32_SYSENTER_ESP 0x175
-+#define MSR_IA32_SYSENTER_EIP 0x176
-+
-+#define MSR_IA32_MCG_CAP       0x179
-+#define MSR_IA32_MCG_STATUS        0x17a
-+#define MSR_IA32_MCG_CTL       0x17b
-+
-+#define MSR_IA32_EVNTSEL0      0x186
-+#define MSR_IA32_EVNTSEL1      0x187
-+
-+#define MSR_IA32_DEBUGCTLMSR       0x1d9
-+#define MSR_IA32_LASTBRANCHFROMIP  0x1db
-+#define MSR_IA32_LASTBRANCHTOIP        0x1dc
-+#define MSR_IA32_LASTINTFROMIP     0x1dd
-+#define MSR_IA32_LASTINTTOIP       0x1de
-+
-+#define MSR_MTRRfix64K_00000  0x250
-+#define MSR_MTRRfix16K_80000  0x258
-+#define MSR_MTRRfix16K_A0000  0x259
-+#define MSR_MTRRfix4K_C0000   0x268
-+#define MSR_MTRRfix4K_C8000   0x269
-+#define MSR_MTRRfix4K_D0000   0x26a
-+#define MSR_MTRRfix4K_D8000   0x26b
-+#define MSR_MTRRfix4K_E0000   0x26c
-+#define MSR_MTRRfix4K_E8000   0x26d
-+#define MSR_MTRRfix4K_F0000   0x26e
-+#define MSR_MTRRfix4K_F8000   0x26f
-+#define MSR_MTRRdefType               0x2ff
-+
-+#define MSR_IA32_MC0_CTL       0x400
-+#define MSR_IA32_MC0_STATUS        0x401
-+#define MSR_IA32_MC0_ADDR      0x402
-+#define MSR_IA32_MC0_MISC      0x403
-+
-+#define MSR_P6_PERFCTR0                       0xc1
-+#define MSR_P6_PERFCTR1                       0xc2
-+#define MSR_P6_EVNTSEL0                       0x186
-+#define MSR_P6_EVNTSEL1                       0x187
-+
-+/* K7/K8 MSRs. Not complete. See the architecture manual for a more complete list. */
-+#define MSR_K7_EVNTSEL0            0xC0010000
-+#define MSR_K7_PERFCTR0            0xC0010004
-+#define MSR_K7_EVNTSEL1            0xC0010001
-+#define MSR_K7_PERFCTR1            0xC0010005
-+#define MSR_K7_EVNTSEL2            0xC0010002
-+#define MSR_K7_PERFCTR2            0xC0010006
-+#define MSR_K7_EVNTSEL3            0xC0010003
-+#define MSR_K7_PERFCTR3            0xC0010007
-+#define MSR_K8_TOP_MEM1                  0xC001001A
-+#define MSR_K8_TOP_MEM2                  0xC001001D
-+#define MSR_K8_SYSCFG            0xC0010010
-+#define MSR_K8_HWCR              0xC0010015
-+
-+/* K6 MSRs */
-+#define MSR_K6_EFER                   0xC0000080
-+#define MSR_K6_STAR                   0xC0000081
-+#define MSR_K6_WHCR                   0xC0000082
-+#define MSR_K6_UWCCR                  0xC0000085
-+#define MSR_K6_PSOR                   0xC0000087
-+#define MSR_K6_PFIR                   0xC0000088
-+
-+/* Centaur-Hauls/IDT defined MSRs. */
-+#define MSR_IDT_FCR1                  0x107
-+#define MSR_IDT_FCR2                  0x108
-+#define MSR_IDT_FCR3                  0x109
-+#define MSR_IDT_FCR4                  0x10a
-+
-+#define MSR_IDT_MCR0                  0x110
-+#define MSR_IDT_MCR1                  0x111
-+#define MSR_IDT_MCR2                  0x112
-+#define MSR_IDT_MCR3                  0x113
-+#define MSR_IDT_MCR4                  0x114
-+#define MSR_IDT_MCR5                  0x115
-+#define MSR_IDT_MCR6                  0x116
-+#define MSR_IDT_MCR7                  0x117
-+#define MSR_IDT_MCR_CTRL              0x120
-+
-+/* VIA Cyrix defined MSRs*/
-+#define MSR_VIA_FCR                   0x1107
-+#define MSR_VIA_LONGHAUL              0x110a
-+#define MSR_VIA_RNG                   0x110b
-+#define MSR_VIA_BCR2                  0x1147
-+
-+/* Intel defined MSRs. */
-+#define MSR_IA32_P5_MC_ADDR           0
-+#define MSR_IA32_P5_MC_TYPE           1
-+#define MSR_IA32_PLATFORM_ID          0x17
-+#define MSR_IA32_EBL_CR_POWERON               0x2a
-+
-+#define MSR_IA32_APICBASE               0x1b
-+#define MSR_IA32_APICBASE_BSP           (1<<8)
-+#define MSR_IA32_APICBASE_ENABLE        (1<<11)
-+#define MSR_IA32_APICBASE_BASE          (0xfffff<<12)
-+
-+/* P4/Xeon+ specific */
-+#define MSR_IA32_MCG_EAX              0x180
-+#define MSR_IA32_MCG_EBX              0x181
-+#define MSR_IA32_MCG_ECX              0x182
-+#define MSR_IA32_MCG_EDX              0x183
-+#define MSR_IA32_MCG_ESI              0x184
-+#define MSR_IA32_MCG_EDI              0x185
-+#define MSR_IA32_MCG_EBP              0x186
-+#define MSR_IA32_MCG_ESP              0x187
-+#define MSR_IA32_MCG_EFLAGS           0x188
-+#define MSR_IA32_MCG_EIP              0x189
-+#define MSR_IA32_MCG_RESERVED         0x18A
-+
-+#define MSR_P6_EVNTSEL0                       0x186
-+#define MSR_P6_EVNTSEL1                       0x187
-+
-+#define MSR_IA32_PERF_STATUS          0x198
-+#define MSR_IA32_PERF_CTL             0x199
-+
-+#define MSR_IA32_THERM_CONTROL                0x19a
-+#define MSR_IA32_THERM_INTERRUPT      0x19b
-+#define MSR_IA32_THERM_STATUS         0x19c
-+#define MSR_IA32_MISC_ENABLE          0x1a0
-+
-+#define MSR_IA32_DEBUGCTLMSR          0x1d9
-+#define MSR_IA32_LASTBRANCHFROMIP     0x1db
-+#define MSR_IA32_LASTBRANCHTOIP               0x1dc
-+#define MSR_IA32_LASTINTFROMIP                0x1dd
-+#define MSR_IA32_LASTINTTOIP          0x1de
-+
-+#define MSR_IA32_MC0_CTL              0x400
-+#define MSR_IA32_MC0_STATUS           0x401
-+#define MSR_IA32_MC0_ADDR             0x402
-+#define MSR_IA32_MC0_MISC             0x403
-+
-+/* Pentium IV performance counter MSRs */
-+#define MSR_P4_BPU_PERFCTR0           0x300
-+#define MSR_P4_BPU_PERFCTR1           0x301
-+#define MSR_P4_BPU_PERFCTR2           0x302
-+#define MSR_P4_BPU_PERFCTR3           0x303
-+#define MSR_P4_MS_PERFCTR0            0x304
-+#define MSR_P4_MS_PERFCTR1            0x305
-+#define MSR_P4_MS_PERFCTR2            0x306
-+#define MSR_P4_MS_PERFCTR3            0x307
-+#define MSR_P4_FLAME_PERFCTR0                 0x308
-+#define MSR_P4_FLAME_PERFCTR1                 0x309
-+#define MSR_P4_FLAME_PERFCTR2                 0x30a
-+#define MSR_P4_FLAME_PERFCTR3                 0x30b
-+#define MSR_P4_IQ_PERFCTR0            0x30c
-+#define MSR_P4_IQ_PERFCTR1            0x30d
-+#define MSR_P4_IQ_PERFCTR2            0x30e
-+#define MSR_P4_IQ_PERFCTR3            0x30f
-+#define MSR_P4_IQ_PERFCTR4            0x310
-+#define MSR_P4_IQ_PERFCTR5            0x311
-+#define MSR_P4_BPU_CCCR0              0x360
-+#define MSR_P4_BPU_CCCR1              0x361
-+#define MSR_P4_BPU_CCCR2              0x362
-+#define MSR_P4_BPU_CCCR3              0x363
-+#define MSR_P4_MS_CCCR0               0x364
-+#define MSR_P4_MS_CCCR1               0x365
-+#define MSR_P4_MS_CCCR2               0x366
-+#define MSR_P4_MS_CCCR3               0x367
-+#define MSR_P4_FLAME_CCCR0            0x368
-+#define MSR_P4_FLAME_CCCR1            0x369
-+#define MSR_P4_FLAME_CCCR2            0x36a
-+#define MSR_P4_FLAME_CCCR3            0x36b
-+#define MSR_P4_IQ_CCCR0               0x36c
-+#define MSR_P4_IQ_CCCR1               0x36d
-+#define MSR_P4_IQ_CCCR2               0x36e
-+#define MSR_P4_IQ_CCCR3               0x36f
-+#define MSR_P4_IQ_CCCR4               0x370
-+#define MSR_P4_IQ_CCCR5               0x371
-+#define MSR_P4_ALF_ESCR0              0x3ca
-+#define MSR_P4_ALF_ESCR1              0x3cb
-+#define MSR_P4_BPU_ESCR0              0x3b2
-+#define MSR_P4_BPU_ESCR1              0x3b3
-+#define MSR_P4_BSU_ESCR0              0x3a0
-+#define MSR_P4_BSU_ESCR1              0x3a1
-+#define MSR_P4_CRU_ESCR0              0x3b8
-+#define MSR_P4_CRU_ESCR1              0x3b9
-+#define MSR_P4_CRU_ESCR2              0x3cc
-+#define MSR_P4_CRU_ESCR3              0x3cd
-+#define MSR_P4_CRU_ESCR4              0x3e0
-+#define MSR_P4_CRU_ESCR5              0x3e1
-+#define MSR_P4_DAC_ESCR0              0x3a8
-+#define MSR_P4_DAC_ESCR1              0x3a9
-+#define MSR_P4_FIRM_ESCR0             0x3a4
-+#define MSR_P4_FIRM_ESCR1             0x3a5
-+#define MSR_P4_FLAME_ESCR0            0x3a6
-+#define MSR_P4_FLAME_ESCR1            0x3a7
-+#define MSR_P4_FSB_ESCR0              0x3a2
-+#define MSR_P4_FSB_ESCR1              0x3a3
-+#define MSR_P4_IQ_ESCR0               0x3ba
-+#define MSR_P4_IQ_ESCR1               0x3bb
-+#define MSR_P4_IS_ESCR0               0x3b4
-+#define MSR_P4_IS_ESCR1               0x3b5
-+#define MSR_P4_ITLB_ESCR0             0x3b6
-+#define MSR_P4_ITLB_ESCR1             0x3b7
-+#define MSR_P4_IX_ESCR0               0x3c8
-+#define MSR_P4_IX_ESCR1               0x3c9
-+#define MSR_P4_MOB_ESCR0              0x3aa
-+#define MSR_P4_MOB_ESCR1              0x3ab
-+#define MSR_P4_MS_ESCR0               0x3c0
-+#define MSR_P4_MS_ESCR1               0x3c1
-+#define MSR_P4_PMH_ESCR0              0x3ac
-+#define MSR_P4_PMH_ESCR1              0x3ad
-+#define MSR_P4_RAT_ESCR0              0x3bc
-+#define MSR_P4_RAT_ESCR1              0x3bd
-+#define MSR_P4_SAAT_ESCR0             0x3ae
-+#define MSR_P4_SAAT_ESCR1             0x3af
-+#define MSR_P4_SSU_ESCR0              0x3be
-+#define MSR_P4_SSU_ESCR1              0x3bf    /* guess: not defined in manual */
-+#define MSR_P4_TBPU_ESCR0             0x3c2
-+#define MSR_P4_TBPU_ESCR1             0x3c3
-+#define MSR_P4_TC_ESCR0               0x3c4
-+#define MSR_P4_TC_ESCR1               0x3c5
-+#define MSR_P4_U2L_ESCR0              0x3b0
-+#define MSR_P4_U2L_ESCR1              0x3b1
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/nmi.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/nmi.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/nmi.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/nmi.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,75 @@
-+/*
-+ *  linux/include/asm-i386/nmi.h
-+ */
-+#ifndef ASM_NMI_H
-+#define ASM_NMI_H
-+
-+#include <linux/pm.h>
-+
-+#include <xen/interface/nmi.h>
-+
-+struct pt_regs;
-+ 
-+typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu);
-+ 
-+/** 
-+ * set_nmi_callback
-+ *
-+ * Set a handler for an NMI. Only one handler may be
-+ * set. Return 1 if the NMI was handled.
-+ */
-+void set_nmi_callback(nmi_callback_t callback);
-+ 
-+/** 
-+ * unset_nmi_callback
-+ *
-+ * Remove the handler previously set.
-+ */
-+void unset_nmi_callback(void);
-+ 
-+#ifdef CONFIG_PM
-+ 
-+/** Replace the PM callback routine for NMI. */
-+struct pm_dev * set_nmi_pm_callback(pm_callback callback);
-+
-+/** Unset the PM callback routine back to the default. */
-+void unset_nmi_pm_callback(struct pm_dev * dev);
-+
-+#else
-+
-+static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
-+{
-+      return 0;
-+} 
-+ 
-+static inline void unset_nmi_pm_callback(struct pm_dev * dev)
-+{
-+}
-+
-+#endif /* CONFIG_PM */
-+ 
-+extern void default_do_nmi(struct pt_regs *);
-+extern void die_nmi(char *str, struct pt_regs *regs);
-+
-+static inline unsigned char get_nmi_reason(void)
-+{
-+        shared_info_t *s = HYPERVISOR_shared_info;
-+        unsigned char reason = 0;
-+
-+        /* construct a value which looks like it came from
-+         * port 0x61.
-+         */
-+        if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
-+                reason |= 0x40;
-+        if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
-+                reason |= 0x80;
-+
-+        return reason;
-+}
-+
-+extern int panic_on_timeout;
-+extern int unknown_nmi_panic;
-+
-+extern int check_nmi_watchdog(void);
-+ 
-+#endif /* ASM_NMI_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/page.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/page.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/page.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/page.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,211 @@
-+#ifndef _X86_64_PAGE_H
-+#define _X86_64_PAGE_H
-+
-+#include <linux/config.h>
-+/* #include <linux/string.h> */
-+#ifndef __ASSEMBLY__
-+#include <linux/kernel.h>
-+#include <linux/types.h>
-+#include <asm/bug.h>
-+#endif
-+#include <xen/interface/xen.h> 
-+#include <xen/foreign_page.h>
-+
-+#define arch_free_page(_page,_order)                  \
-+({    int foreign = PageForeign(_page);               \
-+      if (foreign)                                    \
-+              (PageForeignDestructor(_page))(_page);  \
-+      foreign;                                        \
-+})
-+#define HAVE_ARCH_FREE_PAGE
-+
-+#ifdef CONFIG_XEN_SCRUB_PAGES
-+#define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
-+#else
-+#define scrub_pages(_p,_n) ((void)0)
-+#endif
-+
-+/* PAGE_SHIFT determines the page size */
-+#define PAGE_SHIFT    12
-+#ifdef __ASSEMBLY__
-+#define PAGE_SIZE     (0x1 << PAGE_SHIFT)
-+#else
-+#define PAGE_SIZE     (1UL << PAGE_SHIFT)
-+#endif
-+#define PAGE_MASK     (~(PAGE_SIZE-1))
-+
-+/* See Documentation/x86_64/mm.txt for a description of the memory map. */
-+#define __PHYSICAL_MASK_SHIFT 46
-+#define __PHYSICAL_MASK               ((1UL << __PHYSICAL_MASK_SHIFT) - 1)
-+#define __VIRTUAL_MASK_SHIFT  48
-+#define __VIRTUAL_MASK                ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
-+
-+#define PHYSICAL_PAGE_MASK    (~(PAGE_SIZE-1) & __PHYSICAL_MASK)
-+
-+#define THREAD_ORDER 1 
-+#define THREAD_SIZE  (PAGE_SIZE << THREAD_ORDER)
-+#define CURRENT_MASK (~(THREAD_SIZE-1))
-+
-+#define EXCEPTION_STACK_ORDER 0
-+#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
-+
-+#define DEBUG_STACK_ORDER EXCEPTION_STACK_ORDER
-+#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
-+
-+#define IRQSTACK_ORDER 2
-+#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER)
-+
-+#define STACKFAULT_STACK 1
-+#define DOUBLEFAULT_STACK 2
-+#define NMI_STACK 3
-+#define DEBUG_STACK 4
-+#define MCE_STACK 5
-+#define N_EXCEPTION_STACKS 5  /* hw limit: 7 */
-+
-+#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
-+#define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
-+
-+#define HPAGE_SHIFT PMD_SHIFT
-+#define HPAGE_SIZE    ((1UL) << HPAGE_SHIFT)
-+#define HPAGE_MASK    (~(HPAGE_SIZE - 1))
-+#define HUGETLB_PAGE_ORDER    (HPAGE_SHIFT - PAGE_SHIFT)
-+
-+#ifdef __KERNEL__
-+#ifndef __ASSEMBLY__
-+
-+extern unsigned long end_pfn;
-+
-+#include <asm/maddr.h>
-+
-+void clear_page(void *);
-+void copy_page(void *, void *);
-+
-+#define clear_user_page(page, vaddr, pg)      clear_page(page)
-+#define copy_user_page(to, from, vaddr, pg)   copy_page(to, from)
-+
-+#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
-+#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
-+
-+/*
-+ * These are used to make use of C type-checking..
-+ */
-+typedef struct { unsigned long pte; } pte_t;
-+typedef struct { unsigned long pmd; } pmd_t;
-+typedef struct { unsigned long pud; } pud_t;
-+typedef struct { unsigned long pgd; } pgd_t;
-+#define PTE_MASK      PHYSICAL_PAGE_MASK
-+
-+typedef struct { unsigned long pgprot; } pgprot_t;
-+
-+#define pte_val(x)    (((x).pte & 1) ? pte_machine_to_phys((x).pte) : \
-+                       (x).pte)
-+#define pte_val_ma(x) ((x).pte)
-+
-+static inline unsigned long pmd_val(pmd_t x)
-+{
-+      unsigned long ret = x.pmd;
-+      if (ret) ret = pte_machine_to_phys(ret);
-+      return ret;
-+}
-+
-+static inline unsigned long pud_val(pud_t x)
-+{
-+      unsigned long ret = x.pud;
-+      if (ret) ret = pte_machine_to_phys(ret);
-+      return ret;
-+}
-+
-+static inline unsigned long pgd_val(pgd_t x)
-+{
-+      unsigned long ret = x.pgd;
-+      if (ret) ret = pte_machine_to_phys(ret);
-+      return ret;
-+}
-+
-+#define pgprot_val(x) ((x).pgprot)
-+
-+static inline pte_t __pte(unsigned long x)
-+{
-+      if (x & 1) x = phys_to_machine(x);
-+      return ((pte_t) { (x) });
-+}
-+
-+static inline pmd_t __pmd(unsigned long x)
-+{
-+      if ((x & 1)) x = phys_to_machine(x);
-+      return ((pmd_t) { (x) });
-+}
-+
-+static inline pud_t __pud(unsigned long x)
-+{
-+      if ((x & 1)) x = phys_to_machine(x);
-+      return ((pud_t) { (x) });
-+}
-+
-+static inline pgd_t __pgd(unsigned long x)
-+{
-+      if ((x & 1)) x = phys_to_machine(x);
-+      return ((pgd_t) { (x) });
-+}
-+
-+#define __pgprot(x)   ((pgprot_t) { (x) } )
-+
-+#define __PHYSICAL_START      ((unsigned long)CONFIG_PHYSICAL_START)
-+#define __START_KERNEL                (__START_KERNEL_map + __PHYSICAL_START)
-+#define __START_KERNEL_map    0xffffffff80000000UL
-+#define __PAGE_OFFSET           0xffff880000000000UL  
-+
-+#else
-+#define __PHYSICAL_START      CONFIG_PHYSICAL_START
-+#define __START_KERNEL                (__START_KERNEL_map + __PHYSICAL_START)
-+#define __START_KERNEL_map    0xffffffff80000000
-+#define __PAGE_OFFSET           0xffff880000000000
-+#endif /* !__ASSEMBLY__ */
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+#undef LOAD_OFFSET
-+#define LOAD_OFFSET           0
-+#endif /* CONFIG_XEN_COMPAT_030002 */
-+
-+/* to align the pointer to the (next) page boundary */
-+#define PAGE_ALIGN(addr)      (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-+
-+#define KERNEL_TEXT_SIZE  (40UL*1024*1024)
-+#define KERNEL_TEXT_START 0xffffffff80000000UL 
-+
-+#define PAGE_OFFSET           ((unsigned long)__PAGE_OFFSET)
-+
-+/* Note: __pa(&symbol_visible_to_c) should be always replaced with __pa_symbol.
-+   Otherwise you risk miscompilation. */ 
-+#define __pa(x)                       (((unsigned long)(x)>=__START_KERNEL_map)?(unsigned long)(x) - (unsigned long)__START_KERNEL_map:(unsigned long)(x) - PAGE_OFFSET)
-+/* __pa_symbol should be used for C visible symbols.
-+   This seems to be the official gcc blessed way to do such arithmetic. */ 
-+#define __pa_symbol(x)                \
-+      ({unsigned long v;  \
-+        asm("" : "=r" (v) : "0" (x)); \
-+        __pa(v); })
-+
-+#define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
-+#define __boot_va(x)          __va(x)
-+#define __boot_pa(x)          __pa(x)
-+#ifdef CONFIG_FLATMEM
-+#define pfn_to_page(pfn)      (mem_map + (pfn))
-+#define page_to_pfn(page)     ((unsigned long)((page) - mem_map))
-+#define pfn_valid(pfn)                ((pfn) < end_pfn)
-+#endif
-+
-+#define virt_to_page(kaddr)   pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-+#define virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-+#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
-+
-+#define VM_DATA_DEFAULT_FLAGS \
-+      (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
-+       VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-+
-+#define __HAVE_ARCH_GATE_AREA 1       
-+
-+#endif /* __KERNEL__ */
-+
-+#include <asm-generic/page.h>
-+
-+#endif /* _X86_64_PAGE_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/pci.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/pci.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/pci.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/pci.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,174 @@
-+#ifndef __x8664_PCI_H
-+#define __x8664_PCI_H
-+
-+#include <linux/config.h>
-+#include <asm/io.h>
-+
-+#ifdef __KERNEL__
-+
-+#include <linux/mm.h> /* for struct page */
-+
-+/* Can be used to override the logic in pci_scan_bus for skipping
-+   already-configured bus numbers - to be used for buggy BIOSes
-+   or architectures with incomplete PCI setup by the loader */
-+
-+#ifdef CONFIG_PCI
-+extern unsigned int pcibios_assign_all_busses(void);
-+#else
-+#define pcibios_assign_all_busses()   0
-+#endif
-+#define pcibios_scan_all_fns(a, b)    0
-+
-+extern unsigned long pci_mem_start;
-+#define PCIBIOS_MIN_IO                0x1000
-+#define PCIBIOS_MIN_MEM               (pci_mem_start)
-+
-+#define PCIBIOS_MIN_CARDBUS_IO        0x4000
-+
-+void pcibios_config_init(void);
-+struct pci_bus * pcibios_scan_root(int bus);
-+extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
-+extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
-+
-+void pcibios_set_master(struct pci_dev *dev);
-+void pcibios_penalize_isa_irq(int irq, int active);
-+struct irq_routing_table *pcibios_get_irq_routing_table(void);
-+int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
-+
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <asm/scatterlist.h>
-+#include <linux/string.h>
-+#include <asm/page.h>
-+#include <linux/dma-mapping.h> /* for have_iommu */
-+
-+extern int iommu_setup(char *opt);
-+
-+/* The PCI address space does equal the physical memory
-+ * address space.  The networking and block device layers use
-+ * this boolean for bounce buffer decisions
-+ *
-+ * On AMD64 it mostly equals, but we set it to zero if a hardware
-+ * IOMMU (gart) of sotware IOMMU (swiotlb) is available.
-+ */
-+#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-+
-+#ifdef CONFIG_GART_IOMMU
-+
-+/*
-+ * x86-64 always supports DAC, but sometimes it is useful to force
-+ * devices through the IOMMU to get automatic sg list merging.
-+ * Optional right now.
-+ */
-+extern int iommu_sac_force;
-+#define pci_dac_dma_supported(pci_dev, mask)  (!iommu_sac_force)
-+
-+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)     \
-+      dma_addr_t ADDR_NAME;
-+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)               \
-+      __u32 LEN_NAME;
-+#define pci_unmap_addr(PTR, ADDR_NAME)                        \
-+      ((PTR)->ADDR_NAME)
-+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)               \
-+      (((PTR)->ADDR_NAME) = (VAL))
-+#define pci_unmap_len(PTR, LEN_NAME)                  \
-+      ((PTR)->LEN_NAME)
-+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)         \
-+      (((PTR)->LEN_NAME) = (VAL))
-+
-+#elif defined(CONFIG_SWIOTLB)
-+
-+#define pci_dac_dma_supported(pci_dev, mask)    1
-+
-+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)     \
-+      dma_addr_t ADDR_NAME;
-+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)               \
-+      __u32 LEN_NAME;
-+#define pci_unmap_addr(PTR, ADDR_NAME)                        \
-+      ((PTR)->ADDR_NAME)
-+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)               \
-+      (((PTR)->ADDR_NAME) = (VAL))
-+#define pci_unmap_len(PTR, LEN_NAME)                  \
-+      ((PTR)->LEN_NAME)
-+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)         \
-+      (((PTR)->LEN_NAME) = (VAL))
-+
-+#else
-+/* No IOMMU */
-+
-+#define pci_dac_dma_supported(pci_dev, mask)    1
-+
-+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-+#define pci_unmap_addr(PTR, ADDR_NAME)                (0)
-+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)       do { } while (0)
-+#define pci_unmap_len(PTR, LEN_NAME)          (0)
-+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-+
-+#endif
-+
-+#include <asm-generic/pci-dma-compat.h>
-+
-+static inline dma64_addr_t
-+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
-+{
-+      return ((dma64_addr_t) page_to_phys(page) +
-+              (dma64_addr_t) offset);
-+}
-+
-+static inline struct page *
-+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
-+{
-+      return virt_to_page(__va(dma_addr));    
-+}
-+
-+static inline unsigned long
-+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
-+{
-+      return (dma_addr & ~PAGE_MASK);
-+}
-+
-+static inline void
-+pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-+{
-+}
-+
-+static inline void
-+pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
-+{
-+      flush_write_buffers();
-+}
-+
-+#ifdef CONFIG_PCI
-+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
-+                                      enum pci_dma_burst_strategy *strat,
-+                                      unsigned long *strategy_parameter)
-+{
-+      *strat = PCI_DMA_BURST_INFINITY;
-+      *strategy_parameter = ~0UL;
-+}
-+#endif
-+
-+#define HAVE_PCI_MMAP
-+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-+                             enum pci_mmap_state mmap_state, int write_combine);
-+
-+static inline void pcibios_add_platform_entries(struct pci_dev *dev)
-+{
-+}
-+
-+#endif /* __KERNEL__ */
-+
-+/* generic pci stuff */
-+#ifdef CONFIG_PCI
-+#include <asm-generic/pci.h>
-+#endif
-+
-+/* On Xen we have to scan all functions since Xen hides bridges from
-+ * us.  If a bridge is at fn=0 and that slot has a multifunction
-+ * device, we won't find the additional devices without scanning all
-+ * functions. */
-+#undef pcibios_scan_all_fns
-+#define pcibios_scan_all_fns(a, b)    1
-+
-+#endif /* __x8664_PCI_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/pgalloc.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/pgalloc.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/pgalloc.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/pgalloc.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,198 @@
-+#ifndef _X86_64_PGALLOC_H
-+#define _X86_64_PGALLOC_H
-+
-+#include <asm/fixmap.h>
-+#include <asm/pda.h>
-+#include <linux/threads.h>
-+#include <linux/mm.h>
-+#include <asm/io.h>           /* for phys_to_virt and page_to_pseudophys */
-+
-+#include <xen/features.h>
-+void make_page_readonly(void *va, unsigned int feature);
-+void make_page_writable(void *va, unsigned int feature);
-+void make_pages_readonly(void *va, unsigned int nr, unsigned int feature);
-+void make_pages_writable(void *va, unsigned int nr, unsigned int feature);
-+
-+#define __user_pgd(pgd) ((pgd) + PTRS_PER_PGD)
-+
-+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
-+{
-+      set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)));
-+}
-+
-+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
-+{
-+      if (unlikely((mm)->context.pinned)) {
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                             (unsigned long)__va(page_to_pfn(pte) << PAGE_SHIFT),
-+                             pfn_pte(page_to_pfn(pte), PAGE_KERNEL_RO), 0));
-+              set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT)));
-+      } else {
-+              *(pmd) = __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT));
-+      }
-+}
-+
-+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
-+{
-+      if (unlikely((mm)->context.pinned)) {
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                             (unsigned long)pmd,
-+                             pfn_pte(virt_to_phys(pmd)>>PAGE_SHIFT, 
-+                                     PAGE_KERNEL_RO), 0));
-+              set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)));
-+      } else {
-+              *(pud) =  __pud(_PAGE_TABLE | __pa(pmd));
-+      }
-+}
-+
-+/*
-+ * We need to use the batch mode here, but pgd_pupulate() won't be
-+ * be called frequently.
-+ */
-+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
-+{
-+      if (unlikely((mm)->context.pinned)) {
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                             (unsigned long)pud,
-+                             pfn_pte(virt_to_phys(pud)>>PAGE_SHIFT, 
-+                                     PAGE_KERNEL_RO), 0));
-+              set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud)));
-+              set_pgd(__user_pgd(pgd), __pgd(_PAGE_TABLE | __pa(pud)));
-+      } else {
-+              *(pgd) =  __pgd(_PAGE_TABLE | __pa(pud));
-+              *(__user_pgd(pgd)) = *(pgd);
-+      }
-+}
-+
-+static inline void pmd_free(pmd_t *pmd)
-+{
-+      pte_t *ptep = virt_to_ptep(pmd);
-+
-+      if (!pte_write(*ptep)) {
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                      (unsigned long)pmd,
-+                      pfn_pte(virt_to_phys(pmd)>>PAGE_SHIFT, PAGE_KERNEL),
-+                      0));
-+      }
-+      free_page((unsigned long)pmd);
-+}
-+
-+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-+{
-+        pmd_t *pmd = (pmd_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
-+        return pmd;
-+}
-+
-+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
-+{
-+        pud_t *pud = (pud_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
-+        return pud;
-+}
-+
-+static inline void pud_free(pud_t *pud)
-+{
-+      pte_t *ptep = virt_to_ptep(pud);
-+
-+      if (!pte_write(*ptep)) {
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                      (unsigned long)pud,
-+                      pfn_pte(virt_to_phys(pud)>>PAGE_SHIFT, PAGE_KERNEL),
-+                      0));
-+      }
-+      free_page((unsigned long)pud);
-+}
-+
-+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
-+{
-+        /*
-+         * We allocate two contiguous pages for kernel and user.
-+         */
-+        unsigned boundary;
-+      pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 1);
-+
-+      if (!pgd)
-+              return NULL;
-+      /*
-+       * Copy kernel pointers in from init.
-+       * Could keep a freelist or slab cache of those because the kernel
-+       * part never changes.
-+       */
-+      boundary = pgd_index(__PAGE_OFFSET);
-+      memset(pgd, 0, boundary * sizeof(pgd_t));
-+      memcpy(pgd + boundary,
-+             init_level4_pgt + boundary,
-+             (PTRS_PER_PGD - boundary) * sizeof(pgd_t));
-+
-+      memset(__user_pgd(pgd), 0, PAGE_SIZE); /* clean up user pgd */
-+        /*
-+         * Set level3_user_pgt for vsyscall area
-+         */
-+      set_pgd(__user_pgd(pgd) + pgd_index(VSYSCALL_START), 
-+                mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
-+      return pgd;
-+}
-+
-+static inline void pgd_free(pgd_t *pgd)
-+{
-+      pte_t *ptep = virt_to_ptep(pgd);
-+
-+      if (!pte_write(*ptep)) {
-+              xen_pgd_unpin(__pa(pgd));
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                             (unsigned long)pgd,
-+                             pfn_pte(virt_to_phys(pgd)>>PAGE_SHIFT, PAGE_KERNEL),
-+                             0));
-+      }
-+
-+      ptep = virt_to_ptep(__user_pgd(pgd));
-+
-+      if (!pte_write(*ptep)) {
-+              xen_pgd_unpin(__pa(__user_pgd(pgd)));
-+              BUG_ON(HYPERVISOR_update_va_mapping(
-+                             (unsigned long)__user_pgd(pgd),
-+                             pfn_pte(virt_to_phys(__user_pgd(pgd))>>PAGE_SHIFT, 
-+                                     PAGE_KERNEL),
-+                             0));
-+      }
-+
-+      free_pages((unsigned long)pgd, 1);
-+}
-+
-+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
-+{
-+        pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
-+        if (pte)
-+              make_page_readonly(pte, XENFEAT_writable_page_tables);
-+
-+      return pte;
-+}
-+
-+static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
-+{
-+      struct page *pte;
-+
-+      pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
-+      return pte;
-+}
-+
-+/* Should really implement gc for free page table pages. This could be
-+   done with a reference count in struct page. */
-+
-+static inline void pte_free_kernel(pte_t *pte)
-+{
-+      BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
-+        make_page_writable(pte, XENFEAT_writable_page_tables);
-+      free_page((unsigned long)pte); 
-+}
-+
-+extern void pte_free(struct page *pte);
-+
-+//#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) 
-+//#define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
-+//#define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
-+
-+#define __pte_free_tlb(tlb,x)   pte_free((x))
-+#define __pmd_free_tlb(tlb,x)   pmd_free((x))
-+#define __pud_free_tlb(tlb,x)   pud_free((x))
-+
-+#endif /* _X86_64_PGALLOC_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/pgtable.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/pgtable.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/pgtable.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/pgtable.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,565 @@
-+#ifndef _X86_64_PGTABLE_H
-+#define _X86_64_PGTABLE_H
-+
-+/*
-+ * This file contains the functions and defines necessary to modify and use
-+ * the x86-64 page table tree.
-+ */
-+#include <asm/processor.h>
-+#include <asm/fixmap.h>
-+#include <asm/bitops.h>
-+#include <linux/threads.h>
-+#include <linux/sched.h>
-+#include <asm/pda.h>
-+#ifdef CONFIG_XEN
-+#include <asm/hypervisor.h>
-+
-+extern pud_t level3_user_pgt[512];
-+extern pud_t init_level4_user_pgt[];
-+
-+extern void xen_init_pt(void);
-+
-+#define virt_to_ptep(__va)                                            \
-+({                                                                    \
-+      pgd_t *__pgd = pgd_offset_k((unsigned long)(__va));             \
-+      pud_t *__pud = pud_offset(__pgd, (unsigned long)(__va));        \
-+      pmd_t *__pmd = pmd_offset(__pud, (unsigned long)(__va));        \
-+      pte_offset_kernel(__pmd, (unsigned long)(__va));                \
-+})
-+
-+#define arbitrary_virt_to_machine(__va)                                       \
-+({                                                                    \
-+      maddr_t m = (maddr_t)pte_mfn(*virt_to_ptep(__va)) << PAGE_SHIFT;\
-+      m | ((unsigned long)(__va) & (PAGE_SIZE-1));                    \
-+})
-+#endif
-+
-+extern pud_t level3_kernel_pgt[512];
-+extern pud_t level3_physmem_pgt[512];
-+extern pud_t level3_ident_pgt[512];
-+extern pmd_t level2_kernel_pgt[512];
-+extern pgd_t init_level4_pgt[];
-+extern pgd_t boot_level4_pgt[];
-+extern unsigned long __supported_pte_mask;
-+
-+#define swapper_pg_dir init_level4_pgt
-+
-+extern int nonx_setup(char *str);
-+extern void paging_init(void);
-+extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
-+
-+extern unsigned long pgkern_mask;
-+
-+/*
-+ * ZERO_PAGE is a global shared page that is always zero: used
-+ * for zero-mapped memory areas etc..
-+ */
-+extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
-+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
-+
-+/*
-+ * PGDIR_SHIFT determines what a top-level page table entry can map
-+ */
-+#define PGDIR_SHIFT   39
-+#define PTRS_PER_PGD  512
-+
-+/*
-+ * 3rd level page
-+ */
-+#define PUD_SHIFT     30
-+#define PTRS_PER_PUD  512
-+
-+/*
-+ * PMD_SHIFT determines the size of the area a middle-level
-+ * page table can map
-+ */
-+#define PMD_SHIFT     21
-+#define PTRS_PER_PMD  512
-+
-+/*
-+ * entries per page directory level
-+ */
-+#define PTRS_PER_PTE  512
-+
-+#define pte_ERROR(e) \
-+      printk("%s:%d: bad pte %p(%016lx).\n", __FILE__, __LINE__, &(e), pte_val(e))
-+#define pmd_ERROR(e) \
-+      printk("%s:%d: bad pmd %p(%016lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
-+#define pud_ERROR(e) \
-+      printk("%s:%d: bad pud %p(%016lx).\n", __FILE__, __LINE__, &(e), pud_val(e))
-+#define pgd_ERROR(e) \
-+      printk("%s:%d: bad pgd %p(%016lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
-+
-+#define pgd_none(x)   (!pgd_val(x))
-+#define pud_none(x)   (!pud_val(x))
-+
-+#define set_pte_batched(pteptr, pteval) \
-+      queue_l1_entry_update(pteptr, (pteval))
-+
-+extern inline int pud_present(pud_t pud)      { return !pud_none(pud); }
-+
-+static inline void set_pte(pte_t *dst, pte_t val)
-+{
-+      *dst = val;
-+}
-+
-+#define set_pmd(pmdptr, pmdval) xen_l2_entry_update(pmdptr, (pmdval))
-+#define set_pud(pudptr, pudval) xen_l3_entry_update(pudptr, (pudval))
-+#define set_pgd(pgdptr, pgdval) xen_l4_entry_update(pgdptr, (pgdval))
-+
-+static inline void pud_clear (pud_t * pud)
-+{
-+      set_pud(pud, __pud(0));
-+}
-+
-+#define __user_pgd(pgd) ((pgd) + PTRS_PER_PGD)
-+
-+static inline void pgd_clear (pgd_t * pgd)
-+{
-+        set_pgd(pgd, __pgd(0));
-+        set_pgd(__user_pgd(pgd), __pgd(0));
-+}
-+
-+#define pud_page(pud) \
-+    ((unsigned long) __va(pud_val(pud) & PHYSICAL_PAGE_MASK))
-+
-+/*
-+ * A note on implementation of this atomic 'get-and-clear' operation.
-+ * This is actually very simple because Xen Linux can only run on a single
-+ * processor. Therefore, we cannot race other processors setting the 'accessed'
-+ * or 'dirty' bits on a page-table entry.
-+ * Even if pages are shared between domains, that is not a problem because
-+ * each domain will have separate page tables, with their own versions of
-+ * accessed & dirty state.
-+ */
-+#define ptep_get_and_clear(mm,addr,xp)        __pte_ma(xchg(&(xp)->pte, 0))
-+
-+#if 0
-+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *xp)
-+{
-+        pte_t pte = *xp;
-+        if (pte.pte)
-+                set_pte(xp, __pte_ma(0));
-+        return pte;
-+}
-+#endif
-+
-+struct mm_struct;
-+
-+static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
-+{
-+      pte_t pte;
-+      if (full) {
-+              pte = *ptep;
-+              *ptep = __pte(0);
-+      } else {
-+              pte = ptep_get_and_clear(mm, addr, ptep);
-+      }
-+      return pte;
-+}
-+
-+#define pte_same(a, b)                ((a).pte == (b).pte)
-+
-+#define pte_pgprot(a) (__pgprot((a).pte & ~PHYSICAL_PAGE_MASK))
-+
-+#define PMD_SIZE      (1UL << PMD_SHIFT)
-+#define PMD_MASK      (~(PMD_SIZE-1))
-+#define PUD_SIZE      (1UL << PUD_SHIFT)
-+#define PUD_MASK      (~(PUD_SIZE-1))
-+#define PGDIR_SIZE    (1UL << PGDIR_SHIFT)
-+#define PGDIR_MASK    (~(PGDIR_SIZE-1))
-+
-+#define USER_PTRS_PER_PGD     ((TASK_SIZE-1)/PGDIR_SIZE+1)
-+#define FIRST_USER_ADDRESS    0
-+
-+#ifndef __ASSEMBLY__
-+#define MAXMEM                 0x3fffffffffffUL
-+#define VMALLOC_START    0xffffc20000000000UL
-+#define VMALLOC_END      0xffffe1ffffffffffUL
-+#define MODULES_VADDR    0xffffffff88000000UL
-+#define MODULES_END      0xfffffffffff00000UL
-+#define MODULES_LEN   (MODULES_END - MODULES_VADDR)
-+
-+#define _PAGE_BIT_PRESENT     0
-+#define _PAGE_BIT_RW          1
-+#define _PAGE_BIT_USER                2
-+#define _PAGE_BIT_PWT         3
-+#define _PAGE_BIT_PCD         4
-+#define _PAGE_BIT_ACCESSED    5
-+#define _PAGE_BIT_DIRTY               6
-+#define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page */
-+#define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
-+#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
-+
-+#define _PAGE_PRESENT 0x001
-+#define _PAGE_RW      0x002
-+#define _PAGE_USER    0x004
-+#define _PAGE_PWT     0x008
-+#define _PAGE_PCD     0x010
-+#define _PAGE_ACCESSED        0x020
-+#define _PAGE_DIRTY   0x040
-+#define _PAGE_PSE     0x080   /* 2MB page */
-+#define _PAGE_FILE    0x040   /* nonlinear file mapping, saved PTE; unset:swap */
-+#define _PAGE_GLOBAL  0x100   /* Global TLB entry */
-+
-+#define _PAGE_PROTNONE        0x080   /* If not present */
-+#define _PAGE_NX        (1UL<<_PAGE_BIT_NX)
-+
-+#ifdef CONFIG_XEN_COMPAT_030002
-+extern unsigned int __kernel_page_user;
-+#else
-+#define __kernel_page_user 0
-+#endif
-+
-+#define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
-+#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | __kernel_page_user)
-+
-+#define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
-+
-+#define PAGE_NONE     __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
-+#define PAGE_SHARED   __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-+#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-+#define PAGE_COPY PAGE_COPY_NOEXEC
-+#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-+#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
-+#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-+#define __PAGE_KERNEL \
-+      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
-+#define __PAGE_KERNEL_EXEC \
-+      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | __kernel_page_user)
-+#define __PAGE_KERNEL_NOCACHE \
-+      (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
-+#define __PAGE_KERNEL_RO \
-+      (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | __kernel_page_user)
-+#define __PAGE_KERNEL_VSYSCALL \
-+      (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-+#define __PAGE_KERNEL_VSYSCALL_NOCACHE \
-+      (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
-+#define __PAGE_KERNEL_LARGE \
-+      (__PAGE_KERNEL | _PAGE_PSE)
-+#define __PAGE_KERNEL_LARGE_EXEC \
-+      (__PAGE_KERNEL_EXEC | _PAGE_PSE)
-+
-+/*
-+ * We don't support GLOBAL page in xenolinux64
-+ */
-+#define MAKE_GLOBAL(x) __pgprot((x))
-+
-+#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
-+#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
-+#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
-+#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
-+#define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL)
-+#define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
-+#define PAGE_KERNEL_LARGE MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
-+#define PAGE_KERNEL_VSYSCALL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL_NOCACHE)
-+
-+/*         xwr */
-+#define __P000        PAGE_NONE
-+#define __P001        PAGE_READONLY
-+#define __P010        PAGE_COPY
-+#define __P011        PAGE_COPY
-+#define __P100        PAGE_READONLY_EXEC
-+#define __P101        PAGE_READONLY_EXEC
-+#define __P110        PAGE_COPY_EXEC
-+#define __P111        PAGE_COPY_EXEC
-+
-+#define __S000        PAGE_NONE
-+#define __S001        PAGE_READONLY
-+#define __S010        PAGE_SHARED
-+#define __S011        PAGE_SHARED
-+#define __S100        PAGE_READONLY_EXEC
-+#define __S101        PAGE_READONLY_EXEC
-+#define __S110        PAGE_SHARED_EXEC
-+#define __S111        PAGE_SHARED_EXEC
-+
-+static inline unsigned long pgd_bad(pgd_t pgd)
-+{
-+       unsigned long val = pgd_val(pgd);
-+       val &= ~PTE_MASK;
-+       val &= ~(_PAGE_USER | _PAGE_DIRTY);
-+       return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED);
-+}
-+
-+static inline unsigned long pud_bad(pud_t pud) 
-+{ 
-+       unsigned long val = pud_val(pud);
-+       val &= ~PTE_MASK; 
-+       val &= ~(_PAGE_USER | _PAGE_DIRTY); 
-+       return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED);      
-+} 
-+
-+#define set_pte_at(_mm,addr,ptep,pteval) do {                         \
-+      if (((_mm) != current->mm && (_mm) != &init_mm) ||              \
-+          HYPERVISOR_update_va_mapping((addr), (pteval), 0))          \
-+              set_pte((ptep), (pteval));                              \
-+} while (0)
-+
-+#define pte_none(x)   (!(x).pte)
-+#define pte_present(x)        ((x).pte & (_PAGE_PRESENT | _PAGE_PROTNONE))
-+#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
-+
-+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
-+
-+#define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
-+#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
-+
-+#define pte_page(x)   pfn_to_page(pte_pfn(x))
-+
-+static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
-+{
-+      pte_t pte;
-+        
-+      (pte).pte = (pfn_to_mfn(page_nr) << PAGE_SHIFT);
-+      (pte).pte |= pgprot_val(pgprot);
-+      (pte).pte &= __supported_pte_mask;
-+      return pte;
-+}
-+
-+/*
-+ * The following only work if pte_present() is true.
-+ * Undefined behaviour if not..
-+ */
-+#define __pte_val(x)  ((x).pte)
-+
-+#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
-+static inline int pte_user(pte_t pte)         { return __pte_val(pte) & _PAGE_USER; }
-+static inline int pte_read(pte_t pte)         { return __pte_val(pte) & _PAGE_USER; }
-+static inline int pte_exec(pte_t pte)         { return __pte_val(pte) & _PAGE_USER; }
-+static inline int pte_dirty(pte_t pte)                { return __pte_val(pte) & _PAGE_DIRTY; }
-+static inline int pte_young(pte_t pte)                { return __pte_val(pte) & _PAGE_ACCESSED; }
-+static inline int pte_write(pte_t pte)                { return __pte_val(pte) & _PAGE_RW; }
-+static inline int pte_file(pte_t pte)         { return __pte_val(pte) & _PAGE_FILE; }
-+static inline int pte_huge(pte_t pte)         { return (__pte_val(pte) & __LARGE_PTE) == __LARGE_PTE; }
-+
-+static inline pte_t pte_rdprotect(pte_t pte)  { __pte_val(pte) &= ~_PAGE_USER; return pte; }
-+static inline pte_t pte_exprotect(pte_t pte)  { __pte_val(pte) &= ~_PAGE_USER; return pte; }
-+static inline pte_t pte_mkclean(pte_t pte)    { __pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-+static inline pte_t pte_mkold(pte_t pte)      { __pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-+static inline pte_t pte_wrprotect(pte_t pte)  { __pte_val(pte) &= ~_PAGE_RW; return pte; }
-+static inline pte_t pte_mkread(pte_t pte)     { __pte_val(pte) |= _PAGE_USER; return pte; }
-+static inline pte_t pte_mkexec(pte_t pte)     { __pte_val(pte) |= _PAGE_USER; return pte; }
-+static inline pte_t pte_mkdirty(pte_t pte)    { __pte_val(pte) |= _PAGE_DIRTY; return pte; }
-+static inline pte_t pte_mkyoung(pte_t pte)    { __pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-+static inline pte_t pte_mkwrite(pte_t pte)    { __pte_val(pte) |= _PAGE_RW; return pte; }
-+static inline pte_t pte_mkhuge(pte_t pte)     { __pte_val(pte) |= __LARGE_PTE; return pte; }
-+
-+struct vm_area_struct;
-+
-+static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
-+{
-+      pte_t pte = *ptep;
-+      int ret = pte_dirty(pte);
-+      if (ret)
-+              set_pte(ptep, pte_mkclean(pte));
-+      return ret;
-+}
-+
-+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
-+{
-+      pte_t pte = *ptep;
-+      int ret = pte_young(pte);
-+      if (ret)
-+              set_pte(ptep, pte_mkold(pte));
-+      return ret;
-+}
-+
-+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-+{
-+      pte_t pte = *ptep;
-+      if (pte_write(pte))
-+              set_pte(ptep, pte_wrprotect(pte));
-+}
-+
-+/*
-+ * Macro to mark a page protection value as "uncacheable".
-+ */
-+#define pgprot_noncached(prot)        (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT))
-+
-+static inline int pmd_large(pmd_t pte) { 
-+      return (pmd_val(pte) & __LARGE_PTE) == __LARGE_PTE; 
-+}     
-+
-+
-+/*
-+ * Conversion functions: convert a page and protection to a page entry,
-+ * and a page entry and page directory to the page they refer to.
-+ */
-+
-+/*
-+ * Level 4 access.
-+ * Never use these in the common code.
-+ */
-+#define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & PTE_MASK))
-+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-+#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
-+#define pgd_offset_k(address) (pgd_t *)(init_level4_pgt + pgd_index(address))
-+#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_PRESENT)
-+#define mk_kernel_pgd(address) __pgd((address) | _KERNPG_TABLE)
-+
-+/* PUD - Level3 access */
-+/* to find an entry in a page-table-directory. */
-+#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
-+#define pud_offset(pgd, address) ((pud_t *) pgd_page(*(pgd)) + pud_index(address))
-+static inline pud_t *__pud_offset_k(pud_t *pud, unsigned long address)
-+{ 
-+      return pud + pud_index(address);
-+} 
-+
-+/* Find correct pud via the hidden fourth level page level: */
-+
-+/* This accesses the reference page table of the boot cpu. 
-+   Other CPUs get synced lazily via the page fault handler. */
-+static inline pud_t *pud_offset_k(pgd_t *pgd, unsigned long address)
-+{
-+      return pud_offset(pgd_offset_k(address), address);
-+}
-+
-+/* PMD  - Level 2 access */
-+#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PTE_MASK))
-+#define pmd_page(pmd)         (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-+
-+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
-+#define pmd_offset(dir, address) ((pmd_t *) pud_page(*(dir)) + \
-+                                  pmd_index(address))
-+#define pmd_none(x)   (!pmd_val(x))
-+/* pmd_present doesn't just test the _PAGE_PRESENT bit since wr.p.t.
-+   can temporarily clear it. */
-+#define pmd_present(x)        (pmd_val(x))
-+#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
-+#define pmd_bad(x) ((pmd_val(x) & ~(PTE_MASK | _PAGE_USER | _PAGE_PRESENT)) \
-+                  != (_KERNPG_TABLE & ~(_PAGE_USER | _PAGE_PRESENT)))
-+#define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
-+#define pmd_pfn(x)  ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)
-+
-+#define pte_to_pgoff(pte) ((pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
-+#define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE })
-+#define PTE_FILE_MAX_BITS __PHYSICAL_MASK_SHIFT
-+
-+/* PTE - Level 1 access. */
-+
-+/* page, protection -> pte */
-+#define mk_pte(page, pgprot)  pfn_pte(page_to_pfn(page), (pgprot))
-+#define mk_pte_huge(entry) (pte_val(entry) |= _PAGE_PRESENT | _PAGE_PSE)
-+ 
-+/* physical address -> PTE */
-+static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
-+{ 
-+      pte_t pte;
-+      (pte).pte = physpage | pgprot_val(pgprot); 
-+      return pte; 
-+}
-+ 
-+/* Change flags of a PTE */
-+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-+{ 
-+        (pte).pte &= _PAGE_CHG_MASK;
-+      (pte).pte |= pgprot_val(newprot);
-+      (pte).pte &= __supported_pte_mask;
-+       return pte; 
-+}
-+
-+#define pte_index(address) \
-+              (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-+#define pte_offset_kernel(dir, address) ((pte_t *) pmd_page_kernel(*(dir)) + \
-+                      pte_index(address))
-+
-+/* x86-64 always has all page tables mapped. */
-+#define pte_offset_map(dir,address) pte_offset_kernel(dir,address)
-+#define pte_offset_map_nested(dir,address) pte_offset_kernel(dir,address)
-+#define pte_unmap(pte) /* NOP */
-+#define pte_unmap_nested(pte) /* NOP */ 
-+
-+#define update_mmu_cache(vma,address,pte) do { } while (0)
-+
-+/* We only update the dirty/accessed state if we set
-+ * the dirty bit by hand in the kernel, since the hardware
-+ * will do the accessed bit for us, and we don't want to
-+ * race with other CPU's that might be updating the dirty
-+ * bit at the same time. */
-+#define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-+#if 0
-+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-+      do {                                                              \
-+              if (__dirty) {                                            \
-+                      set_pte(__ptep, __entry);                         \
-+                      flush_tlb_page(__vma, __address);                 \
-+              }                                                         \
-+      } while (0)
-+#endif
-+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-+      do {                                                              \
-+              if (__dirty) {                                            \
-+                      if ( likely((__vma)->vm_mm == current->mm) ) {    \
-+                          BUG_ON(HYPERVISOR_update_va_mapping((__address), (__entry), UVMF_INVLPG|UVMF_MULTI|(unsigned long)((__vma)->vm_mm->cpu_vm_mask.bits))); \
-+                      } else {                                          \
-+                            xen_l1_entry_update((__ptep), (__entry)); \
-+                          flush_tlb_page((__vma), (__address));         \
-+                      }                                                 \
-+              }                                                         \
-+      } while (0)
-+
-+/* Encode and de-code a swap entry */
-+#define __swp_type(x)                 (((x).val >> 1) & 0x3f)
-+#define __swp_offset(x)                       ((x).val >> 8)
-+#define __swp_entry(type, offset)     ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
-+#define __pte_to_swp_entry(pte)               ((swp_entry_t) { pte_val(pte) })
-+#define __swp_entry_to_pte(x)         ((pte_t) { (x).val })
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+extern int kern_addr_valid(unsigned long addr); 
-+
-+#define DOMID_LOCAL (0xFFFFU)
-+
-+int direct_remap_pfn_range(struct vm_area_struct *vma,
-+                            unsigned long address,
-+                            unsigned long mfn,
-+                            unsigned long size,
-+                            pgprot_t prot,
-+                            domid_t  domid);
-+
-+int direct_kernel_remap_pfn_range(unsigned long address, 
-+                                unsigned long mfn,
-+                                unsigned long size, 
-+                                pgprot_t prot,
-+                                domid_t  domid);
-+
-+int create_lookup_pte_addr(struct mm_struct *mm,
-+                           unsigned long address,
-+                           uint64_t *ptep);
-+
-+int touch_pte_range(struct mm_struct *mm,
-+                    unsigned long address,
-+                    unsigned long size);
-+
-+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)               \
-+              direct_remap_pfn_range(vma,vaddr,pfn,size,prot,DOMID_IO)
-+
-+#define MK_IOSPACE_PFN(space, pfn)    (pfn)
-+#define GET_IOSPACE(pfn)              0
-+#define GET_PFN(pfn)                  (pfn)
-+
-+#define HAVE_ARCH_UNMAPPED_AREA
-+
-+#define pgtable_cache_init()   do { } while (0)
-+#define check_pgt_cache()      do { } while (0)
-+
-+#define PAGE_AGP    PAGE_KERNEL_NOCACHE
-+#define HAVE_PAGE_AGP 1
-+
-+/* fs/proc/kcore.c */
-+#define       kc_vaddr_to_offset(v) ((v) & __VIRTUAL_MASK)
-+#define       kc_offset_to_vaddr(o) \
-+   (((o) & (1UL << (__VIRTUAL_MASK_SHIFT-1))) ? ((o) | (~__VIRTUAL_MASK)) : (o))
-+
-+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
-+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
-+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-+#define __HAVE_ARCH_PTE_SAME
-+#include <asm-generic/pgtable.h>
-+
-+#endif /* _X86_64_PGTABLE_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/processor.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/processor.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/processor.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/processor.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,493 @@
-+/*
-+ * include/asm-x86_64/processor.h
-+ *
-+ * Copyright (C) 1994 Linus Torvalds
-+ */
-+
-+#ifndef __ASM_X86_64_PROCESSOR_H
-+#define __ASM_X86_64_PROCESSOR_H
-+
-+#include <asm/segment.h>
-+#include <asm/page.h>
-+#include <asm/types.h>
-+#include <asm/sigcontext.h>
-+#include <asm/cpufeature.h>
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <asm/msr.h>
-+#include <asm/current.h>
-+#include <asm/system.h>
-+#include <asm/mmsegment.h>
-+#include <asm/percpu.h>
-+#include <linux/personality.h>
-+
-+#define TF_MASK               0x00000100
-+#define IF_MASK               0x00000200
-+#define IOPL_MASK     0x00003000
-+#define NT_MASK               0x00004000
-+#define VM_MASK               0x00020000
-+#define AC_MASK               0x00040000
-+#define VIF_MASK      0x00080000      /* virtual interrupt flag */
-+#define VIP_MASK      0x00100000      /* virtual interrupt pending */
-+#define ID_MASK               0x00200000
-+
-+#define desc_empty(desc) \
-+               (!((desc)->a | (desc)->b))
-+
-+#define desc_equal(desc1, desc2) \
-+               (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
-+
-+/*
-+ * Default implementation of macro that returns current
-+ * instruction pointer ("program counter").
-+ */
-+#define current_text_addr() ({ void *pc; asm volatile("leaq 1f(%%rip),%0\n1:":"=r"(pc)); pc; })
-+
-+/*
-+ *  CPU type and hardware bug flags. Kept separately for each CPU.
-+ */
-+
-+struct cpuinfo_x86 {
-+      __u8    x86;            /* CPU family */
-+      __u8    x86_vendor;     /* CPU vendor */
-+      __u8    x86_model;
-+      __u8    x86_mask;
-+      int     cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
-+      __u32   x86_capability[NCAPINTS];
-+      char    x86_vendor_id[16];
-+      char    x86_model_id[64];
-+      int     x86_cache_size;  /* in KB */
-+      int     x86_clflush_size;
-+      int     x86_cache_alignment;
-+      int     x86_tlbsize;    /* number of 4K pages in DTLB/ITLB combined(in pages)*/
-+        __u8    x86_virt_bits, x86_phys_bits;
-+      __u8    x86_max_cores;  /* cpuid returned max cores value */
-+        __u32   x86_power;    
-+      __u32   extended_cpuid_level;   /* Max extended CPUID function supported */
-+      unsigned long loops_per_jiffy;
-+      __u8    apicid;
-+      __u8    booted_cores;   /* number of cores as seen by OS */
-+} ____cacheline_aligned;
-+
-+#define X86_VENDOR_INTEL 0
-+#define X86_VENDOR_CYRIX 1
-+#define X86_VENDOR_AMD 2
-+#define X86_VENDOR_UMC 3
-+#define X86_VENDOR_NEXGEN 4
-+#define X86_VENDOR_CENTAUR 5
-+#define X86_VENDOR_RISE 6
-+#define X86_VENDOR_TRANSMETA 7
-+#define X86_VENDOR_NUM 8
-+#define X86_VENDOR_UNKNOWN 0xff
-+
-+#ifdef CONFIG_SMP
-+extern struct cpuinfo_x86 cpu_data[];
-+#define current_cpu_data cpu_data[smp_processor_id()]
-+#else
-+#define cpu_data (&boot_cpu_data)
-+#define current_cpu_data boot_cpu_data
-+#endif
-+
-+extern char ignore_irq13;
-+
-+extern void identify_cpu(struct cpuinfo_x86 *);
-+extern void print_cpu_info(struct cpuinfo_x86 *);
-+extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
-+
-+/*
-+ * EFLAGS bits
-+ */
-+#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
-+#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
-+#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
-+#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
-+#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
-+#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
-+#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
-+#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
-+#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
-+#define X86_EFLAGS_IOPL       0x00003000 /* IOPL mask */
-+#define X86_EFLAGS_NT 0x00004000 /* Nested Task */
-+#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
-+#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
-+#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
-+#define X86_EFLAGS_VIF        0x00080000 /* Virtual Interrupt Flag */
-+#define X86_EFLAGS_VIP        0x00100000 /* Virtual Interrupt Pending */
-+#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
-+
-+/*
-+ * Intel CPU features in CR4
-+ */
-+#define X86_CR4_VME           0x0001  /* enable vm86 extensions */
-+#define X86_CR4_PVI           0x0002  /* virtual interrupts flag enable */
-+#define X86_CR4_TSD           0x0004  /* disable time stamp at ipl 3 */
-+#define X86_CR4_DE            0x0008  /* enable debugging extensions */
-+#define X86_CR4_PSE           0x0010  /* enable page size extensions */
-+#define X86_CR4_PAE           0x0020  /* enable physical address extensions */
-+#define X86_CR4_MCE           0x0040  /* Machine check enable */
-+#define X86_CR4_PGE           0x0080  /* enable global pages */
-+#define X86_CR4_PCE           0x0100  /* enable performance counters at ipl 3 */
-+#define X86_CR4_OSFXSR                0x0200  /* enable fast FPU save and restore */
-+#define X86_CR4_OSXMMEXCPT    0x0400  /* enable unmasked SSE exceptions */
-+
-+/*
-+ * Save the cr4 feature set we're using (ie
-+ * Pentium 4MB enable and PPro Global page
-+ * enable), so that any CPU's that boot up
-+ * after us can get the correct flags.
-+ */
-+extern unsigned long mmu_cr4_features;
-+
-+static inline void set_in_cr4 (unsigned long mask)
-+{
-+      mmu_cr4_features |= mask;
-+      __asm__("movq %%cr4,%%rax\n\t"
-+              "orq %0,%%rax\n\t"
-+              "movq %%rax,%%cr4\n"
-+              : : "irg" (mask)
-+              :"ax");
-+}
-+
-+static inline void clear_in_cr4 (unsigned long mask)
-+{
-+      mmu_cr4_features &= ~mask;
-+      __asm__("movq %%cr4,%%rax\n\t"
-+              "andq %0,%%rax\n\t"
-+              "movq %%rax,%%cr4\n"
-+              : : "irg" (~mask)
-+              :"ax");
-+}
-+
-+
-+/*
-+ * Bus types
-+ */
-+#define MCA_bus 0
-+#define MCA_bus__is_a_macro
-+
-+/*
-+ * User space process size. 47bits minus one guard page.
-+ */
-+#define TASK_SIZE64   (0x800000000000UL - 4096)
-+
-+/* This decides where the kernel will search for a free chunk of vm
-+ * space during mmap's.
-+ */
-+#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
-+
-+#define TASK_SIZE             (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64)
-+#define TASK_SIZE_OF(child)   ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64)
-+
-+#define TASK_UNMAPPED_BASE    PAGE_ALIGN(TASK_SIZE/3)
-+
-+/*
-+ * Size of io_bitmap.
-+ */
-+#define IO_BITMAP_BITS  65536
-+#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
-+#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
-+#ifndef CONFIG_X86_NO_TSS
-+#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
-+#endif
-+#define INVALID_IO_BITMAP_OFFSET 0x8000
-+
-+struct i387_fxsave_struct {
-+      u16     cwd;
-+      u16     swd;
-+      u16     twd;
-+      u16     fop;
-+      u64     rip;
-+      u64     rdp; 
-+      u32     mxcsr;
-+      u32     mxcsr_mask;
-+      u32     st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
-+      u32     xmm_space[64];  /* 16*16 bytes for each XMM-reg = 128 bytes */
-+      u32     padding[24];
-+} __attribute__ ((aligned (16)));
-+
-+union i387_union {
-+      struct i387_fxsave_struct       fxsave;
-+};
-+
-+#ifndef CONFIG_X86_NO_TSS
-+struct tss_struct {
-+      u32 reserved1;
-+      u64 rsp0;       
-+      u64 rsp1;
-+      u64 rsp2;
-+      u64 reserved2;
-+      u64 ist[7];
-+      u32 reserved3;
-+      u32 reserved4;
-+      u16 reserved5;
-+      u16 io_bitmap_base;
-+      /*
-+       * The extra 1 is there because the CPU will access an
-+       * additional byte beyond the end of the IO permission
-+       * bitmap. The extra byte must be all 1 bits, and must
-+       * be within the limit. Thus we have:
-+       *
-+       * 128 bytes, the bitmap itself, for ports 0..0x3ff
-+       * 8 bytes, for an extra "long" of ~0UL
-+       */
-+      unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
-+} __attribute__((packed)) ____cacheline_aligned;
-+
-+DECLARE_PER_CPU(struct tss_struct,init_tss);
-+#endif
-+
-+extern struct cpuinfo_x86 boot_cpu_data;
-+
-+#ifdef CONFIG_X86_VSMP
-+#define ARCH_MIN_TASKALIGN    (1 << INTERNODE_CACHE_SHIFT)
-+#define ARCH_MIN_MMSTRUCT_ALIGN       (1 << INTERNODE_CACHE_SHIFT)
-+#else
-+#define ARCH_MIN_TASKALIGN    16
-+#define ARCH_MIN_MMSTRUCT_ALIGN       0
-+#endif
-+
-+struct thread_struct {
-+      unsigned long   rsp0;
-+      unsigned long   rsp;
-+      unsigned long   userrsp;        /* Copy from PDA */ 
-+      unsigned long   fs;
-+      unsigned long   gs;
-+      unsigned short  es, ds, fsindex, gsindex;       
-+/* Hardware debugging registers */
-+      unsigned long   debugreg0;  
-+      unsigned long   debugreg1;  
-+      unsigned long   debugreg2;  
-+      unsigned long   debugreg3;  
-+      unsigned long   debugreg6;  
-+      unsigned long   debugreg7;  
-+/* fault info */
-+      unsigned long   cr2, trap_no, error_code;
-+/* floating point info */
-+      union i387_union        i387  __attribute__((aligned(16)));
-+/* IO permissions. the bitmap could be moved into the GDT, that would make
-+   switch faster for a limited number of ioperm using tasks. -AK */
-+      int             ioperm;
-+      unsigned long   *io_bitmap_ptr;
-+      unsigned io_bitmap_max;
-+/* cached TLS descriptors. */
-+      u64 tls_array[GDT_ENTRY_TLS_ENTRIES];
-+      unsigned int    iopl;
-+} __attribute__((aligned(16)));
-+
-+#define INIT_THREAD  { \
-+      .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \
-+}
-+
-+#ifndef CONFIG_X86_NO_TSS
-+#define INIT_TSS  { \
-+      .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \
-+}
-+#endif
-+
-+#define INIT_MMAP \
-+{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
-+
-+#define start_thread(regs,new_rip,new_rsp) do { \
-+      asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));      \
-+      load_gs_index(0);                                                       \
-+      (regs)->rip = (new_rip);                                                 \
-+      (regs)->rsp = (new_rsp);                                                 \
-+      write_pda(oldrsp, (new_rsp));                                            \
-+      (regs)->cs = __USER_CS;                                                  \
-+      (regs)->ss = __USER_DS;                                                  \
-+      (regs)->eflags = 0x200;                                                  \
-+      set_fs(USER_DS);                                                         \
-+} while(0) 
-+
-+#define get_debugreg(var, register)                           \
-+      var = HYPERVISOR_get_debugreg(register)
-+#define set_debugreg(value, register)                 \
-+      HYPERVISOR_set_debugreg(register, value)
-+
-+struct task_struct;
-+struct mm_struct;
-+
-+/* Free all resources held by a thread. */
-+extern void release_thread(struct task_struct *);
-+
-+/* Prepare to copy thread state - unlazy all lazy status */
-+extern void prepare_to_copy(struct task_struct *tsk);
-+
-+/*
-+ * create a kernel thread without removing it from tasklists
-+ */
-+extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+
-+/*
-+ * Return saved PC of a blocked thread.
-+ * What is this good for? it will be always the scheduler or ret_from_fork.
-+ */
-+#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8))
-+
-+extern unsigned long get_wchan(struct task_struct *p);
-+#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1)
-+#define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip)
-+#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
-+
-+
-+struct microcode_header {
-+      unsigned int hdrver;
-+      unsigned int rev;
-+      unsigned int date;
-+      unsigned int sig;
-+      unsigned int cksum;
-+      unsigned int ldrver;
-+      unsigned int pf;
-+      unsigned int datasize;
-+      unsigned int totalsize;
-+      unsigned int reserved[3];
-+};
-+
-+struct microcode {
-+      struct microcode_header hdr;
-+      unsigned int bits[0];
-+};
-+
-+typedef struct microcode microcode_t;
-+typedef struct microcode_header microcode_header_t;
-+
-+/* microcode format is extended from prescott processors */
-+struct extended_signature {
-+      unsigned int sig;
-+      unsigned int pf;
-+      unsigned int cksum;
-+};
-+
-+struct extended_sigtable {
-+      unsigned int count;
-+      unsigned int cksum;
-+      unsigned int reserved[3];
-+      struct extended_signature sigs[0];
-+};
-+
-+/* '6' because it used to be for P6 only (but now covers Pentium 4 as well) */
-+#define MICROCODE_IOCFREE     _IO('6',0)
-+
-+
-+#define ASM_NOP1 K8_NOP1
-+#define ASM_NOP2 K8_NOP2
-+#define ASM_NOP3 K8_NOP3
-+#define ASM_NOP4 K8_NOP4
-+#define ASM_NOP5 K8_NOP5
-+#define ASM_NOP6 K8_NOP6
-+#define ASM_NOP7 K8_NOP7
-+#define ASM_NOP8 K8_NOP8
-+
-+/* Opteron nops */
-+#define K8_NOP1 ".byte 0x90\n"
-+#define K8_NOP2       ".byte 0x66,0x90\n" 
-+#define K8_NOP3       ".byte 0x66,0x66,0x90\n" 
-+#define K8_NOP4       ".byte 0x66,0x66,0x66,0x90\n" 
-+#define K8_NOP5       K8_NOP3 K8_NOP2 
-+#define K8_NOP6       K8_NOP3 K8_NOP3
-+#define K8_NOP7       K8_NOP4 K8_NOP3
-+#define K8_NOP8       K8_NOP4 K8_NOP4
-+
-+#define ASM_NOP_MAX 8
-+
-+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-+static inline void rep_nop(void)
-+{
-+      __asm__ __volatile__("rep;nop": : :"memory");
-+}
-+
-+/* Stop speculative execution */
-+static inline void sync_core(void)
-+{ 
-+      int tmp;
-+      asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
-+} 
-+
-+#define cpu_has_fpu 1
-+
-+#define ARCH_HAS_PREFETCH
-+static inline void prefetch(void *x) 
-+{ 
-+      asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
-+} 
-+
-+#define ARCH_HAS_PREFETCHW 1
-+static inline void prefetchw(void *x) 
-+{ 
-+      alternative_input("prefetcht0 (%1)",
-+                        "prefetchw (%1)",
-+                        X86_FEATURE_3DNOW,
-+                        "r" (x));
-+} 
-+
-+#define ARCH_HAS_SPINLOCK_PREFETCH 1
-+
-+#define spin_lock_prefetch(x)  prefetchw(x)
-+
-+#define cpu_relax()   rep_nop()
-+
-+/*
-+ *      NSC/Cyrix CPU configuration register indexes
-+ */
-+#define CX86_CCR0 0xc0
-+#define CX86_CCR1 0xc1
-+#define CX86_CCR2 0xc2
-+#define CX86_CCR3 0xc3
-+#define CX86_CCR4 0xe8
-+#define CX86_CCR5 0xe9
-+#define CX86_CCR6 0xea
-+#define CX86_CCR7 0xeb
-+#define CX86_DIR0 0xfe
-+#define CX86_DIR1 0xff
-+#define CX86_ARR_BASE 0xc4
-+#define CX86_RCR_BASE 0xdc
-+
-+/*
-+ *      NSC/Cyrix CPU indexed register access macros
-+ */
-+
-+#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
-+
-+#define setCx86(reg, data) do { \
-+      outb((reg), 0x22); \
-+      outb((data), 0x23); \
-+} while (0)
-+
-+static inline void serialize_cpu(void)
-+{
-+      __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
-+}
-+
-+static inline void __monitor(const void *eax, unsigned long ecx,
-+              unsigned long edx)
-+{
-+      /* "monitor %eax,%ecx,%edx;" */
-+      asm volatile(
-+              ".byte 0x0f,0x01,0xc8;"
-+              : :"a" (eax), "c" (ecx), "d"(edx));
-+}
-+
-+static inline void __mwait(unsigned long eax, unsigned long ecx)
-+{
-+      /* "mwait %eax,%ecx;" */
-+      asm volatile(
-+              ".byte 0x0f,0x01,0xc9;"
-+              : :"a" (eax), "c" (ecx));
-+}
-+
-+#define stack_current() \
-+({                                                            \
-+      struct thread_info *ti;                                 \
-+      asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));  \
-+      ti->task;                                       \
-+})
-+
-+#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
-+
-+extern unsigned long boot_option_idle_override;
-+/* Boot loader type from the setup header */
-+extern int bootloader_type;
-+
-+#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
-+
-+#endif /* __ASM_X86_64_PROCESSOR_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/ptrace.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/ptrace.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/ptrace.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/ptrace.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,127 @@
-+#ifndef _X86_64_PTRACE_H
-+#define _X86_64_PTRACE_H
-+
-+#if defined(__ASSEMBLY__) || defined(__FRAME_OFFSETS) 
-+#define R15 0
-+#define R14 8
-+#define R13 16
-+#define R12 24
-+#define RBP 32
-+#define RBX 40
-+/* arguments: interrupts/non tracing syscalls only save upto here*/
-+#define R11 48
-+#define R10 56        
-+#define R9 64
-+#define R8 72
-+#define RAX 80
-+#define RCX 88
-+#define RDX 96
-+#define RSI 104
-+#define RDI 112
-+#define ORIG_RAX 120       /* = ERROR */ 
-+/* end of arguments */        
-+/* cpu exception frame or undefined in case of fast syscall. */
-+#define RIP 128
-+#define CS 136
-+#define EFLAGS 144
-+#define RSP 152
-+#define SS 160
-+#define ARGOFFSET R11
-+#endif /* __ASSEMBLY__ */
-+
-+/* top of stack page */ 
-+#define FRAME_SIZE 168
-+
-+#define PTRACE_OLDSETOPTIONS         21
-+
-+#ifndef __ASSEMBLY__ 
-+
-+struct pt_regs {
-+      unsigned long r15;
-+      unsigned long r14;
-+      unsigned long r13;
-+      unsigned long r12;
-+      unsigned long rbp;
-+      unsigned long rbx;
-+/* arguments: non interrupts/non tracing syscalls only save upto here*/
-+      unsigned long r11;
-+      unsigned long r10;      
-+      unsigned long r9;
-+      unsigned long r8;
-+      unsigned long rax;
-+      unsigned long rcx;
-+      unsigned long rdx;
-+      unsigned long rsi;
-+      unsigned long rdi;
-+      unsigned long orig_rax;
-+/* end of arguments */        
-+/* cpu exception frame or undefined */
-+      unsigned long rip;
-+      unsigned long cs;
-+      unsigned long eflags; 
-+      unsigned long rsp; 
-+      unsigned long ss;
-+/* top of stack page */ 
-+};
-+
-+#endif
-+
-+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-+#define PTRACE_GETREGS            12
-+#define PTRACE_SETREGS            13
-+#define PTRACE_GETFPREGS          14
-+#define PTRACE_SETFPREGS          15
-+#define PTRACE_GETFPXREGS         18
-+#define PTRACE_SETFPXREGS         19
-+
-+/* only useful for access 32bit programs */
-+#define PTRACE_GET_THREAD_AREA    25
-+#define PTRACE_SET_THREAD_AREA    26
-+
-+#define PTRACE_ARCH_PRCTL       30    /* arch_prctl for child */
-+
-+#if defined(__KERNEL__) && !defined(__ASSEMBLY__) 
-+#define user_mode(regs) (!!((regs)->cs & 3))
-+#define user_mode_vm(regs) user_mode(regs)
-+#define instruction_pointer(regs) ((regs)->rip)
-+#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
-+extern unsigned long profile_pc(struct pt_regs *regs);
-+#else
-+#define profile_pc(regs) instruction_pointer(regs)
-+#endif
-+
-+#include <linux/compiler.h>
-+
-+void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
-+
-+struct task_struct;
-+
-+extern unsigned long
-+convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs);
-+
-+enum {
-+        EF_CF   = 0x00000001,
-+        EF_PF   = 0x00000004,
-+        EF_AF   = 0x00000010,
-+        EF_ZF   = 0x00000040,
-+        EF_SF   = 0x00000080,
-+        EF_TF   = 0x00000100,
-+        EF_IE   = 0x00000200,
-+        EF_DF   = 0x00000400,
-+        EF_OF   = 0x00000800,
-+        EF_IOPL = 0x00003000,
-+        EF_IOPL_RING0 = 0x00000000,
-+        EF_IOPL_RING1 = 0x00001000,
-+        EF_IOPL_RING2 = 0x00002000,
-+        EF_NT   = 0x00004000,   /* nested task */
-+        EF_RF   = 0x00010000,   /* resume */
-+        EF_VM   = 0x00020000,   /* virtual mode */
-+        EF_AC   = 0x00040000,   /* alignment */
-+        EF_VIF  = 0x00080000,   /* virtual interrupt */
-+        EF_VIP  = 0x00100000,   /* virtual interrupt pending */
-+        EF_ID   = 0x00200000,   /* id */
-+};
-+
-+#endif
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/smp.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/smp.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/smp.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/smp.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,152 @@
-+#ifndef __ASM_SMP_H
-+#define __ASM_SMP_H
-+
-+/*
-+ * We need the APIC definitions automatically as part of 'smp.h'
-+ */
-+#ifndef __ASSEMBLY__
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+#include <linux/cpumask.h>
-+#include <linux/bitops.h>
-+extern int disable_apic;
-+#endif
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+#ifndef __ASSEMBLY__
-+#include <asm/fixmap.h>
-+#include <asm/mpspec.h>
-+#ifdef CONFIG_X86_IO_APIC
-+#include <asm/io_apic.h>
-+#endif
-+#include <asm/apic.h>
-+#include <asm/thread_info.h>
-+#endif
-+#endif
-+
-+#ifdef CONFIG_SMP
-+#ifndef ASSEMBLY
-+
-+#include <asm/pda.h>
-+
-+struct pt_regs;
-+
-+extern cpumask_t cpu_present_mask;
-+extern cpumask_t cpu_possible_map;
-+extern cpumask_t cpu_online_map;
-+extern cpumask_t cpu_initialized;
-+
-+/*
-+ * Private routines/data
-+ */
-+ 
-+extern void smp_alloc_memory(void);
-+extern volatile unsigned long smp_invalidate_needed;
-+extern int pic_mode;
-+extern void lock_ipi_call_lock(void);
-+extern void unlock_ipi_call_lock(void);
-+extern int smp_num_siblings;
-+extern void smp_send_reschedule(int cpu);
-+void smp_stop_cpu(void);
-+extern int smp_call_function_single(int cpuid, void (*func) (void *info),
-+                              void *info, int retry, int wait);
-+
-+extern cpumask_t cpu_sibling_map[NR_CPUS];
-+extern cpumask_t cpu_core_map[NR_CPUS];
-+extern int phys_proc_id[NR_CPUS];
-+extern int cpu_core_id[NR_CPUS];
-+
-+#define SMP_TRAMPOLINE_BASE 0x6000
-+
-+/*
-+ * On x86 all CPUs are mapped 1:1 to the APIC space.
-+ * This simplifies scheduling and IPI sending and
-+ * compresses data structures.
-+ */
-+
-+static inline int num_booting_cpus(void)
-+{
-+      return cpus_weight(cpu_possible_map);
-+}
-+
-+#define raw_smp_processor_id() read_pda(cpunumber)
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+static inline int hard_smp_processor_id(void)
-+{
-+      /* we don't want to mark this access volatile - bad code generation */
-+      return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID));
-+}
-+#endif
-+
-+extern int safe_smp_processor_id(void);
-+extern int __cpu_disable(void);
-+extern void __cpu_die(unsigned int cpu);
-+extern void prefill_possible_map(void);
-+extern unsigned num_processors;
-+extern unsigned disabled_cpus;
-+
-+#endif /* !ASSEMBLY */
-+
-+#define NO_PROC_ID            0xFF            /* No processor magic marker */
-+
-+#endif
-+
-+#ifndef ASSEMBLY
-+/*
-+ * Some lowlevel functions might want to know about
-+ * the real APIC ID <-> CPU # mapping.
-+ */
-+extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */
-+extern u8 x86_cpu_to_log_apicid[NR_CPUS];
-+extern u8 bios_cpu_apicid[];
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
-+{
-+      return cpus_addr(cpumask)[0];
-+}
-+
-+static inline int cpu_present_to_apicid(int mps_cpu)
-+{
-+      if (mps_cpu < NR_CPUS)
-+              return (int)bios_cpu_apicid[mps_cpu];
-+      else
-+              return BAD_APICID;
-+}
-+#endif
-+
-+#endif /* !ASSEMBLY */
-+
-+#ifndef CONFIG_SMP
-+#define stack_smp_processor_id() 0
-+#define safe_smp_processor_id() 0
-+#define cpu_logical_map(x) (x)
-+#else
-+#include <asm/thread_info.h>
-+#define stack_smp_processor_id() \
-+({                                                            \
-+      struct thread_info *ti;                                 \
-+      __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));      \
-+      ti->cpu;                                                \
-+})
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+#ifdef CONFIG_X86_LOCAL_APIC
-+static __inline int logical_smp_processor_id(void)
-+{
-+      /* we don't want to mark this access volatile - bad code generation */
-+      return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR));
-+}
-+#endif
-+#endif
-+
-+#ifdef CONFIG_SMP
-+#define cpu_physical_id(cpu)          x86_cpu_to_apicid[cpu]
-+#else
-+#define cpu_physical_id(cpu)          boot_cpu_id
-+#endif
-+
-+#endif
-+
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/synch_bitops.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/synch_bitops.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/synch_bitops.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/synch_bitops.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,2 @@
-+
-+#include <asm-i386/mach-xen/asm/synch_bitops.h>
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/system.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/system.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/system.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/system.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,434 @@
-+#ifndef __ASM_SYSTEM_H
-+#define __ASM_SYSTEM_H
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <asm/segment.h>
-+#include <asm/synch_bitops.h>
-+#include <asm/hypervisor.h>
-+#include <xen/interface/arch-x86_64.h>
-+
-+#ifdef __KERNEL__
-+
-+#ifdef CONFIG_SMP
-+#define __vcpu_id smp_processor_id()
-+#else
-+#define __vcpu_id 0
-+#endif
-+
-+#ifdef CONFIG_SMP
-+#define LOCK_PREFIX "lock ; "
-+#else
-+#define LOCK_PREFIX ""
-+#endif
-+
-+#define __STR(x) #x
-+#define STR(x) __STR(x)
-+
-+#define __SAVE(reg,offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
-+#define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
-+
-+/* frame pointer must be last for get_wchan */
-+#define SAVE_CONTEXT    "pushq %%rbp ; movq %%rsi,%%rbp\n\t"
-+#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp\n\t"
-+
-+#define __EXTRA_CLOBBER  \
-+      ,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15"
-+
-+#define switch_to(prev,next,last) \
-+      asm volatile(SAVE_CONTEXT                                                   \
-+                   "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */       \
-+                   "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */    \
-+                   "call __switch_to\n\t"                                       \
-+                   ".globl thread_return\n"                                   \
-+                   "thread_return:\n\t"                                           \
-+                   "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"                       \
-+                   "movq %P[thread_info](%%rsi),%%r8\n\t"                       \
-+                   LOCK "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"               \
-+                   "movq %%rax,%%rdi\n\t"                                       \
-+                   "jc   ret_from_fork\n\t"                                     \
-+                   RESTORE_CONTEXT                                                \
-+                   : "=a" (last)                                                \
-+                   : [next] "S" (next), [prev] "D" (prev),                      \
-+                     [threadrsp] "i" (offsetof(struct task_struct, thread.rsp)), \
-+                     [ti_flags] "i" (offsetof(struct thread_info, flags)),\
-+                     [tif_fork] "i" (TIF_FORK),                         \
-+                     [thread_info] "i" (offsetof(struct task_struct, thread_info)), \
-+                     [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))   \
-+                   : "memory", "cc" __EXTRA_CLOBBER)
-+    
-+
-+extern void load_gs_index(unsigned);
-+
-+/*
-+ * Load a segment. Fall back on loading the zero
-+ * segment if something goes wrong..
-+ */
-+#define loadsegment(seg,value)        \
-+      asm volatile("\n"                       \
-+              "1:\t"                          \
-+              "movl %k0,%%" #seg "\n"         \
-+              "2:\n"                          \
-+              ".section .fixup,\"ax\"\n"      \
-+              "3:\t"                          \
-+              "movl %1,%%" #seg "\n\t"        \
-+              "jmp 2b\n"                      \
-+              ".previous\n"                   \
-+              ".section __ex_table,\"a\"\n\t" \
-+              ".align 8\n\t"                  \
-+              ".quad 1b,3b\n"                 \
-+              ".previous"                     \
-+              : :"r" (value), "r" (0))
-+
-+#define set_debug(value,register) \
-+                __asm__("movq %0,%%db" #register  \
-+              : /* no output */ \
-+              :"r" ((unsigned long) value))
-+
-+
-+#ifdef __KERNEL__
-+struct alt_instr { 
-+      __u8 *instr;            /* original instruction */
-+      __u8 *replacement;
-+      __u8  cpuid;            /* cpuid bit set for replacement */
-+      __u8  instrlen;         /* length of original instruction */
-+      __u8  replacementlen;   /* length of new instruction, <= instrlen */ 
-+      __u8  pad[5];
-+}; 
-+#endif
-+
-+/*
-+ * Alternative instructions for different CPU types or capabilities.
-+ * 
-+ * This allows to use optimized instructions even on generic binary
-+ * kernels.
-+ * 
-+ * length of oldinstr must be longer or equal the length of newinstr
-+ * It can be padded with nops as needed.
-+ * 
-+ * For non barrier like inlines please define new variants
-+ * without volatile and memory clobber.
-+ */
-+#define alternative(oldinstr, newinstr, feature)      \
-+      asm volatile ("661:\n\t" oldinstr "\n662:\n"                 \
-+                    ".section .altinstructions,\"a\"\n"            \
-+                    "  .align 8\n"                                   \
-+                    "  .quad 661b\n"            /* label */          \
-+                    "  .quad 663f\n"            /* new instruction */ \
-+                    "  .byte %c0\n"             /* feature bit */    \
-+                    "  .byte 662b-661b\n"       /* sourcelen */      \
-+                    "  .byte 664f-663f\n"       /* replacementlen */ \
-+                    ".previous\n"                                     \
-+                    ".section .altinstr_replacement,\"ax\"\n"         \
-+                    "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
-+                    ".previous" :: "i" (feature) : "memory")  
-+
-+/*
-+ * Alternative inline assembly with input.
-+ * 
-+ * Peculiarities:
-+ * No memory clobber here. 
-+ * Argument numbers start with 1.
-+ * Best is to use constraints that are fixed size (like (%1) ... "r")
-+ * If you use variable sized constraints like "m" or "g" in the 
-+ * replacement make sure to pad to the worst case length.
-+ */
-+#define alternative_input(oldinstr, newinstr, feature, input...)      \
-+      asm volatile ("661:\n\t" oldinstr "\n662:\n"                    \
-+                    ".section .altinstructions,\"a\"\n"               \
-+                    "  .align 8\n"                                    \
-+                    "  .quad 661b\n"            /* label */           \
-+                    "  .quad 663f\n"            /* new instruction */ \
-+                    "  .byte %c0\n"             /* feature bit */     \
-+                    "  .byte 662b-661b\n"       /* sourcelen */       \
-+                    "  .byte 664f-663f\n"       /* replacementlen */  \
-+                    ".previous\n"                                     \
-+                    ".section .altinstr_replacement,\"ax\"\n"         \
-+                    "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
-+                    ".previous" :: "i" (feature), ##input)
-+
-+/* Like alternative_input, but with a single output argument */
-+#define alternative_io(oldinstr, newinstr, feature, output, input...) \
-+      asm volatile ("661:\n\t" oldinstr "\n662:\n"                    \
-+                    ".section .altinstructions,\"a\"\n"               \
-+                    "  .align 8\n"                                    \
-+                    "  .quad 661b\n"            /* label */           \
-+                    "  .quad 663f\n"            /* new instruction */ \
-+                    "  .byte %c[feat]\n"        /* feature bit */     \
-+                    "  .byte 662b-661b\n"       /* sourcelen */       \
-+                    "  .byte 664f-663f\n"       /* replacementlen */  \
-+                    ".previous\n"                                     \
-+                    ".section .altinstr_replacement,\"ax\"\n"         \
-+                    "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
-+                    ".previous" : output : [feat] "i" (feature), ##input)
-+
-+/*
-+ * Clear and set 'TS' bit respectively
-+ */
-+#define clts() (HYPERVISOR_fpu_taskswitch(0))
-+
-+static inline unsigned long read_cr0(void)
-+{ 
-+      unsigned long cr0;
-+      asm volatile("movq %%cr0,%0" : "=r" (cr0));
-+      return cr0;
-+} 
-+
-+static inline void write_cr0(unsigned long val) 
-+{ 
-+      asm volatile("movq %0,%%cr0" :: "r" (val));
-+} 
-+
-+#define read_cr3() ({ \
-+      unsigned long __dummy; \
-+      asm("movq %%cr3,%0" : "=r" (__dummy)); \
-+      machine_to_phys(__dummy); \
-+})
-+
-+static inline unsigned long read_cr4(void)
-+{ 
-+      unsigned long cr4;
-+      asm("movq %%cr4,%0" : "=r" (cr4));
-+      return cr4;
-+} 
-+
-+static inline void write_cr4(unsigned long val)
-+{ 
-+      asm volatile("movq %0,%%cr4" :: "r" (val));
-+} 
-+
-+#define stts() (HYPERVISOR_fpu_taskswitch(1))
-+
-+#define wbinvd() \
-+      __asm__ __volatile__ ("wbinvd": : :"memory");
-+
-+/*
-+ * On SMP systems, when the scheduler does migration-cost autodetection,
-+ * it needs a way to flush as much of the CPU's caches as possible.
-+ */
-+static inline void sched_cacheflush(void)
-+{
-+      wbinvd();
-+}
-+
-+#endif        /* __KERNEL__ */
-+
-+#define nop() __asm__ __volatile__ ("nop")
-+
-+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
-+
-+#define tas(ptr) (xchg((ptr),1))
-+
-+#define __xg(x) ((volatile long *)(x))
-+
-+static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
-+{
-+      *ptr = val;
-+}
-+
-+#define _set_64bit set_64bit
-+
-+/*
-+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
-+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
-+ *      but generally the primitive is invalid, *ptr is output argument. --ANK
-+ */
-+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-+{
-+      switch (size) {
-+              case 1:
-+                      __asm__ __volatile__("xchgb %b0,%1"
-+                              :"=q" (x)
-+                              :"m" (*__xg(ptr)), "0" (x)
-+                              :"memory");
-+                      break;
-+              case 2:
-+                      __asm__ __volatile__("xchgw %w0,%1"
-+                              :"=r" (x)
-+                              :"m" (*__xg(ptr)), "0" (x)
-+                              :"memory");
-+                      break;
-+              case 4:
-+                      __asm__ __volatile__("xchgl %k0,%1"
-+                              :"=r" (x)
-+                              :"m" (*__xg(ptr)), "0" (x)
-+                              :"memory");
-+                      break;
-+              case 8:
-+                      __asm__ __volatile__("xchgq %0,%1"
-+                              :"=r" (x)
-+                              :"m" (*__xg(ptr)), "0" (x)
-+                              :"memory");
-+                      break;
-+      }
-+      return x;
-+}
-+
-+/*
-+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
-+ * store NEW in MEM.  Return the initial value in MEM.  Success is
-+ * indicated by comparing RETURN with OLD.
-+ */
-+
-+#define __HAVE_ARCH_CMPXCHG 1
-+
-+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
-+                                    unsigned long new, int size)
-+{
-+      unsigned long prev;
-+      switch (size) {
-+      case 1:
-+              __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
-+                                   : "=a"(prev)
-+                                   : "q"(new), "m"(*__xg(ptr)), "0"(old)
-+                                   : "memory");
-+              return prev;
-+      case 2:
-+              __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__xg(ptr)), "0"(old)
-+                                   : "memory");
-+              return prev;
-+      case 4:
-+              __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__xg(ptr)), "0"(old)
-+                                   : "memory");
-+              return prev;
-+      case 8:
-+              __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
-+                                   : "=a"(prev)
-+                                   : "r"(new), "m"(*__xg(ptr)), "0"(old)
-+                                   : "memory");
-+              return prev;
-+      }
-+      return old;
-+}
-+
-+#define cmpxchg(ptr,o,n)\
-+      ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
-+                                      (unsigned long)(n),sizeof(*(ptr))))
-+
-+#ifdef CONFIG_SMP
-+#define smp_mb()      mb()
-+#define smp_rmb()     rmb()
-+#define smp_wmb()     wmb()
-+#define smp_read_barrier_depends()    do {} while(0)
-+#else
-+#define smp_mb()      barrier()
-+#define smp_rmb()     barrier()
-+#define smp_wmb()     barrier()
-+#define smp_read_barrier_depends()    do {} while(0)
-+#endif
-+
-+    
-+/*
-+ * Force strict CPU ordering.
-+ * And yes, this is required on UP too when we're talking
-+ * to devices.
-+ */
-+#define mb()  asm volatile("mfence":::"memory")
-+#define rmb() asm volatile("lfence":::"memory")
-+
-+#ifdef CONFIG_UNORDERED_IO
-+#define wmb() asm volatile("sfence" ::: "memory")
-+#else
-+#define wmb() asm volatile("" ::: "memory")
-+#endif
-+#define read_barrier_depends()        do {} while(0)
-+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
-+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
-+
-+#define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
-+
-+
-+/* 
-+ * The use of 'barrier' in the following reflects their use as local-lock
-+ * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
-+ * critical operations are executed. All critical operations must complete
-+ * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
-+ * includes these barriers, for example.
-+ */
-+
-+#define __cli()                                                               \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      _vcpu->evtchn_upcall_mask = 1;                                  \
-+      preempt_enable_no_resched();                                    \
-+      barrier();                                                      \
-+} while (0)
-+
-+#define __sti()                                                               \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      barrier();                                                      \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      _vcpu->evtchn_upcall_mask = 0;                                  \
-+      barrier(); /* unmask then check (avoid races) */                \
-+      if ( unlikely(_vcpu->evtchn_upcall_pending) )                   \
-+              force_evtchn_callback();                                \
-+      preempt_enable();                                               \
-+} while (0)
-+
-+#define __save_flags(x)                                                       \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      (x) = _vcpu->evtchn_upcall_mask;                                \
-+      preempt_enable();                                               \
-+} while (0)
-+
-+#define __restore_flags(x)                                            \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      barrier();                                                      \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
-+              barrier(); /* unmask then check (avoid races) */        \
-+              if ( unlikely(_vcpu->evtchn_upcall_pending) )           \
-+                      force_evtchn_callback();                        \
-+              preempt_enable();                                       \
-+      } else                                                          \
-+              preempt_enable_no_resched();                            \
-+} while (0)
-+
-+#define __save_and_cli(x)                                             \
-+do {                                                                  \
-+      vcpu_info_t *_vcpu;                                             \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      (x) = _vcpu->evtchn_upcall_mask;                                \
-+      _vcpu->evtchn_upcall_mask = 1;                                  \
-+      preempt_enable_no_resched();                                    \
-+      barrier();                                                      \
-+} while (0)
-+
-+#define local_irq_save(x)     __save_and_cli(x)
-+#define local_irq_restore(x)  __restore_flags(x)
-+#define local_save_flags(x)   __save_flags(x)
-+#define local_irq_disable()   __cli()
-+#define local_irq_enable()    __sti()
-+
-+/* Cannot use preempt_enable() here as we would recurse in preempt_sched(). */
-+#define irqs_disabled()                                                       \
-+({    int ___x;                                                       \
-+      vcpu_info_t *_vcpu;                                             \
-+      preempt_disable();                                              \
-+      _vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];          \
-+      ___x = (_vcpu->evtchn_upcall_mask != 0);                        \
-+      preempt_enable_no_resched();                                    \
-+      ___x; })
-+
-+void safe_halt(void);
-+void halt(void);
-+
-+void cpu_idle_wait(void);
-+
-+extern unsigned long arch_align_stack(unsigned long sp);
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/timer.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/timer.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/timer.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/timer.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,67 @@
-+#ifndef _ASMi386_TIMER_H
-+#define _ASMi386_TIMER_H
-+#include <linux/init.h>
-+
-+/**
-+ * struct timer_ops - used to define a timer source
-+ *
-+ * @name: name of the timer.
-+ * @init: Probes and initializes the timer. Takes clock= override 
-+ *        string as an argument. Returns 0 on success, anything else
-+ *        on failure.
-+ * @mark_offset: called by the timer interrupt.
-+ * @get_offset:  called by gettimeofday(). Returns the number of microseconds
-+ *               since the last timer interupt.
-+ * @monotonic_clock: returns the number of nanoseconds since the init of the
-+ *                   timer.
-+ * @delay: delays this many clock cycles.
-+ */
-+struct timer_opts {
-+      char* name;
-+      void (*mark_offset)(void);
-+      unsigned long (*get_offset)(void);
-+      unsigned long long (*monotonic_clock)(void);
-+      void (*delay)(unsigned long);
-+      unsigned long (*read_timer)(void);
-+      int (*suspend)(pm_message_t state);
-+      int (*resume)(void);
-+};
-+
-+struct init_timer_opts {
-+      int (*init)(char *override);
-+      struct timer_opts *opts;
-+};
-+
-+#define TICK_SIZE (tick_nsec / 1000)
-+
-+extern struct timer_opts* __init select_timer(void);
-+extern void clock_fallback(void);
-+void setup_pit_timer(void);
-+
-+/* Modifiers for buggy PIT handling */
-+
-+extern int pit_latch_buggy;
-+
-+extern struct timer_opts *cur_timer;
-+extern int timer_ack;
-+
-+/* list of externed timers */
-+extern struct timer_opts timer_none;
-+extern struct timer_opts timer_pit;
-+extern struct init_timer_opts timer_pit_init;
-+extern struct init_timer_opts timer_tsc_init;
-+#ifdef CONFIG_X86_CYCLONE_TIMER
-+extern struct init_timer_opts timer_cyclone_init;
-+#endif
-+
-+extern unsigned long calibrate_tsc(void);
-+extern void init_cpu_khz(void);
-+#ifdef CONFIG_HPET_TIMER
-+extern struct init_timer_opts timer_hpet_init;
-+extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr);
-+#endif
-+
-+#ifdef CONFIG_X86_PM_TIMER
-+extern struct init_timer_opts timer_pmtmr_init;
-+#endif
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/tlbflush.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/tlbflush.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/tlbflush.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/tlbflush.h 2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,104 @@
-+#ifndef _X8664_TLBFLUSH_H
-+#define _X8664_TLBFLUSH_H
-+
-+#include <linux/config.h>
-+#include <linux/mm.h>
-+#include <asm/processor.h>
-+
-+#define __flush_tlb() xen_tlb_flush()
-+
-+/*
-+ * Global pages have to be flushed a bit differently. Not a real
-+ * performance problem because this does not happen often.
-+ */
-+#define __flush_tlb_global()  xen_tlb_flush()
-+
-+
-+extern unsigned long pgkern_mask;
-+
-+#define __flush_tlb_all() __flush_tlb_global()
-+
-+#define __flush_tlb_one(addr) xen_invlpg((unsigned long)addr)
-+
-+
-+/*
-+ * TLB flushing:
-+ *
-+ *  - flush_tlb() flushes the current mm struct TLBs
-+ *  - flush_tlb_all() flushes all processes TLBs
-+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
-+ *  - flush_tlb_page(vma, vmaddr) flushes one page
-+ *  - flush_tlb_range(vma, start, end) flushes a range of pages
-+ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
-+ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
-+ *
-+ * x86-64 can only flush individual pages or full VMs. For a range flush
-+ * we always do the full VM. Might be worth trying if for a small
-+ * range a few INVLPGs in a row are a win.
-+ */
-+
-+#ifndef CONFIG_SMP
-+
-+#define flush_tlb() __flush_tlb()
-+#define flush_tlb_all() __flush_tlb_all()
-+#define local_flush_tlb() __flush_tlb()
-+
-+static inline void flush_tlb_mm(struct mm_struct *mm)
-+{
-+      if (mm == current->active_mm)
-+              __flush_tlb();
-+}
-+
-+static inline void flush_tlb_page(struct vm_area_struct *vma,
-+      unsigned long addr)
-+{
-+      if (vma->vm_mm == current->active_mm)
-+              __flush_tlb_one(addr);
-+}
-+
-+static inline void flush_tlb_range(struct vm_area_struct *vma,
-+      unsigned long start, unsigned long end)
-+{
-+      if (vma->vm_mm == current->active_mm)
-+              __flush_tlb();
-+}
-+
-+#else
-+
-+#include <asm/smp.h>
-+
-+#define local_flush_tlb() \
-+      __flush_tlb()
-+
-+extern void flush_tlb_all(void);
-+extern void flush_tlb_current_task(void);
-+extern void flush_tlb_mm(struct mm_struct *);
-+extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
-+
-+#define flush_tlb()   flush_tlb_current_task()
-+
-+static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
-+{
-+      flush_tlb_mm(vma->vm_mm);
-+}
-+
-+#define TLBSTATE_OK   1
-+#define TLBSTATE_LAZY 2
-+
-+/* Roughly an IPI every 20MB with 4k pages for freeing page table
-+   ranges. Cost is about 42k of memory for each CPU. */
-+#define ARCH_FREE_PTE_NR 5350 
-+
-+#endif
-+
-+#define flush_tlb_kernel_range(start, end) flush_tlb_all()
-+
-+static inline void flush_tlb_pgtables(struct mm_struct *mm,
-+                                    unsigned long start, unsigned long end)
-+{
-+      /* x86_64 does not keep any page table caches in a software TLB.
-+         The CPUs do in their hardware TLBs, but they are handled
-+         by the normal TLB flushing algorithms. */
-+}
-+
-+#endif /* _X8664_TLBFLUSH_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/vga.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/vga.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/vga.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/vga.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,20 @@
-+/*
-+ *    Access to VGA videoram
-+ *
-+ *    (c) 1998 Martin Mares <mj@ucw.cz>
-+ */
-+
-+#ifndef _LINUX_ASM_VGA_H_
-+#define _LINUX_ASM_VGA_H_
-+
-+/*
-+ *    On the PC, we can just recalculate addresses and then
-+ *    access the videoram directly without any black magic.
-+ */
-+
-+#define VGA_MAP_MEM(x) (unsigned long)isa_bus_to_virt(x)
-+
-+#define vga_readb(x) (*(x))
-+#define vga_writeb(x,y) (*(y) = (x))
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/xenoprof.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/xenoprof.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/xenoprof.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/xenoprof.h 2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1 @@
-+#include <asm-i386/mach-xen/asm/xenoprof.h>
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/xor.h linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/xor.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/asm/xor.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/asm/xor.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,328 @@
-+/*
-+ * x86-64 changes / gcc fixes from Andi Kleen. 
-+ * Copyright 2002 Andi Kleen, SuSE Labs.
-+ *
-+ * This hasn't been optimized for the hammer yet, but there are likely
-+ * no advantages to be gotten from x86-64 here anyways.
-+ */
-+
-+typedef struct { unsigned long a,b; } __attribute__((aligned(16))) xmm_store_t;
-+
-+/* Doesn't use gcc to save the XMM registers, because there is no easy way to 
-+   tell it to do a clts before the register saving. */
-+#define XMMS_SAVE do {                                \
-+      preempt_disable();                      \
-+      if (!(current_thread_info()->status & TS_USEDFPU))      \
-+              clts();                         \
-+      __asm__ __volatile__ (                  \
-+              "movups %%xmm0,(%1)     ;\n\t"  \
-+              "movups %%xmm1,0x10(%1) ;\n\t"  \
-+              "movups %%xmm2,0x20(%1) ;\n\t"  \
-+              "movups %%xmm3,0x30(%1) ;\n\t"  \
-+              : "=&r" (cr0)                   \
-+              : "r" (xmm_save)                \
-+              : "memory");                    \
-+} while(0)
-+
-+#define XMMS_RESTORE do {                     \
-+      asm volatile (                          \
-+              "sfence                 ;\n\t"  \
-+              "movups (%1),%%xmm0     ;\n\t"  \
-+              "movups 0x10(%1),%%xmm1 ;\n\t"  \
-+              "movups 0x20(%1),%%xmm2 ;\n\t"  \
-+              "movups 0x30(%1),%%xmm3 ;\n\t"  \
-+              :                               \
-+              : "r" (cr0), "r" (xmm_save)     \
-+              : "memory");                    \
-+      if (!(current_thread_info()->status & TS_USEDFPU))      \
-+              stts();                         \
-+      preempt_enable();                       \
-+} while(0)
-+
-+#define OFFS(x)               "16*("#x")"
-+#define PF_OFFS(x)    "256+16*("#x")"
-+#define       PF0(x)          "       prefetchnta "PF_OFFS(x)"(%[p1])         ;\n"
-+#define LD(x,y)               "       movaps   "OFFS(x)"(%[p1]), %%xmm"#y"    ;\n"
-+#define ST(x,y)               "       movaps %%xmm"#y",   "OFFS(x)"(%[p1])    ;\n"
-+#define PF1(x)                "       prefetchnta "PF_OFFS(x)"(%[p2])         ;\n"
-+#define PF2(x)                "       prefetchnta "PF_OFFS(x)"(%[p3])         ;\n"
-+#define PF3(x)                "       prefetchnta "PF_OFFS(x)"(%[p4])         ;\n"
-+#define PF4(x)                "       prefetchnta "PF_OFFS(x)"(%[p5])         ;\n"
-+#define PF5(x)                "       prefetchnta "PF_OFFS(x)"(%[p6])         ;\n"
-+#define XO1(x,y)      "       xorps   "OFFS(x)"(%[p2]), %%xmm"#y"     ;\n"
-+#define XO2(x,y)      "       xorps   "OFFS(x)"(%[p3]), %%xmm"#y"     ;\n"
-+#define XO3(x,y)      "       xorps   "OFFS(x)"(%[p4]), %%xmm"#y"     ;\n"
-+#define XO4(x,y)      "       xorps   "OFFS(x)"(%[p5]), %%xmm"#y"     ;\n"
-+#define XO5(x,y)      "       xorps   "OFFS(x)"(%[p6]), %%xmm"#y"     ;\n"
-+
-+
-+static void
-+xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
-+{
-+        unsigned int lines = bytes >> 8;
-+      unsigned long cr0;
-+      xmm_store_t xmm_save[4];
-+
-+      XMMS_SAVE;
-+
-+        asm volatile (
-+#undef BLOCK
-+#define BLOCK(i) \
-+              LD(i,0)                                 \
-+                      LD(i+1,1)                       \
-+              PF1(i)                                  \
-+                              PF1(i+2)                \
-+                              LD(i+2,2)               \
-+                                      LD(i+3,3)       \
-+              PF0(i+4)                                \
-+                              PF0(i+6)                \
-+              XO1(i,0)                                \
-+                      XO1(i+1,1)                      \
-+                              XO1(i+2,2)              \
-+                                      XO1(i+3,3)      \
-+              ST(i,0)                                 \
-+                      ST(i+1,1)                       \
-+                              ST(i+2,2)               \
-+                                      ST(i+3,3)       \
-+
-+
-+              PF0(0)
-+                              PF0(2)
-+
-+      " .align 32                     ;\n"
-+        " 1:                            ;\n"
-+
-+              BLOCK(0)
-+              BLOCK(4)
-+              BLOCK(8)
-+              BLOCK(12)
-+
-+        "       addq %[inc], %[p1]           ;\n"
-+        "       addq %[inc], %[p2]           ;\n"
-+              "               decl %[cnt] ; jnz 1b"
-+      : [p1] "+r" (p1), [p2] "+r" (p2), [cnt] "+r" (lines)
-+      : [inc] "r" (256UL) 
-+        : "memory");
-+
-+      XMMS_RESTORE;
-+}
-+
-+static void
-+xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+        unsigned long *p3)
-+{
-+      unsigned int lines = bytes >> 8;
-+      xmm_store_t xmm_save[4];
-+      unsigned long cr0;
-+
-+      XMMS_SAVE;
-+
-+        __asm__ __volatile__ (
-+#undef BLOCK
-+#define BLOCK(i) \
-+              PF1(i)                                  \
-+                              PF1(i+2)                \
-+              LD(i,0)                                 \
-+                      LD(i+1,1)                       \
-+                              LD(i+2,2)               \
-+                                      LD(i+3,3)       \
-+              PF2(i)                                  \
-+                              PF2(i+2)                \
-+              PF0(i+4)                                \
-+                              PF0(i+6)                \
-+              XO1(i,0)                                \
-+                      XO1(i+1,1)                      \
-+                              XO1(i+2,2)              \
-+                                      XO1(i+3,3)      \
-+              XO2(i,0)                                \
-+                      XO2(i+1,1)                      \
-+                              XO2(i+2,2)              \
-+                                      XO2(i+3,3)      \
-+              ST(i,0)                                 \
-+                      ST(i+1,1)                       \
-+                              ST(i+2,2)               \
-+                                      ST(i+3,3)       \
-+
-+
-+              PF0(0)
-+                              PF0(2)
-+
-+      " .align 32                     ;\n"
-+        " 1:                            ;\n"
-+
-+              BLOCK(0)
-+              BLOCK(4)
-+              BLOCK(8)
-+              BLOCK(12)
-+
-+        "       addq %[inc], %[p1]           ;\n"
-+        "       addq %[inc], %[p2]          ;\n"
-+        "       addq %[inc], %[p3]           ;\n"
-+              "               decl %[cnt] ; jnz 1b"
-+      : [cnt] "+r" (lines),
-+        [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3)
-+      : [inc] "r" (256UL)
-+      : "memory"); 
-+      XMMS_RESTORE;
-+}
-+
-+static void
-+xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+        unsigned long *p3, unsigned long *p4)
-+{
-+      unsigned int lines = bytes >> 8;
-+      xmm_store_t xmm_save[4]; 
-+      unsigned long cr0;
-+
-+      XMMS_SAVE;
-+
-+        __asm__ __volatile__ (
-+#undef BLOCK
-+#define BLOCK(i) \
-+              PF1(i)                                  \
-+                              PF1(i+2)                \
-+              LD(i,0)                                 \
-+                      LD(i+1,1)                       \
-+                              LD(i+2,2)               \
-+                                      LD(i+3,3)       \
-+              PF2(i)                                  \
-+                              PF2(i+2)                \
-+              XO1(i,0)                                \
-+                      XO1(i+1,1)                      \
-+                              XO1(i+2,2)              \
-+                                      XO1(i+3,3)      \
-+              PF3(i)                                  \
-+                              PF3(i+2)                \
-+              PF0(i+4)                                \
-+                              PF0(i+6)                \
-+              XO2(i,0)                                \
-+                      XO2(i+1,1)                      \
-+                              XO2(i+2,2)              \
-+                                      XO2(i+3,3)      \
-+              XO3(i,0)                                \
-+                      XO3(i+1,1)                      \
-+                              XO3(i+2,2)              \
-+                                      XO3(i+3,3)      \
-+              ST(i,0)                                 \
-+                      ST(i+1,1)                       \
-+                              ST(i+2,2)               \
-+                                      ST(i+3,3)       \
-+
-+
-+              PF0(0)
-+                              PF0(2)
-+
-+      " .align 32                     ;\n"
-+        " 1:                            ;\n"
-+
-+              BLOCK(0)
-+              BLOCK(4)
-+              BLOCK(8)
-+              BLOCK(12)
-+
-+        "       addq %[inc], %[p1]           ;\n"
-+        "       addq %[inc], %[p2]           ;\n"
-+        "       addq %[inc], %[p3]           ;\n"
-+        "       addq %[inc], %[p4]           ;\n"
-+      "       decl %[cnt] ; jnz 1b"
-+      : [cnt] "+c" (lines),
-+        [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3), [p4] "+r" (p4)
-+      : [inc] "r" (256UL)
-+        : "memory" );
-+
-+      XMMS_RESTORE;
-+}
-+
-+static void
-+xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+        unsigned long *p3, unsigned long *p4, unsigned long *p5)
-+{
-+        unsigned int lines = bytes >> 8;
-+      xmm_store_t xmm_save[4];
-+      unsigned long cr0;
-+
-+      XMMS_SAVE;
-+
-+        __asm__ __volatile__ (
-+#undef BLOCK
-+#define BLOCK(i) \
-+              PF1(i)                                  \
-+                              PF1(i+2)                \
-+              LD(i,0)                                 \
-+                      LD(i+1,1)                       \
-+                              LD(i+2,2)               \
-+                                      LD(i+3,3)       \
-+              PF2(i)                                  \
-+                              PF2(i+2)                \
-+              XO1(i,0)                                \
-+                      XO1(i+1,1)                      \
-+                              XO1(i+2,2)              \
-+                                      XO1(i+3,3)      \
-+              PF3(i)                                  \
-+                              PF3(i+2)                \
-+              XO2(i,0)                                \
-+                      XO2(i+1,1)                      \
-+                              XO2(i+2,2)              \
-+                                      XO2(i+3,3)      \
-+              PF4(i)                                  \
-+                              PF4(i+2)                \
-+              PF0(i+4)                                \
-+                              PF0(i+6)                \
-+              XO3(i,0)                                \
-+                      XO3(i+1,1)                      \
-+                              XO3(i+2,2)              \
-+                                      XO3(i+3,3)      \
-+              XO4(i,0)                                \
-+                      XO4(i+1,1)                      \
-+                              XO4(i+2,2)              \
-+                                      XO4(i+3,3)      \
-+              ST(i,0)                                 \
-+                      ST(i+1,1)                       \
-+                              ST(i+2,2)               \
-+                                      ST(i+3,3)       \
-+
-+
-+              PF0(0)
-+                              PF0(2)
-+
-+      " .align 32                     ;\n"
-+        " 1:                            ;\n"
-+
-+              BLOCK(0)
-+              BLOCK(4)
-+              BLOCK(8)
-+              BLOCK(12)
-+
-+        "       addq %[inc], %[p1]           ;\n"
-+        "       addq %[inc], %[p2]           ;\n"
-+        "       addq %[inc], %[p3]           ;\n"
-+        "       addq %[inc], %[p4]           ;\n"
-+        "       addq %[inc], %[p5]           ;\n"
-+      "       decl %[cnt] ; jnz 1b"
-+      : [cnt] "+c" (lines),
-+        [p1] "+r" (p1), [p2] "+r" (p2), [p3] "+r" (p3), [p4] "+r" (p4), 
-+        [p5] "+r" (p5)
-+      : [inc] "r" (256UL)
-+      : "memory");
-+
-+      XMMS_RESTORE;
-+}
-+
-+static struct xor_block_template xor_block_sse = {
-+        .name = "generic_sse",
-+        .do_2 = xor_sse_2,
-+        .do_3 = xor_sse_3,
-+        .do_4 = xor_sse_4,
-+        .do_5 = xor_sse_5,
-+};
-+
-+#undef XOR_TRY_TEMPLATES
-+#define XOR_TRY_TEMPLATES                             \
-+      do {                                            \
-+              xor_speed(&xor_block_sse);      \
-+      } while (0)
-+
-+/* We force the use of the SSE xor block because it can write around L2.
-+   We may also be able to load into the L1 only depending on how the cpu
-+   deals with a load to a line that is being prefetched.  */
-+#define XOR_SELECT_TEMPLATE(FASTEST) (&xor_block_sse)
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/irq_vectors.h linux-2.6.16.33/include/asm-x86_64/mach-xen/irq_vectors.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/irq_vectors.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/irq_vectors.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,123 @@
-+/*
-+ * This file should contain #defines for all of the interrupt vector
-+ * numbers used by this architecture.
-+ *
-+ * In addition, there are some standard defines:
-+ *
-+ *    FIRST_EXTERNAL_VECTOR:
-+ *            The first free place for external interrupts
-+ *
-+ *    SYSCALL_VECTOR:
-+ *            The IRQ vector a syscall makes the user to kernel transition
-+ *            under.
-+ *
-+ *    TIMER_IRQ:
-+ *            The IRQ number the timer interrupt comes in at.
-+ *
-+ *    NR_IRQS:
-+ *            The total number of interrupt vectors (including all the
-+ *            architecture specific interrupts) needed.
-+ *
-+ */                   
-+#ifndef _ASM_IRQ_VECTORS_H
-+#define _ASM_IRQ_VECTORS_H
-+
-+/*
-+ * IDT vectors usable for external interrupt sources start
-+ * at 0x20:
-+ */
-+#define FIRST_EXTERNAL_VECTOR 0x20
-+
-+#define SYSCALL_VECTOR                0x80
-+
-+/*
-+ * Vectors 0x20-0x2f are used for ISA interrupts.
-+ */
-+
-+#if 0
-+/*
-+ * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
-+ *
-+ *  some of the following vectors are 'rare', they are merged
-+ *  into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
-+ *  TLB, reschedule and local APIC vectors are performance-critical.
-+ *
-+ *  Vectors 0xf0-0xfa are free (reserved for future Linux use).
-+ */
-+#define INVALIDATE_TLB_VECTOR 0xfd
-+#define RESCHEDULE_VECTOR     0xfc
-+#define CALL_FUNCTION_VECTOR  0xfb
-+
-+#define THERMAL_APIC_VECTOR   0xf0
-+/*
-+ * Local APIC timer IRQ vector is on a different priority level,
-+ * to work around the 'lost local interrupt if more than 2 IRQ
-+ * sources per level' errata.
-+ */
-+#define LOCAL_TIMER_VECTOR    0xef
-+#endif
-+
-+#define SPURIOUS_APIC_VECTOR  0xff
-+#define ERROR_APIC_VECTOR     0xfe
-+
-+/*
-+ * First APIC vector available to drivers: (vectors 0x30-0xee)
-+ * we start at 0x31 to spread out vectors evenly between priority
-+ * levels. (0x80 is the syscall vector)
-+ */
-+#define FIRST_DEVICE_VECTOR   0x31
-+#define FIRST_SYSTEM_VECTOR   0xef
-+
-+/*
-+ * 16 8259A IRQ's, 208 potential APIC interrupt sources.
-+ * Right now the APIC is mostly only used for SMP.
-+ * 256 vectors is an architectural limit. (we can have
-+ * more than 256 devices theoretically, but they will
-+ * have to use shared interrupts)
-+ * Since vectors 0x00-0x1f are used/reserved for the CPU,
-+ * the usable vector space is 0x20-0xff (224 vectors)
-+ */
-+
-+#define RESCHEDULE_VECTOR     0
-+#define CALL_FUNCTION_VECTOR  1
-+#define NR_IPIS                       2
-+
-+/*
-+ * The maximum number of vectors supported by i386 processors
-+ * is limited to 256. For processors other than i386, NR_VECTORS
-+ * should be changed accordingly.
-+ */
-+#define NR_VECTORS 256
-+
-+#define FPU_IRQ                       13
-+
-+#define       FIRST_VM86_IRQ          3
-+#define LAST_VM86_IRQ         15
-+#define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15)
-+
-+/*
-+ * The flat IRQ space is divided into two regions:
-+ *  1. A one-to-one mapping of real physical IRQs. This space is only used
-+ *     if we have physical device-access privilege. This region is at the 
-+ *     start of the IRQ space so that existing device drivers do not need
-+ *     to be modified to translate physical IRQ numbers into our IRQ space.
-+ *  3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
-+ *     are bound using the provided bind/unbind functions.
-+ */
-+
-+#define PIRQ_BASE             0
-+#define NR_PIRQS              256
-+
-+#define DYNIRQ_BASE           (PIRQ_BASE + NR_PIRQS)
-+#define NR_DYNIRQS            256
-+
-+#define NR_IRQS                       (NR_PIRQS + NR_DYNIRQS)
-+#define NR_IRQ_VECTORS                NR_IRQS
-+
-+#define pirq_to_irq(_x)               ((_x) + PIRQ_BASE)
-+#define irq_to_pirq(_x)               ((_x) - PIRQ_BASE)
-+
-+#define dynirq_to_irq(_x)     ((_x) + DYNIRQ_BASE)
-+#define irq_to_dynirq(_x)     ((_x) - DYNIRQ_BASE)
-+
-+#endif /* _ASM_IRQ_VECTORS_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/mach_time.h linux-2.6.16.33/include/asm-x86_64/mach-xen/mach_time.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/mach_time.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/mach_time.h    2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,122 @@
-+/*
-+ *  include/asm-i386/mach-default/mach_time.h
-+ *
-+ *  Machine specific set RTC function for generic.
-+ *  Split out from time.c by Osamu Tomita <tomita@cinet.co.jp>
-+ */
-+#ifndef _MACH_TIME_H
-+#define _MACH_TIME_H
-+
-+#include <asm-i386/mc146818rtc.h>
-+
-+/* for check timing call set_rtc_mmss() 500ms     */
-+/* used in arch/i386/time.c::do_timer_interrupt() */
-+#define USEC_AFTER    500000
-+#define USEC_BEFORE   500000
-+
-+/*
-+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
-+ * called 500 ms after the second nowtime has started, because when
-+ * nowtime is written into the registers of the CMOS clock, it will
-+ * jump to the next second precisely 500 ms later. Check the Motorola
-+ * MC146818A or Dallas DS12887 data sheet for details.
-+ *
-+ * BUG: This routine does not handle hour overflow properly; it just
-+ *      sets the minutes. Usually you'll only notice that after reboot!
-+ */
-+static inline int mach_set_rtc_mmss(unsigned long nowtime)
-+{
-+      int retval = 0;
-+      int real_seconds, real_minutes, cmos_minutes;
-+      unsigned char save_control, save_freq_select;
-+
-+      save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-+      CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-+
-+      save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-+      CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-+
-+      cmos_minutes = CMOS_READ(RTC_MINUTES);
-+      if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-+              BCD_TO_BIN(cmos_minutes);
-+
-+      /*
-+       * since we're only adjusting minutes and seconds,
-+       * don't interfere with hour overflow. This avoids
-+       * messing with unknown time zones but requires your
-+       * RTC not to be off by more than 15 minutes
-+       */
-+      real_seconds = nowtime % 60;
-+      real_minutes = nowtime / 60;
-+      if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-+              real_minutes += 30;             /* correct for half hour time zone */
-+      real_minutes %= 60;
-+
-+      if (abs(real_minutes - cmos_minutes) < 30) {
-+              if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-+                      BIN_TO_BCD(real_seconds);
-+                      BIN_TO_BCD(real_minutes);
-+              }
-+              CMOS_WRITE(real_seconds,RTC_SECONDS);
-+              CMOS_WRITE(real_minutes,RTC_MINUTES);
-+      } else {
-+              printk(KERN_WARNING
-+                     "set_rtc_mmss: can't update from %d to %d\n",
-+                     cmos_minutes, real_minutes);
-+              retval = -1;
-+      }
-+
-+      /* The following flags have to be released exactly in this order,
-+       * otherwise the DS12887 (popular MC146818A clone with integrated
-+       * battery and quartz) will not reset the oscillator and will not
-+       * update precisely 500 ms later. You won't find this mentioned in
-+       * the Dallas Semiconductor data sheets, but who believes data
-+       * sheets anyway ...                           -- Markus Kuhn
-+       */
-+      CMOS_WRITE(save_control, RTC_CONTROL);
-+      CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-+
-+      return retval;
-+}
-+
-+static inline unsigned long mach_get_cmos_time(void)
-+{
-+      unsigned int year, mon, day, hour, min, sec;
-+      int i;
-+
-+      /* The Linux interpretation of the CMOS clock register contents:
-+       * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-+       * RTC registers show the second which has precisely just started.
-+       * Let's hope other operating systems interpret the RTC the same way.
-+       */
-+      /* read RTC exactly on falling edge of update flag */
-+      for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
-+              if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-+                      break;
-+      for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
-+              if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-+                      break;
-+      do { /* Isn't this overkill ? UIP above should guarantee consistency */
-+              sec = CMOS_READ(RTC_SECONDS);
-+              min = CMOS_READ(RTC_MINUTES);
-+              hour = CMOS_READ(RTC_HOURS);
-+              day = CMOS_READ(RTC_DAY_OF_MONTH);
-+              mon = CMOS_READ(RTC_MONTH);
-+              year = CMOS_READ(RTC_YEAR);
-+      } while (sec != CMOS_READ(RTC_SECONDS));
-+      if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-+        {
-+          BCD_TO_BIN(sec);
-+          BCD_TO_BIN(min);
-+          BCD_TO_BIN(hour);
-+          BCD_TO_BIN(day);
-+          BCD_TO_BIN(mon);
-+          BCD_TO_BIN(year);
-+        }
-+      if ((year += 1900) < 1970)
-+              year += 100;
-+
-+      return mktime(year, mon, day, hour, min, sec);
-+}
-+
-+#endif /* !_MACH_TIME_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/mach_timer.h linux-2.6.16.33/include/asm-x86_64/mach-xen/mach_timer.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/mach_timer.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/mach_timer.h   2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,48 @@
-+/*
-+ *  include/asm-i386/mach-default/mach_timer.h
-+ *
-+ *  Machine specific calibrate_tsc() for generic.
-+ *  Split out from timer_tsc.c by Osamu Tomita <tomita@cinet.co.jp>
-+ */
-+/* ------ Calibrate the TSC ------- 
-+ * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
-+ * Too much 64-bit arithmetic here to do this cleanly in C, and for
-+ * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
-+ * output busy loop as low as possible. We avoid reading the CTC registers
-+ * directly because of the awkward 8-bit access mechanism of the 82C54
-+ * device.
-+ */
-+#ifndef _MACH_TIMER_H
-+#define _MACH_TIMER_H
-+
-+#define CALIBRATE_LATCH       (5 * LATCH)
-+
-+static inline void mach_prepare_counter(void)
-+{
-+       /* Set the Gate high, disable speaker */
-+      outb((inb(0x61) & ~0x02) | 0x01, 0x61);
-+
-+      /*
-+       * Now let's take care of CTC channel 2
-+       *
-+       * Set the Gate high, program CTC channel 2 for mode 0,
-+       * (interrupt on terminal count mode), binary count,
-+       * load 5 * LATCH count, (LSB and MSB) to begin countdown.
-+       *
-+       * Some devices need a delay here.
-+       */
-+      outb(0xb0, 0x43);                       /* binary, mode 0, LSB/MSB, Ch 2 */
-+      outb_p(CALIBRATE_LATCH & 0xff, 0x42);   /* LSB of count */
-+      outb_p(CALIBRATE_LATCH >> 8, 0x42);       /* MSB of count */
-+}
-+
-+static inline void mach_countup(unsigned long *count_p)
-+{
-+      unsigned long count = 0;
-+      do {
-+              count++;
-+      } while ((inb_p(0x61) & 0x20) == 0);
-+      *count_p = count;
-+}
-+
-+#endif /* !_MACH_TIMER_H */
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/setup_arch_post.h linux-2.6.16.33/include/asm-x86_64/mach-xen/setup_arch_post.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/setup_arch_post.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/setup_arch_post.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,63 @@
-+/**
-+ * machine_specific_* - Hooks for machine specific setup.
-+ *
-+ * Description:
-+ *    This is included late in kernel/setup.c so that it can make
-+ *    use of all of the static functions.
-+ **/
-+
-+#include <xen/interface/callback.h>
-+
-+extern void hypervisor_callback(void);
-+extern void failsafe_callback(void);
-+extern void nmi(void);
-+
-+static void __init machine_specific_arch_setup(void)
-+{
-+      int ret;
-+      static struct callback_register __initdata event = {
-+              .type = CALLBACKTYPE_event,
-+              .address = (unsigned long) hypervisor_callback,
-+      };
-+      static struct callback_register __initdata failsafe = {
-+              .type = CALLBACKTYPE_failsafe,
-+              .address = (unsigned long)failsafe_callback,
-+      };
-+      static struct callback_register __initdata syscall = {
-+              .type = CALLBACKTYPE_syscall,
-+              .address = (unsigned long)system_call,
-+      };
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      static struct callback_register __initdata nmi_cb = {
-+              .type = CALLBACKTYPE_nmi,
-+              .address = (unsigned long)nmi,
-+      };
-+#endif
-+
-+      ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
-+      if (ret == 0)
-+              ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
-+      if (ret == 0)
-+              ret = HYPERVISOR_callback_op(CALLBACKOP_register, &syscall);
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (ret == -ENOSYS)
-+              ret = HYPERVISOR_set_callbacks(
-+                      event.address,
-+                      failsafe.address,
-+                      syscall.address);
-+#endif
-+      BUG_ON(ret);
-+
-+#ifdef CONFIG_X86_LOCAL_APIC
-+      ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
-+#ifdef CONFIG_XEN_COMPAT_030002
-+      if (ret == -ENOSYS) {
-+              static struct xennmi_callback __initdata cb = {
-+                      .handler_address = (unsigned long)nmi
-+              };
-+
-+              HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
-+      }
-+#endif
-+#endif
-+}
-diff -Nur linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/setup_arch_pre.h linux-2.6.16.33/include/asm-x86_64/mach-xen/setup_arch_pre.h
---- linux-2.6.16.33-noxen/include/asm-x86_64/mach-xen/setup_arch_pre.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/asm-x86_64/mach-xen/setup_arch_pre.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,5 @@
-+/* Hook to call BIOS initialisation function */
-+
-+#define ARCH_SETUP machine_specific_arch_setup();
-+
-+static void __init machine_specific_arch_setup(void);
-diff -Nur linux-2.6.16.33-noxen/include/linux/aio.h linux-2.6.16.33/include/linux/aio.h
---- linux-2.6.16.33-noxen/include/linux/aio.h  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/aio.h        2007-05-23 21:00:01.000000000 +0000
-@@ -191,6 +191,11 @@
-       struct aio_ring_info    ring_info;
-       struct work_struct      wq;
-+#ifdef CONFIG_EPOLL
-+      // poll integration
-+      wait_queue_head_t       poll_wait;
-+      struct file             *file;
-+#endif
- };
- /* prototypes */
-diff -Nur linux-2.6.16.33-noxen/include/linux/elfnote.h linux-2.6.16.33/include/linux/elfnote.h
---- linux-2.6.16.33-noxen/include/linux/elfnote.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/linux/elfnote.h    2007-05-23 21:00:01.000000000 +0000
-@@ -0,0 +1,90 @@
-+#ifndef _LINUX_ELFNOTE_H
-+#define _LINUX_ELFNOTE_H
-+/*
-+ * Helper macros to generate ELF Note structures, which are put into a
-+ * PT_NOTE segment of the final vmlinux image.  These are useful for
-+ * including name-value pairs of metadata into the kernel binary (or
-+ * modules?) for use by external programs.
-+ *
-+ * Each note has three parts: a name, a type and a desc.  The name is
-+ * intended to distinguish the note's originator, so it would be a
-+ * company, project, subsystem, etc; it must be in a suitable form for
-+ * use in a section name.  The type is an integer which is used to tag
-+ * the data, and is considered to be within the "name" namespace (so
-+ * "FooCo"'s type 42 is distinct from "BarProj"'s type 42).  The
-+ * "desc" field is the actual data.  There are no constraints on the
-+ * desc field's contents, though typically they're fairly small.
-+ *
-+ * All notes from a given NAME are put into a section named
-+ * .note.NAME.  When the kernel image is finally linked, all the notes
-+ * are packed into a single .notes section, which is mapped into the
-+ * PT_NOTE segment.  Because notes for a given name are grouped into
-+ * the same section, they'll all be adjacent the output file.
-+ *
-+ * This file defines macros for both C and assembler use.  Their
-+ * syntax is slightly different, but they're semantically similar.
-+ *
-+ * See the ELF specification for more detail about ELF notes.
-+ */
-+
-+#ifdef __ASSEMBLER__
-+/*
-+ * Generate a structure with the same shape as Elf{32,64}_Nhdr (which
-+ * turn out to be the same size and shape), followed by the name and
-+ * desc data with appropriate padding.  The 'desctype' argument is the
-+ * assembler pseudo op defining the type of the data e.g. .asciz while
-+ * 'descdata' is the data itself e.g.  "hello, world".
-+ *
-+ * e.g. ELFNOTE(XYZCo, 42, .asciz, "forty-two")
-+ *      ELFNOTE(XYZCo, 12, .long, 0xdeadbeef)
-+ */
-+#define ELFNOTE(name, type, desctype, descdata)       \
-+.pushsection .note.name                       ;       \
-+  .align 4                            ;       \
-+  .long 2f - 1f               /* namesz */    ;       \
-+  .long 4f - 3f               /* descsz */    ;       \
-+  .long type                          ;       \
-+1:.asciz "name"                               ;       \
-+2:.align 4                            ;       \
-+3:desctype descdata                   ;       \
-+4:.align 4                            ;       \
-+.popsection                           ;
-+#else /* !__ASSEMBLER__ */
-+#include <linux/elf.h>
-+/*
-+ * Use an anonymous structure which matches the shape of
-+ * Elf{32,64}_Nhdr, but includes the name and desc data.  The size and
-+ * type of name and desc depend on the macro arguments.  "name" must
-+ * be a literal string, and "desc" must be passed by value.  You may
-+ * only define one note per line, since __LINE__ is used to generate
-+ * unique symbols.
-+ */
-+#define _ELFNOTE_PASTE(a,b)   a##b
-+#define _ELFNOTE(size, name, unique, type, desc)                      \
-+      static const struct {                                           \
-+              struct elf##size##_note _nhdr;                          \
-+              unsigned char _name[sizeof(name)]                       \
-+              __attribute__((aligned(sizeof(Elf##size##_Word))));     \
-+              typeof(desc) _desc                                      \
-+                           __attribute__((aligned(sizeof(Elf##size##_Word)))); \
-+      } _ELFNOTE_PASTE(_note_, unique)                                \
-+              __attribute_used__                                      \
-+              __attribute__((section(".note." name),                  \
-+                             aligned(sizeof(Elf##size##_Word)),       \
-+                             unused)) = {                             \
-+              {                                                       \
-+                      sizeof(name),                                   \
-+                      sizeof(desc),                                   \
-+                      type,                                           \
-+              },                                                      \
-+              name,                                                   \
-+              desc                                                    \
-+      }
-+#define ELFNOTE(size, name, type, desc)               \
-+      _ELFNOTE(size, name, __LINE__, type, desc)
-+
-+#define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc)
-+#define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc)
-+#endif        /* __ASSEMBLER__ */
-+
-+#endif /* _LINUX_ELFNOTE_H */
-diff -Nur linux-2.6.16.33-noxen/include/linux/ethtool.h linux-2.6.16.33/include/linux/ethtool.h
---- linux-2.6.16.33-noxen/include/linux/ethtool.h      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/ethtool.h    2007-05-23 21:00:01.000000000 +0000
-@@ -408,6 +408,8 @@
- #define ETHTOOL_GPERMADDR     0x00000020 /* Get permanent hardware address */
- #define ETHTOOL_GUFO          0x00000021 /* Get UFO enable (ethtool_value) */
- #define ETHTOOL_SUFO          0x00000022 /* Set UFO enable (ethtool_value) */
-+#define ETHTOOL_GGSO          0x00000023 /* Get GSO enable (ethtool_value) */
-+#define ETHTOOL_SGSO          0x00000024 /* Set GSO enable (ethtool_value) */
- /* compatibility with older code */
- #define SPARC_ETH_GSET                ETHTOOL_GSET
-diff -Nur linux-2.6.16.33-noxen/include/linux/eventpoll.h linux-2.6.16.33/include/linux/eventpoll.h
---- linux-2.6.16.33-noxen/include/linux/eventpoll.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/eventpoll.h  2007-05-23 21:00:01.000000000 +0000
-@@ -86,6 +86,12 @@
- }
-+/*
-+ * called by aio code to create fd that can poll the  aio event queueQ
-+ */
-+struct eventpoll;
-+int ep_getfd(int *efd, struct inode **einode, struct file **efile,
-+             struct eventpoll *ep, struct file_operations *fops);
- #else
- static inline void eventpoll_init_file(struct file *file) {}
-diff -Nur linux-2.6.16.33-noxen/include/linux/gfp.h linux-2.6.16.33/include/linux/gfp.h
---- linux-2.6.16.33-noxen/include/linux/gfp.h  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/gfp.h        2007-01-08 15:00:46.000000000 +0000
-@@ -98,7 +98,11 @@
-  */
- #ifndef HAVE_ARCH_FREE_PAGE
--static inline void arch_free_page(struct page *page, int order) { }
-+/*
-+ * If arch_free_page returns non-zero then the generic free_page code can
-+ * immediately bail: the arch-specific function has done all the work.
-+ */
-+static inline int arch_free_page(struct page *page, int order) { return 0; }
- #endif
- extern struct page *
-diff -Nur linux-2.6.16.33-noxen/include/linux/highmem.h linux-2.6.16.33/include/linux/highmem.h
---- linux-2.6.16.33-noxen/include/linux/highmem.h      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/highmem.h    2007-01-08 15:00:46.000000000 +0000
-@@ -13,10 +13,16 @@
- /* declarations for linux/mm/highmem.c */
- unsigned int nr_free_highpages(void);
-+#ifdef CONFIG_XEN
-+void kmap_flush_unused(void);
-+#endif
- #else /* CONFIG_HIGHMEM */
- static inline unsigned int nr_free_highpages(void) { return 0; }
-+#ifdef CONFIG_XEN
-+static inline void kmap_flush_unused(void) { }
-+#endif
- static inline void *kmap(struct page *page)
- {
-diff -Nur linux-2.6.16.33-noxen/include/linux/interrupt.h linux-2.6.16.33/include/linux/interrupt.h
---- linux-2.6.16.33-noxen/include/linux/interrupt.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/interrupt.h  2007-01-08 15:00:46.000000000 +0000
-@@ -58,6 +58,12 @@
- extern void enable_irq(unsigned int irq);
- #endif
-+#ifdef CONFIG_HAVE_IRQ_IGNORE_UNHANDLED
-+int irq_ignore_unhandled(unsigned int irq);
-+#else
-+#define irq_ignore_unhandled(irq) 0
-+#endif
-+
- #ifndef __ARCH_SET_SOFTIRQ_PENDING
- #define set_softirq_pending(x) (local_softirq_pending() = (x))
- #define or_softirq_pending(x)  (local_softirq_pending() |= (x))
-diff -Nur linux-2.6.16.33-noxen/include/linux/kernel.h linux-2.6.16.33/include/linux/kernel.h
---- linux-2.6.16.33-noxen/include/linux/kernel.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/kernel.h     2007-05-23 21:00:01.000000000 +0000
-@@ -111,6 +111,8 @@
-       __attribute__ ((format (printf, 3, 4)));
- extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
-       __attribute__ ((format (printf, 3, 0)));
-+extern char *kasprintf(gfp_t gfp, const char *fmt, ...)
-+      __attribute__ ((format (printf, 2, 3)));
- extern int sscanf(const char *, const char *, ...)
-       __attribute__ ((format (scanf, 2, 3)));
-diff -Nur linux-2.6.16.33-noxen/include/linux/kernel.h~ linux-2.6.16.33/include/linux/kernel.h~
---- linux-2.6.16.33-noxen/include/linux/kernel.h~      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/linux/kernel.h~    2006-11-22 18:06:31.000000000 +0000
-@@ -0,0 +1,332 @@
-+#ifndef _LINUX_KERNEL_H
-+#define _LINUX_KERNEL_H
-+
-+/*
-+ * 'kernel.h' contains some often-used function prototypes etc
-+ */
-+
-+#ifdef __KERNEL__
-+
-+#include <stdarg.h>
-+#include <linux/linkage.h>
-+#include <linux/stddef.h>
-+#include <linux/types.h>
-+#include <linux/compiler.h>
-+#include <linux/bitops.h>
-+#include <asm/byteorder.h>
-+#include <asm/bug.h>
-+
-+extern const char linux_banner[];
-+
-+#define INT_MAX               ((int)(~0U>>1))
-+#define INT_MIN               (-INT_MAX - 1)
-+#define UINT_MAX      (~0U)
-+#define LONG_MAX      ((long)(~0UL>>1))
-+#define LONG_MIN      (-LONG_MAX - 1)
-+#define ULONG_MAX     (~0UL)
-+
-+#define STACK_MAGIC   0xdeadbeef
-+
-+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-+#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
-+
-+#define       KERN_EMERG      "<0>"   /* system is unusable                   */
-+#define       KERN_ALERT      "<1>"   /* action must be taken immediately     */
-+#define       KERN_CRIT       "<2>"   /* critical conditions                  */
-+#define       KERN_ERR        "<3>"   /* error conditions                     */
-+#define       KERN_WARNING    "<4>"   /* warning conditions                   */
-+#define       KERN_NOTICE     "<5>"   /* normal but significant condition     */
-+#define       KERN_INFO       "<6>"   /* informational                        */
-+#define       KERN_DEBUG      "<7>"   /* debug-level messages                 */
-+
-+extern int console_printk[];
-+
-+#define console_loglevel (console_printk[0])
-+#define default_message_loglevel (console_printk[1])
-+#define minimum_console_loglevel (console_printk[2])
-+#define default_console_loglevel (console_printk[3])
-+
-+struct completion;
-+struct pt_regs;
-+struct user;
-+
-+/**
-+ * might_sleep - annotation for functions that can sleep
-+ *
-+ * this macro will print a stack trace if it is executed in an atomic
-+ * context (spinlock, irq-handler, ...).
-+ *
-+ * This is a useful debugging help to be able to catch problems early and not
-+ * be biten later when the calling function happens to sleep when it is not
-+ * supposed to.
-+ */
-+#ifdef CONFIG_PREEMPT_VOLUNTARY
-+extern int cond_resched(void);
-+# define might_resched() cond_resched()
-+#else
-+# define might_resched() do { } while (0)
-+#endif
-+
-+#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
-+  void __might_sleep(char *file, int line);
-+# define might_sleep() \
-+      do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0)
-+#else
-+# define might_sleep() do { might_resched(); } while (0)
-+#endif
-+
-+#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0)
-+
-+#define abs(x) ({                             \
-+              int __x = (x);                  \
-+              (__x < 0) ? -__x : __x;         \
-+      })
-+
-+#define labs(x) ({                            \
-+              long __x = (x);                 \
-+              (__x < 0) ? -__x : __x;         \
-+      })
-+
-+extern struct notifier_block *panic_notifier_list;
-+extern long (*panic_blink)(long time);
-+NORET_TYPE void panic(const char * fmt, ...)
-+      __attribute__ ((NORET_AND format (printf, 1, 2)));
-+fastcall NORET_TYPE void do_exit(long error_code)
-+      ATTRIB_NORET;
-+NORET_TYPE void complete_and_exit(struct completion *, long)
-+      ATTRIB_NORET;
-+extern unsigned long simple_strtoul(const char *,char **,unsigned int);
-+extern long simple_strtol(const char *,char **,unsigned int);
-+extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
-+extern long long simple_strtoll(const char *,char **,unsigned int);
-+extern int sprintf(char * buf, const char * fmt, ...)
-+      __attribute__ ((format (printf, 2, 3)));
-+extern int vsprintf(char *buf, const char *, va_list)
-+      __attribute__ ((format (printf, 2, 0)));
-+extern int snprintf(char * buf, size_t size, const char * fmt, ...)
-+      __attribute__ ((format (printf, 3, 4)));
-+extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
-+      __attribute__ ((format (printf, 3, 0)));
-+extern int scnprintf(char * buf, size_t size, const char * fmt, ...)
-+      __attribute__ ((format (printf, 3, 4)));
-+extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
-+      __attribute__ ((format (printf, 3, 0)));
-+
-+extern int sscanf(const char *, const char *, ...)
-+      __attribute__ ((format (scanf, 2, 3)));
-+extern int vsscanf(const char *, const char *, va_list)
-+      __attribute__ ((format (scanf, 2, 0)));
-+
-+extern int get_option(char **str, int *pint);
-+extern char *get_options(const char *str, int nints, int *ints);
-+extern unsigned long long memparse(char *ptr, char **retptr);
-+
-+extern int __kernel_text_address(unsigned long addr);
-+extern int kernel_text_address(unsigned long addr);
-+extern int session_of_pgrp(int pgrp);
-+
-+extern void dump_thread(struct pt_regs *regs, struct user *dump);
-+
-+#ifdef CONFIG_PRINTK
-+asmlinkage int vprintk(const char *fmt, va_list args)
-+      __attribute__ ((format (printf, 1, 0)));
-+asmlinkage int printk(const char * fmt, ...)
-+      __attribute__ ((format (printf, 1, 2)));
-+#else
-+static inline int vprintk(const char *s, va_list args)
-+      __attribute__ ((format (printf, 1, 0)));
-+static inline int vprintk(const char *s, va_list args) { return 0; }
-+static inline int printk(const char *s, ...)
-+      __attribute__ ((format (printf, 1, 2)));
-+static inline int printk(const char *s, ...) { return 0; }
-+#endif
-+
-+unsigned long int_sqrt(unsigned long);
-+
-+static inline int __attribute_pure__ long_log2(unsigned long x)
-+{
-+      int r = 0;
-+      for (x >>= 1; x > 0; x >>= 1)
-+              r++;
-+      return r;
-+}
-+
-+static inline unsigned long __attribute_const__ roundup_pow_of_two(unsigned long x)
-+{
-+      return (1UL << fls(x - 1));
-+}
-+
-+extern int printk_ratelimit(void);
-+extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst);
-+
-+static inline void console_silent(void)
-+{
-+      console_loglevel = 0;
-+}
-+
-+static inline void console_verbose(void)
-+{
-+      if (console_loglevel)
-+              console_loglevel = 15;
-+}
-+
-+extern void bust_spinlocks(int yes);
-+extern int oops_in_progress;          /* If set, an oops, panic(), BUG() or die() is in progress */
-+extern __deprecated_for_modules int panic_timeout;
-+extern int panic_on_oops;
-+extern int tainted;
-+extern const char *print_tainted(void);
-+extern void add_taint(unsigned);
-+
-+/* Values used for system_state */
-+extern enum system_states {
-+      SYSTEM_BOOTING,
-+      SYSTEM_RUNNING,
-+      SYSTEM_HALT,
-+      SYSTEM_POWER_OFF,
-+      SYSTEM_RESTART,
-+      SYSTEM_SUSPEND_DISK,
-+} system_state;
-+
-+#define TAINT_PROPRIETARY_MODULE      (1<<0)
-+#define TAINT_FORCED_MODULE           (1<<1)
-+#define TAINT_UNSAFE_SMP              (1<<2)
-+#define TAINT_FORCED_RMMOD            (1<<3)
-+#define TAINT_MACHINE_CHECK           (1<<4)
-+#define TAINT_BAD_PAGE                        (1<<5)
-+
-+extern void dump_stack(void);
-+
-+#ifdef DEBUG
-+#define pr_debug(fmt,arg...) \
-+      printk(KERN_DEBUG fmt,##arg)
-+#else
-+#define pr_debug(fmt,arg...) \
-+      do { } while (0)
-+#endif
-+
-+#define pr_info(fmt,arg...) \
-+      printk(KERN_INFO fmt,##arg)
-+
-+/*
-+ *      Display an IP address in readable format.
-+ */
-+
-+#define NIPQUAD(addr) \
-+      ((unsigned char *)&addr)[0], \
-+      ((unsigned char *)&addr)[1], \
-+      ((unsigned char *)&addr)[2], \
-+      ((unsigned char *)&addr)[3]
-+#define NIPQUAD_FMT "%u.%u.%u.%u"
-+
-+#define NIP6(addr) \
-+      ntohs((addr).s6_addr16[0]), \
-+      ntohs((addr).s6_addr16[1]), \
-+      ntohs((addr).s6_addr16[2]), \
-+      ntohs((addr).s6_addr16[3]), \
-+      ntohs((addr).s6_addr16[4]), \
-+      ntohs((addr).s6_addr16[5]), \
-+      ntohs((addr).s6_addr16[6]), \
-+      ntohs((addr).s6_addr16[7])
-+#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
-+#define NIP6_SEQFMT "%04x%04x%04x%04x%04x%04x%04x%04x"
-+
-+#if defined(__LITTLE_ENDIAN)
-+#define HIPQUAD(addr) \
-+      ((unsigned char *)&addr)[3], \
-+      ((unsigned char *)&addr)[2], \
-+      ((unsigned char *)&addr)[1], \
-+      ((unsigned char *)&addr)[0]
-+#elif defined(__BIG_ENDIAN)
-+#define HIPQUAD       NIPQUAD
-+#else
-+#error "Please fix asm/byteorder.h"
-+#endif /* __LITTLE_ENDIAN */
-+
-+/*
-+ * min()/max() macros that also do
-+ * strict type-checking.. See the
-+ * "unnecessary" pointer comparison.
-+ */
-+#define min(x,y) ({ \
-+      typeof(x) _x = (x);     \
-+      typeof(y) _y = (y);     \
-+      (void) (&_x == &_y);            \
-+      _x < _y ? _x : _y; })
-+
-+#define max(x,y) ({ \
-+      typeof(x) _x = (x);     \
-+      typeof(y) _y = (y);     \
-+      (void) (&_x == &_y);            \
-+      _x > _y ? _x : _y; })
-+
-+/*
-+ * ..and if you can't take the strict
-+ * types, you can specify one yourself.
-+ *
-+ * Or not use min/max at all, of course.
-+ */
-+#define min_t(type,x,y) \
-+      ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
-+#define max_t(type,x,y) \
-+      ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
-+
-+
-+/**
-+ * container_of - cast a member of a structure out to the containing structure
-+ * @ptr:      the pointer to the member.
-+ * @type:     the type of the container struct this is embedded in.
-+ * @member:   the name of the member within the struct.
-+ *
-+ */
-+#define container_of(ptr, type, member) ({                    \
-+        const typeof( ((type *)0)->member ) *__mptr = (ptr);  \
-+        (type *)( (char *)__mptr - offsetof(type,member) );})
-+
-+/*
-+ * Check at compile time that something is of a particular type.
-+ * Always evaluates to 1 so you may use it easily in comparisons.
-+ */
-+#define typecheck(type,x) \
-+({    type __dummy; \
-+      typeof(x) __dummy2; \
-+      (void)(&__dummy == &__dummy2); \
-+      1; \
-+})
-+
-+/*
-+ * Check at compile time that 'function' is a certain type, or is a pointer
-+ * to that type (needs to use typedef for the function type.)
-+ */
-+#define typecheck_fn(type,function) \
-+({    typeof(type) __tmp = function; \
-+      (void)__tmp; \
-+})
-+
-+#endif /* __KERNEL__ */
-+
-+#define SI_LOAD_SHIFT 16
-+struct sysinfo {
-+      long uptime;                    /* Seconds since boot */
-+      unsigned long loads[3];         /* 1, 5, and 15 minute load averages */
-+      unsigned long totalram;         /* Total usable main memory size */
-+      unsigned long freeram;          /* Available memory size */
-+      unsigned long sharedram;        /* Amount of shared memory */
-+      unsigned long bufferram;        /* Memory used by buffers */
-+      unsigned long totalswap;        /* Total swap space size */
-+      unsigned long freeswap;         /* swap space still available */
-+      unsigned short procs;           /* Number of current processes */
-+      unsigned short pad;             /* explicit padding for m68k */
-+      unsigned long totalhigh;        /* Total high memory size */
-+      unsigned long freehigh;         /* Available high memory size */
-+      unsigned int mem_unit;          /* Memory unit size in bytes */
-+      char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
-+};
-+
-+/* Force a compilation error if condition is true */
-+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-+
-+/* Trap pasters of __FUNCTION__ at compile-time */
-+#define __FUNCTION__ (__func__)
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/linux/kexec.h linux-2.6.16.33/include/linux/kexec.h
---- linux-2.6.16.33-noxen/include/linux/kexec.h        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/kexec.h      2007-01-08 15:00:46.000000000 +0000
-@@ -31,6 +31,13 @@
- #error KEXEC_ARCH not defined
- #endif
-+#ifndef KEXEC_ARCH_HAS_PAGE_MACROS
-+#define kexec_page_to_pfn(page)  page_to_pfn(page)
-+#define kexec_pfn_to_page(pfn)   pfn_to_page(pfn)
-+#define kexec_virt_to_phys(addr) virt_to_phys(addr)
-+#define kexec_phys_to_virt(addr) phys_to_virt(addr)
-+#endif
-+
- /*
-  * This structure is used to hold the arguments that are used when loading
-  * kernel binaries.
-@@ -91,6 +98,12 @@
- extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET;
- extern int machine_kexec_prepare(struct kimage *image);
- extern void machine_kexec_cleanup(struct kimage *image);
-+#ifdef CONFIG_XEN
-+extern int xen_machine_kexec_load(struct kimage *image);
-+extern void xen_machine_kexec_unload(struct kimage *image);
-+extern void xen_machine_kexec_setup_resources(void);
-+extern void xen_machine_kexec_register_resources(struct resource *res);
-+#endif
- extern asmlinkage long sys_kexec_load(unsigned long entry,
-                                       unsigned long nr_segments,
-                                       struct kexec_segment __user *segments,
-diff -Nur linux-2.6.16.33-noxen/include/linux/mm.h linux-2.6.16.33/include/linux/mm.h
---- linux-2.6.16.33-noxen/include/linux/mm.h   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/mm.h 2007-01-08 15:00:46.000000000 +0000
-@@ -166,6 +166,9 @@
- #define VM_NONLINEAR  0x00800000      /* Is non-linear (remap_file_pages) */
- #define VM_MAPPED_COPY        0x01000000      /* T if mapped copy of data (nommu mmap) */
- #define VM_INSERTPAGE 0x02000000      /* The vma has had "vm_insert_page()" done on it */
-+#ifdef CONFIG_XEN
-+#define VM_FOREIGN    0x04000000      /* Has pages belonging to another VM */
-+#endif
- #ifndef VM_STACK_DEFAULT_FLAGS                /* arch can override this */
- #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
-@@ -1012,6 +1015,13 @@
- #define FOLL_GET      0x04    /* do get_page on page */
- #define FOLL_ANON     0x08    /* give ZERO_PAGE if no pgtable */
-+#ifdef CONFIG_XEN
-+typedef int (*pte_fn_t)(pte_t *pte, struct page *pmd_page, unsigned long addr,
-+                      void *data);
-+extern int apply_to_page_range(struct mm_struct *mm, unsigned long address,
-+                             unsigned long size, pte_fn_t fn, void *data);
-+#endif
-+
- #ifdef CONFIG_PROC_FS
- void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
- #else
-diff -Nur linux-2.6.16.33-noxen/include/linux/netdevice.h linux-2.6.16.33/include/linux/netdevice.h
---- linux-2.6.16.33-noxen/include/linux/netdevice.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/netdevice.h  2007-05-23 21:00:01.000000000 +0000
-@@ -230,7 +230,8 @@
-       __LINK_STATE_SCHED,
-       __LINK_STATE_NOCARRIER,
-       __LINK_STATE_RX_SCHED,
--      __LINK_STATE_LINKWATCH_PENDING
-+      __LINK_STATE_LINKWATCH_PENDING,
-+      __LINK_STATE_QDISC_RUNNING,
- };
-@@ -306,9 +307,17 @@
- #define NETIF_F_HW_VLAN_RX    256     /* Receive VLAN hw acceleration */
- #define NETIF_F_HW_VLAN_FILTER        512     /* Receive filtering on VLAN */
- #define NETIF_F_VLAN_CHALLENGED       1024    /* Device cannot handle VLAN packets */
--#define NETIF_F_TSO           2048    /* Can offload TCP/IP segmentation */
-+#define NETIF_F_GSO           2048    /* Enable software GSO. */
- #define NETIF_F_LLTX          4096    /* LockLess TX */
--#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
-+
-+      /* Segmentation offload features */
-+#define NETIF_F_GSO_SHIFT     16
-+#define NETIF_F_TSO           (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
-+#define NETIF_F_UFO           (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
-+#define NETIF_F_GSO_ROBUST    (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
-+
-+#define NETIF_F_GEN_CSUM      (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
-+#define NETIF_F_ALL_CSUM      (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
-       struct net_device       *next_sched;
-@@ -394,6 +403,9 @@
-       struct list_head        qdisc_list;
-       unsigned long           tx_queue_len;   /* Max frames per queue allowed */
-+      /* Partially transmitted GSO packet. */
-+      struct sk_buff          *gso_skb;
-+
-       /* ingress path synchronizer */
-       spinlock_t              ingress_lock;
-       struct Qdisc            *qdisc_ingress;
-@@ -402,7 +414,7 @@
-  * One part is mostly used on xmit path (device)
-  */
-       /* hard_start_xmit synchronizer */
--      spinlock_t              xmit_lock ____cacheline_aligned_in_smp;
-+      spinlock_t              _xmit_lock ____cacheline_aligned_in_smp;
-       /* cpu id of processor entered to hard_start_xmit or -1,
-          if nobody entered there.
-        */
-@@ -527,6 +539,9 @@
-                                        struct net_device *,
-                                        struct packet_type *,
-                                        struct net_device *);
-+      struct sk_buff          *(*gso_segment)(struct sk_buff *skb,
-+                                              int features);
-+      int                     (*gso_send_check)(struct sk_buff *skb);
-       void                    *af_packet_priv;
-       struct list_head        list;
- };
-@@ -693,7 +708,8 @@
- extern int            dev_set_mtu(struct net_device *, int);
- extern int            dev_set_mac_address(struct net_device *,
-                                           struct sockaddr *);
--extern void           dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
-+extern int            dev_hard_start_xmit(struct sk_buff *skb,
-+                                          struct net_device *dev);
- extern void           dev_init(void);
-@@ -900,11 +916,43 @@
-       clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
- }
-+static inline void netif_tx_lock(struct net_device *dev)
-+{
-+      spin_lock(&dev->_xmit_lock);
-+      dev->xmit_lock_owner = smp_processor_id();
-+}
-+
-+static inline void netif_tx_lock_bh(struct net_device *dev)
-+{
-+      spin_lock_bh(&dev->_xmit_lock);
-+      dev->xmit_lock_owner = smp_processor_id();
-+}
-+
-+static inline int netif_tx_trylock(struct net_device *dev)
-+{
-+      int ok = spin_trylock(&dev->_xmit_lock);
-+      if (likely(ok))
-+              dev->xmit_lock_owner = smp_processor_id();
-+      return ok;
-+}
-+
-+static inline void netif_tx_unlock(struct net_device *dev)
-+{
-+      dev->xmit_lock_owner = -1;
-+      spin_unlock(&dev->_xmit_lock);
-+}
-+
-+static inline void netif_tx_unlock_bh(struct net_device *dev)
-+{
-+      dev->xmit_lock_owner = -1;
-+      spin_unlock_bh(&dev->_xmit_lock);
-+}
-+
- static inline void netif_tx_disable(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       netif_stop_queue(dev);
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- /* These functions live elsewhere (drivers/net/net_init.c, but related) */
-@@ -932,6 +980,7 @@
- extern int            weight_p;
- extern int            netdev_set_master(struct net_device *dev, struct net_device *master);
- extern int skb_checksum_help(struct sk_buff *skb, int inward);
-+extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
- #ifdef CONFIG_BUG
- extern void netdev_rx_csum_fault(struct net_device *dev);
- #else
-@@ -951,6 +1000,19 @@
- extern void linkwatch_run_queue(void);
-+static inline int skb_gso_ok(struct sk_buff *skb, int features)
-+{
-+      int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT;
-+      return (features & feature) == feature;
-+}
-+
-+static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
-+{
-+      return skb_is_gso(skb) &&
-+             (!skb_gso_ok(skb, dev->features) ||
-+              unlikely(skb->ip_summed != CHECKSUM_HW));
-+}
-+
- #endif /* __KERNEL__ */
- #endif        /* _LINUX_DEV_H */
-diff -Nur linux-2.6.16.33-noxen/include/linux/oprofile.h linux-2.6.16.33/include/linux/oprofile.h
---- linux-2.6.16.33-noxen/include/linux/oprofile.h     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/oprofile.h   2007-05-23 21:00:01.000000000 +0000
-@@ -16,6 +16,8 @@
- #include <linux/types.h>
- #include <linux/spinlock.h>
- #include <asm/atomic.h>
-+
-+#include <xen/interface/xenoprof.h>
-  
- struct super_block;
- struct dentry;
-@@ -27,6 +29,11 @@
-       /* create any necessary configuration files in the oprofile fs.
-        * Optional. */
-       int (*create_files)(struct super_block * sb, struct dentry * root);
-+      /* setup active domains with Xen */
-+      int (*set_active)(int *active_domains, unsigned int adomains);
-+        /* setup passive domains with Xen */
-+        int (*set_passive)(int *passive_domains, unsigned int pdomains);
-+      
-       /* Do any necessary interrupt setup. Optional. */
-       int (*setup)(void);
-       /* Do any necessary interrupt shutdown. Optional. */
-@@ -68,6 +75,8 @@
- /* add a backtrace entry, to be called from the ->backtrace callback */
- void oprofile_add_trace(unsigned long eip);
-+/* add a domain switch entry */
-+int oprofile_add_domain_switch(int32_t domain_id);
- /**
-  * Create a file of the given name as a child of the given root, with
-diff -Nur linux-2.6.16.33-noxen/include/linux/rcupdate.h linux-2.6.16.33/include/linux/rcupdate.h
---- linux-2.6.16.33-noxen/include/linux/rcupdate.h     2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/rcupdate.h   2007-05-23 21:00:01.000000000 +0000
-@@ -134,6 +134,7 @@
- }
- extern int rcu_pending(int cpu);
-+extern int rcu_needs_cpu(int cpu);
- /**
-  * rcu_read_lock - mark the beginning of an RCU read-side critical section.
-diff -Nur linux-2.6.16.33-noxen/include/linux/skbuff.h linux-2.6.16.33/include/linux/skbuff.h
---- linux-2.6.16.33-noxen/include/linux/skbuff.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/linux/skbuff.h     2007-01-08 15:00:46.000000000 +0000
-@@ -134,9 +134,10 @@
- struct skb_shared_info {
-       atomic_t        dataref;
-       unsigned short  nr_frags;
--      unsigned short  tso_size;
--      unsigned short  tso_segs;
--      unsigned short  ufo_size;
-+      unsigned short  gso_size;
-+      /* Warning: this field is not always filled in (UFO)! */
-+      unsigned short  gso_segs;
-+      unsigned short  gso_type;
-       unsigned int    ip6_frag_id;
-       struct sk_buff  *frag_list;
-       skb_frag_t      frags[MAX_SKB_FRAGS];
-@@ -168,6 +169,14 @@
-       SKB_FCLONE_CLONE,
- };
-+enum {
-+      SKB_GSO_TCPV4 = 1 << 0,
-+      SKB_GSO_UDPV4 = 1 << 1,
-+
-+      /* This indicates the skb is from an untrusted source. */
-+      SKB_GSO_DODGY = 1 << 2,
-+};
-+
- /** 
-  *    struct sk_buff - socket buffer
-  *    @next: Next buffer in list
-@@ -189,6 +198,8 @@
-  *    @local_df: allow local fragmentation
-  *    @cloned: Head may be cloned (check refcnt to be sure)
-  *    @nohdr: Payload reference only, must not modify header
-+ *    @proto_data_valid: Protocol data validated since arriving at localhost
-+ *    @proto_csum_blank: Protocol csum must be added before leaving localhost
-  *    @pkt_type: Packet class
-  *    @fclone: skbuff clone status
-  *    @ip_summed: Driver fed us an IP checksum
-@@ -265,7 +276,13 @@
-                               nfctinfo:3;
-       __u8                    pkt_type:3,
-                               fclone:2,
-+#ifndef CONFIG_XEN
-                               ipvs_property:1;
-+#else
-+                              ipvs_property:1,
-+                              proto_data_valid:1,
-+                              proto_csum_blank:1;
-+#endif
-       __be16                  protocol;
-       void                    (*destructor)(struct sk_buff *skb);
-@@ -321,7 +338,8 @@
- extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
-                                           unsigned int size,
--                                          gfp_t priority);
-+                                          gfp_t priority,
-+                                          int fclone);
- extern void          kfree_skbmem(struct sk_buff *skb);
- extern struct sk_buff *skb_clone(struct sk_buff *skb,
-                                gfp_t priority);
-@@ -1051,7 +1069,7 @@
-       return skb;
- }
- #else
--extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask);
-+extern struct sk_buff *__dev_alloc_skb(unsigned int length, gfp_t gfp_mask);
- #endif
- /**
-@@ -1148,18 +1166,34 @@
-       return 0;
- }
-+static inline int __skb_linearize(struct sk_buff *skb)
-+{
-+      return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
-+}
-+
- /**
-  *    skb_linearize - convert paged skb to linear one
-  *    @skb: buffer to linarize
-- *    @gfp: allocation mode
-  *
-  *    If there is no free memory -ENOMEM is returned, otherwise zero
-  *    is returned and the old skb data released.
-  */
--extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
--static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
-+static inline int skb_linearize(struct sk_buff *skb)
-+{
-+      return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
-+}
-+
-+/**
-+ *    skb_linearize_cow - make sure skb is linear and writable
-+ *    @skb: buffer to process
-+ *
-+ *    If there is no free memory -ENOMEM is returned, otherwise zero
-+ *    is returned and the old skb data released.
-+ */
-+static inline int skb_linearize_cow(struct sk_buff *skb)
- {
--      return __skb_linearize(skb, gfp);
-+      return skb_is_nonlinear(skb) || skb_cloned(skb) ?
-+             __skb_linearize(skb) : 0;
- }
- /**
-@@ -1254,6 +1288,7 @@
-                                struct sk_buff *skb1, const u32 len);
- extern void          skb_release_data(struct sk_buff *skb);
-+extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
- static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
-                                      int len, void *buffer)
-@@ -1377,5 +1412,10 @@
- static inline void nf_reset(struct sk_buff *skb) {}
- #endif /* CONFIG_NETFILTER */
-+static inline int skb_is_gso(const struct sk_buff *skb)
-+{
-+      return skb_shinfo(skb)->gso_size;
-+}
-+
- #endif        /* __KERNEL__ */
- #endif        /* _LINUX_SKBUFF_H */
-diff -Nur linux-2.6.16.33-noxen/include/net/pkt_sched.h linux-2.6.16.33/include/net/pkt_sched.h
---- linux-2.6.16.33-noxen/include/net/pkt_sched.h      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/net/pkt_sched.h    2007-05-23 21:00:01.000000000 +0000
-@@ -218,12 +218,13 @@
-               struct rtattr *tab);
- extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
--extern int qdisc_restart(struct net_device *dev);
-+extern void __qdisc_run(struct net_device *dev);
- static inline void qdisc_run(struct net_device *dev)
- {
--      while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
--              /* NOTHING */;
-+      if (!netif_queue_stopped(dev) &&
-+          !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
-+              __qdisc_run(dev);
- }
- extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
-diff -Nur linux-2.6.16.33-noxen/include/net/protocol.h linux-2.6.16.33/include/net/protocol.h
---- linux-2.6.16.33-noxen/include/net/protocol.h       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/net/protocol.h     2007-05-23 21:00:01.000000000 +0000
-@@ -37,6 +37,9 @@
- struct net_protocol {
-       int                     (*handler)(struct sk_buff *skb);
-       void                    (*err_handler)(struct sk_buff *skb, u32 info);
-+      int                     (*gso_send_check)(struct sk_buff *skb);
-+      struct sk_buff         *(*gso_segment)(struct sk_buff *skb,
-+                                             int features);
-       int                     no_policy;
- };
-diff -Nur linux-2.6.16.33-noxen/include/net/sock.h linux-2.6.16.33/include/net/sock.h
---- linux-2.6.16.33-noxen/include/net/sock.h   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/net/sock.h 2007-05-23 21:00:01.000000000 +0000
-@@ -1064,9 +1064,13 @@
- {
-       __sk_dst_set(sk, dst);
-       sk->sk_route_caps = dst->dev->features;
-+      if (sk->sk_route_caps & NETIF_F_GSO)
-+              sk->sk_route_caps |= NETIF_F_TSO;
-       if (sk->sk_route_caps & NETIF_F_TSO) {
-               if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
-                       sk->sk_route_caps &= ~NETIF_F_TSO;
-+              else 
-+                      sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
-       }
- }
-diff -Nur linux-2.6.16.33-noxen/include/net/tcp.h linux-2.6.16.33/include/net/tcp.h
---- linux-2.6.16.33-noxen/include/net/tcp.h    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/include/net/tcp.h  2007-05-23 21:00:01.000000000 +0000
-@@ -552,13 +552,13 @@
-  */
- static inline int tcp_skb_pcount(const struct sk_buff *skb)
- {
--      return skb_shinfo(skb)->tso_segs;
-+      return skb_shinfo(skb)->gso_segs;
- }
- /* This is valid iff tcp_skb_pcount() > 1. */
- static inline int tcp_skb_mss(const struct sk_buff *skb)
- {
--      return skb_shinfo(skb)->tso_size;
-+      return skb_shinfo(skb)->gso_size;
- }
- static inline void tcp_dec_pcount_approx(__u32 *count,
-@@ -1063,6 +1063,9 @@
- extern int tcp_v4_destroy_sock(struct sock *sk);
-+extern int tcp_v4_gso_send_check(struct sk_buff *skb);
-+extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
-+
- #ifdef CONFIG_PROC_FS
- extern int  tcp4_proc_init(void);
- extern void tcp4_proc_exit(void);
-diff -Nur linux-2.6.16.33-noxen/include/xen/balloon.h linux-2.6.16.33/include/xen/balloon.h
---- linux-2.6.16.33-noxen/include/xen/balloon.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/balloon.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,57 @@
-+/******************************************************************************
-+ * balloon.h
-+ *
-+ * Xen balloon driver - enables returning/claiming memory to/from Xen.
-+ *
-+ * Copyright (c) 2003, B Dragovic
-+ * Copyright (c) 2003-2004, M Williamson, K Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __ASM_BALLOON_H__
-+#define __ASM_BALLOON_H__
-+
-+/*
-+ * Inform the balloon driver that it should allow some slop for device-driver
-+ * memory activities.
-+ */
-+void balloon_update_driver_allowance(long delta);
-+
-+/* Allocate/free a set of empty pages in low memory (i.e., no RAM mapped). */
-+struct page **alloc_empty_pages_and_pagevec(int nr_pages);
-+void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages);
-+
-+void balloon_release_driver_page(struct page *page);
-+
-+/*
-+ * Prevent the balloon driver from changing the memory reservation during
-+ * a driver critical region.
-+ */
-+extern spinlock_t balloon_lock;
-+#define balloon_lock(__flags)   spin_lock_irqsave(&balloon_lock, __flags)
-+#define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags)
-+
-+#endif /* __ASM_BALLOON_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/cpu_hotplug.h linux-2.6.16.33/include/xen/cpu_hotplug.h
---- linux-2.6.16.33-noxen/include/xen/cpu_hotplug.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/cpu_hotplug.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,44 @@
-+#ifndef __XEN_CPU_HOTPLUG_H__
-+#define __XEN_CPU_HOTPLUG_H__
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/cpumask.h>
-+
-+#if defined(CONFIG_HOTPLUG_CPU)
-+
-+#if defined(CONFIG_X86)
-+void cpu_initialize_context(unsigned int cpu);
-+#else
-+#define cpu_initialize_context(cpu)   ((void)0)
-+#endif
-+
-+int cpu_up_check(unsigned int cpu);
-+void init_xenbus_allowed_cpumask(void);
-+int smp_suspend(void);
-+void smp_resume(void);
-+
-+void cpu_bringup(void);
-+
-+#else /* !defined(CONFIG_HOTPLUG_CPU) */
-+
-+#define cpu_up_check(cpu)             (0)
-+#define init_xenbus_allowed_cpumask() ((void)0)
-+
-+static inline int smp_suspend(void)
-+{
-+      if (num_online_cpus() > 1) {
-+              printk(KERN_WARNING "Can't suspend SMP guests "
-+                     "without CONFIG_HOTPLUG_CPU\n");
-+              return -EOPNOTSUPP;
-+      }
-+      return 0;
-+}
-+
-+static inline void smp_resume(void)
-+{
-+}
-+
-+#endif /* !defined(CONFIG_HOTPLUG_CPU) */
-+
-+#endif /* __XEN_CPU_HOTPLUG_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/driver_util.h linux-2.6.16.33/include/xen/driver_util.h
---- linux-2.6.16.33-noxen/include/xen/driver_util.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/driver_util.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,16 @@
-+
-+#ifndef __ASM_XEN_DRIVER_UTIL_H__
-+#define __ASM_XEN_DRIVER_UTIL_H__
-+
-+#include <linux/config.h>
-+#include <linux/vmalloc.h>
-+
-+/* Allocate/destroy a 'vmalloc' VM area. */
-+extern struct vm_struct *alloc_vm_area(unsigned long size);
-+extern void free_vm_area(struct vm_struct *area);
-+
-+/* Lock an area so that PTEs are accessible in the current address space. */
-+extern void lock_vm_area(struct vm_struct *area);
-+extern void unlock_vm_area(struct vm_struct *area);
-+
-+#endif /* __ASM_XEN_DRIVER_UTIL_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/evtchn.h linux-2.6.16.33/include/xen/evtchn.h
---- linux-2.6.16.33-noxen/include/xen/evtchn.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/evtchn.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,114 @@
-+/******************************************************************************
-+ * evtchn.h
-+ * 
-+ * Communication via Xen event channels.
-+ * Also definitions for the device that demuxes notifications to userspace.
-+ * 
-+ * Copyright (c) 2004-2005, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __ASM_EVTCHN_H__
-+#define __ASM_EVTCHN_H__
-+
-+#include <linux/config.h>
-+#include <linux/interrupt.h>
-+#include <asm/hypervisor.h>
-+#include <asm/ptrace.h>
-+#include <asm/synch_bitops.h>
-+#include <xen/interface/event_channel.h>
-+#include <linux/smp.h>
-+
-+/*
-+ * LOW-LEVEL DEFINITIONS
-+ */
-+
-+/*
-+ * Dynamically bind an event source to an IRQ-like callback handler.
-+ * On some platforms this may not be implemented via the Linux IRQ subsystem.
-+ * The IRQ argument passed to the callback handler is the same as returned
-+ * from the bind call. It may not correspond to a Linux IRQ number.
-+ * Returns IRQ or negative errno.
-+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
-+ */
-+extern int bind_evtchn_to_irqhandler(
-+      unsigned int evtchn,
-+      irqreturn_t (*handler)(int, void *, struct pt_regs *),
-+      unsigned long irqflags,
-+      const char *devname,
-+      void *dev_id);
-+extern int bind_virq_to_irqhandler(
-+      unsigned int virq,
-+      unsigned int cpu,
-+      irqreturn_t (*handler)(int, void *, struct pt_regs *),
-+      unsigned long irqflags,
-+      const char *devname,
-+      void *dev_id);
-+extern int bind_ipi_to_irqhandler(
-+      unsigned int ipi,
-+      unsigned int cpu,
-+      irqreturn_t (*handler)(int, void *, struct pt_regs *),
-+      unsigned long irqflags,
-+      const char *devname,
-+      void *dev_id);
-+
-+/*
-+ * Common unbind function for all event sources. Takes IRQ to unbind from.
-+ * Automatically closes the underlying event channel (even for bindings
-+ * made with bind_evtchn_to_irqhandler()).
-+ */
-+extern void unbind_from_irqhandler(unsigned int irq, void *dev_id);
-+
-+extern void irq_resume(void);
-+
-+/* Entry point for notifications into Linux subsystems. */
-+asmlinkage void evtchn_do_upcall(struct pt_regs *regs);
-+
-+/* Entry point for notifications into the userland character device. */
-+extern void evtchn_device_upcall(int port);
-+
-+extern void mask_evtchn(int port);
-+extern void unmask_evtchn(int port);
-+
-+static inline void clear_evtchn(int port)
-+{
-+      shared_info_t *s = HYPERVISOR_shared_info;
-+      synch_clear_bit(port, &s->evtchn_pending[0]);
-+}
-+
-+static inline void notify_remote_via_evtchn(int port)
-+{
-+      struct evtchn_send send = { .port = port };
-+      (void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
-+}
-+
-+/*
-+ * Unlike notify_remote_via_evtchn(), this is safe to use across
-+ * save/restore. Notifications on a broken connection are silently dropped.
-+ */
-+extern void notify_remote_via_irq(int irq);
-+
-+#endif /* __ASM_EVTCHN_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/features.h linux-2.6.16.33/include/xen/features.h
---- linux-2.6.16.33-noxen/include/xen/features.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/features.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,20 @@
-+/******************************************************************************
-+ * features.h
-+ *
-+ * Query the features reported by Xen.
-+ *
-+ * Copyright (c) 2006, Ian Campbell
-+ */
-+
-+#ifndef __ASM_XEN_FEATURES_H__
-+#define __ASM_XEN_FEATURES_H__
-+
-+#include <xen/interface/version.h>
-+
-+extern void setup_xen_features(void);
-+
-+extern u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
-+
-+#define xen_feature(flag)     (xen_features[flag])
-+
-+#endif /* __ASM_XEN_FEATURES_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/foreign_page.h linux-2.6.16.33/include/xen/foreign_page.h
---- linux-2.6.16.33-noxen/include/xen/foreign_page.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/foreign_page.h 2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,30 @@
-+/******************************************************************************
-+ * foreign_page.h
-+ * 
-+ * Provide a "foreign" page type, that is owned by a foreign allocator and 
-+ * not the normal buddy allocator in page_alloc.c
-+ * 
-+ * Copyright (c) 2004, K A Fraser
-+ */
-+
-+#ifndef __ASM_XEN_FOREIGN_PAGE_H__
-+#define __ASM_XEN_FOREIGN_PAGE_H__
-+
-+#define PG_foreign            PG_arch_1
-+
-+#define PageForeign(page)     test_bit(PG_foreign, &(page)->flags)
-+
-+#define SetPageForeign(page, dtor) do {               \
-+      set_bit(PG_foreign, &(page)->flags);    \
-+      (page)->mapping = (void *)dtor;         \
-+} while (0)
-+
-+#define ClearPageForeign(page) do {           \
-+      clear_bit(PG_foreign, &(page)->flags);  \
-+      (page)->mapping = NULL;                 \
-+} while (0)
-+
-+#define PageForeignDestructor(page)   \
-+      ( (void (*) (struct page *)) (page)->mapping )
-+
-+#endif /* __ASM_XEN_FOREIGN_PAGE_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/gnttab.h linux-2.6.16.33/include/xen/gnttab.h
---- linux-2.6.16.33-noxen/include/xen/gnttab.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/gnttab.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,152 @@
-+/******************************************************************************
-+ * gnttab.h
-+ * 
-+ * Two sets of functionality:
-+ * 1. Granting foreign access to our memory reservation.
-+ * 2. Accessing others' memory reservations via grant references.
-+ * (i.e., mechanisms for both sender and recipient of grant references)
-+ * 
-+ * Copyright (c) 2004-2005, K A Fraser
-+ * Copyright (c) 2005, Christopher Clark
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __ASM_GNTTAB_H__
-+#define __ASM_GNTTAB_H__
-+
-+#include <linux/config.h>
-+#include <asm/hypervisor.h>
-+#include <asm/maddr.h> /* maddr_t */
-+#include <xen/interface/grant_table.h>
-+#include <xen/features.h>
-+
-+/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
-+#ifdef __ia64__
-+#define NR_GRANT_FRAMES 1
-+#else
-+#define NR_GRANT_FRAMES 4
-+#endif
-+
-+struct gnttab_free_callback {
-+      struct gnttab_free_callback *next;
-+      void (*fn)(void *);
-+      void *arg;
-+      u16 count;
-+};
-+
-+int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
-+                              int readonly);
-+
-+/*
-+ * End access through the given grant reference, iff the grant entry is no
-+ * longer in use.  Return 1 if the grant entry was freed, 0 if it is still in
-+ * use.
-+ */
-+int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly);
-+
-+/*
-+ * Eventually end access through the given grant reference, and once that
-+ * access has been ended, free the given page too.  Access will be ended
-+ * immediately iff the grant entry is not in use, otherwise it will happen
-+ * some time later.  page may be 0, in which case no freeing will occur.
-+ */
-+void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
-+                             unsigned long page);
-+
-+int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn);
-+
-+unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref);
-+unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
-+
-+int gnttab_query_foreign_access(grant_ref_t ref);
-+
-+/*
-+ * operations on reserved batches of grant references
-+ */
-+int gnttab_alloc_grant_references(u16 count, grant_ref_t *pprivate_head);
-+
-+void gnttab_free_grant_reference(grant_ref_t ref);
-+
-+void gnttab_free_grant_references(grant_ref_t head);
-+
-+int gnttab_empty_grant_references(const grant_ref_t *pprivate_head);
-+
-+int gnttab_claim_grant_reference(grant_ref_t *pprivate_head);
-+
-+void gnttab_release_grant_reference(grant_ref_t *private_head,
-+                                  grant_ref_t release);
-+
-+void gnttab_request_free_callback(struct gnttab_free_callback *callback,
-+                                void (*fn)(void *), void *arg, u16 count);
-+void gnttab_cancel_free_callback(struct gnttab_free_callback *callback);
-+
-+void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
-+                                   unsigned long frame, int readonly);
-+
-+void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
-+                                     unsigned long pfn);
-+
-+#ifdef __ia64__
-+#define gnttab_map_vaddr(map) __va(map.dev_bus_addr)
-+#else
-+#define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
-+#endif
-+
-+int gnttab_suspend(void);
-+int gnttab_resume(void);
-+
-+static inline void
-+gnttab_set_map_op(struct gnttab_map_grant_ref *map, maddr_t addr,
-+                uint32_t flags, grant_ref_t ref, domid_t domid)
-+{
-+      if (flags & GNTMAP_contains_pte)
-+              map->host_addr = addr;
-+      else if (xen_feature(XENFEAT_auto_translated_physmap))
-+              map->host_addr = __pa(addr);
-+      else
-+              map->host_addr = addr;
-+
-+      map->flags = flags;
-+      map->ref = ref;
-+      map->dom = domid;
-+}
-+
-+static inline void
-+gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, maddr_t addr,
-+                  uint32_t flags, grant_handle_t handle)
-+{
-+      if (flags & GNTMAP_contains_pte)
-+              unmap->host_addr = addr;
-+      else if (xen_feature(XENFEAT_auto_translated_physmap))
-+              unmap->host_addr = __pa(addr);
-+      else
-+              unmap->host_addr = addr;
-+
-+      unmap->handle = handle;
-+      unmap->dev_bus_addr = 0;
-+}
-+
-+#endif /* __ASM_GNTTAB_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/hvm.h linux-2.6.16.33/include/xen/hvm.h
---- linux-2.6.16.33-noxen/include/xen/hvm.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/hvm.h  2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,24 @@
-+/* Simple wrappers around HVM functions */
-+#ifndef XEN_HVM_H__
-+#define XEN_HVM_H__
-+
-+#include <xen/interface/hvm/params.h>
-+#include <asm/hypercall.h>
-+
-+static inline unsigned long hvm_get_parameter(int idx)
-+{
-+      struct xen_hvm_param xhv;
-+      int r;
-+
-+      xhv.domid = DOMID_SELF;
-+      xhv.index = idx;
-+      r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
-+      if (r < 0) {
-+              printk(KERN_ERR "cannot get hvm parameter %d: %d.\n",
-+                     idx, r);
-+              return 0;
-+      }
-+      return xhv.value;
-+}
-+
-+#endif /* XEN_HVM_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/hypervisor_sysfs.h linux-2.6.16.33/include/xen/hypervisor_sysfs.h
---- linux-2.6.16.33-noxen/include/xen/hypervisor_sysfs.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/hypervisor_sysfs.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,32 @@
-+/*
-+ *  copyright (c) 2006 IBM Corporation
-+ *  Authored by: Mike D. Day <ncmike@us.ibm.com>
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License version 2 as
-+ *  published by the Free Software Foundation.
-+ */
-+
-+#ifndef _HYP_SYSFS_H_
-+#define _HYP_SYSFS_H_
-+
-+#include <linux/kobject.h>
-+#include <linux/sysfs.h>
-+
-+#define HYPERVISOR_ATTR_RO(_name) \
-+static struct hyp_sysfs_attr  _name##_attr = __ATTR_RO(_name)
-+
-+#define HYPERVISOR_ATTR_RW(_name) \
-+static struct hyp_sysfs_attr _name##_attr = \
-+      __ATTR(_name, 0644, _name##_show, _name##_store)
-+
-+extern struct subsystem hypervisor_subsys;
-+
-+struct hyp_sysfs_attr {
-+      struct attribute attr;
-+      ssize_t (*show)(struct hyp_sysfs_attr *, char *);
-+      ssize_t (*store)(struct hyp_sysfs_attr *, const char *, size_t);
-+      void *hyp_attr_data;
-+};
-+
-+#endif /* _HYP_SYSFS_H_ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/COPYING linux-2.6.16.33/include/xen/interface/COPYING
---- linux-2.6.16.33-noxen/include/xen/interface/COPYING        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/COPYING      2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,38 @@
-+XEN NOTICE
-+==========
-+
-+This copyright applies to all files within this subdirectory and its
-+subdirectories:
-+  include/public/*.h
-+  include/public/hvm/*.h
-+  include/public/io/*.h
-+
-+The intention is that these files can be freely copied into the source
-+tree of an operating system when porting that OS to run on Xen. Doing
-+so does *not* cause the OS to become subject to the terms of the GPL.
-+
-+All other files in the Xen source distribution are covered by version
-+2 of the GNU General Public License except where explicitly stated
-+otherwise within individual source files.
-+
-+ -- Keir Fraser (on behalf of the Xen team)
-+
-+=====================================================================
-+
-+Permission is hereby granted, free of charge, to any person obtaining a copy
-+of this software and associated documentation files (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.
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/acm.h linux-2.6.16.33/include/xen/interface/acm.h
---- linux-2.6.16.33-noxen/include/xen/interface/acm.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/acm.h        2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,205 @@
-+/*
-+ * acm.h: Xen access control module interface defintions
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Reiner Sailer <sailer@watson.ibm.com>
-+ * Copyright (c) 2005, International Business Machines Corporation.
-+ */
-+
-+#ifndef _XEN_PUBLIC_ACM_H
-+#define _XEN_PUBLIC_ACM_H
-+
-+#include "xen.h"
-+
-+/* if ACM_DEBUG defined, all hooks should
-+ * print a short trace message (comment it out
-+ * when not in testing mode )
-+ */
-+/* #define ACM_DEBUG */
-+
-+#ifdef ACM_DEBUG
-+#  define printkd(fmt, args...) printk(fmt,## args)
-+#else
-+#  define printkd(fmt, args...)
-+#endif
-+
-+/* default ssid reference value if not supplied */
-+#define ACM_DEFAULT_SSID  0x0
-+#define ACM_DEFAULT_LOCAL_SSID  0x0
-+
-+/* Internal ACM ERROR types */
-+#define ACM_OK     0
-+#define ACM_UNDEF   -1
-+#define ACM_INIT_SSID_ERROR  -2
-+#define ACM_INIT_SOID_ERROR  -3
-+#define ACM_ERROR          -4
-+
-+/* External ACCESS DECISIONS */
-+#define ACM_ACCESS_PERMITTED        0
-+#define ACM_ACCESS_DENIED           -111
-+#define ACM_NULL_POINTER_ERROR      -200
-+
-+/* primary policy in lower 4 bits */
-+#define ACM_NULL_POLICY 0
-+#define ACM_CHINESE_WALL_POLICY 1
-+#define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2
-+#define ACM_POLICY_UNDEFINED 15
-+
-+/* combinations have secondary policy component in higher 4bit */
-+#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY \
-+    ((ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY << 4) | ACM_CHINESE_WALL_POLICY)
-+
-+/* policy: */
-+#define ACM_POLICY_NAME(X) \
-+ ((X) == (ACM_NULL_POLICY)) ? "NULL" :                        \
-+    ((X) == (ACM_CHINESE_WALL_POLICY)) ? "CHINESE WALL" :        \
-+    ((X) == (ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "SIMPLE TYPE ENFORCEMENT" : \
-+    ((X) == (ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT" : \
-+     "UNDEFINED"
-+
-+/* the following policy versions must be increased
-+ * whenever the interpretation of the related
-+ * policy's data structure changes
-+ */
-+#define ACM_POLICY_VERSION 2
-+#define ACM_CHWALL_VERSION 1
-+#define ACM_STE_VERSION  1
-+
-+/* defines a ssid reference used by xen */
-+typedef uint32_t ssidref_t;
-+
-+/* hooks that are known to domains */
-+#define ACMHOOK_none    0
-+#define ACMHOOK_sharing 1
-+
-+/* -------security policy relevant type definitions-------- */
-+
-+/* type identifier; compares to "equal" or "not equal" */
-+typedef uint16_t domaintype_t;
-+
-+/* CHINESE WALL POLICY DATA STRUCTURES
-+ *
-+ * current accumulated conflict type set:
-+ * When a domain is started and has a type that is in
-+ * a conflict set, the conflicting types are incremented in
-+ * the aggregate set. When a domain is destroyed, the 
-+ * conflicting types to its type are decremented.
-+ * If a domain has multiple types, this procedure works over
-+ * all those types.
-+ *
-+ * conflict_aggregate_set[i] holds the number of
-+ *   running domains that have a conflict with type i.
-+ *
-+ * running_types[i] holds the number of running domains
-+ *        that include type i in their ssidref-referenced type set
-+ *
-+ * conflict_sets[i][j] is "0" if type j has no conflict
-+ *    with type i and is "1" otherwise.
-+ */
-+/* high-16 = version, low-16 = check magic */
-+#define ACM_MAGIC  0x0001debc
-+
-+/* each offset in bytes from start of the struct they
-+ * are part of */
-+
-+/* each buffer consists of all policy information for
-+ * the respective policy given in the policy code
-+ *
-+ * acm_policy_buffer, acm_chwall_policy_buffer,
-+ * and acm_ste_policy_buffer need to stay 32-bit aligned
-+ * because we create binary policies also with external
-+ * tools that assume packed representations (e.g. the java tool)
-+ */
-+struct acm_policy_buffer {
-+    uint32_t policy_version; /* ACM_POLICY_VERSION */
-+    uint32_t magic;
-+    uint32_t len;
-+    uint32_t policy_reference_offset;
-+    uint32_t primary_policy_code;
-+    uint32_t primary_buffer_offset;
-+    uint32_t secondary_policy_code;
-+    uint32_t secondary_buffer_offset;
-+};
-+
-+struct acm_policy_reference_buffer {
-+    uint32_t len;
-+};
-+
-+struct acm_chwall_policy_buffer {
-+    uint32_t policy_version; /* ACM_CHWALL_VERSION */
-+    uint32_t policy_code;
-+    uint32_t chwall_max_types;
-+    uint32_t chwall_max_ssidrefs;
-+    uint32_t chwall_max_conflictsets;
-+    uint32_t chwall_ssid_offset;
-+    uint32_t chwall_conflict_sets_offset;
-+    uint32_t chwall_running_types_offset;
-+    uint32_t chwall_conflict_aggregate_offset;
-+};
-+
-+struct acm_ste_policy_buffer {
-+    uint32_t policy_version; /* ACM_STE_VERSION */
-+    uint32_t policy_code;
-+    uint32_t ste_max_types;
-+    uint32_t ste_max_ssidrefs;
-+    uint32_t ste_ssid_offset;
-+};
-+
-+struct acm_stats_buffer {
-+    uint32_t magic;
-+    uint32_t len;
-+    uint32_t primary_policy_code;
-+    uint32_t primary_stats_offset;
-+    uint32_t secondary_policy_code;
-+    uint32_t secondary_stats_offset;
-+};
-+
-+struct acm_ste_stats_buffer {
-+    uint32_t ec_eval_count;
-+    uint32_t gt_eval_count;
-+    uint32_t ec_denied_count;
-+    uint32_t gt_denied_count;
-+    uint32_t ec_cachehit_count;
-+    uint32_t gt_cachehit_count;
-+};
-+
-+struct acm_ssid_buffer {
-+    uint32_t len;
-+    ssidref_t ssidref;
-+    uint32_t policy_reference_offset;
-+    uint32_t primary_policy_code;
-+    uint32_t primary_max_types;
-+    uint32_t primary_types_offset;
-+    uint32_t secondary_policy_code;
-+    uint32_t secondary_max_types;
-+    uint32_t secondary_types_offset;
-+};
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/acm_ops.h linux-2.6.16.33/include/xen/interface/acm_ops.h
---- linux-2.6.16.33-noxen/include/xen/interface/acm_ops.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/acm_ops.h    2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,120 @@
-+/*
-+ * acm_ops.h: Xen access control module hypervisor commands
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Reiner Sailer <sailer@watson.ibm.com>
-+ * Copyright (c) 2005,2006 International Business Machines Corporation.
-+ */
-+
-+#ifndef __XEN_PUBLIC_ACM_OPS_H__
-+#define __XEN_PUBLIC_ACM_OPS_H__
-+
-+#include "xen.h"
-+#include "acm.h"
-+
-+/*
-+ * Make sure you increment the interface version whenever you modify this file!
-+ * This makes sure that old versions of acm tools will stop working in a
-+ * well-defined way (rather than crashing the machine, for instance).
-+ */
-+#define ACM_INTERFACE_VERSION   0xAAAA0008
-+
-+/************************************************************************/
-+
-+/*
-+ * Prototype for this hypercall is:
-+ *  int acm_op(int cmd, void *args)
-+ * @cmd  == ACMOP_??? (access control module operation).
-+ * @args == Operation-specific extra arguments (NULL if none).
-+ */
-+
-+
-+#define ACMOP_setpolicy         1
-+struct acm_setpolicy {
-+    /* IN */
-+    uint32_t interface_version;
-+    XEN_GUEST_HANDLE(void) pushcache;
-+    uint32_t pushcache_size;
-+};
-+
-+
-+#define ACMOP_getpolicy         2
-+struct acm_getpolicy {
-+    /* IN */
-+    uint32_t interface_version;
-+    XEN_GUEST_HANDLE(void) pullcache;
-+    uint32_t pullcache_size;
-+};
-+
-+
-+#define ACMOP_dumpstats         3
-+struct acm_dumpstats {
-+    /* IN */
-+    uint32_t interface_version;
-+    XEN_GUEST_HANDLE(void) pullcache;
-+    uint32_t pullcache_size;
-+};
-+
-+
-+#define ACMOP_getssid           4
-+#define ACM_GETBY_ssidref  1
-+#define ACM_GETBY_domainid 2
-+struct acm_getssid {
-+    /* IN */
-+    uint32_t interface_version;
-+    uint32_t get_ssid_by; /* ACM_GETBY_* */
-+    union {
-+        domaintype_t domainid;
-+        ssidref_t    ssidref;
-+    } id;
-+    XEN_GUEST_HANDLE(void) ssidbuf;
-+    uint32_t ssidbuf_size;
-+};
-+
-+#define ACMOP_getdecision      5
-+struct acm_getdecision {
-+    /* IN */
-+    uint32_t interface_version;
-+    uint32_t get_decision_by1; /* ACM_GETBY_* */
-+    uint32_t get_decision_by2; /* ACM_GETBY_* */
-+    union {
-+        domaintype_t domainid;
-+        ssidref_t    ssidref;
-+    } id1;
-+    union {
-+        domaintype_t domainid;
-+        ssidref_t    ssidref;
-+    } id2;
-+    uint32_t hook;
-+    /* OUT */
-+    uint32_t acm_decision;
-+};
-+
-+#endif /* __XEN_PUBLIC_ACM_OPS_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/arch-ia64.h linux-2.6.16.33/include/xen/interface/arch-ia64.h
---- linux-2.6.16.33-noxen/include/xen/interface/arch-ia64.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/arch-ia64.h  2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,500 @@
-+/******************************************************************************
-+ * arch-ia64/hypervisor-if.h
-+ * 
-+ * Guest OS interface to IA64 Xen.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ */
-+
-+#ifndef __HYPERVISOR_IF_IA64_H__
-+#define __HYPERVISOR_IF_IA64_H__
-+
-+/* Structural guest handles introduced in 0x00030201. */
-+#if __XEN_INTERFACE_VERSION__ >= 0x00030201
-+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
-+    typedef struct { type *p; } __guest_handle_ ## name
-+#else
-+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
-+    typedef type * __guest_handle_ ## name
-+#endif
-+
-+#define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
-+#define XEN_GUEST_HANDLE(name)          __guest_handle_ ## name
-+#define set_xen_guest_handle(hnd, val)  do { (hnd).p = val; } while (0)
-+#ifdef __XEN_TOOLS__
-+#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+/* Guest handles for primitive C types. */
-+__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
-+__DEFINE_XEN_GUEST_HANDLE(uint,  unsigned int);
-+__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
-+__DEFINE_XEN_GUEST_HANDLE(u64,   unsigned long);
-+DEFINE_XEN_GUEST_HANDLE(char);
-+DEFINE_XEN_GUEST_HANDLE(int);
-+DEFINE_XEN_GUEST_HANDLE(long);
-+DEFINE_XEN_GUEST_HANDLE(void);
-+
-+typedef unsigned long xen_pfn_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
-+#endif
-+
-+/* Arch specific VIRQs definition */
-+#define VIRQ_ITC        VIRQ_ARCH_0 /* V. Virtual itc timer */
-+#define VIRQ_MCA_CMC    VIRQ_ARCH_1 /* MCA cmc interrupt */
-+#define VIRQ_MCA_CPE    VIRQ_ARCH_2 /* MCA cpe interrupt */
-+
-+/* Maximum number of virtual CPUs in multi-processor guests. */
-+/* WARNING: before changing this, check that shared_info fits on a page */
-+#define MAX_VIRT_CPUS 64
-+
-+#ifndef __ASSEMBLY__
-+
-+typedef unsigned long xen_ulong_t;
-+
-+#define INVALID_MFN       (~0UL)
-+
-+#define MEM_G   (1UL << 30)
-+#define MEM_M   (1UL << 20)
-+
-+#define MMIO_START       (3 * MEM_G)
-+#define MMIO_SIZE        (512 * MEM_M)
-+
-+#define VGA_IO_START     0xA0000UL
-+#define VGA_IO_SIZE      0x20000
-+
-+#define LEGACY_IO_START  (MMIO_START + MMIO_SIZE)
-+#define LEGACY_IO_SIZE   (64*MEM_M)
-+
-+#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE)
-+#define IO_PAGE_SIZE  PAGE_SIZE
-+
-+#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE)
-+#define STORE_PAGE_SIZE        PAGE_SIZE
-+
-+#define BUFFER_IO_PAGE_START (STORE_PAGE_START+PAGE_SIZE)
-+#define BUFFER_IO_PAGE_SIZE PAGE_SIZE
-+
-+#define IO_SAPIC_START   0xfec00000UL
-+#define IO_SAPIC_SIZE    0x100000
-+
-+#define PIB_START 0xfee00000UL
-+#define PIB_SIZE 0x200000
-+
-+#define GFW_START        (4*MEM_G -16*MEM_M)
-+#define GFW_SIZE         (16*MEM_M)
-+
-+struct pt_fpreg {
-+    union {
-+        unsigned long bits[2];
-+        long double __dummy;    /* force 16-byte alignment */
-+    } u;
-+};
-+
-+struct cpu_user_regs {
-+    /* The following registers are saved by SAVE_MIN: */
-+    unsigned long b6;  /* scratch */
-+    unsigned long b7;  /* scratch */
-+
-+    unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */
-+    unsigned long ar_ssd; /* reserved for future use (scratch) */
-+
-+    unsigned long r8;  /* scratch (return value register 0) */
-+    unsigned long r9;  /* scratch (return value register 1) */
-+    unsigned long r10; /* scratch (return value register 2) */
-+    unsigned long r11; /* scratch (return value register 3) */
-+
-+    unsigned long cr_ipsr; /* interrupted task's psr */
-+    unsigned long cr_iip;  /* interrupted task's instruction pointer */
-+    unsigned long cr_ifs;  /* interrupted task's function state */
-+
-+    unsigned long ar_unat; /* interrupted task's NaT register (preserved) */
-+    unsigned long ar_pfs;  /* prev function state  */
-+    unsigned long ar_rsc;  /* RSE configuration */
-+    /* The following two are valid only if cr_ipsr.cpl > 0: */
-+    unsigned long ar_rnat;  /* RSE NaT */
-+    unsigned long ar_bspstore; /* RSE bspstore */
-+
-+    unsigned long pr;  /* 64 predicate registers (1 bit each) */
-+    unsigned long b0;  /* return pointer (bp) */
-+    unsigned long loadrs;  /* size of dirty partition << 16 */
-+
-+    unsigned long r1;  /* the gp pointer */
-+    unsigned long r12; /* interrupted task's memory stack pointer */
-+    unsigned long r13; /* thread pointer */
-+
-+    unsigned long ar_fpsr;  /* floating point status (preserved) */
-+    unsigned long r15;  /* scratch */
-+
-+ /* The remaining registers are NOT saved for system calls.  */
-+
-+    unsigned long r14;  /* scratch */
-+    unsigned long r2;  /* scratch */
-+    unsigned long r3;  /* scratch */
-+    unsigned long r16;  /* scratch */
-+    unsigned long r17;  /* scratch */
-+    unsigned long r18;  /* scratch */
-+    unsigned long r19;  /* scratch */
-+    unsigned long r20;  /* scratch */
-+    unsigned long r21;  /* scratch */
-+    unsigned long r22;  /* scratch */
-+    unsigned long r23;  /* scratch */
-+    unsigned long r24;  /* scratch */
-+    unsigned long r25;  /* scratch */
-+    unsigned long r26;  /* scratch */
-+    unsigned long r27;  /* scratch */
-+    unsigned long r28;  /* scratch */
-+    unsigned long r29;  /* scratch */
-+    unsigned long r30;  /* scratch */
-+    unsigned long r31;  /* scratch */
-+    unsigned long ar_ccv;  /* compare/exchange value (scratch) */
-+
-+    /*
-+     * Floating point registers that the kernel considers scratch:
-+     */
-+    struct pt_fpreg f6;  /* scratch */
-+    struct pt_fpreg f7;  /* scratch */
-+    struct pt_fpreg f8;  /* scratch */
-+    struct pt_fpreg f9;  /* scratch */
-+    struct pt_fpreg f10;  /* scratch */
-+    struct pt_fpreg f11;  /* scratch */
-+    unsigned long r4;  /* preserved */
-+    unsigned long r5;  /* preserved */
-+    unsigned long r6;  /* preserved */
-+    unsigned long r7;  /* preserved */
-+    unsigned long eml_unat;    /* used for emulating instruction */
-+    unsigned long pad0;     /* alignment pad */
-+
-+};
-+typedef struct cpu_user_regs cpu_user_regs_t;
-+
-+union vac {
-+    unsigned long value;
-+    struct {
-+        int a_int:1;
-+        int a_from_int_cr:1;
-+        int a_to_int_cr:1;
-+        int a_from_psr:1;
-+        int a_from_cpuid:1;
-+        int a_cover:1;
-+        int a_bsw:1;
-+        long reserved:57;
-+    };
-+};
-+typedef union vac vac_t;
-+
-+union vdc {
-+    unsigned long value;
-+    struct {
-+        int d_vmsw:1;
-+        int d_extint:1;
-+        int d_ibr_dbr:1;
-+        int d_pmc:1;
-+        int d_to_pmd:1;
-+        int d_itm:1;
-+        long reserved:58;
-+    };
-+};
-+typedef union vdc vdc_t;
-+
-+struct mapped_regs {
-+    union vac   vac;
-+    union vdc   vdc;
-+    unsigned long  virt_env_vaddr;
-+    unsigned long  reserved1[29];
-+    unsigned long  vhpi;
-+    unsigned long  reserved2[95];
-+    union {
-+        unsigned long  vgr[16];
-+        unsigned long bank1_regs[16]; // bank1 regs (r16-r31) when bank0 active
-+    };
-+    union {
-+        unsigned long  vbgr[16];
-+        unsigned long bank0_regs[16]; // bank0 regs (r16-r31) when bank1 active
-+    };
-+    unsigned long  vnat;
-+    unsigned long  vbnat;
-+    unsigned long  vcpuid[5];
-+    unsigned long  reserved3[11];
-+    unsigned long  vpsr;
-+    unsigned long  vpr;
-+    unsigned long  reserved4[76];
-+    union {
-+        unsigned long  vcr[128];
-+        struct {
-+            unsigned long dcr;  // CR0
-+            unsigned long itm;
-+            unsigned long iva;
-+            unsigned long rsv1[5];
-+            unsigned long pta;  // CR8
-+            unsigned long rsv2[7];
-+            unsigned long ipsr;  // CR16
-+            unsigned long isr;
-+            unsigned long rsv3;
-+            unsigned long iip;
-+            unsigned long ifa;
-+            unsigned long itir;
-+            unsigned long iipa;
-+            unsigned long ifs;
-+            unsigned long iim;  // CR24
-+            unsigned long iha;
-+            unsigned long rsv4[38];
-+            unsigned long lid;  // CR64
-+            unsigned long ivr;
-+            unsigned long tpr;
-+            unsigned long eoi;
-+            unsigned long irr[4];
-+            unsigned long itv;  // CR72
-+            unsigned long pmv;
-+            unsigned long cmcv;
-+            unsigned long rsv5[5];
-+            unsigned long lrr0;  // CR80
-+            unsigned long lrr1;
-+            unsigned long rsv6[46];
-+        };
-+    };
-+    union {
-+        unsigned long  reserved5[128];
-+        struct {
-+            unsigned long precover_ifs;
-+            unsigned long unat;  // not sure if this is needed until NaT arch is done
-+            int interrupt_collection_enabled; // virtual psr.ic
-+            /* virtual interrupt deliverable flag is evtchn_upcall_mask in
-+             * shared info area now. interrupt_mask_addr is the address
-+             * of evtchn_upcall_mask for current vcpu
-+             */
-+            unsigned char *interrupt_mask_addr;
-+            int pending_interruption;
-+            int incomplete_regframe; // see SDM vol2 6.8
-+            unsigned char vpsr_pp;
-+            unsigned char reserved5_2[7];
-+            unsigned long reserved5_1[3];
-+            int metaphysical_mode; // 1 = use metaphys mapping, 0 = use virtual
-+            int banknum; // 0 or 1, which virtual register bank is active
-+            unsigned long rrs[8]; // region registers
-+            unsigned long krs[8]; // kernel registers
-+            unsigned long pkrs[8]; // protection key registers
-+            unsigned long tmp[8]; // temp registers (e.g. for hyperprivops)
-+        };
-+    };
-+};
-+typedef struct mapped_regs mapped_regs_t;
-+
-+struct vpd {
-+    struct mapped_regs vpd_low;
-+    unsigned long  reserved6[3456];
-+    unsigned long  vmm_avail[128];
-+    unsigned long  reserved7[4096];
-+};
-+typedef struct vpd vpd_t;
-+
-+struct arch_vcpu_info {
-+};
-+typedef struct arch_vcpu_info arch_vcpu_info_t;
-+
-+struct arch_shared_info {
-+    /* PFN of the start_info page.  */
-+    unsigned long start_info_pfn;
-+
-+    /* Interrupt vector for event channel.  */
-+    int evtchn_vector;
-+
-+    uint64_t pad[32];
-+};
-+typedef struct arch_shared_info arch_shared_info_t;
-+
-+typedef unsigned long xen_callback_t;
-+
-+struct ia64_tr_entry {
-+    unsigned long pte;
-+    unsigned long itir;
-+    unsigned long vadr;
-+    unsigned long rid;
-+};
-+
-+struct vcpu_extra_regs {
-+    struct ia64_tr_entry itrs[8];
-+    struct ia64_tr_entry dtrs[8];
-+    unsigned long iva;
-+    unsigned long dcr;
-+    unsigned long event_callback_ip;
-+};
-+
-+struct vcpu_guest_context {
-+#define VGCF_EXTRA_REGS (1<<1)        /* Get/Set extra regs.  */
-+    unsigned long flags;       /* VGCF_* flags */
-+
-+    struct cpu_user_regs user_regs;
-+    struct vcpu_extra_regs extra_regs;
-+    unsigned long privregs_pfn;
-+};
-+typedef struct vcpu_guest_context vcpu_guest_context_t;
-+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-+
-+/* dom0 vp op */
-+#define __HYPERVISOR_ia64_dom0vp_op     __HYPERVISOR_arch_0
-+/*  Map io space in machine address to dom0 physical address space.
-+    Currently physical assigned address equals to machine address.  */
-+#define IA64_DOM0VP_ioremap             0
-+
-+/* Convert a pseudo physical page frame number to the corresponding
-+   machine page frame number. If no page is assigned, INVALID_MFN or
-+   GPFN_INV_MASK is returned depending on domain's non-vti/vti mode.  */
-+#define IA64_DOM0VP_phystomach          1
-+
-+/* Convert a machine page frame number to the corresponding pseudo physical
-+   page frame number of the caller domain.  */
-+#define IA64_DOM0VP_machtophys          3
-+
-+/* Reserved for future use.  */
-+#define IA64_DOM0VP_iounmap             4
-+
-+/* Unmap and free pages contained in the specified pseudo physical region.  */
-+#define IA64_DOM0VP_zap_physmap         5
-+
-+/* Assign machine page frame to dom0's pseudo physical address space.  */
-+#define IA64_DOM0VP_add_physmap         6
-+
-+/* expose the p2m table into domain */
-+#define IA64_DOM0VP_expose_p2m          7
-+
-+/* xen perfmon */
-+#define IA64_DOM0VP_perfmon             8
-+
-+/* gmfn version of IA64_DOM0VP_add_physmap */
-+#define IA64_DOM0VP_add_physmap_with_gmfn       9
-+
-+// flags for page assignement to pseudo physical address space
-+#define _ASSIGN_readonly                0
-+#define ASSIGN_readonly                 (1UL << _ASSIGN_readonly)
-+#define ASSIGN_writable                 (0UL << _ASSIGN_readonly) // dummy flag
-+/* Internal only: memory attribute must be WC/UC/UCE.  */
-+#define _ASSIGN_nocache                 1
-+#define ASSIGN_nocache                  (1UL << _ASSIGN_nocache)
-+// tlb tracking
-+#define _ASSIGN_tlb_track               2
-+#define ASSIGN_tlb_track                (1UL << _ASSIGN_tlb_track)
-+/* Internal only: associated with PGC_allocated bit */
-+#define _ASSIGN_pgc_allocated           3
-+#define ASSIGN_pgc_allocated            (1UL << _ASSIGN_pgc_allocated)
-+
-+/* This structure has the same layout of struct ia64_boot_param, defined in
-+   <asm/system.h>.  It is redefined here to ease use.  */
-+struct xen_ia64_boot_param {
-+      unsigned long command_line;     /* physical address of cmd line args */
-+      unsigned long efi_systab;       /* physical address of EFI system table */
-+      unsigned long efi_memmap;       /* physical address of EFI memory map */
-+      unsigned long efi_memmap_size;  /* size of EFI memory map */
-+      unsigned long efi_memdesc_size; /* size of an EFI memory map descriptor */
-+      unsigned int  efi_memdesc_version;      /* memory descriptor version */
-+      struct {
-+              unsigned short num_cols;        /* number of columns on console.  */
-+              unsigned short num_rows;        /* number of rows on console.  */
-+              unsigned short orig_x;  /* cursor's x position */
-+              unsigned short orig_y;  /* cursor's y position */
-+      } console_info;
-+      unsigned long fpswa;            /* physical address of the fpswa interface */
-+      unsigned long initrd_start;
-+      unsigned long initrd_size;
-+      unsigned long domain_start;     /* va where the boot time domain begins */
-+      unsigned long domain_size;      /* how big is the boot domain */
-+};
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+/* Size of the shared_info area (this is not related to page size).  */
-+#define XSI_SHIFT                     14
-+#define XSI_SIZE                      (1 << XSI_SHIFT)
-+/* Log size of mapped_regs area (64 KB - only 4KB is used).  */
-+#define XMAPPEDREGS_SHIFT             12
-+#define XMAPPEDREGS_SIZE              (1 << XMAPPEDREGS_SHIFT)
-+/* Offset of XASI (Xen arch shared info) wrt XSI_BASE.  */
-+#define XMAPPEDREGS_OFS                       XSI_SIZE
-+
-+/* Hyperprivops.  */
-+#define HYPERPRIVOP_RFI                       0x1
-+#define HYPERPRIVOP_RSM_DT            0x2
-+#define HYPERPRIVOP_SSM_DT            0x3
-+#define HYPERPRIVOP_COVER             0x4
-+#define HYPERPRIVOP_ITC_D             0x5
-+#define HYPERPRIVOP_ITC_I             0x6
-+#define HYPERPRIVOP_SSM_I             0x7
-+#define HYPERPRIVOP_GET_IVR           0x8
-+#define HYPERPRIVOP_GET_TPR           0x9
-+#define HYPERPRIVOP_SET_TPR           0xa
-+#define HYPERPRIVOP_EOI                       0xb
-+#define HYPERPRIVOP_SET_ITM           0xc
-+#define HYPERPRIVOP_THASH             0xd
-+#define HYPERPRIVOP_PTC_GA            0xe
-+#define HYPERPRIVOP_ITR_D             0xf
-+#define HYPERPRIVOP_GET_RR            0x10
-+#define HYPERPRIVOP_SET_RR            0x11
-+#define HYPERPRIVOP_SET_KR            0x12
-+#define HYPERPRIVOP_FC                        0x13
-+#define HYPERPRIVOP_GET_CPUID         0x14
-+#define HYPERPRIVOP_GET_PMD           0x15
-+#define HYPERPRIVOP_GET_EFLAG         0x16
-+#define HYPERPRIVOP_SET_EFLAG         0x17
-+#define HYPERPRIVOP_RSM_BE            0x18
-+#define HYPERPRIVOP_GET_PSR           0x19
-+#define HYPERPRIVOP_MAX                       0x19
-+
-+/* Fast and light hypercalls.  */
-+#define __HYPERVISOR_ia64_fast_eoi    0x0200
-+
-+/* Xencomm macros.  */
-+#define XENCOMM_INLINE_MASK 0xf800000000000000UL
-+#define XENCOMM_INLINE_FLAG 0x8000000000000000UL
-+
-+#define XENCOMM_IS_INLINE(addr) \
-+  (((unsigned long)(addr) & XENCOMM_INLINE_MASK) == XENCOMM_INLINE_FLAG)
-+#define XENCOMM_INLINE_ADDR(addr) \
-+  ((unsigned long)(addr) & ~XENCOMM_INLINE_MASK)
-+
-+/* xen perfmon */
-+#ifdef XEN
-+#ifndef __ASSEMBLY__
-+#ifndef _ASM_IA64_PERFMON_H
-+
-+#include <xen/list.h>   // asm/perfmon.h requires struct list_head
-+#include <asm/perfmon.h>
-+// for PFM_xxx and pfarg_features_t, pfarg_context_t, pfarg_reg_t, pfarg_load_t
-+
-+#endif /* _ASM_IA64_PERFMON_H */
-+
-+DEFINE_XEN_GUEST_HANDLE(pfarg_features_t);
-+DEFINE_XEN_GUEST_HANDLE(pfarg_context_t);
-+DEFINE_XEN_GUEST_HANDLE(pfarg_reg_t);
-+DEFINE_XEN_GUEST_HANDLE(pfarg_load_t);
-+#endif /* __ASSEMBLY__ */
-+#endif /* XEN */
-+
-+#endif /* __HYPERVISOR_IF_IA64_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/arch-powerpc.h linux-2.6.16.33/include/xen/interface/arch-powerpc.h
---- linux-2.6.16.33-noxen/include/xen/interface/arch-powerpc.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/arch-powerpc.h       2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,121 @@
-+/*
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (C) IBM Corp. 2005, 2006
-+ *
-+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_ARCH_PPC_64_H__
-+#define __XEN_PUBLIC_ARCH_PPC_64_H__
-+
-+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
-+    typedef struct { \
-+        int __pad[(sizeof (long long) - sizeof (void *)) / sizeof (int)]; \
-+        type *p; \
-+    } __attribute__((__aligned__(8))) __guest_handle_ ## name
-+
-+#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
-+#define XEN_GUEST_HANDLE(name)        __guest_handle_ ## name
-+#define set_xen_guest_handle(hnd, val) \
-+    do { \
-+        if (sizeof ((hnd).__pad)) \
-+            (hnd).__pad[0] = 0; \
-+        (hnd).p = val; \
-+    } while (0)
-+
-+#ifdef __XEN_TOOLS__
-+#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+/* Guest handles for primitive C types. */
-+__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
-+__DEFINE_XEN_GUEST_HANDLE(uint,  unsigned int);
-+__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
-+DEFINE_XEN_GUEST_HANDLE(char);
-+DEFINE_XEN_GUEST_HANDLE(int);
-+DEFINE_XEN_GUEST_HANDLE(long);
-+DEFINE_XEN_GUEST_HANDLE(void);
-+
-+typedef unsigned long long xen_pfn_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
-+#endif
-+
-+/*
-+ * Pointers and other address fields inside interface structures are padded to
-+ * 64 bits. This means that field alignments aren't different between 32- and
-+ * 64-bit architectures. 
-+ */
-+/* NB. Multi-level macro ensures __LINE__ is expanded before concatenation. */
-+#define __MEMORY_PADDING(_X)
-+#define _MEMORY_PADDING(_X)  __MEMORY_PADDING(_X)
-+#define MEMORY_PADDING       _MEMORY_PADDING(__LINE__)
-+
-+/* And the trap vector is... */
-+#define TRAP_INSTR "li 0,-1; sc" /* XXX just "sc"? */
-+
-+#ifndef __ASSEMBLY__
-+
-+#define XENCOMM_INLINE_FLAG (1UL << 63)
-+
-+typedef uint64_t xen_ulong_t;
-+
-+/* User-accessible registers: need to be saved/restored for every nested Xen
-+ * invocation. */
-+struct cpu_user_regs
-+{
-+    uint64_t gprs[32];
-+    uint64_t lr;
-+    uint64_t ctr;
-+    uint64_t srr0;
-+    uint64_t srr1;
-+    uint64_t pc;
-+    uint64_t msr;
-+    uint64_t fpscr;
-+    uint64_t xer;
-+    uint64_t hid4;
-+    uint32_t cr;
-+    uint32_t entry_vector;
-+};
-+typedef struct cpu_user_regs cpu_user_regs_t;
-+
-+typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ /* XXX timebase */
-+
-+/* ONLY used to communicate with dom0! See also struct exec_domain. */
-+struct vcpu_guest_context {
-+    cpu_user_regs_t user_regs;         /* User-level CPU registers     */
-+    uint64_t sdr1;                     /* Pagetable base               */
-+    /* XXX etc */
-+};
-+typedef struct vcpu_guest_context vcpu_guest_context_t;
-+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-+
-+struct arch_shared_info {
-+    uint64_t pad[32];
-+};
-+
-+struct arch_vcpu_info {
-+};
-+
-+/* Support for multi-processor guests. */
-+#define MAX_VIRT_CPUS 32
-+#endif
-+
-+#endif
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/arch-x86/xen-x86_32.h linux-2.6.16.33/include/xen/interface/arch-x86/xen-x86_32.h
---- linux-2.6.16.33-noxen/include/xen/interface/arch-x86/xen-x86_32.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/arch-x86/xen-x86_32.h        2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,151 @@
-+/******************************************************************************
-+ * xen-x86_32.h
-+ * 
-+ * Guest OS interface to x86 32-bit Xen.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2004-2006, K A Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__
-+#define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__
-+
-+/*
-+ * Hypercall interface:
-+ *  Input:  %ebx, %ecx, %edx, %esi, %edi (arguments 1-5)
-+ *  Output: %eax
-+ * Access is via hypercall page (set up by guest loader or via a Xen MSR):
-+ *  call hypercall_page + hypercall-number * 32
-+ * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx)
-+ */
-+
-+#if __XEN_INTERFACE_VERSION__ < 0x00030203
-+/*
-+ * Legacy hypercall interface:
-+ * As above, except the entry sequence to the hypervisor is:
-+ *  mov $hypercall-number*32,%eax ; int $0x82
-+ */
-+#define TRAP_INSTR "int $0x82"
-+#endif
-+
-+/*
-+ * These flat segments are in the Xen-private section of every GDT. Since these
-+ * are also present in the initial GDT, many OSes will be able to avoid
-+ * installing their own GDT.
-+ */
-+#define FLAT_RING1_CS 0xe019    /* GDT index 259 */
-+#define FLAT_RING1_DS 0xe021    /* GDT index 260 */
-+#define FLAT_RING1_SS 0xe021    /* GDT index 260 */
-+#define FLAT_RING3_CS 0xe02b    /* GDT index 261 */
-+#define FLAT_RING3_DS 0xe033    /* GDT index 262 */
-+#define FLAT_RING3_SS 0xe033    /* GDT index 262 */
-+
-+#define FLAT_KERNEL_CS FLAT_RING1_CS
-+#define FLAT_KERNEL_DS FLAT_RING1_DS
-+#define FLAT_KERNEL_SS FLAT_RING1_SS
-+#define FLAT_USER_CS    FLAT_RING3_CS
-+#define FLAT_USER_DS    FLAT_RING3_DS
-+#define FLAT_USER_SS    FLAT_RING3_SS
-+
-+/*
-+ * Virtual addresses beyond this are not modifiable by guest OSes. The 
-+ * machine->physical mapping table starts at this address, read-only.
-+ */
-+#ifdef CONFIG_X86_PAE
-+#define __HYPERVISOR_VIRT_START 0xF5800000
-+#define __MACH2PHYS_VIRT_START  0xF5800000
-+#define __MACH2PHYS_VIRT_END    0xF6800000
-+#else
-+#define __HYPERVISOR_VIRT_START 0xFC000000
-+#define __MACH2PHYS_VIRT_START  0xFC000000
-+#define __MACH2PHYS_VIRT_END    0xFC400000
-+#endif
-+
-+#ifndef HYPERVISOR_VIRT_START
-+#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
-+#endif
-+
-+#define MACH2PHYS_VIRT_START  mk_unsigned_long(__MACH2PHYS_VIRT_START)
-+#define MACH2PHYS_VIRT_END    mk_unsigned_long(__MACH2PHYS_VIRT_END)
-+#define MACH2PHYS_NR_ENTRIES  ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2)
-+#ifndef machine_to_phys_mapping
-+#define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START)
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+
-+struct cpu_user_regs {
-+    uint32_t ebx;
-+    uint32_t ecx;
-+    uint32_t edx;
-+    uint32_t esi;
-+    uint32_t edi;
-+    uint32_t ebp;
-+    uint32_t eax;
-+    uint16_t error_code;    /* private */
-+    uint16_t entry_vector;  /* private */
-+    uint32_t eip;
-+    uint16_t cs;
-+    uint8_t  saved_upcall_mask;
-+    uint8_t  _pad0;
-+    uint32_t eflags;        /* eflags.IF == !saved_upcall_mask */
-+    uint32_t esp;
-+    uint16_t ss, _pad1;
-+    uint16_t es, _pad2;
-+    uint16_t ds, _pad3;
-+    uint16_t fs, _pad4;
-+    uint16_t gs, _pad5;
-+};
-+typedef struct cpu_user_regs cpu_user_regs_t;
-+DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
-+
-+/*
-+ * Page-directory addresses above 4GB do not fit into architectural %cr3.
-+ * When accessing %cr3, or equivalent field in vcpu_guest_context, guests
-+ * must use the following accessor macros to pack/unpack valid MFNs.
-+ */
-+#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
-+#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
-+
-+struct arch_vcpu_info {
-+    unsigned long cr2;
-+    unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */
-+};
-+typedef struct arch_vcpu_info arch_vcpu_info_t;
-+
-+struct xen_callback {
-+    unsigned long cs;
-+    unsigned long eip;
-+};
-+typedef struct xen_callback xen_callback_t;
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/arch-x86/xen-x86_64.h linux-2.6.16.33/include/xen/interface/arch-x86/xen-x86_64.h
---- linux-2.6.16.33-noxen/include/xen/interface/arch-x86/xen-x86_64.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/arch-x86/xen-x86_64.h        2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,208 @@
-+/******************************************************************************
-+ * xen-x86_64.h
-+ * 
-+ * Guest OS interface to x86 64-bit Xen.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2004-2006, K A Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
-+#define __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
-+
-+/*
-+ * Hypercall interface:
-+ *  Input:  %rdi, %rsi, %rdx, %r10, %r8 (arguments 1-5)
-+ *  Output: %rax
-+ * Access is via hypercall page (set up by guest loader or via a Xen MSR):
-+ *  call hypercall_page + hypercall-number * 32
-+ * Clobbered: argument registers (e.g., 2-arg hypercall clobbers %rdi,%rsi)
-+ */
-+
-+#if __XEN_INTERFACE_VERSION__ < 0x00030203
-+/*
-+ * Legacy hypercall interface:
-+ * As above, except the entry sequence to the hypervisor is:
-+ *  mov $hypercall-number*32,%eax ; syscall
-+ * Clobbered: %rcx, %r11, argument registers (as above)
-+ */
-+#define TRAP_INSTR "syscall"
-+#endif
-+
-+/*
-+ * 64-bit segment selectors
-+ * These flat segments are in the Xen-private section of every GDT. Since these
-+ * are also present in the initial GDT, many OSes will be able to avoid
-+ * installing their own GDT.
-+ */
-+
-+#define FLAT_RING3_CS32 0xe023  /* GDT index 260 */
-+#define FLAT_RING3_CS64 0xe033  /* GDT index 261 */
-+#define FLAT_RING3_DS32 0xe02b  /* GDT index 262 */
-+#define FLAT_RING3_DS64 0x0000  /* NULL selector */
-+#define FLAT_RING3_SS32 0xe02b  /* GDT index 262 */
-+#define FLAT_RING3_SS64 0xe02b  /* GDT index 262 */
-+
-+#define FLAT_KERNEL_DS64 FLAT_RING3_DS64
-+#define FLAT_KERNEL_DS32 FLAT_RING3_DS32
-+#define FLAT_KERNEL_DS   FLAT_KERNEL_DS64
-+#define FLAT_KERNEL_CS64 FLAT_RING3_CS64
-+#define FLAT_KERNEL_CS32 FLAT_RING3_CS32
-+#define FLAT_KERNEL_CS   FLAT_KERNEL_CS64
-+#define FLAT_KERNEL_SS64 FLAT_RING3_SS64
-+#define FLAT_KERNEL_SS32 FLAT_RING3_SS32
-+#define FLAT_KERNEL_SS   FLAT_KERNEL_SS64
-+
-+#define FLAT_USER_DS64 FLAT_RING3_DS64
-+#define FLAT_USER_DS32 FLAT_RING3_DS32
-+#define FLAT_USER_DS   FLAT_USER_DS64
-+#define FLAT_USER_CS64 FLAT_RING3_CS64
-+#define FLAT_USER_CS32 FLAT_RING3_CS32
-+#define FLAT_USER_CS   FLAT_USER_CS64
-+#define FLAT_USER_SS64 FLAT_RING3_SS64
-+#define FLAT_USER_SS32 FLAT_RING3_SS32
-+#define FLAT_USER_SS   FLAT_USER_SS64
-+
-+#define __HYPERVISOR_VIRT_START 0xFFFF800000000000
-+#define __HYPERVISOR_VIRT_END   0xFFFF880000000000
-+#define __MACH2PHYS_VIRT_START  0xFFFF800000000000
-+#define __MACH2PHYS_VIRT_END    0xFFFF804000000000
-+
-+#ifndef HYPERVISOR_VIRT_START
-+#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
-+#define HYPERVISOR_VIRT_END   mk_unsigned_long(__HYPERVISOR_VIRT_END)
-+#endif
-+
-+#define MACH2PHYS_VIRT_START  mk_unsigned_long(__MACH2PHYS_VIRT_START)
-+#define MACH2PHYS_VIRT_END    mk_unsigned_long(__MACH2PHYS_VIRT_END)
-+#define MACH2PHYS_NR_ENTRIES  ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
-+#ifndef machine_to_phys_mapping
-+#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+
-+/*
-+ * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
-+ *  @which == SEGBASE_*  ;  @base == 64-bit base address
-+ * Returns 0 on success.
-+ */
-+#define SEGBASE_FS          0
-+#define SEGBASE_GS_USER     1
-+#define SEGBASE_GS_KERNEL   2
-+#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
-+
-+/*
-+ * int HYPERVISOR_iret(void)
-+ * All arguments are on the kernel stack, in the following format.
-+ * Never returns if successful. Current kernel context is lost.
-+ * The saved CS is mapped as follows:
-+ *   RING0 -> RING3 kernel mode.
-+ *   RING1 -> RING3 kernel mode.
-+ *   RING2 -> RING3 kernel mode.
-+ *   RING3 -> RING3 user mode.
-+ * However RING0 indicates that the guest kernel should return to iteself
-+ * directly with
-+ *      orb   $3,1*8(%rsp)
-+ *      iretq
-+ * If flags contains VGCF_in_syscall:
-+ *   Restore RAX, RIP, RFLAGS, RSP.
-+ *   Discard R11, RCX, CS, SS.
-+ * Otherwise:
-+ *   Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
-+ * All other registers are saved on hypercall entry and restored to user.
-+ */
-+/* Guest exited in SYSCALL context? Return to guest with SYSRET? */
-+#define _VGCF_in_syscall 8
-+#define VGCF_in_syscall  (1<<_VGCF_in_syscall)
-+#define VGCF_IN_SYSCALL  VGCF_in_syscall
-+struct iret_context {
-+    /* Top of stack (%rsp at point of hypercall). */
-+    uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
-+    /* Bottom of iret stack frame. */
-+};
-+
-+#ifdef __GNUC__
-+/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
-+#define __DECL_REG(name) union { uint64_t r ## name, e ## name; }
-+#else
-+/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */
-+#define __DECL_REG(name) uint64_t r ## name
-+#endif
-+
-+struct cpu_user_regs {
-+    uint64_t r15;
-+    uint64_t r14;
-+    uint64_t r13;
-+    uint64_t r12;
-+    __DECL_REG(bp);
-+    __DECL_REG(bx);
-+    uint64_t r11;
-+    uint64_t r10;
-+    uint64_t r9;
-+    uint64_t r8;
-+    __DECL_REG(ax);
-+    __DECL_REG(cx);
-+    __DECL_REG(dx);
-+    __DECL_REG(si);
-+    __DECL_REG(di);
-+    uint32_t error_code;    /* private */
-+    uint32_t entry_vector;  /* private */
-+    __DECL_REG(ip);
-+    uint16_t cs, _pad0[1];
-+    uint8_t  saved_upcall_mask;
-+    uint8_t  _pad1[3];
-+    __DECL_REG(flags);      /* rflags.IF == !saved_upcall_mask */
-+    __DECL_REG(sp);
-+    uint16_t ss, _pad2[3];
-+    uint16_t es, _pad3[3];
-+    uint16_t ds, _pad4[3];
-+    uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base.     */
-+    uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
-+};
-+typedef struct cpu_user_regs cpu_user_regs_t;
-+DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
-+
-+#undef __DECL_REG
-+
-+#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
-+#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
-+
-+struct arch_vcpu_info {
-+    unsigned long cr2;
-+    unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
-+};
-+typedef struct arch_vcpu_info arch_vcpu_info_t;
-+
-+typedef unsigned long xen_callback_t;
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/arch-x86/xen.h linux-2.6.16.33/include/xen/interface/arch-x86/xen.h
---- linux-2.6.16.33-noxen/include/xen/interface/arch-x86/xen.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/arch-x86/xen.h       2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,190 @@
-+/******************************************************************************
-+ * arch-x86/xen.h
-+ * 
-+ * Guest OS interface to x86 Xen.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2004-2006, K A Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__
-+#define __XEN_PUBLIC_ARCH_X86_XEN_H__
-+
-+/* Structural guest handles introduced in 0x00030201. */
-+#if __XEN_INTERFACE_VERSION__ >= 0x00030201
-+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
-+    typedef struct { type *p; } __guest_handle_ ## name
-+#else
-+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
-+    typedef type * __guest_handle_ ## name
-+#endif
-+
-+#define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
-+#define XEN_GUEST_HANDLE(name)          __guest_handle_ ## name
-+#define set_xen_guest_handle(hnd, val)  do { (hnd).p = val; } while (0)
-+#ifdef __XEN_TOOLS__
-+#define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
-+#endif
-+
-+#ifndef __ASSEMBLY__
-+/* Guest handles for primitive C types. */
-+__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
-+__DEFINE_XEN_GUEST_HANDLE(uint,  unsigned int);
-+__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
-+DEFINE_XEN_GUEST_HANDLE(char);
-+DEFINE_XEN_GUEST_HANDLE(int);
-+DEFINE_XEN_GUEST_HANDLE(long);
-+DEFINE_XEN_GUEST_HANDLE(void);
-+
-+typedef unsigned long xen_pfn_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
-+#endif
-+
-+#if defined(__i386__)
-+#include "xen-x86_32.h"
-+#elif defined(__x86_64__)
-+#include "xen-x86_64.h"
-+#endif
-+
-+/*
-+ * SEGMENT DESCRIPTOR TABLES
-+ */
-+/*
-+ * A number of GDT entries are reserved by Xen. These are not situated at the
-+ * start of the GDT because some stupid OSes export hard-coded selector values
-+ * in their ABI. These hard-coded values are always near the start of the GDT,
-+ * so Xen places itself out of the way, at the far end of the GDT.
-+ */
-+#define FIRST_RESERVED_GDT_PAGE  14
-+#define FIRST_RESERVED_GDT_BYTE  (FIRST_RESERVED_GDT_PAGE * 4096)
-+#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
-+
-+/* Maximum number of virtual CPUs in multi-processor guests. */
-+#define MAX_VIRT_CPUS 32
-+
-+#ifndef __ASSEMBLY__
-+
-+typedef unsigned long xen_ulong_t;
-+
-+/*
-+ * Send an array of these to HYPERVISOR_set_trap_table().
-+ * The privilege level specifies which modes may enter a trap via a software
-+ * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate
-+ * privilege levels as follows:
-+ *  Level == 0: Noone may enter
-+ *  Level == 1: Kernel may enter
-+ *  Level == 2: Kernel may enter
-+ *  Level == 3: Everyone may enter
-+ */
-+#define TI_GET_DPL(_ti)      ((_ti)->flags & 3)
-+#define TI_GET_IF(_ti)       ((_ti)->flags & 4)
-+#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
-+#define TI_SET_IF(_ti,_if)   ((_ti)->flags |= ((!!(_if))<<2))
-+struct trap_info {
-+    uint8_t       vector;  /* exception vector                              */
-+    uint8_t       flags;   /* 0-3: privilege level; 4: clear event enable?  */
-+    uint16_t      cs;      /* code selector                                 */
-+    unsigned long address; /* code offset                                   */
-+};
-+typedef struct trap_info trap_info_t;
-+DEFINE_XEN_GUEST_HANDLE(trap_info_t);
-+
-+typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
-+
-+/*
-+ * The following is all CPU context. Note that the fpu_ctxt block is filled 
-+ * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
-+ */
-+struct vcpu_guest_context {
-+    /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
-+    struct { char x[512]; } fpu_ctxt;       /* User-level FPU registers     */
-+#define VGCF_I387_VALID                (1<<0)
-+#define VGCF_IN_KERNEL                 (1<<2)
-+#define _VGCF_i387_valid               0
-+#define VGCF_i387_valid                (1<<_VGCF_i387_valid)
-+#define _VGCF_in_kernel                2
-+#define VGCF_in_kernel                 (1<<_VGCF_in_kernel)
-+#define _VGCF_failsafe_disables_events 3
-+#define VGCF_failsafe_disables_events  (1<<_VGCF_failsafe_disables_events)
-+#define _VGCF_syscall_disables_events  4
-+#define VGCF_syscall_disables_events   (1<<_VGCF_syscall_disables_events)
-+    unsigned long flags;                    /* VGCF_* flags                 */
-+    struct cpu_user_regs user_regs;         /* User-level CPU registers     */
-+    struct trap_info trap_ctxt[256];        /* Virtual IDT                  */
-+    unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
-+    unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
-+    unsigned long kernel_ss, kernel_sp;     /* Virtual TSS (only SS1/SP1)   */
-+    unsigned long ctrlreg[8];               /* CR0-CR7 (control registers)  */
-+    unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
-+#ifdef __i386__
-+    unsigned long event_callback_cs;        /* CS:EIP of event callback     */
-+    unsigned long event_callback_eip;
-+    unsigned long failsafe_callback_cs;     /* CS:EIP of failsafe callback  */
-+    unsigned long failsafe_callback_eip;
-+#else
-+    unsigned long event_callback_eip;
-+    unsigned long failsafe_callback_eip;
-+    unsigned long syscall_callback_eip;
-+#endif
-+    unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
-+#ifdef __x86_64__
-+    /* Segment base addresses. */
-+    uint64_t      fs_base;
-+    uint64_t      gs_base_kernel;
-+    uint64_t      gs_base_user;
-+#endif
-+};
-+typedef struct vcpu_guest_context vcpu_guest_context_t;
-+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-+
-+struct arch_shared_info {
-+    unsigned long max_pfn;                  /* max pfn that appears in table */
-+    /* Frame containing list of mfns containing list of mfns containing p2m. */
-+    xen_pfn_t     pfn_to_mfn_frame_list_list;
-+    unsigned long nmi_reason;
-+    uint64_t pad[32];
-+};
-+typedef struct arch_shared_info arch_shared_info_t;
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+/*
-+ * Prefix forces emulation of some non-trapping instructions.
-+ * Currently only CPUID.
-+ */
-+#ifdef __ASSEMBLY__
-+#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
-+#define XEN_CPUID          XEN_EMULATE_PREFIX cpuid
-+#else
-+#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
-+#define XEN_CPUID          XEN_EMULATE_PREFIX "cpuid"
-+#endif
-+
-+#endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/arch-x86_32.h linux-2.6.16.33/include/xen/interface/arch-x86_32.h
---- linux-2.6.16.33-noxen/include/xen/interface/arch-x86_32.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/arch-x86_32.h        2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,27 @@
-+/******************************************************************************
-+ * arch-x86_32.h
-+ * 
-+ * Guest OS interface to x86 32-bit Xen.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2004-2006, K A Fraser
-+ */
-+
-+#include "arch-x86/xen.h"
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/arch-x86_64.h linux-2.6.16.33/include/xen/interface/arch-x86_64.h
---- linux-2.6.16.33-noxen/include/xen/interface/arch-x86_64.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/arch-x86_64.h        2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,27 @@
-+/******************************************************************************
-+ * arch-x86_64.h
-+ * 
-+ * Guest OS interface to x86 64-bit Xen.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2004-2006, K A Fraser
-+ */
-+
-+#include "arch-x86/xen.h"
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/callback.h linux-2.6.16.33/include/xen/interface/callback.h
---- linux-2.6.16.33-noxen/include/xen/interface/callback.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/callback.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,92 @@
-+/******************************************************************************
-+ * callback.h
-+ *
-+ * Register guest OS callbacks with Xen.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2006, Ian Campbell
-+ */
-+
-+#ifndef __XEN_PUBLIC_CALLBACK_H__
-+#define __XEN_PUBLIC_CALLBACK_H__
-+
-+#include "xen.h"
-+
-+/*
-+ * Prototype for this hypercall is:
-+ *   long callback_op(int cmd, void *extra_args)
-+ * @cmd        == CALLBACKOP_??? (callback operation).
-+ * @extra_args == Operation-specific extra arguments (NULL if none).
-+ */
-+
-+#define CALLBACKTYPE_event                 0
-+#define CALLBACKTYPE_failsafe              1
-+#define CALLBACKTYPE_syscall               2 /* x86_64 only */
-+/*
-+ * sysenter is only available on x86_32 with the
-+ * supervisor_mode_kernel option enabled.
-+ */
-+#define CALLBACKTYPE_sysenter              3
-+#define CALLBACKTYPE_nmi                   4
-+
-+/*
-+ * Disable event deliver during callback? This flag is ignored for event and
-+ * NMI callbacks: event delivery is unconditionally disabled.
-+ */
-+#define _CALLBACKF_mask_events             0
-+#define CALLBACKF_mask_events              (1U << _CALLBACKF_mask_events)
-+
-+/*
-+ * Register a callback.
-+ */
-+#define CALLBACKOP_register                0
-+struct callback_register {
-+    uint16_t type;
-+    uint16_t flags;
-+    xen_callback_t address;
-+};
-+typedef struct callback_register callback_register_t;
-+DEFINE_XEN_GUEST_HANDLE(callback_register_t);
-+
-+/*
-+ * Unregister a callback.
-+ *
-+ * Not all callbacks can be unregistered. -EINVAL will be returned if
-+ * you attempt to unregister such a callback.
-+ */
-+#define CALLBACKOP_unregister              1
-+struct callback_unregister {
-+    uint16_t type;
-+    uint16_t _unused;
-+};
-+typedef struct callback_unregister callback_unregister_t;
-+DEFINE_XEN_GUEST_HANDLE(callback_unregister_t);
-+
-+#endif /* __XEN_PUBLIC_CALLBACK_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/dom0_ops.h linux-2.6.16.33/include/xen/interface/dom0_ops.h
---- linux-2.6.16.33-noxen/include/xen/interface/dom0_ops.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/dom0_ops.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,120 @@
-+/******************************************************************************
-+ * dom0_ops.h
-+ * 
-+ * Process command requests from domain-0 guest OS.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2002-2003, B Dragovic
-+ * Copyright (c) 2002-2006, K Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_DOM0_OPS_H__
-+#define __XEN_PUBLIC_DOM0_OPS_H__
-+
-+#include "xen.h"
-+#include "platform.h"
-+
-+#if __XEN_INTERFACE_VERSION__ >= 0x00030204
-+#error "dom0_ops.h is a compatibility interface only"
-+#endif
-+
-+#define DOM0_INTERFACE_VERSION XENPF_INTERFACE_VERSION
-+
-+#define DOM0_SETTIME          XENPF_settime
-+#define dom0_settime          xenpf_settime
-+#define dom0_settime_t        xenpf_settime_t
-+
-+#define DOM0_ADD_MEMTYPE      XENPF_add_memtype
-+#define dom0_add_memtype      xenpf_add_memtype
-+#define dom0_add_memtype_t    xenpf_add_memtype_t
-+
-+#define DOM0_DEL_MEMTYPE      XENPF_del_memtype
-+#define dom0_del_memtype      xenpf_del_memtype
-+#define dom0_del_memtype_t    xenpf_del_memtype_t
-+
-+#define DOM0_READ_MEMTYPE     XENPF_read_memtype
-+#define dom0_read_memtype     xenpf_read_memtype
-+#define dom0_read_memtype_t   xenpf_read_memtype_t
-+
-+#define DOM0_MICROCODE        XENPF_microcode_update
-+#define dom0_microcode        xenpf_microcode_update
-+#define dom0_microcode_t      xenpf_microcode_update_t
-+
-+#define DOM0_PLATFORM_QUIRK   XENPF_platform_quirk
-+#define dom0_platform_quirk   xenpf_platform_quirk
-+#define dom0_platform_quirk_t xenpf_platform_quirk_t
-+
-+typedef uint64_t cpumap_t;
-+
-+/* Unsupported legacy operation -- defined for API compatibility. */
-+#define DOM0_MSR                 15
-+struct dom0_msr {
-+    /* IN variables. */
-+    uint32_t write;
-+    cpumap_t cpu_mask;
-+    uint32_t msr;
-+    uint32_t in1;
-+    uint32_t in2;
-+    /* OUT variables. */
-+    uint32_t out1;
-+    uint32_t out2;
-+};
-+typedef struct dom0_msr dom0_msr_t;
-+DEFINE_XEN_GUEST_HANDLE(dom0_msr_t);
-+
-+/* Unsupported legacy operation -- defined for API compatibility. */
-+#define DOM0_PHYSICAL_MEMORY_MAP 40
-+struct dom0_memory_map_entry {
-+    uint64_t start, end;
-+    uint32_t flags; /* reserved */
-+    uint8_t  is_ram;
-+};
-+typedef struct dom0_memory_map_entry dom0_memory_map_entry_t;
-+DEFINE_XEN_GUEST_HANDLE(dom0_memory_map_entry_t);
-+
-+struct dom0_op {
-+    uint32_t cmd;
-+    uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
-+    union {
-+        struct dom0_msr               msr;
-+        struct dom0_settime           settime;
-+        struct dom0_add_memtype       add_memtype;
-+        struct dom0_del_memtype       del_memtype;
-+        struct dom0_read_memtype      read_memtype;
-+        struct dom0_microcode         microcode;
-+        struct dom0_platform_quirk    platform_quirk;
-+        struct dom0_memory_map_entry  physical_memory_map;
-+        uint8_t                       pad[128];
-+    } u;
-+};
-+typedef struct dom0_op dom0_op_t;
-+DEFINE_XEN_GUEST_HANDLE(dom0_op_t);
-+
-+#endif /* __XEN_PUBLIC_DOM0_OPS_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/domctl.h linux-2.6.16.33/include/xen/interface/domctl.h
---- linux-2.6.16.33-noxen/include/xen/interface/domctl.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/domctl.h     2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,437 @@
-+/******************************************************************************
-+ * domctl.h
-+ * 
-+ * Domain management operations. For use by node control stack.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2002-2003, B Dragovic
-+ * Copyright (c) 2002-2006, K Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_DOMCTL_H__
-+#define __XEN_PUBLIC_DOMCTL_H__
-+
-+#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
-+#error "domctl operations are intended for use by node control tools only"
-+#endif
-+
-+#include "xen.h"
-+
-+#define XEN_DOMCTL_INTERFACE_VERSION 0x00000004
-+
-+struct xenctl_cpumap {
-+    XEN_GUEST_HANDLE(uint8_t) bitmap;
-+    uint32_t nr_cpus;
-+};
-+
-+/*
-+ * NB. xen_domctl.domain is an IN/OUT parameter for this operation.
-+ * If it is specified as zero, an id is auto-allocated and returned.
-+ */
-+#define XEN_DOMCTL_createdomain       1
-+struct xen_domctl_createdomain {
-+    /* IN parameters */
-+    uint32_t ssidref;
-+    xen_domain_handle_t handle;
-+ /* Is this an HVM guest (as opposed to a PV guest)? */
-+#define _XEN_DOMCTL_CDF_hvm_guest 0
-+#define XEN_DOMCTL_CDF_hvm_guest  (1U<<_XEN_DOMCTL_CDF_hvm_guest)
-+    uint32_t flags;
-+};
-+typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t);
-+
-+#define XEN_DOMCTL_destroydomain      2
-+#define XEN_DOMCTL_pausedomain        3
-+#define XEN_DOMCTL_unpausedomain      4
-+
-+#define XEN_DOMCTL_getdomaininfo      5
-+struct xen_domctl_getdomaininfo {
-+    /* OUT variables. */
-+    domid_t  domain;              /* Also echoed in domctl.domain */
-+ /* Domain is scheduled to die. */
-+#define _XEN_DOMINF_dying     0
-+#define XEN_DOMINF_dying      (1U<<_XEN_DOMINF_dying)
-+ /* Domain is an HVM guest (as opposed to a PV guest). */
-+#define _XEN_DOMINF_hvm_guest 1
-+#define XEN_DOMINF_hvm_guest  (1U<<_XEN_DOMINF_hvm_guest)
-+ /* The guest OS has shut down. */
-+#define _XEN_DOMINF_shutdown  2
-+#define XEN_DOMINF_shutdown   (1U<<_XEN_DOMINF_shutdown)
-+ /* Currently paused by control software. */
-+#define _XEN_DOMINF_paused    3
-+#define XEN_DOMINF_paused     (1U<<_XEN_DOMINF_paused)
-+ /* Currently blocked pending an event.     */
-+#define _XEN_DOMINF_blocked   4
-+#define XEN_DOMINF_blocked    (1U<<_XEN_DOMINF_blocked)
-+ /* Domain is currently running.            */
-+#define _XEN_DOMINF_running   5
-+#define XEN_DOMINF_running    (1U<<_XEN_DOMINF_running)
-+ /* CPU to which this domain is bound.      */
-+#define XEN_DOMINF_cpumask      255
-+#define XEN_DOMINF_cpushift       8
-+ /* XEN_DOMINF_shutdown guest-supplied code.  */
-+#define XEN_DOMINF_shutdownmask 255
-+#define XEN_DOMINF_shutdownshift 16
-+    uint32_t flags;              /* XEN_DOMINF_* */
-+    uint64_t tot_pages;
-+    uint64_t max_pages;
-+    uint64_t shared_info_frame;  /* GMFN of shared_info struct */
-+    uint64_t cpu_time;
-+    uint32_t nr_online_vcpus;    /* Number of VCPUs currently online. */
-+    uint32_t max_vcpu_id;        /* Maximum VCPUID in use by this domain. */
-+    uint32_t ssidref;
-+    xen_domain_handle_t handle;
-+};
-+typedef struct xen_domctl_getdomaininfo xen_domctl_getdomaininfo_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t);
-+
-+
-+#define XEN_DOMCTL_getmemlist         6
-+struct xen_domctl_getmemlist {
-+    /* IN variables. */
-+    /* Max entries to write to output buffer. */
-+    uint64_t max_pfns;
-+    /* Start index in guest's page list. */
-+    uint64_t start_pfn;
-+    XEN_GUEST_HANDLE(xen_pfn_t) buffer;
-+    /* OUT variables. */
-+    uint64_t num_pfns;
-+};
-+typedef struct xen_domctl_getmemlist xen_domctl_getmemlist_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getmemlist_t);
-+
-+
-+#define XEN_DOMCTL_getpageframeinfo   7
-+
-+#define XEN_DOMCTL_PFINFO_LTAB_SHIFT 28
-+#define XEN_DOMCTL_PFINFO_NOTAB   (0x0<<28)
-+#define XEN_DOMCTL_PFINFO_L1TAB   (0x1<<28)
-+#define XEN_DOMCTL_PFINFO_L2TAB   (0x2<<28)
-+#define XEN_DOMCTL_PFINFO_L3TAB   (0x3<<28)
-+#define XEN_DOMCTL_PFINFO_L4TAB   (0x4<<28)
-+#define XEN_DOMCTL_PFINFO_LTABTYPE_MASK (0x7<<28)
-+#define XEN_DOMCTL_PFINFO_LPINTAB (0x1<<31)
-+#define XEN_DOMCTL_PFINFO_XTAB    (0xf<<28) /* invalid page */
-+#define XEN_DOMCTL_PFINFO_LTAB_MASK (0xf<<28)
-+
-+struct xen_domctl_getpageframeinfo {
-+    /* IN variables. */
-+    uint64_t gmfn;        /* GMFN to query */
-+    /* OUT variables. */
-+    /* Is the page PINNED to a type? */
-+    uint32_t type;         /* see above type defs */
-+};
-+typedef struct xen_domctl_getpageframeinfo xen_domctl_getpageframeinfo_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo_t);
-+
-+
-+#define XEN_DOMCTL_getpageframeinfo2  8
-+struct xen_domctl_getpageframeinfo2 {
-+    /* IN variables. */
-+    uint64_t num;
-+    /* IN/OUT variables. */
-+    XEN_GUEST_HANDLE(ulong) array;
-+};
-+typedef struct xen_domctl_getpageframeinfo2 xen_domctl_getpageframeinfo2_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo2_t);
-+
-+
-+/*
-+ * Control shadow pagetables operation
-+ */
-+#define XEN_DOMCTL_shadow_op         10
-+
-+/* Disable shadow mode. */
-+#define XEN_DOMCTL_SHADOW_OP_OFF         0
-+
-+/* Enable shadow mode (mode contains ORed XEN_DOMCTL_SHADOW_ENABLE_* flags). */
-+#define XEN_DOMCTL_SHADOW_OP_ENABLE      32
-+
-+/* Log-dirty bitmap operations. */
-+ /* Return the bitmap and clean internal copy for next round. */
-+#define XEN_DOMCTL_SHADOW_OP_CLEAN       11
-+ /* Return the bitmap but do not modify internal copy. */
-+#define XEN_DOMCTL_SHADOW_OP_PEEK        12
-+
-+/* Memory allocation accessors. */
-+#define XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION   30
-+#define XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION   31
-+
-+/* Legacy enable operations. */
-+ /* Equiv. to ENABLE with no mode flags. */
-+#define XEN_DOMCTL_SHADOW_OP_ENABLE_TEST       1
-+ /* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */
-+#define XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY   2
-+ /* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */
-+#define XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE  3
-+
-+/* Mode flags for XEN_DOMCTL_SHADOW_OP_ENABLE. */
-+ /*
-+  * Shadow pagetables are refcounted: guest does not use explicit mmu
-+  * operations nor write-protect its pagetables.
-+  */
-+#define XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT  (1 << 1)
-+ /*
-+  * Log pages in a bitmap as they are dirtied.
-+  * Used for live relocation to determine which pages must be re-sent.
-+  */
-+#define XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY (1 << 2)
-+ /*
-+  * Automatically translate GPFNs into MFNs.
-+  */
-+#define XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE (1 << 3)
-+ /*
-+  * Xen does not steal virtual address space from the guest.
-+  * Requires HVM support.
-+  */
-+#define XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL  (1 << 4)
-+
-+struct xen_domctl_shadow_op_stats {
-+    uint32_t fault_count;
-+    uint32_t dirty_count;
-+};
-+typedef struct xen_domctl_shadow_op_stats xen_domctl_shadow_op_stats_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_stats_t);
-+
-+struct xen_domctl_shadow_op {
-+    /* IN variables. */
-+    uint32_t       op;       /* XEN_DOMCTL_SHADOW_OP_* */
-+
-+    /* OP_ENABLE */
-+    uint32_t       mode;     /* XEN_DOMCTL_SHADOW_ENABLE_* */
-+
-+    /* OP_GET_ALLOCATION / OP_SET_ALLOCATION */
-+    uint32_t       mb;       /* Shadow memory allocation in MB */
-+
-+    /* OP_PEEK / OP_CLEAN */
-+    XEN_GUEST_HANDLE(ulong) dirty_bitmap;
-+    uint64_t       pages;    /* Size of buffer. Updated with actual size. */
-+    struct xen_domctl_shadow_op_stats stats;
-+};
-+typedef struct xen_domctl_shadow_op xen_domctl_shadow_op_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_t);
-+
-+
-+#define XEN_DOMCTL_max_mem           11
-+struct xen_domctl_max_mem {
-+    /* IN variables. */
-+    uint64_t max_memkb;
-+};
-+typedef struct xen_domctl_max_mem xen_domctl_max_mem_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_mem_t);
-+
-+
-+#define XEN_DOMCTL_setvcpucontext    12
-+#define XEN_DOMCTL_getvcpucontext    13
-+struct xen_domctl_vcpucontext {
-+    uint32_t              vcpu;                  /* IN */
-+    XEN_GUEST_HANDLE(vcpu_guest_context_t) ctxt; /* IN/OUT */
-+};
-+typedef struct xen_domctl_vcpucontext xen_domctl_vcpucontext_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpucontext_t);
-+
-+
-+#define XEN_DOMCTL_getvcpuinfo       14
-+struct xen_domctl_getvcpuinfo {
-+    /* IN variables. */
-+    uint32_t vcpu;
-+    /* OUT variables. */
-+    uint8_t  online;                  /* currently online (not hotplugged)? */
-+    uint8_t  blocked;                 /* blocked waiting for an event? */
-+    uint8_t  running;                 /* currently scheduled on its CPU? */
-+    uint64_t cpu_time;                /* total cpu time consumed (ns) */
-+    uint32_t cpu;                     /* current mapping   */
-+};
-+typedef struct xen_domctl_getvcpuinfo xen_domctl_getvcpuinfo_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getvcpuinfo_t);
-+
-+
-+/* Get/set which physical cpus a vcpu can execute on. */
-+#define XEN_DOMCTL_setvcpuaffinity    9
-+#define XEN_DOMCTL_getvcpuaffinity   25
-+struct xen_domctl_vcpuaffinity {
-+    uint32_t  vcpu;              /* IN */
-+    struct xenctl_cpumap cpumap; /* IN/OUT */
-+};
-+typedef struct xen_domctl_vcpuaffinity xen_domctl_vcpuaffinity_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuaffinity_t);
-+
-+
-+#define XEN_DOMCTL_max_vcpus         15
-+struct xen_domctl_max_vcpus {
-+    uint32_t max;           /* maximum number of vcpus */
-+};
-+typedef struct xen_domctl_max_vcpus xen_domctl_max_vcpus_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t);
-+
-+
-+#define XEN_DOMCTL_scheduler_op      16
-+/* Scheduler types. */
-+#define XEN_SCHEDULER_SEDF     4
-+#define XEN_SCHEDULER_CREDIT   5
-+/* Set or get info? */
-+#define XEN_DOMCTL_SCHEDOP_putinfo 0
-+#define XEN_DOMCTL_SCHEDOP_getinfo 1
-+struct xen_domctl_scheduler_op {
-+    uint32_t sched_id;  /* XEN_SCHEDULER_* */
-+    uint32_t cmd;       /* XEN_DOMCTL_SCHEDOP_* */
-+    union {
-+        struct xen_domctl_sched_sedf {
-+            uint64_t period;
-+            uint64_t slice;
-+            uint64_t latency;
-+            uint32_t extratime;
-+            uint32_t weight;
-+        } sedf;
-+        struct xen_domctl_sched_credit {
-+            uint16_t weight;
-+            uint16_t cap;
-+        } credit;
-+    } u;
-+};
-+typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_scheduler_op_t);
-+
-+
-+#define XEN_DOMCTL_setdomainhandle   17
-+struct xen_domctl_setdomainhandle {
-+    xen_domain_handle_t handle;
-+};
-+typedef struct xen_domctl_setdomainhandle xen_domctl_setdomainhandle_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdomainhandle_t);
-+
-+
-+#define XEN_DOMCTL_setdebugging      18
-+struct xen_domctl_setdebugging {
-+    uint8_t enable;
-+};
-+typedef struct xen_domctl_setdebugging xen_domctl_setdebugging_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdebugging_t);
-+
-+
-+#define XEN_DOMCTL_irq_permission    19
-+struct xen_domctl_irq_permission {
-+    uint8_t pirq;
-+    uint8_t allow_access;    /* flag to specify enable/disable of IRQ access */
-+};
-+typedef struct xen_domctl_irq_permission xen_domctl_irq_permission_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_irq_permission_t);
-+
-+
-+#define XEN_DOMCTL_iomem_permission  20
-+struct xen_domctl_iomem_permission {
-+    uint64_t first_mfn;       /* first page (physical page number) in range */
-+    uint64_t nr_mfns;         /* number of pages in range (>0) */
-+    uint8_t  allow_access;    /* allow (!0) or deny (0) access to range? */
-+};
-+typedef struct xen_domctl_iomem_permission xen_domctl_iomem_permission_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_iomem_permission_t);
-+
-+
-+#define XEN_DOMCTL_ioport_permission 21
-+struct xen_domctl_ioport_permission {
-+    uint32_t first_port;              /* first port int range */
-+    uint32_t nr_ports;                /* size of port range */
-+    uint8_t  allow_access;            /* allow or deny access to range? */
-+};
-+typedef struct xen_domctl_ioport_permission xen_domctl_ioport_permission_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_permission_t);
-+
-+#define XEN_DOMCTL_hypercall_init    22
-+struct xen_domctl_hypercall_init {
-+    uint64_t  gmfn;            /* GMFN to be initialised */
-+};
-+typedef struct xen_domctl_hypercall_init xen_domctl_hypercall_init_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_hypercall_init_t);
-+
-+#define XEN_DOMCTL_arch_setup        23
-+#define _XEN_DOMAINSETUP_hvm_guest 0
-+#define XEN_DOMAINSETUP_hvm_guest  (1UL<<_XEN_DOMAINSETUP_hvm_guest)
-+#define _XEN_DOMAINSETUP_query 1 /* Get parameters (for save)  */
-+#define XEN_DOMAINSETUP_query  (1UL<<_XEN_DOMAINSETUP_query)
-+typedef struct xen_domctl_arch_setup {
-+    uint64_t flags;      /* XEN_DOMAINSETUP_* */
-+#ifdef __ia64__
-+    uint64_t bp;            /* mpaddr of boot param area */
-+    uint64_t maxmem;        /* Highest memory address for MDT.  */
-+    uint64_t xsi_va;        /* Xen shared_info area virtual address.  */
-+    uint32_t hypercall_imm; /* Break imm for Xen hypercalls.  */
-+#endif
-+} xen_domctl_arch_setup_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_arch_setup_t);
-+
-+#define XEN_DOMCTL_settimeoffset     24
-+struct xen_domctl_settimeoffset {
-+    int32_t  time_offset_seconds; /* applied to domain wallclock time */
-+};
-+typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t);
-+
-+#define XEN_DOMCTL_real_mode_area     26
-+struct xen_domctl_real_mode_area {
-+    uint32_t log; /* log2 of Real Mode Area size */
-+};
-+typedef struct xen_domctl_real_mode_area xen_domctl_real_mode_area_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t);
-+
-+struct xen_domctl {
-+    uint32_t cmd;
-+    uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
-+    domid_t  domain;
-+    union {
-+        struct xen_domctl_createdomain      createdomain;
-+        struct xen_domctl_getdomaininfo     getdomaininfo;
-+        struct xen_domctl_getmemlist        getmemlist;
-+        struct xen_domctl_getpageframeinfo  getpageframeinfo;
-+        struct xen_domctl_getpageframeinfo2 getpageframeinfo2;
-+        struct xen_domctl_vcpuaffinity      vcpuaffinity;
-+        struct xen_domctl_shadow_op         shadow_op;
-+        struct xen_domctl_max_mem           max_mem;
-+        struct xen_domctl_vcpucontext       vcpucontext;
-+        struct xen_domctl_getvcpuinfo       getvcpuinfo;
-+        struct xen_domctl_max_vcpus         max_vcpus;
-+        struct xen_domctl_scheduler_op      scheduler_op;
-+        struct xen_domctl_setdomainhandle   setdomainhandle;
-+        struct xen_domctl_setdebugging      setdebugging;
-+        struct xen_domctl_irq_permission    irq_permission;
-+        struct xen_domctl_iomem_permission  iomem_permission;
-+        struct xen_domctl_ioport_permission ioport_permission;
-+        struct xen_domctl_hypercall_init    hypercall_init;
-+        struct xen_domctl_arch_setup        arch_setup;
-+        struct xen_domctl_settimeoffset     settimeoffset;
-+        struct xen_domctl_real_mode_area    real_mode_area;
-+        uint8_t                             pad[128];
-+    } u;
-+};
-+typedef struct xen_domctl xen_domctl_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_domctl_t);
-+
-+#endif /* __XEN_PUBLIC_DOMCTL_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/elfnote.h linux-2.6.16.33/include/xen/interface/elfnote.h
---- linux-2.6.16.33-noxen/include/xen/interface/elfnote.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/elfnote.h    2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,179 @@
-+/******************************************************************************
-+ * elfnote.h
-+ *
-+ * Definitions used for the Xen ELF notes.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2006, Ian Campbell, XenSource Ltd.
-+ */
-+
-+#ifndef __XEN_PUBLIC_ELFNOTE_H__
-+#define __XEN_PUBLIC_ELFNOTE_H__
-+
-+/*
-+ * The notes should live in a SHT_NOTE segment and have "Xen" in the
-+ * name field.
-+ *
-+ * Numeric types are either 4 or 8 bytes depending on the content of
-+ * the desc field.
-+ *
-+ * LEGACY indicated the fields in the legacy __xen_guest string which
-+ * this a note type replaces.
-+ */
-+
-+/*
-+ * NAME=VALUE pair (string).
-+ *
-+ * LEGACY: FEATURES and PAE
-+ */
-+#define XEN_ELFNOTE_INFO           0
-+
-+/*
-+ * The virtual address of the entry point (numeric).
-+ *
-+ * LEGACY: VIRT_ENTRY
-+ */
-+#define XEN_ELFNOTE_ENTRY          1
-+
-+/* The virtual address of the hypercall transfer page (numeric).
-+ *
-+ * LEGACY: HYPERCALL_PAGE. (n.b. legacy value is a physical page
-+ * number not a virtual address)
-+ */
-+#define XEN_ELFNOTE_HYPERCALL_PAGE 2
-+
-+/* The virtual address where the kernel image should be mapped (numeric).
-+ *
-+ * Defaults to 0.
-+ *
-+ * LEGACY: VIRT_BASE
-+ */
-+#define XEN_ELFNOTE_VIRT_BASE      3
-+
-+/*
-+ * The offset of the ELF paddr field from the acutal required
-+ * psuedo-physical address (numeric).
-+ *
-+ * This is used to maintain backwards compatibility with older kernels
-+ * which wrote __PAGE_OFFSET into that field. This field defaults to 0
-+ * if not present.
-+ *
-+ * LEGACY: ELF_PADDR_OFFSET. (n.b. legacy default is VIRT_BASE)
-+ */
-+#define XEN_ELFNOTE_PADDR_OFFSET   4
-+
-+/*
-+ * The version of Xen that we work with (string).
-+ *
-+ * LEGACY: XEN_VER
-+ */
-+#define XEN_ELFNOTE_XEN_VERSION    5
-+
-+/*
-+ * The name of the guest operating system (string).
-+ *
-+ * LEGACY: GUEST_OS
-+ */
-+#define XEN_ELFNOTE_GUEST_OS       6
-+
-+/*
-+ * The version of the guest operating system (string).
-+ *
-+ * LEGACY: GUEST_VER
-+ */
-+#define XEN_ELFNOTE_GUEST_VERSION  7
-+
-+/*
-+ * The loader type (string).
-+ *
-+ * LEGACY: LOADER
-+ */
-+#define XEN_ELFNOTE_LOADER         8
-+
-+/*
-+ * The kernel supports PAE (x86/32 only, string = "yes" or "no").
-+ *
-+ * LEGACY: PAE (n.b. The legacy interface included a provision to
-+ * indicate 'extended-cr3' support allowing L3 page tables to be
-+ * placed above 4G. It is assumed that any kernel new enough to use
-+ * these ELF notes will include this and therefore "yes" here is
-+ * equivalent to "yes[entended-cr3]" in the __xen_guest interface.
-+ */
-+#define XEN_ELFNOTE_PAE_MODE       9
-+
-+/*
-+ * The features supported/required by this kernel (string).
-+ *
-+ * The string must consist of a list of feature names (as given in
-+ * features.h, without the "XENFEAT_" prefix) separated by '|'
-+ * characters. If a feature is required for the kernel to function
-+ * then the feature name must be preceded by a '!' character.
-+ *
-+ * LEGACY: FEATURES
-+ */
-+#define XEN_ELFNOTE_FEATURES      10
-+
-+/*
-+ * The kernel requires the symbol table to be loaded (string = "yes" or "no")
-+ * LEGACY: BSD_SYMTAB (n.b. The legacy treated the presence or absence
-+ * of this string as a boolean flag rather than requiring "yes" or
-+ * "no".
-+ */
-+#define XEN_ELFNOTE_BSD_SYMTAB    11
-+
-+/*
-+ * The lowest address the hypervisor hole can begin at (numeric).
-+ *
-+ * This must not be set higher than HYPERVISOR_VIRT_START. Its presence
-+ * also indicates to the hypervisor that the kernel can deal with the
-+ * hole starting at a higher address.
-+ */
-+#define XEN_ELFNOTE_HV_START_LOW  12
-+
-+/*
-+ * System information exported through crash notes.
-+ *
-+ * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_INFO 
-+ * note in case of a system crash. This note will contain various
-+ * information about the system, see xen/include/xen/elfcore.h.
-+ */
-+#define XEN_ELFNOTE_CRASH_INFO 0x1000001
-+
-+/*
-+ * System registers exported through crash notes.
-+ *
-+ * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_REGS 
-+ * note per cpu in case of a system crash. This note is architecture
-+ * specific and will contain registers not saved in the "CORE" note.
-+ * See xen/include/xen/elfcore.h for more information.
-+ */
-+#define XEN_ELFNOTE_CRASH_REGS 0x1000002
-+
-+#endif /* __XEN_PUBLIC_ELFNOTE_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/event_channel.h linux-2.6.16.33/include/xen/interface/event_channel.h
---- linux-2.6.16.33-noxen/include/xen/interface/event_channel.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/event_channel.h      2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,251 @@
-+/******************************************************************************
-+ * event_channel.h
-+ * 
-+ * Event channels between domains.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2003-2004, K A Fraser.
-+ */
-+
-+#ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
-+#define __XEN_PUBLIC_EVENT_CHANNEL_H__
-+
-+/*
-+ * Prototype for this hypercall is:
-+ *  int event_channel_op(int cmd, void *args)
-+ * @cmd  == EVTCHNOP_??? (event-channel operation).
-+ * @args == Operation-specific extra arguments (NULL if none).
-+ */
-+
-+typedef uint32_t evtchn_port_t;
-+DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
-+
-+/*
-+ * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
-+ * accepting interdomain bindings from domain <remote_dom>. A fresh port
-+ * is allocated in <dom> and returned as <port>.
-+ * NOTES:
-+ *  1. If the caller is unprivileged then <dom> must be DOMID_SELF.
-+ *  2. <rdom> may be DOMID_SELF, allowing loopback connections.
-+ */
-+#define EVTCHNOP_alloc_unbound    6
-+struct evtchn_alloc_unbound {
-+    /* IN parameters */
-+    domid_t dom, remote_dom;
-+    /* OUT parameters */
-+    evtchn_port_t port;
-+};
-+typedef struct evtchn_alloc_unbound evtchn_alloc_unbound_t;
-+
-+/*
-+ * EVTCHNOP_bind_interdomain: Construct an interdomain event channel between
-+ * the calling domain and <remote_dom>. <remote_dom,remote_port> must identify
-+ * a port that is unbound and marked as accepting bindings from the calling
-+ * domain. A fresh port is allocated in the calling domain and returned as
-+ * <local_port>.
-+ * NOTES:
-+ *  2. <remote_dom> may be DOMID_SELF, allowing loopback connections.
-+ */
-+#define EVTCHNOP_bind_interdomain 0
-+struct evtchn_bind_interdomain {
-+    /* IN parameters. */
-+    domid_t remote_dom;
-+    evtchn_port_t remote_port;
-+    /* OUT parameters. */
-+    evtchn_port_t local_port;
-+};
-+typedef struct evtchn_bind_interdomain evtchn_bind_interdomain_t;
-+
-+/*
-+ * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified
-+ * vcpu.
-+ * NOTES:
-+ *  1. Virtual IRQs are classified as per-vcpu or global. See the VIRQ list
-+ *     in xen.h for the classification of each VIRQ.
-+ *  2. Global VIRQs must be allocated on VCPU0 but can subsequently be
-+ *     re-bound via EVTCHNOP_bind_vcpu.
-+ *  3. Per-vcpu VIRQs may be bound to at most one event channel per vcpu.
-+ *     The allocated event channel is bound to the specified vcpu and the
-+ *     binding cannot be changed.
-+ */
-+#define EVTCHNOP_bind_virq        1
-+struct evtchn_bind_virq {
-+    /* IN parameters. */
-+    uint32_t virq;
-+    uint32_t vcpu;
-+    /* OUT parameters. */
-+    evtchn_port_t port;
-+};
-+typedef struct evtchn_bind_virq evtchn_bind_virq_t;
-+
-+/*
-+ * EVTCHNOP_bind_pirq: Bind a local event channel to PIRQ <irq>.
-+ * NOTES:
-+ *  1. A physical IRQ may be bound to at most one event channel per domain.
-+ *  2. Only a sufficiently-privileged domain may bind to a physical IRQ.
-+ */
-+#define EVTCHNOP_bind_pirq        2
-+struct evtchn_bind_pirq {
-+    /* IN parameters. */
-+    uint32_t pirq;
-+#define BIND_PIRQ__WILL_SHARE 1
-+    uint32_t flags; /* BIND_PIRQ__* */
-+    /* OUT parameters. */
-+    evtchn_port_t port;
-+};
-+typedef struct evtchn_bind_pirq evtchn_bind_pirq_t;
-+
-+/*
-+ * EVTCHNOP_bind_ipi: Bind a local event channel to receive events.
-+ * NOTES:
-+ *  1. The allocated event channel is bound to the specified vcpu. The binding
-+ *     may not be changed.
-+ */
-+#define EVTCHNOP_bind_ipi         7
-+struct evtchn_bind_ipi {
-+    uint32_t vcpu;
-+    /* OUT parameters. */
-+    evtchn_port_t port;
-+};
-+typedef struct evtchn_bind_ipi evtchn_bind_ipi_t;
-+
-+/*
-+ * EVTCHNOP_close: Close a local event channel <port>. If the channel is
-+ * interdomain then the remote end is placed in the unbound state
-+ * (EVTCHNSTAT_unbound), awaiting a new connection.
-+ */
-+#define EVTCHNOP_close            3
-+struct evtchn_close {
-+    /* IN parameters. */
-+    evtchn_port_t port;
-+};
-+typedef struct evtchn_close evtchn_close_t;
-+
-+/*
-+ * EVTCHNOP_send: Send an event to the remote end of the channel whose local
-+ * endpoint is <port>.
-+ */
-+#define EVTCHNOP_send             4
-+struct evtchn_send {
-+    /* IN parameters. */
-+    evtchn_port_t port;
-+};
-+typedef struct evtchn_send evtchn_send_t;
-+
-+/*
-+ * EVTCHNOP_status: Get the current status of the communication channel which
-+ * has an endpoint at <dom, port>.
-+ * NOTES:
-+ *  1. <dom> may be specified as DOMID_SELF.
-+ *  2. Only a sufficiently-privileged domain may obtain the status of an event
-+ *     channel for which <dom> is not DOMID_SELF.
-+ */
-+#define EVTCHNOP_status           5
-+struct evtchn_status {
-+    /* IN parameters */
-+    domid_t  dom;
-+    evtchn_port_t port;
-+    /* OUT parameters */
-+#define EVTCHNSTAT_closed       0  /* Channel is not in use.                 */
-+#define EVTCHNSTAT_unbound      1  /* Channel is waiting interdom connection.*/
-+#define EVTCHNSTAT_interdomain  2  /* Channel is connected to remote domain. */
-+#define EVTCHNSTAT_pirq         3  /* Channel is bound to a phys IRQ line.   */
-+#define EVTCHNSTAT_virq         4  /* Channel is bound to a virtual IRQ line */
-+#define EVTCHNSTAT_ipi          5  /* Channel is bound to a virtual IPI line */
-+    uint32_t status;
-+    uint32_t vcpu;                 /* VCPU to which this channel is bound.   */
-+    union {
-+        struct {
-+            domid_t dom;
-+        } unbound; /* EVTCHNSTAT_unbound */
-+        struct {
-+            domid_t dom;
-+            evtchn_port_t port;
-+        } interdomain; /* EVTCHNSTAT_interdomain */
-+        uint32_t pirq;      /* EVTCHNSTAT_pirq        */
-+        uint32_t virq;      /* EVTCHNSTAT_virq        */
-+    } u;
-+};
-+typedef struct evtchn_status evtchn_status_t;
-+
-+/*
-+ * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an
-+ * event is pending.
-+ * NOTES:
-+ *  1. IPI-bound channels always notify the vcpu specified at bind time.
-+ *     This binding cannot be changed.
-+ *  2. Per-VCPU VIRQ channels always notify the vcpu specified at bind time.
-+ *     This binding cannot be changed.
-+ *  3. All other channels notify vcpu0 by default. This default is set when
-+ *     the channel is allocated (a port that is freed and subsequently reused
-+ *     has its binding reset to vcpu0).
-+ */
-+#define EVTCHNOP_bind_vcpu        8
-+struct evtchn_bind_vcpu {
-+    /* IN parameters. */
-+    evtchn_port_t port;
-+    uint32_t vcpu;
-+};
-+typedef struct evtchn_bind_vcpu evtchn_bind_vcpu_t;
-+
-+/*
-+ * EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver
-+ * a notification to the appropriate VCPU if an event is pending.
-+ */
-+#define EVTCHNOP_unmask           9
-+struct evtchn_unmask {
-+    /* IN parameters. */
-+    evtchn_port_t port;
-+};
-+typedef struct evtchn_unmask evtchn_unmask_t;
-+
-+/*
-+ * Argument to event_channel_op_compat() hypercall. Superceded by new
-+ * event_channel_op() hypercall since 0x00030202.
-+ */
-+struct evtchn_op {
-+    uint32_t cmd; /* EVTCHNOP_* */
-+    union {
-+        struct evtchn_alloc_unbound    alloc_unbound;
-+        struct evtchn_bind_interdomain bind_interdomain;
-+        struct evtchn_bind_virq        bind_virq;
-+        struct evtchn_bind_pirq        bind_pirq;
-+        struct evtchn_bind_ipi         bind_ipi;
-+        struct evtchn_close            close;
-+        struct evtchn_send             send;
-+        struct evtchn_status           status;
-+        struct evtchn_bind_vcpu        bind_vcpu;
-+        struct evtchn_unmask           unmask;
-+    } u;
-+};
-+typedef struct evtchn_op evtchn_op_t;
-+DEFINE_XEN_GUEST_HANDLE(evtchn_op_t);
-+
-+#endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/features.h linux-2.6.16.33/include/xen/interface/features.h
---- linux-2.6.16.33-noxen/include/xen/interface/features.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/features.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,71 @@
-+/******************************************************************************
-+ * features.h
-+ * 
-+ * Feature flags, reported by XENVER_get_features.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2006, Keir Fraser <keir@xensource.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_FEATURES_H__
-+#define __XEN_PUBLIC_FEATURES_H__
-+
-+/*
-+ * If set, the guest does not need to write-protect its pagetables, and can
-+ * update them via direct writes.
-+ */
-+#define XENFEAT_writable_page_tables       0
-+
-+/*
-+ * If set, the guest does not need to write-protect its segment descriptor
-+ * tables, and can update them via direct writes.
-+ */
-+#define XENFEAT_writable_descriptor_tables 1
-+
-+/*
-+ * If set, translation between the guest's 'pseudo-physical' address space
-+ * and the host's machine address space are handled by the hypervisor. In this
-+ * mode the guest does not need to perform phys-to/from-machine translations
-+ * when performing page table operations.
-+ */
-+#define XENFEAT_auto_translated_physmap    2
-+
-+/* If set, the guest is running in supervisor mode (e.g., x86 ring 0). */
-+#define XENFEAT_supervisor_mode_kernel     3
-+
-+/*
-+ * If set, the guest does not need to allocate x86 PAE page directories
-+ * below 4GB. This flag is usually implied by auto_translated_physmap.
-+ */
-+#define XENFEAT_pae_pgdir_above_4gb        4
-+
-+#define XENFEAT_NR_SUBMAPS 1
-+
-+#endif /* __XEN_PUBLIC_FEATURES_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/grant_table.h linux-2.6.16.33/include/xen/interface/grant_table.h
---- linux-2.6.16.33-noxen/include/xen/interface/grant_table.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/grant_table.h        2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,380 @@
-+/******************************************************************************
-+ * grant_table.h
-+ * 
-+ * Interface for granting foreign access to page frames, and receiving
-+ * page-ownership transfers.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2004, K A Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_GRANT_TABLE_H__
-+#define __XEN_PUBLIC_GRANT_TABLE_H__
-+
-+
-+/***********************************
-+ * GRANT TABLE REPRESENTATION
-+ */
-+
-+/* Some rough guidelines on accessing and updating grant-table entries
-+ * in a concurrency-safe manner. For more information, Linux contains a
-+ * reference implementation for guest OSes (arch/xen/kernel/grant_table.c).
-+ * 
-+ * NB. WMB is a no-op on current-generation x86 processors. However, a
-+ *     compiler barrier will still be required.
-+ * 
-+ * Introducing a valid entry into the grant table:
-+ *  1. Write ent->domid.
-+ *  2. Write ent->frame:
-+ *      GTF_permit_access:   Frame to which access is permitted.
-+ *      GTF_accept_transfer: Pseudo-phys frame slot being filled by new
-+ *                           frame, or zero if none.
-+ *  3. Write memory barrier (WMB).
-+ *  4. Write ent->flags, inc. valid type.
-+ * 
-+ * Invalidating an unused GTF_permit_access entry:
-+ *  1. flags = ent->flags.
-+ *  2. Observe that !(flags & (GTF_reading|GTF_writing)).
-+ *  3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).
-+ *  NB. No need for WMB as reuse of entry is control-dependent on success of
-+ *      step 3, and all architectures guarantee ordering of ctrl-dep writes.
-+ *
-+ * Invalidating an in-use GTF_permit_access entry:
-+ *  This cannot be done directly. Request assistance from the domain controller
-+ *  which can set a timeout on the use of a grant entry and take necessary
-+ *  action. (NB. This is not yet implemented!).
-+ * 
-+ * Invalidating an unused GTF_accept_transfer entry:
-+ *  1. flags = ent->flags.
-+ *  2. Observe that !(flags & GTF_transfer_committed). [*]
-+ *  3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).
-+ *  NB. No need for WMB as reuse of entry is control-dependent on success of
-+ *      step 3, and all architectures guarantee ordering of ctrl-dep writes.
-+ *  [*] If GTF_transfer_committed is set then the grant entry is 'committed'.
-+ *      The guest must /not/ modify the grant entry until the address of the
-+ *      transferred frame is written. It is safe for the guest to spin waiting
-+ *      for this to occur (detect by observing GTF_transfer_completed in
-+ *      ent->flags).
-+ *
-+ * Invalidating a committed GTF_accept_transfer entry:
-+ *  1. Wait for (ent->flags & GTF_transfer_completed).
-+ *
-+ * Changing a GTF_permit_access from writable to read-only:
-+ *  Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing.
-+ * 
-+ * Changing a GTF_permit_access from read-only to writable:
-+ *  Use SMP-safe bit-setting instruction.
-+ */
-+
-+/*
-+ * A grant table comprises a packed array of grant entries in one or more
-+ * page frames shared between Xen and a guest.
-+ * [XEN]: This field is written by Xen and read by the sharing guest.
-+ * [GST]: This field is written by the guest and read by Xen.
-+ */
-+struct grant_entry {
-+    /* GTF_xxx: various type and flag information.  [XEN,GST] */
-+    uint16_t flags;
-+    /* The domain being granted foreign privileges. [GST] */
-+    domid_t  domid;
-+    /*
-+     * GTF_permit_access: Frame that @domid is allowed to map and access. [GST]
-+     * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN]
-+     */
-+    uint32_t frame;
-+};
-+typedef struct grant_entry grant_entry_t;
-+
-+/*
-+ * Type of grant entry.
-+ *  GTF_invalid: This grant entry grants no privileges.
-+ *  GTF_permit_access: Allow @domid to map/access @frame.
-+ *  GTF_accept_transfer: Allow @domid to transfer ownership of one page frame
-+ *                       to this guest. Xen writes the page number to @frame.
-+ */
-+#define GTF_invalid         (0U<<0)
-+#define GTF_permit_access   (1U<<0)
-+#define GTF_accept_transfer (2U<<0)
-+#define GTF_type_mask       (3U<<0)
-+
-+/*
-+ * Subflags for GTF_permit_access.
-+ *  GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
-+ *  GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
-+ *  GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
-+ */
-+#define _GTF_readonly       (2)
-+#define GTF_readonly        (1U<<_GTF_readonly)
-+#define _GTF_reading        (3)
-+#define GTF_reading         (1U<<_GTF_reading)
-+#define _GTF_writing        (4)
-+#define GTF_writing         (1U<<_GTF_writing)
-+
-+/*
-+ * Subflags for GTF_accept_transfer:
-+ *  GTF_transfer_committed: Xen sets this flag to indicate that it is committed
-+ *      to transferring ownership of a page frame. When a guest sees this flag
-+ *      it must /not/ modify the grant entry until GTF_transfer_completed is
-+ *      set by Xen.
-+ *  GTF_transfer_completed: It is safe for the guest to spin-wait on this flag
-+ *      after reading GTF_transfer_committed. Xen will always write the frame
-+ *      address, followed by ORing this flag, in a timely manner.
-+ */
-+#define _GTF_transfer_committed (2)
-+#define GTF_transfer_committed  (1U<<_GTF_transfer_committed)
-+#define _GTF_transfer_completed (3)
-+#define GTF_transfer_completed  (1U<<_GTF_transfer_completed)
-+
-+
-+/***********************************
-+ * GRANT TABLE QUERIES AND USES
-+ */
-+
-+/*
-+ * Reference to a grant entry in a specified domain's grant table.
-+ */
-+typedef uint32_t grant_ref_t;
-+
-+/*
-+ * Handle to track a mapping created via a grant reference.
-+ */
-+typedef uint32_t grant_handle_t;
-+
-+/*
-+ * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access
-+ * by devices and/or host CPUs. If successful, <handle> is a tracking number
-+ * that must be presented later to destroy the mapping(s). On error, <handle>
-+ * is a negative status code.
-+ * NOTES:
-+ *  1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address
-+ *     via which I/O devices may access the granted frame.
-+ *  2. If GNTMAP_host_map is specified then a mapping will be added at
-+ *     either a host virtual address in the current address space, or at
-+ *     a PTE at the specified machine address.  The type of mapping to
-+ *     perform is selected through the GNTMAP_contains_pte flag, and the 
-+ *     address is specified in <host_addr>.
-+ *  3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a
-+ *     host mapping is destroyed by other means then it is *NOT* guaranteed
-+ *     to be accounted to the correct grant reference!
-+ */
-+#define GNTTABOP_map_grant_ref        0
-+struct gnttab_map_grant_ref {
-+    /* IN parameters. */
-+    uint64_t host_addr;
-+    uint32_t flags;               /* GNTMAP_* */
-+    grant_ref_t ref;
-+    domid_t  dom;
-+    /* OUT parameters. */
-+    int16_t  status;              /* GNTST_* */
-+    grant_handle_t handle;
-+    uint64_t dev_bus_addr;
-+};
-+typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t;
-+DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t);
-+
-+/*
-+ * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings
-+ * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that
-+ * field is ignored. If non-zero, they must refer to a device/host mapping
-+ * that is tracked by <handle>
-+ * NOTES:
-+ *  1. The call may fail in an undefined manner if either mapping is not
-+ *     tracked by <handle>.
-+ *  3. After executing a batch of unmaps, it is guaranteed that no stale
-+ *     mappings will remain in the device or host TLBs.
-+ */
-+#define GNTTABOP_unmap_grant_ref      1
-+struct gnttab_unmap_grant_ref {
-+    /* IN parameters. */
-+    uint64_t host_addr;
-+    uint64_t dev_bus_addr;
-+    grant_handle_t handle;
-+    /* OUT parameters. */
-+    int16_t  status;              /* GNTST_* */
-+};
-+typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t;
-+DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t);
-+
-+/*
-+ * GNTTABOP_setup_table: Set up a grant table for <dom> comprising at least
-+ * <nr_frames> pages. The frame addresses are written to the <frame_list>.
-+ * Only <nr_frames> addresses are written, even if the table is larger.
-+ * NOTES:
-+ *  1. <dom> may be specified as DOMID_SELF.
-+ *  2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.
-+ *  3. Xen may not support more than a single grant-table page per domain.
-+ */
-+#define GNTTABOP_setup_table          2
-+struct gnttab_setup_table {
-+    /* IN parameters. */
-+    domid_t  dom;
-+    uint32_t nr_frames;
-+    /* OUT parameters. */
-+    int16_t  status;              /* GNTST_* */
-+    XEN_GUEST_HANDLE(ulong) frame_list;
-+};
-+typedef struct gnttab_setup_table gnttab_setup_table_t;
-+DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t);
-+
-+/*
-+ * GNTTABOP_dump_table: Dump the contents of the grant table to the
-+ * xen console. Debugging use only.
-+ */
-+#define GNTTABOP_dump_table           3
-+struct gnttab_dump_table {
-+    /* IN parameters. */
-+    domid_t dom;
-+    /* OUT parameters. */
-+    int16_t status;               /* GNTST_* */
-+};
-+typedef struct gnttab_dump_table gnttab_dump_table_t;
-+DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t);
-+
-+/*
-+ * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The
-+ * foreign domain has previously registered its interest in the transfer via
-+ * <domid, ref>.
-+ * 
-+ * Note that, even if the transfer fails, the specified page no longer belongs
-+ * to the calling domain *unless* the error is GNTST_bad_page.
-+ */
-+#define GNTTABOP_transfer                4
-+struct gnttab_transfer {
-+    /* IN parameters. */
-+    xen_pfn_t     mfn;
-+    domid_t       domid;
-+    grant_ref_t   ref;
-+    /* OUT parameters. */
-+    int16_t       status;
-+};
-+typedef struct gnttab_transfer gnttab_transfer_t;
-+DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t);
-+
-+
-+/*
-+ * GNTTABOP_copy: Hypervisor based copy
-+ * source and destinations can be eithers MFNs or, for foreign domains,
-+ * grant references. the foreign domain has to grant read/write access
-+ * in its grant table.
-+ *
-+ * The flags specify what type source and destinations are (either MFN
-+ * or grant reference).
-+ *
-+ * Note that this can also be used to copy data between two domains
-+ * via a third party if the source and destination domains had previously
-+ * grant appropriate access to their pages to the third party.
-+ *
-+ * source_offset specifies an offset in the source frame, dest_offset
-+ * the offset in the target frame and  len specifies the number of
-+ * bytes to be copied.
-+ */
-+
-+#define _GNTCOPY_source_gref      (0)
-+#define GNTCOPY_source_gref       (1<<_GNTCOPY_source_gref)
-+#define _GNTCOPY_dest_gref        (1)
-+#define GNTCOPY_dest_gref         (1<<_GNTCOPY_dest_gref)
-+
-+#define GNTTABOP_copy                 5
-+typedef struct gnttab_copy {
-+    /* IN parameters. */
-+    struct {
-+        union {
-+            grant_ref_t ref;
-+            xen_pfn_t   gmfn;
-+        } u;
-+        domid_t  domid;
-+        uint16_t offset;
-+    } source, dest;
-+    uint16_t      len;
-+    uint16_t      flags;          /* GNTCOPY_* */
-+    /* OUT parameters. */
-+    int16_t       status;
-+} gnttab_copy_t;
-+DEFINE_XEN_GUEST_HANDLE(gnttab_copy_t);
-+
-+
-+/*
-+ * Bitfield values for update_pin_status.flags.
-+ */
-+ /* Map the grant entry for access by I/O devices. */
-+#define _GNTMAP_device_map      (0)
-+#define GNTMAP_device_map       (1<<_GNTMAP_device_map)
-+ /* Map the grant entry for access by host CPUs. */
-+#define _GNTMAP_host_map        (1)
-+#define GNTMAP_host_map         (1<<_GNTMAP_host_map)
-+ /* Accesses to the granted frame will be restricted to read-only access. */
-+#define _GNTMAP_readonly        (2)
-+#define GNTMAP_readonly         (1<<_GNTMAP_readonly)
-+ /*
-+  * GNTMAP_host_map subflag:
-+  *  0 => The host mapping is usable only by the guest OS.
-+  *  1 => The host mapping is usable by guest OS + current application.
-+  */
-+#define _GNTMAP_application_map (3)
-+#define GNTMAP_application_map  (1<<_GNTMAP_application_map)
-+
-+ /*
-+  * GNTMAP_contains_pte subflag:
-+  *  0 => This map request contains a host virtual address.
-+  *  1 => This map request contains the machine addess of the PTE to update.
-+  */
-+#define _GNTMAP_contains_pte    (4)
-+#define GNTMAP_contains_pte     (1<<_GNTMAP_contains_pte)
-+
-+/*
-+ * Values for error status returns. All errors are -ve.
-+ */
-+#define GNTST_okay             (0)  /* Normal return.                        */
-+#define GNTST_general_error    (-1) /* General undefined error.              */
-+#define GNTST_bad_domain       (-2) /* Unrecognsed domain id.                */
-+#define GNTST_bad_gntref       (-3) /* Unrecognised or inappropriate gntref. */
-+#define GNTST_bad_handle       (-4) /* Unrecognised or inappropriate handle. */
-+#define GNTST_bad_virt_addr    (-5) /* Inappropriate virtual address to map. */
-+#define GNTST_bad_dev_addr     (-6) /* Inappropriate device address to unmap.*/
-+#define GNTST_no_device_space  (-7) /* Out of space in I/O MMU.              */
-+#define GNTST_permission_denied (-8) /* Not enough privilege for operation.  */
-+#define GNTST_bad_page         (-9) /* Specified page was invalid for op.    */
-+#define GNTST_bad_copy_arg    (-10) /* copy arguments cross page boundary */
-+
-+#define GNTTABOP_error_msgs {                   \
-+    "okay",                                     \
-+    "undefined error",                          \
-+    "unrecognised domain id",                   \
-+    "invalid grant reference",                  \
-+    "invalid mapping handle",                   \
-+    "invalid virtual address",                  \
-+    "invalid device address",                   \
-+    "no spare translation slot in the I/O MMU", \
-+    "permission denied",                        \
-+    "bad page",                                 \
-+    "copy arguments cross page boundary"        \
-+}
-+
-+#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/hvm/e820.h linux-2.6.16.33/include/xen/interface/hvm/e820.h
---- linux-2.6.16.33-noxen/include/xen/interface/hvm/e820.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/hvm/e820.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,47 @@
-+
-+/*
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ */
-+
-+#ifndef __XEN_PUBLIC_HVM_E820_H__
-+#define __XEN_PUBLIC_HVM_E820_H__
-+
-+/* PC BIOS standard E820 types. */
-+#define E820_RAM          1
-+#define E820_RESERVED     2
-+#define E820_ACPI         3
-+#define E820_NVS          4
-+
-+/* E820 location in HVM virtual address space. */
-+#define E820_MAP_PAGE        0x00090000
-+#define E820_MAP_NR_OFFSET   0x000001E8
-+#define E820_MAP_OFFSET      0x000002D0
-+
-+struct e820entry {
-+    uint64_t addr;
-+    uint64_t size;
-+    uint32_t type;
-+} __attribute__((packed));
-+
-+#define HVM_BELOW_4G_RAM_END        0xF0000000
-+
-+#define HVM_BELOW_4G_MMIO_START     HVM_BELOW_4G_RAM_END
-+#define HVM_BELOW_4G_MMIO_LENGTH    ((1ULL << 32) - HVM_BELOW_4G_MMIO_START)
-+
-+#endif /* __XEN_PUBLIC_HVM_E820_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/hvm/hvm_info_table.h linux-2.6.16.33/include/xen/interface/hvm/hvm_info_table.h
---- linux-2.6.16.33-noxen/include/xen/interface/hvm/hvm_info_table.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/hvm/hvm_info_table.h 2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,41 @@
-+/******************************************************************************
-+ * hvm/hvm_info_table.h
-+ * 
-+ * HVM parameter and information table, written into guest memory map.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ */
-+
-+#ifndef __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__
-+#define __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__
-+
-+#define HVM_INFO_PFN         0x09F
-+#define HVM_INFO_OFFSET      0x800
-+#define HVM_INFO_PADDR       ((HVM_INFO_PFN << 12) + HVM_INFO_OFFSET)
-+
-+struct hvm_info_table {
-+    char        signature[8]; /* "HVM INFO" */
-+    uint32_t    length;
-+    uint8_t     checksum;
-+    uint8_t     acpi_enabled;
-+    uint8_t     apic_mode;
-+    uint32_t    nr_vcpus;
-+};
-+
-+#endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/hvm/hvm_op.h linux-2.6.16.33/include/xen/interface/hvm/hvm_op.h
---- linux-2.6.16.33-noxen/include/xen/interface/hvm/hvm_op.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/hvm/hvm_op.h 2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,53 @@
-+#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__
-+#define __XEN_PUBLIC_HVM_HVM_OP_H__
-+
-+/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */
-+#define HVMOP_set_param           0
-+#define HVMOP_get_param           1
-+struct xen_hvm_param {
-+    domid_t  domid;    /* IN */
-+    uint32_t index;    /* IN */
-+    uint64_t value;    /* IN/OUT */
-+};
-+typedef struct xen_hvm_param xen_hvm_param_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t);
-+
-+/* Set the logical level of one of a domain's PCI INTx wires. */
-+#define HVMOP_set_pci_intx_level  2
-+struct xen_hvm_set_pci_intx_level {
-+    /* Domain to be updated. */
-+    domid_t  domid;
-+    /* PCI INTx identification in PCI topology (domain:bus:device:intx). */
-+    uint8_t  domain, bus, device, intx;
-+    /* Assertion level (0 = unasserted, 1 = asserted). */
-+    uint8_t  level;
-+};
-+typedef struct xen_hvm_set_pci_intx_level xen_hvm_set_pci_intx_level_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t);
-+
-+/* Set the logical level of one of a domain's ISA IRQ wires. */
-+#define HVMOP_set_isa_irq_level   3
-+struct xen_hvm_set_isa_irq_level {
-+    /* Domain to be updated. */
-+    domid_t  domid;
-+    /* ISA device identification, by ISA IRQ (0-15). */
-+    uint8_t  isa_irq;
-+    /* Assertion level (0 = unasserted, 1 = asserted). */
-+    uint8_t  level;
-+};
-+typedef struct xen_hvm_set_isa_irq_level xen_hvm_set_isa_irq_level_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t);
-+
-+#define HVMOP_set_pci_link_route  4
-+struct xen_hvm_set_pci_link_route {
-+    /* Domain to be updated. */
-+    domid_t  domid;
-+    /* PCI link identifier (0-3). */
-+    uint8_t  link;
-+    /* ISA IRQ (1-15), or 0 (disable link). */
-+    uint8_t  isa_irq;
-+};
-+typedef struct xen_hvm_set_pci_link_route xen_hvm_set_pci_link_route_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_link_route_t);
-+
-+#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/hvm/ioreq.h linux-2.6.16.33/include/xen/interface/hvm/ioreq.h
---- linux-2.6.16.33-noxen/include/xen/interface/hvm/ioreq.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/hvm/ioreq.h  2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,97 @@
-+/*
-+ * ioreq.h: I/O request definitions for device models
-+ * Copyright (c) 2004, Intel Corporation.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ */
-+
-+#ifndef _IOREQ_H_
-+#define _IOREQ_H_
-+
-+#define IOREQ_READ      1
-+#define IOREQ_WRITE     0
-+
-+#define STATE_IOREQ_NONE        0
-+#define STATE_IOREQ_READY       1
-+#define STATE_IOREQ_INPROCESS   2
-+#define STATE_IORESP_READY      3
-+
-+#define IOREQ_TYPE_PIO          0 /* pio */
-+#define IOREQ_TYPE_COPY         1 /* mmio ops */
-+#define IOREQ_TYPE_AND          2
-+#define IOREQ_TYPE_OR           3
-+#define IOREQ_TYPE_XOR          4
-+#define IOREQ_TYPE_XCHG         5
-+#define IOREQ_TYPE_ADD          6
-+
-+/*
-+ * VMExit dispatcher should cooperate with instruction decoder to
-+ * prepare this structure and notify service OS and DM by sending
-+ * virq
-+ */
-+struct ioreq {
-+    uint64_t addr;          /*  physical address            */
-+    uint64_t size;          /*  size in bytes               */
-+    uint64_t count;         /*  for rep prefixes            */
-+    uint64_t data;          /*  data (or paddr of data)     */
-+    uint8_t state:4;
-+    uint8_t data_is_ptr:1;  /*  if 1, data above is the guest paddr 
-+                             *   of the real data to use.   */
-+    uint8_t dir:1;          /*  1=read, 0=write             */
-+    uint8_t df:1;
-+    uint8_t type;           /* I/O type                     */
-+    uint64_t io_count;      /* How many IO done on a vcpu   */
-+};
-+typedef struct ioreq ioreq_t;
-+
-+struct vcpu_iodata {
-+    struct ioreq         vp_ioreq;
-+    /* Event channel port */
-+    unsigned int    vp_eport;   /* VMX vcpu uses this to notify DM */
-+};
-+typedef struct vcpu_iodata vcpu_iodata_t;
-+
-+struct shared_iopage {
-+    struct vcpu_iodata   vcpu_iodata[1];
-+};
-+typedef struct shared_iopage shared_iopage_t;
-+
-+#define IOREQ_BUFFER_SLOT_NUM     80
-+struct buffered_iopage {
-+    unsigned long   read_pointer;
-+    unsigned long   write_pointer;
-+    ioreq_t         ioreq[IOREQ_BUFFER_SLOT_NUM];
-+};            /* sizeof this structure must be in one page */
-+typedef struct buffered_iopage buffered_iopage_t;
-+
-+#define ACPI_PM1A_EVT_BLK_ADDRESS           0x0000000000001f40
-+#define ACPI_PM1A_CNT_BLK_ADDRESS           (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
-+#define ACPI_PM_TMR_BLK_ADDRESS             (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
-+
-+#endif /* _IOREQ_H_ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/hvm/params.h linux-2.6.16.33/include/xen/interface/hvm/params.h
---- linux-2.6.16.33-noxen/include/xen/interface/hvm/params.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/hvm/params.h 2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,36 @@
-+
-+/*
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ */
-+
-+#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
-+#define __XEN_PUBLIC_HVM_PARAMS_H__
-+
-+#include "hvm_op.h"
-+
-+/* Parameter space for HVMOP_{set,get}_param. */
-+#define HVM_PARAM_CALLBACK_IRQ 0
-+#define HVM_PARAM_STORE_PFN    1
-+#define HVM_PARAM_STORE_EVTCHN 2
-+#define HVM_PARAM_PAE_ENABLED  4
-+#define HVM_PARAM_IOREQ_PFN    5
-+#define HVM_PARAM_BUFIOREQ_PFN 6
-+#define HVM_NR_PARAMS          7
-+
-+#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/hvm/vmx_assist.h linux-2.6.16.33/include/xen/interface/hvm/vmx_assist.h
---- linux-2.6.16.33-noxen/include/xen/interface/hvm/vmx_assist.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/hvm/vmx_assist.h     2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,116 @@
-+/*
-+ * vmx_assist.h: Context definitions for the VMXASSIST world switch.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Leendert van Doorn, leendert@watson.ibm.com
-+ * Copyright (c) 2005, International Business Machines Corporation.
-+ */
-+
-+#ifndef _VMX_ASSIST_H_
-+#define _VMX_ASSIST_H_
-+
-+#define VMXASSIST_BASE         0xD0000
-+#define VMXASSIST_MAGIC        0x17101966
-+#define VMXASSIST_MAGIC_OFFSET (VMXASSIST_BASE+8)
-+
-+#define VMXASSIST_NEW_CONTEXT (VMXASSIST_BASE + 12)
-+#define VMXASSIST_OLD_CONTEXT (VMXASSIST_NEW_CONTEXT + 4)
-+
-+#ifndef __ASSEMBLY__
-+
-+union vmcs_arbytes {
-+    struct arbyte_fields {
-+        unsigned int seg_type : 4,
-+            s         : 1,
-+            dpl       : 2,
-+            p         : 1,
-+            reserved0 : 4,
-+            avl       : 1,
-+            reserved1 : 1,
-+            default_ops_size: 1,
-+            g         : 1,
-+            null_bit  : 1,
-+            reserved2 : 15;
-+    } fields;
-+    unsigned int bytes;
-+};
-+
-+/*
-+ * World switch state
-+ */
-+struct vmx_assist_context {
-+    uint32_t  eip;        /* execution pointer */
-+    uint32_t  esp;        /* stack pointer */
-+    uint32_t  eflags;     /* flags register */
-+    uint32_t  cr0;
-+    uint32_t  cr3;        /* page table directory */
-+    uint32_t  cr4;
-+    uint32_t  idtr_limit; /* idt */
-+    uint32_t  idtr_base;
-+    uint32_t  gdtr_limit; /* gdt */
-+    uint32_t  gdtr_base;
-+    uint32_t  cs_sel;     /* cs selector */
-+    uint32_t  cs_limit;
-+    uint32_t  cs_base;
-+    union vmcs_arbytes cs_arbytes;
-+    uint32_t  ds_sel;     /* ds selector */
-+    uint32_t  ds_limit;
-+    uint32_t  ds_base;
-+    union vmcs_arbytes ds_arbytes;
-+    uint32_t  es_sel;     /* es selector */
-+    uint32_t  es_limit;
-+    uint32_t  es_base;
-+    union vmcs_arbytes es_arbytes;
-+    uint32_t  ss_sel;     /* ss selector */
-+    uint32_t  ss_limit;
-+    uint32_t  ss_base;
-+    union vmcs_arbytes ss_arbytes;
-+    uint32_t  fs_sel;     /* fs selector */
-+    uint32_t  fs_limit;
-+    uint32_t  fs_base;
-+    union vmcs_arbytes fs_arbytes;
-+    uint32_t  gs_sel;     /* gs selector */
-+    uint32_t  gs_limit;
-+    uint32_t  gs_base;
-+    union vmcs_arbytes gs_arbytes;
-+    uint32_t  tr_sel;     /* task selector */
-+    uint32_t  tr_limit;
-+    uint32_t  tr_base;
-+    union vmcs_arbytes tr_arbytes;
-+    uint32_t  ldtr_sel;   /* ldtr selector */
-+    uint32_t  ldtr_limit;
-+    uint32_t  ldtr_base;
-+    union vmcs_arbytes ldtr_arbytes;
-+};
-+typedef struct vmx_assist_context vmx_assist_context_t;
-+
-+#endif /* __ASSEMBLY__ */
-+
-+#endif /* _VMX_ASSIST_H_ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/blkif.h linux-2.6.16.33/include/xen/interface/io/blkif.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/blkif.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/blkif.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,126 @@
-+/******************************************************************************
-+ * blkif.h
-+ * 
-+ * Unified block-device I/O interface for Xen guest OSes.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2003-2004, Keir Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_IO_BLKIF_H__
-+#define __XEN_PUBLIC_IO_BLKIF_H__
-+
-+#include "ring.h"
-+#include "../grant_table.h"
-+
-+/*
-+ * Front->back notifications: When enqueuing a new request, sending a
-+ * notification can be made conditional on req_event (i.e., the generic
-+ * hold-off mechanism provided by the ring macros). Backends must set
-+ * req_event appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
-+ * 
-+ * Back->front notifications: When enqueuing a new response, sending a
-+ * notification can be made conditional on rsp_event (i.e., the generic
-+ * hold-off mechanism provided by the ring macros). Frontends must set
-+ * rsp_event appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
-+ */
-+
-+#ifndef blkif_vdev_t
-+#define blkif_vdev_t   uint16_t
-+#endif
-+#define blkif_sector_t uint64_t
-+
-+/*
-+ * REQUEST CODES.
-+ */
-+#define BLKIF_OP_READ              0
-+#define BLKIF_OP_WRITE             1
-+/*
-+ * Recognised only if "feature-barrier" is present in backend xenbus info.
-+ * The "feature_barrier" node contains a boolean indicating whether barrier
-+ * requests are likely to succeed or fail. Either way, a barrier request
-+ * may fail at any time with BLKIF_RSP_EOPNOTSUPP if it is unsupported by
-+ * the underlying block-device hardware. The boolean simply indicates whether
-+ * or not it is worthwhile for the frontend to attempt barrier requests.
-+ * If a backend does not recognise BLKIF_OP_WRITE_BARRIER, it should *not*
-+ * create the "feature-barrier" node!
-+ */
-+#define BLKIF_OP_WRITE_BARRIER     2
-+
-+/*
-+ * Maximum scatter/gather segments per request.
-+ * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE.
-+ * NB. This could be 12 if the ring indexes weren't stored in the same page.
-+ */
-+#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
-+
-+struct blkif_request {
-+    uint8_t        operation;    /* BLKIF_OP_???                         */
-+    uint8_t        nr_segments;  /* number of segments                   */
-+    blkif_vdev_t   handle;       /* only for read/write requests         */
-+    uint64_t       id;           /* private guest value, echoed in resp  */
-+    blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
-+    struct blkif_request_segment {
-+        grant_ref_t gref;        /* reference to I/O buffer frame        */
-+        /* @first_sect: first sector in frame to transfer (inclusive).   */
-+        /* @last_sect: last sector in frame to transfer (inclusive).     */
-+        uint8_t     first_sect, last_sect;
-+    } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-+};
-+typedef struct blkif_request blkif_request_t;
-+
-+struct blkif_response {
-+    uint64_t        id;              /* copied from request */
-+    uint8_t         operation;       /* copied from request */
-+    int16_t         status;          /* BLKIF_RSP_???       */
-+};
-+typedef struct blkif_response blkif_response_t;
-+
-+/*
-+ * STATUS RETURN CODES.
-+ */
-+ /* Operation not supported (only happens on barrier writes). */
-+#define BLKIF_RSP_EOPNOTSUPP  -2
-+ /* Operation failed for some unspecified reason (-EIO). */
-+#define BLKIF_RSP_ERROR       -1
-+ /* Operation completed successfully. */
-+#define BLKIF_RSP_OKAY         0
-+
-+/*
-+ * Generate blkif ring structures and types.
-+ */
-+
-+DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);
-+
-+#define VDISK_CDROM        0x1
-+#define VDISK_REMOVABLE    0x2
-+#define VDISK_READONLY     0x4
-+
-+#endif /* __XEN_PUBLIC_IO_BLKIF_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/console.h linux-2.6.16.33/include/xen/interface/io/console.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/console.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/console.h 2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,51 @@
-+/******************************************************************************
-+ * console.h
-+ * 
-+ * Console I/O interface for Xen guest OSes.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2005, Keir Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_IO_CONSOLE_H__
-+#define __XEN_PUBLIC_IO_CONSOLE_H__
-+
-+typedef uint32_t XENCONS_RING_IDX;
-+
-+#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
-+
-+struct xencons_interface {
-+    char in[1024];
-+    char out[2048];
-+    XENCONS_RING_IDX in_cons, in_prod;
-+    XENCONS_RING_IDX out_cons, out_prod;
-+};
-+
-+#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/fbif.h linux-2.6.16.33/include/xen/interface/io/fbif.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/fbif.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/fbif.h    2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,138 @@
-+/*
-+ * fbif.h -- Xen virtual frame buffer device
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
-+ * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_IO_FBIF_H__
-+#define __XEN_PUBLIC_IO_FBIF_H__
-+
-+/* Out events (frontend -> backend) */
-+
-+/*
-+ * Out events may be sent only when requested by backend, and receipt
-+ * of an unknown out event is an error.
-+ */
-+
-+/* Event type 1 currently not used */
-+/*
-+ * Framebuffer update notification event
-+ * Capable frontend sets feature-update in xenstore.
-+ * Backend requests it by setting request-update in xenstore.
-+ */
-+#define XENFB_TYPE_UPDATE 2
-+
-+struct xenfb_update
-+{
-+    uint8_t type;    /* XENFB_TYPE_UPDATE */
-+    int32_t x;      /* source x */
-+    int32_t y;      /* source y */
-+    int32_t width;  /* rect width */
-+    int32_t height; /* rect height */
-+};
-+
-+#define XENFB_OUT_EVENT_SIZE 40
-+
-+union xenfb_out_event
-+{
-+    uint8_t type;
-+    struct xenfb_update update;
-+    char pad[XENFB_OUT_EVENT_SIZE];
-+};
-+
-+/* In events (backend -> frontend) */
-+
-+/*
-+ * Frontends should ignore unknown in events.
-+ * No in events currently defined.
-+ */
-+
-+#define XENFB_IN_EVENT_SIZE 40
-+
-+union xenfb_in_event
-+{
-+    uint8_t type;
-+    char pad[XENFB_IN_EVENT_SIZE];
-+};
-+
-+/* shared page */
-+
-+#define XENFB_IN_RING_SIZE 1024
-+#define XENFB_IN_RING_LEN (XENFB_IN_RING_SIZE / XENFB_IN_EVENT_SIZE)
-+#define XENFB_IN_RING_OFFS 1024
-+#define XENFB_IN_RING(page) \
-+    ((union xenfb_in_event *)((char *)(page) + XENFB_IN_RING_OFFS))
-+#define XENFB_IN_RING_REF(page, idx) \
-+    (XENFB_IN_RING((page))[(idx) % XENFB_IN_RING_LEN])
-+
-+#define XENFB_OUT_RING_SIZE 2048
-+#define XENFB_OUT_RING_LEN (XENFB_OUT_RING_SIZE / XENFB_OUT_EVENT_SIZE)
-+#define XENFB_OUT_RING_OFFS (XENFB_IN_RING_OFFS + XENFB_IN_RING_SIZE)
-+#define XENFB_OUT_RING(page) \
-+    ((union xenfb_out_event *)((char *)(page) + XENFB_OUT_RING_OFFS))
-+#define XENFB_OUT_RING_REF(page, idx) \
-+    (XENFB_OUT_RING((page))[(idx) % XENFB_OUT_RING_LEN])
-+
-+struct xenfb_page
-+{
-+    uint32_t in_cons, in_prod;
-+    uint32_t out_cons, out_prod;
-+
-+    int32_t width;          /* the width of the framebuffer (in pixels) */
-+    int32_t height;         /* the height of the framebuffer (in pixels) */
-+    uint32_t line_length;   /* the length of a row of pixels (in bytes) */
-+    uint32_t mem_length;    /* the length of the framebuffer (in bytes) */
-+    uint8_t depth;          /* the depth of a pixel (in bits) */
-+
-+    /*
-+     * Framebuffer page directory
-+     *
-+     * Each directory page holds PAGE_SIZE / sizeof(*pd)
-+     * framebuffer pages, and can thus map up to PAGE_SIZE *
-+     * PAGE_SIZE / sizeof(*pd) bytes.  With PAGE_SIZE == 4096 and
-+     * sizeof(unsigned long) == 4, that's 4 Megs.  Two directory
-+     * pages should be enough for a while.
-+     */
-+    unsigned long pd[2];
-+};
-+
-+/*
-+ * Wart: xenkbd needs to know resolution.  Put it here until a better
-+ * solution is found, but don't leak it to the backend.
-+ */
-+#ifdef __KERNEL__
-+#define XENFB_WIDTH 800
-+#define XENFB_HEIGHT 600
-+#define XENFB_DEPTH 32
-+#endif
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/kbdif.h linux-2.6.16.33/include/xen/interface/io/kbdif.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/kbdif.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/kbdif.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,130 @@
-+/*
-+ * kbdif.h -- Xen virtual keyboard/mouse
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
-+ * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_IO_KBDIF_H__
-+#define __XEN_PUBLIC_IO_KBDIF_H__
-+
-+/* In events (backend -> frontend) */
-+
-+/*
-+ * Frontends should ignore unknown in events.
-+ */
-+
-+/* Pointer movement event */
-+#define XENKBD_TYPE_MOTION  1
-+/* Event type 2 currently not used */
-+/* Key event (includes pointer buttons) */
-+#define XENKBD_TYPE_KEY     3
-+/*
-+ * Pointer position event
-+ * Capable backend sets feature-abs-pointer in xenstore.
-+ * Frontend requests ot instead of XENKBD_TYPE_MOTION by setting
-+ * request-abs-update in xenstore.
-+ */
-+#define XENKBD_TYPE_POS     4
-+
-+struct xenkbd_motion
-+{
-+    uint8_t type;        /* XENKBD_TYPE_MOTION */
-+    int32_t rel_x;       /* relative X motion */
-+    int32_t rel_y;       /* relative Y motion */
-+};
-+
-+struct xenkbd_key
-+{
-+    uint8_t type;         /* XENKBD_TYPE_KEY */
-+    uint8_t pressed;      /* 1 if pressed; 0 otherwise */
-+    uint32_t keycode;     /* KEY_* from linux/input.h */
-+};
-+
-+struct xenkbd_position
-+{
-+    uint8_t type;        /* XENKBD_TYPE_POS */
-+    int32_t abs_x;       /* absolute X position (in FB pixels) */
-+    int32_t abs_y;       /* absolute Y position (in FB pixels) */
-+};
-+
-+#define XENKBD_IN_EVENT_SIZE 40
-+
-+union xenkbd_in_event
-+{
-+    uint8_t type;
-+    struct xenkbd_motion motion;
-+    struct xenkbd_key key;
-+    struct xenkbd_position pos;
-+    char pad[XENKBD_IN_EVENT_SIZE];
-+};
-+
-+/* Out events (frontend -> backend) */
-+
-+/*
-+ * Out events may be sent only when requested by backend, and receipt
-+ * of an unknown out event is an error.
-+ * No out events currently defined.
-+ */
-+
-+#define XENKBD_OUT_EVENT_SIZE 40
-+
-+union xenkbd_out_event
-+{
-+    uint8_t type;
-+    char pad[XENKBD_OUT_EVENT_SIZE];
-+};
-+
-+/* shared page */
-+
-+#define XENKBD_IN_RING_SIZE 2048
-+#define XENKBD_IN_RING_LEN (XENKBD_IN_RING_SIZE / XENKBD_IN_EVENT_SIZE)
-+#define XENKBD_IN_RING_OFFS 1024
-+#define XENKBD_IN_RING(page) \
-+    ((union xenkbd_in_event *)((char *)(page) + XENKBD_IN_RING_OFFS))
-+#define XENKBD_IN_RING_REF(page, idx) \
-+    (XENKBD_IN_RING((page))[(idx) % XENKBD_IN_RING_LEN])
-+
-+#define XENKBD_OUT_RING_SIZE 1024
-+#define XENKBD_OUT_RING_LEN (XENKBD_OUT_RING_SIZE / XENKBD_OUT_EVENT_SIZE)
-+#define XENKBD_OUT_RING_OFFS (XENKBD_IN_RING_OFFS + XENKBD_IN_RING_SIZE)
-+#define XENKBD_OUT_RING(page) \
-+    ((union xenkbd_out_event *)((char *)(page) + XENKBD_OUT_RING_OFFS))
-+#define XENKBD_OUT_RING_REF(page, idx) \
-+    (XENKBD_OUT_RING((page))[(idx) % XENKBD_OUT_RING_LEN])
-+
-+struct xenkbd_page
-+{
-+    uint32_t in_cons, in_prod;
-+    uint32_t out_cons, out_prod;
-+};
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/netif.h linux-2.6.16.33/include/xen/interface/io/netif.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/netif.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/netif.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,184 @@
-+/******************************************************************************
-+ * netif.h
-+ * 
-+ * Unified network-device I/O interface for Xen guest OSes.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2003-2004, Keir Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_IO_NETIF_H__
-+#define __XEN_PUBLIC_IO_NETIF_H__
-+
-+#include "ring.h"
-+#include "../grant_table.h"
-+
-+/*
-+ * Notifications after enqueuing any type of message should be conditional on
-+ * the appropriate req_event or rsp_event field in the shared ring.
-+ * If the client sends notification for rx requests then it should specify
-+ * feature 'feature-rx-notify' via xenbus. Otherwise the backend will assume
-+ * that it cannot safely queue packets (as it may not be kicked to send them).
-+ */
-+
-+/*
-+ * This is the 'wire' format for packets:
-+ *  Request 1: netif_tx_request -- NETTXF_* (any flags)
-+ * [Request 2: netif_tx_extra]  (only if request 1 has NETTXF_extra_info)
-+ * [Request 3: netif_tx_extra]  (only if request 2 has XEN_NETIF_EXTRA_MORE)
-+ *  Request 4: netif_tx_request -- NETTXF_more_data
-+ *  Request 5: netif_tx_request -- NETTXF_more_data
-+ *  ...
-+ *  Request N: netif_tx_request -- 0
-+ */
-+
-+/* Protocol checksum field is blank in the packet (hardware offload)? */
-+#define _NETTXF_csum_blank     (0)
-+#define  NETTXF_csum_blank     (1U<<_NETTXF_csum_blank)
-+
-+/* Packet data has been validated against protocol checksum. */
-+#define _NETTXF_data_validated (1)
-+#define  NETTXF_data_validated (1U<<_NETTXF_data_validated)
-+
-+/* Packet continues in the next request descriptor. */
-+#define _NETTXF_more_data      (2)
-+#define  NETTXF_more_data      (1U<<_NETTXF_more_data)
-+
-+/* Packet to be followed by extra descriptor(s). */
-+#define _NETTXF_extra_info     (3)
-+#define  NETTXF_extra_info     (1U<<_NETTXF_extra_info)
-+
-+struct netif_tx_request {
-+    grant_ref_t gref;      /* Reference to buffer page */
-+    uint16_t offset;       /* Offset within buffer page */
-+    uint16_t flags;        /* NETTXF_* */
-+    uint16_t id;           /* Echoed in response message. */
-+    uint16_t size;         /* Packet size in bytes.       */
-+};
-+typedef struct netif_tx_request netif_tx_request_t;
-+
-+/* Types of netif_extra_info descriptors. */
-+#define XEN_NETIF_EXTRA_TYPE_NONE  (0)  /* Never used - invalid */
-+#define XEN_NETIF_EXTRA_TYPE_GSO   (1)  /* u.gso */
-+#define XEN_NETIF_EXTRA_TYPE_MAX   (2)
-+
-+/* netif_extra_info flags. */
-+#define _XEN_NETIF_EXTRA_FLAG_MORE (0)
-+#define XEN_NETIF_EXTRA_FLAG_MORE  (1U<<_XEN_NETIF_EXTRA_FLAG_MORE)
-+
-+/* GSO types - only TCPv4 currently supported. */
-+#define XEN_NETIF_GSO_TYPE_TCPV4        (1)
-+
-+/*
-+ * This structure needs to fit within both netif_tx_request and
-+ * netif_rx_response for compatibility.
-+ */
-+struct netif_extra_info {
-+    uint8_t type;  /* XEN_NETIF_EXTRA_TYPE_* */
-+    uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */
-+
-+    union {
-+        struct {
-+            /*
-+             * Maximum payload size of each segment. For example, for TCP this
-+             * is just the path MSS.
-+             */
-+            uint16_t size;
-+
-+            /*
-+             * GSO type. This determines the protocol of the packet and any
-+             * extra features required to segment the packet properly.
-+             */
-+            uint8_t type; /* XEN_NETIF_GSO_TYPE_* */
-+
-+            /* Future expansion. */
-+            uint8_t pad;
-+
-+            /*
-+             * GSO features. This specifies any extra GSO features required
-+             * to process this packet, such as ECN support for TCPv4.
-+             */
-+            uint16_t features; /* XEN_NETIF_GSO_FEAT_* */
-+        } gso;
-+
-+        uint16_t pad[3];
-+    } u;
-+};
-+
-+struct netif_tx_response {
-+    uint16_t id;
-+    int16_t  status;       /* NETIF_RSP_* */
-+};
-+typedef struct netif_tx_response netif_tx_response_t;
-+
-+struct netif_rx_request {
-+    uint16_t    id;        /* Echoed in response message.        */
-+    grant_ref_t gref;      /* Reference to incoming granted frame */
-+};
-+typedef struct netif_rx_request netif_rx_request_t;
-+
-+/* Packet data has been validated against protocol checksum. */
-+#define _NETRXF_data_validated (0)
-+#define  NETRXF_data_validated (1U<<_NETRXF_data_validated)
-+
-+/* Protocol checksum field is blank in the packet (hardware offload)? */
-+#define _NETRXF_csum_blank     (1)
-+#define  NETRXF_csum_blank     (1U<<_NETRXF_csum_blank)
-+
-+/* Packet continues in the next request descriptor. */
-+#define _NETRXF_more_data      (2)
-+#define  NETRXF_more_data      (1U<<_NETRXF_more_data)
-+
-+/* Packet to be followed by extra descriptor(s). */
-+#define _NETRXF_extra_info     (3)
-+#define  NETRXF_extra_info     (1U<<_NETRXF_extra_info)
-+
-+struct netif_rx_response {
-+    uint16_t id;
-+    uint16_t offset;       /* Offset in page of start of received packet  */
-+    uint16_t flags;        /* NETRXF_* */
-+    int16_t  status;       /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */
-+};
-+typedef struct netif_rx_response netif_rx_response_t;
-+
-+/*
-+ * Generate netif ring structures and types.
-+ */
-+
-+DEFINE_RING_TYPES(netif_tx, struct netif_tx_request, struct netif_tx_response);
-+DEFINE_RING_TYPES(netif_rx, struct netif_rx_request, struct netif_rx_response);
-+
-+#define NETIF_RSP_DROPPED         -2
-+#define NETIF_RSP_ERROR           -1
-+#define NETIF_RSP_OKAY             0
-+/* No response: used for auxiliary requests (e.g., netif_tx_extra). */
-+#define NETIF_RSP_NULL             1
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/pciif.h linux-2.6.16.33/include/xen/interface/io/pciif.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/pciif.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/pciif.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,83 @@
-+/*
-+ * PCI Backend/Frontend Common Data Structures & Macros
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#ifndef __XEN_PCI_COMMON_H__
-+#define __XEN_PCI_COMMON_H__
-+
-+/* Be sure to bump this number if you change this file */
-+#define XEN_PCI_MAGIC "7"
-+
-+/* xen_pci_sharedinfo flags */
-+#define _XEN_PCIF_active     (0)
-+#define XEN_PCIF_active      (1<<_XEN_PCI_active)
-+
-+/* xen_pci_op commands */
-+#define XEN_PCI_OP_conf_read    (0)
-+#define XEN_PCI_OP_conf_write   (1)
-+
-+/* xen_pci_op error numbers */
-+#define XEN_PCI_ERR_success          (0)
-+#define XEN_PCI_ERR_dev_not_found   (-1)
-+#define XEN_PCI_ERR_invalid_offset  (-2)
-+#define XEN_PCI_ERR_access_denied   (-3)
-+#define XEN_PCI_ERR_not_implemented (-4)
-+/* XEN_PCI_ERR_op_failed - backend failed to complete the operation */
-+#define XEN_PCI_ERR_op_failed       (-5)
-+
-+struct xen_pci_op {
-+    /* IN: what action to perform: XEN_PCI_OP_* */
-+    uint32_t cmd;
-+
-+    /* OUT: will contain an error number (if any) from errno.h */
-+    int32_t err;
-+
-+    /* IN: which device to touch */
-+    uint32_t domain; /* PCI Domain/Segment */
-+    uint32_t bus;
-+    uint32_t devfn;
-+
-+    /* IN: which configuration registers to touch */
-+    int32_t offset;
-+    int32_t size;
-+
-+    /* IN/OUT: Contains the result after a READ or the value to WRITE */
-+    uint32_t value;
-+};
-+
-+struct xen_pci_sharedinfo {
-+    /* flags - XEN_PCIF_* */
-+    uint32_t flags;
-+    struct xen_pci_op op;
-+};
-+
-+#endif /* __XEN_PCI_COMMON_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/ring.h linux-2.6.16.33/include/xen/interface/io/ring.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/ring.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/ring.h    2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,299 @@
-+/******************************************************************************
-+ * ring.h
-+ * 
-+ * Shared producer-consumer ring macros.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Tim Deegan and Andrew Warfield November 2004.
-+ */
-+
-+#ifndef __XEN_PUBLIC_IO_RING_H__
-+#define __XEN_PUBLIC_IO_RING_H__
-+
-+typedef unsigned int RING_IDX;
-+
-+/* Round a 32-bit unsigned constant down to the nearest power of two. */
-+#define __RD2(_x)  (((_x) & 0x00000002) ? 0x2                  : ((_x) & 0x1))
-+#define __RD4(_x)  (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2    : __RD2(_x))
-+#define __RD8(_x)  (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4    : __RD4(_x))
-+#define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8    : __RD8(_x))
-+#define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x))
-+
-+/*
-+ * Calculate size of a shared ring, given the total available space for the
-+ * ring and indexes (_sz), and the name tag of the request/response structure.
-+ * A ring contains as many entries as will fit, rounded down to the nearest 
-+ * power of two (so we can mask with (size-1) to loop around).
-+ */
-+#define __RING_SIZE(_s, _sz) \
-+    (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
-+
-+/*
-+ * Macros to make the correct C datatypes for a new kind of ring.
-+ * 
-+ * To make a new ring datatype, you need to have two message structures,
-+ * let's say request_t, and response_t already defined.
-+ *
-+ * In a header where you want the ring datatype declared, you then do:
-+ *
-+ *     DEFINE_RING_TYPES(mytag, request_t, response_t);
-+ *
-+ * These expand out to give you a set of types, as you can see below.
-+ * The most important of these are:
-+ * 
-+ *     mytag_sring_t      - The shared ring.
-+ *     mytag_front_ring_t - The 'front' half of the ring.
-+ *     mytag_back_ring_t  - The 'back' half of the ring.
-+ *
-+ * To initialize a ring in your code you need to know the location and size
-+ * of the shared memory area (PAGE_SIZE, for instance). To initialise
-+ * the front half:
-+ *
-+ *     mytag_front_ring_t front_ring;
-+ *     SHARED_RING_INIT((mytag_sring_t *)shared_page);
-+ *     FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
-+ *
-+ * Initializing the back follows similarly (note that only the front
-+ * initializes the shared ring):
-+ *
-+ *     mytag_back_ring_t back_ring;
-+ *     BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
-+ */
-+
-+#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t)                     \
-+                                                                        \
-+/* Shared ring entry */                                                 \
-+union __name##_sring_entry {                                            \
-+    __req_t req;                                                        \
-+    __rsp_t rsp;                                                        \
-+};                                                                      \
-+                                                                        \
-+/* Shared ring page */                                                  \
-+struct __name##_sring {                                                 \
-+    RING_IDX req_prod, req_event;                                       \
-+    RING_IDX rsp_prod, rsp_event;                                       \
-+    uint8_t  pad[48];                                                   \
-+    union __name##_sring_entry ring[1]; /* variable-length */           \
-+};                                                                      \
-+                                                                        \
-+/* "Front" end's private variables */                                   \
-+struct __name##_front_ring {                                            \
-+    RING_IDX req_prod_pvt;                                              \
-+    RING_IDX rsp_cons;                                                  \
-+    unsigned int nr_ents;                                               \
-+    struct __name##_sring *sring;                                       \
-+};                                                                      \
-+                                                                        \
-+/* "Back" end's private variables */                                    \
-+struct __name##_back_ring {                                             \
-+    RING_IDX rsp_prod_pvt;                                              \
-+    RING_IDX req_cons;                                                  \
-+    unsigned int nr_ents;                                               \
-+    struct __name##_sring *sring;                                       \
-+};                                                                      \
-+                                                                        \
-+/* Syntactic sugar */                                                   \
-+typedef struct __name##_sring __name##_sring_t;                         \
-+typedef struct __name##_front_ring __name##_front_ring_t;               \
-+typedef struct __name##_back_ring __name##_back_ring_t
-+
-+/*
-+ * Macros for manipulating rings.
-+ * 
-+ * FRONT_RING_whatever works on the "front end" of a ring: here 
-+ * requests are pushed on to the ring and responses taken off it.
-+ * 
-+ * BACK_RING_whatever works on the "back end" of a ring: here 
-+ * requests are taken off the ring and responses put on.
-+ * 
-+ * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL. 
-+ * This is OK in 1-for-1 request-response situations where the 
-+ * requestor (front end) never has more than RING_SIZE()-1
-+ * outstanding requests.
-+ */
-+
-+/* Initialising empty rings */
-+#define SHARED_RING_INIT(_s) do {                                       \
-+    (_s)->req_prod  = (_s)->rsp_prod  = 0;                              \
-+    (_s)->req_event = (_s)->rsp_event = 1;                              \
-+    memset((_s)->pad, 0, sizeof((_s)->pad));                            \
-+} while(0)
-+
-+#define FRONT_RING_INIT(_r, _s, __size) do {                            \
-+    (_r)->req_prod_pvt = 0;                                             \
-+    (_r)->rsp_cons = 0;                                                 \
-+    (_r)->nr_ents = __RING_SIZE(_s, __size);                            \
-+    (_r)->sring = (_s);                                                 \
-+} while (0)
-+
-+#define BACK_RING_INIT(_r, _s, __size) do {                             \
-+    (_r)->rsp_prod_pvt = 0;                                             \
-+    (_r)->req_cons = 0;                                                 \
-+    (_r)->nr_ents = __RING_SIZE(_s, __size);                            \
-+    (_r)->sring = (_s);                                                 \
-+} while (0)
-+
-+/* Initialize to existing shared indexes -- for recovery */
-+#define FRONT_RING_ATTACH(_r, _s, __size) do {                          \
-+    (_r)->sring = (_s);                                                 \
-+    (_r)->req_prod_pvt = (_s)->req_prod;                                \
-+    (_r)->rsp_cons = (_s)->rsp_prod;                                    \
-+    (_r)->nr_ents = __RING_SIZE(_s, __size);                            \
-+} while (0)
-+
-+#define BACK_RING_ATTACH(_r, _s, __size) do {                           \
-+    (_r)->sring = (_s);                                                 \
-+    (_r)->rsp_prod_pvt = (_s)->rsp_prod;                                \
-+    (_r)->req_cons = (_s)->req_prod;                                    \
-+    (_r)->nr_ents = __RING_SIZE(_s, __size);                            \
-+} while (0)
-+
-+/* How big is this ring? */
-+#define RING_SIZE(_r)                                                   \
-+    ((_r)->nr_ents)
-+
-+/* Number of free requests (for use on front side only). */
-+#define RING_FREE_REQUESTS(_r)                                          \
-+    (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
-+
-+/* Test if there is an empty slot available on the front ring.
-+ * (This is only meaningful from the front. )
-+ */
-+#define RING_FULL(_r)                                                   \
-+    (RING_FREE_REQUESTS(_r) == 0)
-+
-+/* Test if there are outstanding messages to be processed on a ring. */
-+#define RING_HAS_UNCONSUMED_RESPONSES(_r)                               \
-+    ((_r)->sring->rsp_prod - (_r)->rsp_cons)
-+
-+#ifdef __GNUC__
-+#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({                             \
-+    unsigned int req = (_r)->sring->req_prod - (_r)->req_cons;          \
-+    unsigned int rsp = RING_SIZE(_r) -                                  \
-+        ((_r)->req_cons - (_r)->rsp_prod_pvt);                          \
-+    req < rsp ? req : rsp;                                              \
-+})
-+#else
-+/* Same as above, but without the nice GCC ({ ... }) syntax. */
-+#define RING_HAS_UNCONSUMED_REQUESTS(_r)                                \
-+    ((((_r)->sring->req_prod - (_r)->req_cons) <                        \
-+      (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ?        \
-+     ((_r)->sring->req_prod - (_r)->req_cons) :                         \
-+     (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
-+#endif
-+
-+/* Direct access to individual ring elements, by index. */
-+#define RING_GET_REQUEST(_r, _idx)                                      \
-+    (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
-+
-+#define RING_GET_RESPONSE(_r, _idx)                                     \
-+    (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
-+
-+/* Loop termination condition: Would the specified index overflow the ring? */
-+#define RING_REQUEST_CONS_OVERFLOW(_r, _cons)                           \
-+    (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
-+
-+#define RING_PUSH_REQUESTS(_r) do {                                     \
-+    wmb(); /* back sees requests /before/ updated producer index */     \
-+    (_r)->sring->req_prod = (_r)->req_prod_pvt;                         \
-+} while (0)
-+
-+#define RING_PUSH_RESPONSES(_r) do {                                    \
-+    wmb(); /* front sees responses /before/ updated producer index */   \
-+    (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt;                         \
-+} while (0)
-+
-+/*
-+ * Notification hold-off (req_event and rsp_event):
-+ * 
-+ * When queueing requests or responses on a shared ring, it may not always be
-+ * necessary to notify the remote end. For example, if requests are in flight
-+ * in a backend, the front may be able to queue further requests without
-+ * notifying the back (if the back checks for new requests when it queues
-+ * responses).
-+ * 
-+ * When enqueuing requests or responses:
-+ * 
-+ *  Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument
-+ *  is a boolean return value. True indicates that the receiver requires an
-+ *  asynchronous notification.
-+ * 
-+ * After dequeuing requests or responses (before sleeping the connection):
-+ * 
-+ *  Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES().
-+ *  The second argument is a boolean return value. True indicates that there
-+ *  are pending messages on the ring (i.e., the connection should not be put
-+ *  to sleep).
-+ * 
-+ *  These macros will set the req_event/rsp_event field to trigger a
-+ *  notification on the very next message that is enqueued. If you want to
-+ *  create batches of work (i.e., only receive a notification after several
-+ *  messages have been enqueued) then you will need to create a customised
-+ *  version of the FINAL_CHECK macro in your own code, which sets the event
-+ *  field appropriately.
-+ */
-+
-+#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do {           \
-+    RING_IDX __old = (_r)->sring->req_prod;                             \
-+    RING_IDX __new = (_r)->req_prod_pvt;                                \
-+    wmb(); /* back sees requests /before/ updated producer index */     \
-+    (_r)->sring->req_prod = __new;                                      \
-+    mb(); /* back sees new requests /before/ we check req_event */      \
-+    (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) <           \
-+                 (RING_IDX)(__new - __old));                            \
-+} while (0)
-+
-+#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do {          \
-+    RING_IDX __old = (_r)->sring->rsp_prod;                             \
-+    RING_IDX __new = (_r)->rsp_prod_pvt;                                \
-+    wmb(); /* front sees responses /before/ updated producer index */   \
-+    (_r)->sring->rsp_prod = __new;                                      \
-+    mb(); /* front sees new responses /before/ we check rsp_event */    \
-+    (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) <           \
-+                 (RING_IDX)(__new - __old));                            \
-+} while (0)
-+
-+#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do {             \
-+    (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r);                   \
-+    if (_work_to_do) break;                                             \
-+    (_r)->sring->req_event = (_r)->req_cons + 1;                        \
-+    mb();                                                               \
-+    (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r);                   \
-+} while (0)
-+
-+#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do {            \
-+    (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r);                  \
-+    if (_work_to_do) break;                                             \
-+    (_r)->sring->rsp_event = (_r)->rsp_cons + 1;                        \
-+    mb();                                                               \
-+    (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r);                  \
-+} while (0)
-+
-+#endif /* __XEN_PUBLIC_IO_RING_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/tpmif.h linux-2.6.16.33/include/xen/interface/io/tpmif.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/tpmif.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/tpmif.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,77 @@
-+/******************************************************************************
-+ * tpmif.h
-+ *
-+ * TPM I/O interface for Xen guest OSes.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2005, IBM Corporation
-+ *
-+ * Author: Stefan Berger, stefanb@us.ibm.com
-+ * Grant table support: Mahadevan Gomathisankaran
-+ *
-+ * This code has been derived from tools/libxc/xen/io/netif.h
-+ *
-+ * Copyright (c) 2003-2004, Keir Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_IO_TPMIF_H__
-+#define __XEN_PUBLIC_IO_TPMIF_H__
-+
-+#include "../grant_table.h"
-+
-+struct tpmif_tx_request {
-+    unsigned long addr;   /* Machine address of packet.   */
-+    grant_ref_t ref;      /* grant table access reference */
-+    uint16_t unused;
-+    uint16_t size;        /* Packet size in bytes.        */
-+};
-+typedef struct tpmif_tx_request tpmif_tx_request_t;
-+
-+/*
-+ * The TPMIF_TX_RING_SIZE defines the number of pages the
-+ * front-end and backend can exchange (= size of array).
-+ */
-+typedef uint32_t TPMIF_RING_IDX;
-+
-+#define TPMIF_TX_RING_SIZE 10
-+
-+/* This structure must fit in a memory page. */
-+
-+struct tpmif_ring {
-+    struct tpmif_tx_request req;
-+};
-+typedef struct tpmif_ring tpmif_ring_t;
-+
-+struct tpmif_tx_interface {
-+    struct tpmif_ring ring[TPMIF_TX_RING_SIZE];
-+};
-+typedef struct tpmif_tx_interface tpmif_tx_interface_t;
-+
-+#endif
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/xenbus.h linux-2.6.16.33/include/xen/interface/io/xenbus.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/xenbus.h    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/xenbus.h  2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,73 @@
-+/*****************************************************************************
-+ * xenbus.h
-+ *
-+ * Xenbus protocol details.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (C) 2005 XenSource Ltd.
-+ */
-+
-+#ifndef _XEN_PUBLIC_IO_XENBUS_H
-+#define _XEN_PUBLIC_IO_XENBUS_H
-+
-+/*
-+ * The state of either end of the Xenbus, i.e. the current communication
-+ * status of initialisation across the bus.  States here imply nothing about
-+ * the state of the connection between the driver and the kernel's device
-+ * layers.
-+ */
-+enum xenbus_state {
-+    XenbusStateUnknown       = 0,
-+
-+    XenbusStateInitialising  = 1,
-+
-+    /*
-+     * InitWait: Finished early initialisation but waiting for information
-+     * from the peer or hotplug scripts.
-+     */
-+    XenbusStateInitWait      = 2,
-+
-+    /*
-+     * Initialised: Waiting for a connection from the peer.
-+     */
-+    XenbusStateInitialised   = 3,
-+
-+    XenbusStateConnected     = 4,
-+
-+    /*
-+     * Closing: The device is being closed due to an error or an unplug event.
-+     */
-+    XenbusStateClosing       = 5,
-+
-+    XenbusStateClosed        = 6
-+};
-+typedef enum xenbus_state XenbusState;
-+
-+#endif /* _XEN_PUBLIC_IO_XENBUS_H */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/io/xs_wire.h linux-2.6.16.33/include/xen/interface/io/xs_wire.h
---- linux-2.6.16.33-noxen/include/xen/interface/io/xs_wire.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/io/xs_wire.h 2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,116 @@
-+/*
-+ * Details of the "wire" protocol between Xen Store Daemon and client
-+ * library or guest kernel.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (C) 2005 Rusty Russell IBM Corporation
-+ */
-+
-+#ifndef _XS_WIRE_H
-+#define _XS_WIRE_H
-+
-+enum xsd_sockmsg_type
-+{
-+    XS_DEBUG,
-+    XS_DIRECTORY,
-+    XS_READ,
-+    XS_GET_PERMS,
-+    XS_WATCH,
-+    XS_UNWATCH,
-+    XS_TRANSACTION_START,
-+    XS_TRANSACTION_END,
-+    XS_INTRODUCE,
-+    XS_RELEASE,
-+    XS_GET_DOMAIN_PATH,
-+    XS_WRITE,
-+    XS_MKDIR,
-+    XS_RM,
-+    XS_SET_PERMS,
-+    XS_WATCH_EVENT,
-+    XS_ERROR,
-+    XS_IS_DOMAIN_INTRODUCED
-+};
-+
-+#define XS_WRITE_NONE "NONE"
-+#define XS_WRITE_CREATE "CREATE"
-+#define XS_WRITE_CREATE_EXCL "CREATE|EXCL"
-+
-+/* We hand errors as strings, for portability. */
-+struct xsd_errors
-+{
-+    int errnum;
-+    const char *errstring;
-+};
-+#define XSD_ERROR(x) { x, #x }
-+static struct xsd_errors xsd_errors[] __attribute__((unused)) = {
-+    XSD_ERROR(EINVAL),
-+    XSD_ERROR(EACCES),
-+    XSD_ERROR(EEXIST),
-+    XSD_ERROR(EISDIR),
-+    XSD_ERROR(ENOENT),
-+    XSD_ERROR(ENOMEM),
-+    XSD_ERROR(ENOSPC),
-+    XSD_ERROR(EIO),
-+    XSD_ERROR(ENOTEMPTY),
-+    XSD_ERROR(ENOSYS),
-+    XSD_ERROR(EROFS),
-+    XSD_ERROR(EBUSY),
-+    XSD_ERROR(EAGAIN),
-+    XSD_ERROR(EISCONN)
-+};
-+
-+struct xsd_sockmsg
-+{
-+    uint32_t type;  /* XS_??? */
-+    uint32_t req_id;/* Request identifier, echoed in daemon's response.  */
-+    uint32_t tx_id; /* Transaction id (0 if not related to a transaction). */
-+    uint32_t len;   /* Length of data following this. */
-+
-+    /* Generally followed by nul-terminated string(s). */
-+};
-+
-+enum xs_watch_type
-+{
-+    XS_WATCH_PATH = 0,
-+    XS_WATCH_TOKEN
-+};
-+
-+/* Inter-domain shared memory communications. */
-+#define XENSTORE_RING_SIZE 1024
-+typedef uint32_t XENSTORE_RING_IDX;
-+#define MASK_XENSTORE_IDX(idx) ((idx) & (XENSTORE_RING_SIZE-1))
-+struct xenstore_domain_interface {
-+    char req[XENSTORE_RING_SIZE]; /* Requests to xenstore daemon. */
-+    char rsp[XENSTORE_RING_SIZE]; /* Replies and async watch events. */
-+    XENSTORE_RING_IDX req_cons, req_prod;
-+    XENSTORE_RING_IDX rsp_cons, rsp_prod;
-+};
-+
-+#endif /* _XS_WIRE_H */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/kexec.h linux-2.6.16.33/include/xen/interface/kexec.h
---- linux-2.6.16.33-noxen/include/xen/interface/kexec.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/kexec.h      2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,137 @@
-+/******************************************************************************
-+ * kexec.h - Public portion
-+ * 
-+ * Xen port written by:
-+ * - Simon 'Horms' Horman <horms@verge.net.au>
-+ * - Magnus Damm <magnus@valinux.co.jp>
-+ */
-+
-+#ifndef _XEN_PUBLIC_KEXEC_H
-+#define _XEN_PUBLIC_KEXEC_H
-+
-+
-+/* This file describes the Kexec / Kdump hypercall interface for Xen.
-+ *
-+ * Kexec under vanilla Linux allows a user to reboot the physical machine 
-+ * into a new user-specified kernel. The Xen port extends this idea
-+ * to allow rebooting of the machine from dom0. When kexec for dom0
-+ * is used to reboot,  both the hypervisor and the domains get replaced
-+ * with some other kernel. It is possible to kexec between vanilla
-+ * Linux and Xen and back again. Xen to Xen works well too.
-+ *
-+ * The hypercall interface for kexec can be divided into three main
-+ * types of hypercall operations:
-+ *
-+ * 1) Range information:
-+ *    This is used by the dom0 kernel to ask the hypervisor about various 
-+ *    address information. This information is needed to allow kexec-tools 
-+ *    to fill in the ELF headers for /proc/vmcore properly.
-+ *
-+ * 2) Load and unload of images:
-+ *    There are no big surprises here, the kexec binary from kexec-tools
-+ *    runs in userspace in dom0. The tool loads/unloads data into the
-+ *    dom0 kernel such as new kernel, initramfs and hypervisor. When
-+ *    loaded the dom0 kernel performs a load hypercall operation, and
-+ *    before releasing all page references the dom0 kernel calls unload.
-+ *
-+ * 3) Kexec operation:
-+ *    This is used to start a previously loaded kernel.
-+ */
-+
-+#include "xen.h"
-+
-+#if defined(__i386__) || defined(__x86_64__)
-+#define KEXEC_XEN_NO_PAGES 17
-+#endif
-+
-+/*
-+ * Prototype for this hypercall is:
-+ *  int kexec_op(int cmd, void *args)
-+ * @cmd  == KEXEC_CMD_... 
-+ *          KEXEC operation to perform
-+ * @args == Operation-specific extra arguments (NULL if none).
-+ */
-+
-+/*
-+ * Kexec supports two types of operation:
-+ * - kexec into a regular kernel, very similar to a standard reboot
-+ *   - KEXEC_TYPE_DEFAULT is used to specify this type
-+ * - kexec into a special "crash kernel", aka kexec-on-panic
-+ *   - KEXEC_TYPE_CRASH is used to specify this type
-+ *   - parts of our system may be broken at kexec-on-panic time
-+ *     - the code should be kept as simple and self-contained as possible
-+ */
-+
-+#define KEXEC_TYPE_DEFAULT 0
-+#define KEXEC_TYPE_CRASH   1
-+
-+
-+/* The kexec implementation for Xen allows the user to load two
-+ * types of kernels, KEXEC_TYPE_DEFAULT and KEXEC_TYPE_CRASH.
-+ * All data needed for a kexec reboot is kept in one xen_kexec_image_t
-+ * per "instance". The data mainly consists of machine address lists to pages
-+ * together with destination addresses. The data in xen_kexec_image_t
-+ * is passed to the "code page" which is one page of code that performs
-+ * the final relocations before jumping to the new kernel.
-+ */
-+ 
-+typedef struct xen_kexec_image {
-+#if defined(__i386__) || defined(__x86_64__)
-+    unsigned long page_list[KEXEC_XEN_NO_PAGES];
-+#endif
-+    unsigned long indirection_page;
-+    unsigned long start_address;
-+} xen_kexec_image_t;
-+
-+/*
-+ * Perform kexec having previously loaded a kexec or kdump kernel
-+ * as appropriate.
-+ * type == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH [in]
-+ */
-+#define KEXEC_CMD_kexec                 0
-+typedef struct xen_kexec_exec {
-+    int type;
-+} xen_kexec_exec_t;
-+
-+/*
-+ * Load/Unload kernel image for kexec or kdump.
-+ * type  == KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH [in]
-+ * image == relocation information for kexec (ignored for unload) [in]
-+ */
-+#define KEXEC_CMD_kexec_load            1
-+#define KEXEC_CMD_kexec_unload          2
-+typedef struct xen_kexec_load {
-+    int type;
-+    xen_kexec_image_t image;
-+} xen_kexec_load_t;
-+
-+#define KEXEC_RANGE_MA_CRASH 0   /* machine address and size of crash area */
-+#define KEXEC_RANGE_MA_XEN   1   /* machine address and size of Xen itself */
-+#define KEXEC_RANGE_MA_CPU   2   /* machine address and size of a CPU note */
-+
-+/*
-+ * Find the address and size of certain memory areas
-+ * range == KEXEC_RANGE_... [in]
-+ * nr    == physical CPU number (starting from 0) if KEXEC_RANGE_MA_CPU [in]
-+ * size  == number of bytes reserved in window [out]
-+ * start == address of the first byte in the window [out]
-+ */
-+#define KEXEC_CMD_kexec_get_range       3
-+typedef struct xen_kexec_range {
-+    int range;
-+    int nr;
-+    unsigned long size;
-+    unsigned long start;
-+} xen_kexec_range_t;
-+
-+#endif /* _XEN_PUBLIC_KEXEC_H */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/memory.h linux-2.6.16.33/include/xen/interface/memory.h
---- linux-2.6.16.33-noxen/include/xen/interface/memory.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/memory.h     2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,276 @@
-+/******************************************************************************
-+ * memory.h
-+ * 
-+ * Memory reservation and information.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_MEMORY_H__
-+#define __XEN_PUBLIC_MEMORY_H__
-+
-+/*
-+ * Increase or decrease the specified domain's memory reservation. Returns the
-+ * number of extents successfully allocated or freed.
-+ * arg == addr of struct xen_memory_reservation.
-+ */
-+#define XENMEM_increase_reservation 0
-+#define XENMEM_decrease_reservation 1
-+#define XENMEM_populate_physmap     6
-+struct xen_memory_reservation {
-+
-+    /*
-+     * XENMEM_increase_reservation:
-+     *   OUT: MFN (*not* GMFN) bases of extents that were allocated
-+     * XENMEM_decrease_reservation:
-+     *   IN:  GMFN bases of extents to free
-+     * XENMEM_populate_physmap:
-+     *   IN:  GPFN bases of extents to populate with memory
-+     *   OUT: GMFN bases of extents that were allocated
-+     *   (NB. This command also updates the mach_to_phys translation table)
-+     */
-+    XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
-+
-+    /* Number of extents, and size/alignment of each (2^extent_order pages). */
-+    xen_ulong_t    nr_extents;
-+    unsigned int   extent_order;
-+
-+    /*
-+     * Maximum # bits addressable by the user of the allocated region (e.g., 
-+     * I/O devices often have a 32-bit limitation even in 64-bit systems). If 
-+     * zero then the user has no addressing restriction.
-+     * This field is not used by XENMEM_decrease_reservation.
-+     */
-+    unsigned int   address_bits;
-+
-+    /*
-+     * Domain whose reservation is being changed.
-+     * Unprivileged domains can specify only DOMID_SELF.
-+     */
-+    domid_t        domid;
-+};
-+typedef struct xen_memory_reservation xen_memory_reservation_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t);
-+
-+/*
-+ * An atomic exchange of memory pages. If return code is zero then
-+ * @out.extent_list provides GMFNs of the newly-allocated memory.
-+ * Returns zero on complete success, otherwise a negative error code.
-+ * On complete success then always @nr_exchanged == @in.nr_extents.
-+ * On partial success @nr_exchanged indicates how much work was done.
-+ */
-+#define XENMEM_exchange             11
-+struct xen_memory_exchange {
-+    /*
-+     * [IN] Details of memory extents to be exchanged (GMFN bases).
-+     * Note that @in.address_bits is ignored and unused.
-+     */
-+    struct xen_memory_reservation in;
-+
-+    /*
-+     * [IN/OUT] Details of new memory extents.
-+     * We require that:
-+     *  1. @in.domid == @out.domid
-+     *  2. @in.nr_extents  << @in.extent_order == 
-+     *     @out.nr_extents << @out.extent_order
-+     *  3. @in.extent_start and @out.extent_start lists must not overlap
-+     *  4. @out.extent_start lists GPFN bases to be populated
-+     *  5. @out.extent_start is overwritten with allocated GMFN bases
-+     */
-+    struct xen_memory_reservation out;
-+
-+    /*
-+     * [OUT] Number of input extents that were successfully exchanged:
-+     *  1. The first @nr_exchanged input extents were successfully
-+     *     deallocated.
-+     *  2. The corresponding first entries in the output extent list correctly
-+     *     indicate the GMFNs that were successfully exchanged.
-+     *  3. All other input and output extents are untouched.
-+     *  4. If not all input exents are exchanged then the return code of this
-+     *     command will be non-zero.
-+     *  5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
-+     */
-+    xen_ulong_t nr_exchanged;
-+};
-+typedef struct xen_memory_exchange xen_memory_exchange_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t);
-+
-+/*
-+ * Returns the maximum machine frame number of mapped RAM in this system.
-+ * This command always succeeds (it never returns an error code).
-+ * arg == NULL.
-+ */
-+#define XENMEM_maximum_ram_page     2
-+
-+/*
-+ * Returns the current or maximum memory reservation, in pages, of the
-+ * specified domain (may be DOMID_SELF). Returns -ve errcode on failure.
-+ * arg == addr of domid_t.
-+ */
-+#define XENMEM_current_reservation  3
-+#define XENMEM_maximum_reservation  4
-+
-+/*
-+ * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
-+ * mapping table. Architectures which do not have a m2p table do not implement
-+ * this command.
-+ * arg == addr of xen_machphys_mfn_list_t.
-+ */
-+#define XENMEM_machphys_mfn_list    5
-+struct xen_machphys_mfn_list {
-+    /*
-+     * Size of the 'extent_start' array. Fewer entries will be filled if the
-+     * machphys table is smaller than max_extents * 2MB.
-+     */
-+    unsigned int max_extents;
-+
-+    /*
-+     * Pointer to buffer to fill with list of extent starts. If there are
-+     * any large discontiguities in the machine address space, 2MB gaps in
-+     * the machphys table will be represented by an MFN base of zero.
-+     */
-+    XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
-+
-+    /*
-+     * Number of extents written to the above array. This will be smaller
-+     * than 'max_extents' if the machphys table is smaller than max_e * 2MB.
-+     */
-+    unsigned int nr_extents;
-+};
-+typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t);
-+
-+/*
-+ * Returns the location in virtual address space of the machine_to_phys
-+ * mapping table. Architectures which do not have a m2p table, or which do not
-+ * map it by default into guest address space, do not implement this command.
-+ * arg == addr of xen_machphys_mapping_t.
-+ */
-+#define XENMEM_machphys_mapping     12
-+struct xen_machphys_mapping {
-+    xen_ulong_t v_start, v_end; /* Start and end virtual addresses.   */
-+    xen_ulong_t max_mfn;        /* Maximum MFN that can be looked up. */
-+};
-+typedef struct xen_machphys_mapping xen_machphys_mapping_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
-+
-+/*
-+ * Sets the GPFN at which a particular page appears in the specified guest's
-+ * pseudophysical address space.
-+ * arg == addr of xen_add_to_physmap_t.
-+ */
-+#define XENMEM_add_to_physmap      7
-+struct xen_add_to_physmap {
-+    /* Which domain to change the mapping for. */
-+    domid_t domid;
-+
-+    /* Source mapping space. */
-+#define XENMAPSPACE_shared_info 0 /* shared info page */
-+#define XENMAPSPACE_grant_table 1 /* grant table page */
-+    unsigned int space;
-+
-+    /* Index into source mapping space. */
-+    xen_ulong_t idx;
-+
-+    /* GPFN where the source mapping page should appear. */
-+    xen_pfn_t     gpfn;
-+};
-+typedef struct xen_add_to_physmap xen_add_to_physmap_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);
-+
-+/*
-+ * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error
-+ * code on failure. This call only works for auto-translated guests.
-+ */
-+#define XENMEM_translate_gpfn_list  8
-+struct xen_translate_gpfn_list {
-+    /* Which domain to translate for? */
-+    domid_t domid;
-+
-+    /* Length of list. */
-+    xen_ulong_t nr_gpfns;
-+
-+    /* List of GPFNs to translate. */
-+    XEN_GUEST_HANDLE(xen_pfn_t) gpfn_list;
-+
-+    /*
-+     * Output list to contain MFN translations. May be the same as the input
-+     * list (in which case each input GPFN is overwritten with the output MFN).
-+     */
-+    XEN_GUEST_HANDLE(xen_pfn_t) mfn_list;
-+};
-+typedef struct xen_translate_gpfn_list xen_translate_gpfn_list_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_translate_gpfn_list_t);
-+
-+/*
-+ * Returns the pseudo-physical memory map as it was when the domain
-+ * was started (specified by XENMEM_set_memory_map).
-+ * arg == addr of xen_memory_map_t.
-+ */
-+#define XENMEM_memory_map           9
-+struct xen_memory_map {
-+    /*
-+     * On call the number of entries which can be stored in buffer. On
-+     * return the number of entries which have been stored in
-+     * buffer.
-+     */
-+    unsigned int nr_entries;
-+
-+    /*
-+     * Entries in the buffer are in the same format as returned by the
-+     * BIOS INT 0x15 EAX=0xE820 call.
-+     */
-+    XEN_GUEST_HANDLE(void) buffer;
-+};
-+typedef struct xen_memory_map xen_memory_map_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t);
-+
-+/*
-+ * Returns the real physical memory map. Passes the same structure as
-+ * XENMEM_memory_map.
-+ * arg == addr of xen_memory_map_t.
-+ */
-+#define XENMEM_machine_memory_map   10
-+
-+/*
-+ * Set the pseudo-physical memory map of a domain, as returned by
-+ * XENMEM_memory_map.
-+ * arg == addr of xen_foreign_memory_map_t.
-+ */
-+#define XENMEM_set_memory_map       13
-+struct xen_foreign_memory_map {
-+    domid_t domid;
-+    struct xen_memory_map map;
-+};
-+typedef struct xen_foreign_memory_map xen_foreign_memory_map_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t);
-+
-+#endif /* __XEN_PUBLIC_MEMORY_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/nmi.h linux-2.6.16.33/include/xen/interface/nmi.h
---- linux-2.6.16.33-noxen/include/xen/interface/nmi.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/nmi.h        2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,78 @@
-+/******************************************************************************
-+ * nmi.h
-+ * 
-+ * NMI callback registration and reason codes.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_NMI_H__
-+#define __XEN_PUBLIC_NMI_H__
-+
-+/*
-+ * NMI reason codes:
-+ * Currently these are x86-specific, stored in arch_shared_info.nmi_reason.
-+ */
-+ /* I/O-check error reported via ISA port 0x61, bit 6. */
-+#define _XEN_NMIREASON_io_error     0
-+#define XEN_NMIREASON_io_error      (1UL << _XEN_NMIREASON_io_error)
-+ /* Parity error reported via ISA port 0x61, bit 7. */
-+#define _XEN_NMIREASON_parity_error 1
-+#define XEN_NMIREASON_parity_error  (1UL << _XEN_NMIREASON_parity_error)
-+ /* Unknown hardware-generated NMI. */
-+#define _XEN_NMIREASON_unknown      2
-+#define XEN_NMIREASON_unknown       (1UL << _XEN_NMIREASON_unknown)
-+
-+/*
-+ * long nmi_op(unsigned int cmd, void *arg)
-+ * NB. All ops return zero on success, else a negative error code.
-+ */
-+
-+/*
-+ * Register NMI callback for this (calling) VCPU. Currently this only makes
-+ * sense for domain 0, vcpu 0. All other callers will be returned EINVAL.
-+ * arg == pointer to xennmi_callback structure.
-+ */
-+#define XENNMI_register_callback   0
-+struct xennmi_callback {
-+    unsigned long handler_address;
-+    unsigned long pad;
-+};
-+typedef struct xennmi_callback xennmi_callback_t;
-+DEFINE_XEN_GUEST_HANDLE(xennmi_callback_t);
-+
-+/*
-+ * Deregister NMI callback for this (calling) VCPU.
-+ * arg == NULL.
-+ */
-+#define XENNMI_unregister_callback 1
-+
-+#endif /* __XEN_PUBLIC_NMI_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/physdev.h linux-2.6.16.33/include/xen/interface/physdev.h
---- linux-2.6.16.33-noxen/include/xen/interface/physdev.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/physdev.h    2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,169 @@
-+/*
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ */
-+
-+#ifndef __XEN_PUBLIC_PHYSDEV_H__
-+#define __XEN_PUBLIC_PHYSDEV_H__
-+
-+/*
-+ * Prototype for this hypercall is:
-+ *  int physdev_op(int cmd, void *args)
-+ * @cmd  == PHYSDEVOP_??? (physdev operation).
-+ * @args == Operation-specific extra arguments (NULL if none).
-+ */
-+
-+/*
-+ * Notify end-of-interrupt (EOI) for the specified IRQ.
-+ * @arg == pointer to physdev_eoi structure.
-+ */
-+#define PHYSDEVOP_eoi                   12
-+struct physdev_eoi {
-+    /* IN */
-+    uint32_t irq;
-+};
-+typedef struct physdev_eoi physdev_eoi_t;
-+DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
-+
-+/*
-+ * Query the status of an IRQ line.
-+ * @arg == pointer to physdev_irq_status_query structure.
-+ */
-+#define PHYSDEVOP_irq_status_query       5
-+struct physdev_irq_status_query {
-+    /* IN */
-+    uint32_t irq;
-+    /* OUT */
-+    uint32_t flags; /* XENIRQSTAT_* */
-+};
-+typedef struct physdev_irq_status_query physdev_irq_status_query_t;
-+DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);
-+
-+/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
-+#define _XENIRQSTAT_needs_eoi   (0)
-+#define  XENIRQSTAT_needs_eoi   (1U<<_XENIRQSTAT_needs_eoi)
-+
-+/* IRQ shared by multiple guests? */
-+#define _XENIRQSTAT_shared      (1)
-+#define  XENIRQSTAT_shared      (1U<<_XENIRQSTAT_shared)
-+
-+/*
-+ * Set the current VCPU's I/O privilege level.
-+ * @arg == pointer to physdev_set_iopl structure.
-+ */
-+#define PHYSDEVOP_set_iopl               6
-+struct physdev_set_iopl {
-+    /* IN */
-+    uint32_t iopl;
-+};
-+typedef struct physdev_set_iopl physdev_set_iopl_t;
-+DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);
-+
-+/*
-+ * Set the current VCPU's I/O-port permissions bitmap.
-+ * @arg == pointer to physdev_set_iobitmap structure.
-+ */
-+#define PHYSDEVOP_set_iobitmap           7
-+struct physdev_set_iobitmap {
-+    /* IN */
-+    XEN_GUEST_HANDLE_00030205(uint8_t) bitmap;
-+    uint32_t nr_ports;
-+};
-+typedef struct physdev_set_iobitmap physdev_set_iobitmap_t;
-+DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);
-+
-+/*
-+ * Read or write an IO-APIC register.
-+ * @arg == pointer to physdev_apic structure.
-+ */
-+#define PHYSDEVOP_apic_read              8
-+#define PHYSDEVOP_apic_write             9
-+struct physdev_apic {
-+    /* IN */
-+    unsigned long apic_physbase;
-+    uint32_t reg;
-+    /* IN or OUT */
-+    uint32_t value;
-+};
-+typedef struct physdev_apic physdev_apic_t;
-+DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);
-+
-+/*
-+ * Allocate or free a physical upcall vector for the specified IRQ line.
-+ * @arg == pointer to physdev_irq structure.
-+ */
-+#define PHYSDEVOP_alloc_irq_vector      10
-+#define PHYSDEVOP_free_irq_vector       11
-+struct physdev_irq {
-+    /* IN */
-+    uint32_t irq;
-+    /* IN or OUT */
-+    uint32_t vector;
-+};
-+typedef struct physdev_irq physdev_irq_t;
-+DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
-+
-+/*
-+ * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
-+ * hypercall since 0x00030202.
-+ */
-+struct physdev_op {
-+    uint32_t cmd;
-+    union {
-+        struct physdev_irq_status_query      irq_status_query;
-+        struct physdev_set_iopl              set_iopl;
-+        struct physdev_set_iobitmap          set_iobitmap;
-+        struct physdev_apic                  apic_op;
-+        struct physdev_irq                   irq_op;
-+    } u;
-+};
-+typedef struct physdev_op physdev_op_t;
-+DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
-+
-+/*
-+ * Notify that some PIRQ-bound event channels have been unmasked.
-+ * ** This command is obsolete since interface version 0x00030202 and is **
-+ * ** unsupported by newer versions of Xen.                              **
-+ */
-+#define PHYSDEVOP_IRQ_UNMASK_NOTIFY      4
-+
-+/*
-+ * These all-capitals physdev operation names are superceded by the new names
-+ * (defined above) since interface version 0x00030202.
-+ */
-+#define PHYSDEVOP_IRQ_STATUS_QUERY       PHYSDEVOP_irq_status_query
-+#define PHYSDEVOP_SET_IOPL               PHYSDEVOP_set_iopl
-+#define PHYSDEVOP_SET_IOBITMAP           PHYSDEVOP_set_iobitmap
-+#define PHYSDEVOP_APIC_READ              PHYSDEVOP_apic_read
-+#define PHYSDEVOP_APIC_WRITE             PHYSDEVOP_apic_write
-+#define PHYSDEVOP_ASSIGN_VECTOR          PHYSDEVOP_alloc_irq_vector
-+#define PHYSDEVOP_FREE_VECTOR            PHYSDEVOP_free_irq_vector
-+#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi
-+#define PHYSDEVOP_IRQ_SHARED             XENIRQSTAT_shared
-+
-+#endif /* __XEN_PUBLIC_PHYSDEV_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/platform.h linux-2.6.16.33/include/xen/interface/platform.h
---- linux-2.6.16.33-noxen/include/xen/interface/platform.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/platform.h   2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,143 @@
-+/******************************************************************************
-+ * platform.h
-+ * 
-+ * Hardware platform operations. Intended for use by domain-0 kernel.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2002-2006, K Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_PLATFORM_H__
-+#define __XEN_PUBLIC_PLATFORM_H__
-+
-+#include "xen.h"
-+
-+#define XENPF_INTERFACE_VERSION 0x03000001
-+
-+/*
-+ * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
-+ * 1 January, 1970 if the current system time was <system_time>.
-+ */
-+#define XENPF_settime             17
-+struct xenpf_settime {
-+    /* IN variables. */
-+    uint32_t secs;
-+    uint32_t nsecs;
-+    uint64_t system_time;
-+};
-+typedef struct xenpf_settime xenpf_settime_t;
-+DEFINE_XEN_GUEST_HANDLE(xenpf_settime_t);
-+
-+/*
-+ * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type.
-+ * On x86, @type is an architecture-defined MTRR memory type.
-+ * On success, returns the MTRR that was used (@reg) and a handle that can
-+ * be passed to XENPF_DEL_MEMTYPE to accurately tear down the new setting.
-+ * (x86-specific).
-+ */
-+#define XENPF_add_memtype         31
-+struct xenpf_add_memtype {
-+    /* IN variables. */
-+    xen_pfn_t mfn;
-+    uint64_t nr_mfns;
-+    uint32_t type;
-+    /* OUT variables. */
-+    uint32_t handle;
-+    uint32_t reg;
-+};
-+typedef struct xenpf_add_memtype xenpf_add_memtype_t;
-+DEFINE_XEN_GUEST_HANDLE(xenpf_add_memtype_t);
-+
-+/*
-+ * Tear down an existing memory-range type. If @handle is remembered then it
-+ * should be passed in to accurately tear down the correct setting (in case
-+ * of overlapping memory regions with differing types). If it is not known
-+ * then @handle should be set to zero. In all cases @reg must be set.
-+ * (x86-specific).
-+ */
-+#define XENPF_del_memtype         32
-+struct xenpf_del_memtype {
-+    /* IN variables. */
-+    uint32_t handle;
-+    uint32_t reg;
-+};
-+typedef struct xenpf_del_memtype xenpf_del_memtype_t;
-+DEFINE_XEN_GUEST_HANDLE(xenpf_del_memtype_t);
-+
-+/* Read current type of an MTRR (x86-specific). */
-+#define XENPF_read_memtype        33
-+struct xenpf_read_memtype {
-+    /* IN variables. */
-+    uint32_t reg;
-+    /* OUT variables. */
-+    xen_pfn_t mfn;
-+    uint64_t nr_mfns;
-+    uint32_t type;
-+};
-+typedef struct xenpf_read_memtype xenpf_read_memtype_t;
-+DEFINE_XEN_GUEST_HANDLE(xenpf_read_memtype_t);
-+
-+#define XENPF_microcode_update    35
-+struct xenpf_microcode_update {
-+    /* IN variables. */
-+    XEN_GUEST_HANDLE(void) data;      /* Pointer to microcode data */
-+    uint32_t length;                  /* Length of microcode data. */
-+};
-+typedef struct xenpf_microcode_update xenpf_microcode_update_t;
-+DEFINE_XEN_GUEST_HANDLE(xenpf_microcode_update_t);
-+
-+#define XENPF_platform_quirk      39
-+#define QUIRK_NOIRQBALANCING      1 /* Do not restrict IO-APIC RTE targets */
-+#define QUIRK_IOAPIC_BAD_REGSEL   2 /* IO-APIC REGSEL forgets its value    */
-+#define QUIRK_IOAPIC_GOOD_REGSEL  3 /* IO-APIC REGSEL behaves properly     */
-+struct xenpf_platform_quirk {
-+    /* IN variables. */
-+    uint32_t quirk_id;
-+};
-+typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
-+DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
-+
-+struct xen_platform_op {
-+    uint32_t cmd;
-+    uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
-+    union {
-+        struct xenpf_settime           settime;
-+        struct xenpf_add_memtype       add_memtype;
-+        struct xenpf_del_memtype       del_memtype;
-+        struct xenpf_read_memtype      read_memtype;
-+        struct xenpf_microcode_update  microcode;
-+        struct xenpf_platform_quirk    platform_quirk;
-+        uint8_t                        pad[128];
-+    } u;
-+};
-+typedef struct xen_platform_op xen_platform_op_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_platform_op_t);
-+
-+#endif /* __XEN_PUBLIC_PLATFORM_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/sched.h linux-2.6.16.33/include/xen/interface/sched.h
---- linux-2.6.16.33-noxen/include/xen/interface/sched.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/sched.h      2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,121 @@
-+/******************************************************************************
-+ * sched.h
-+ * 
-+ * Scheduler state interactions
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_SCHED_H__
-+#define __XEN_PUBLIC_SCHED_H__
-+
-+#include "event_channel.h"
-+
-+/*
-+ * The prototype for this hypercall is:
-+ *  long sched_op(int cmd, void *arg)
-+ * @cmd == SCHEDOP_??? (scheduler operation).
-+ * @arg == Operation-specific extra argument(s), as described below.
-+ * 
-+ * Versions of Xen prior to 3.0.2 provided only the following legacy version
-+ * of this hypercall, supporting only the commands yield, block and shutdown:
-+ *  long sched_op(int cmd, unsigned long arg)
-+ * @cmd == SCHEDOP_??? (scheduler operation).
-+ * @arg == 0               (SCHEDOP_yield and SCHEDOP_block)
-+ *      == SHUTDOWN_* code (SCHEDOP_shutdown)
-+ * This legacy version is available to new guests as sched_op_compat().
-+ */
-+
-+/*
-+ * Voluntarily yield the CPU.
-+ * @arg == NULL.
-+ */
-+#define SCHEDOP_yield       0
-+
-+/*
-+ * Block execution of this VCPU until an event is received for processing.
-+ * If called with event upcalls masked, this operation will atomically
-+ * reenable event delivery and check for pending events before blocking the
-+ * VCPU. This avoids a "wakeup waiting" race.
-+ * @arg == NULL.
-+ */
-+#define SCHEDOP_block       1
-+
-+/*
-+ * Halt execution of this domain (all VCPUs) and notify the system controller.
-+ * @arg == pointer to sched_shutdown structure.
-+ */
-+#define SCHEDOP_shutdown    2
-+struct sched_shutdown {
-+    unsigned int reason; /* SHUTDOWN_* */
-+};
-+typedef struct sched_shutdown sched_shutdown_t;
-+DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t);
-+
-+/*
-+ * Poll a set of event-channel ports. Return when one or more are pending. An
-+ * optional timeout may be specified.
-+ * @arg == pointer to sched_poll structure.
-+ */
-+#define SCHEDOP_poll        3
-+struct sched_poll {
-+    XEN_GUEST_HANDLE(evtchn_port_t) ports;
-+    unsigned int nr_ports;
-+    uint64_t timeout;
-+};
-+typedef struct sched_poll sched_poll_t;
-+DEFINE_XEN_GUEST_HANDLE(sched_poll_t);
-+
-+/*
-+ * Declare a shutdown for another domain. The main use of this function is
-+ * in interpreting shutdown requests and reasons for fully-virtualized
-+ * domains.  A para-virtualized domain may use SCHEDOP_shutdown directly.
-+ * @arg == pointer to sched_remote_shutdown structure.
-+ */
-+#define SCHEDOP_remote_shutdown        4
-+struct sched_remote_shutdown {
-+    domid_t domain_id;         /* Remote domain ID */
-+    unsigned int reason;       /* SHUTDOWN_xxx reason */
-+};
-+typedef struct sched_remote_shutdown sched_remote_shutdown_t;
-+DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_t);
-+
-+/*
-+ * Reason codes for SCHEDOP_shutdown. These may be interpreted by control
-+ * software to determine the appropriate action. For the most part, Xen does
-+ * not care about the shutdown code.
-+ */
-+#define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
-+#define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
-+#define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
-+#define SHUTDOWN_crash      3  /* Tell controller we've crashed.             */
-+
-+#endif /* __XEN_PUBLIC_SCHED_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/sysctl.h linux-2.6.16.33/include/xen/interface/sysctl.h
---- linux-2.6.16.33-noxen/include/xen/interface/sysctl.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/sysctl.h     2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,169 @@
-+/******************************************************************************
-+ * sysctl.h
-+ * 
-+ * System management operations. For use by node control stack.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2002-2006, K Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_SYSCTL_H__
-+#define __XEN_PUBLIC_SYSCTL_H__
-+
-+#if !defined(__XEN__) && !defined(__XEN_TOOLS__)
-+#error "sysctl operations are intended for use by node control tools only"
-+#endif
-+
-+#include "xen.h"
-+#include "domctl.h"
-+
-+#define XEN_SYSCTL_INTERFACE_VERSION 0x00000002
-+
-+/*
-+ * Read console content from Xen buffer ring.
-+ */
-+#define XEN_SYSCTL_readconsole       1
-+struct xen_sysctl_readconsole {
-+    /* IN variables. */
-+    uint32_t clear;                /* Non-zero -> clear after reading. */
-+    XEN_GUEST_HANDLE(char) buffer; /* Buffer start */
-+    /* IN/OUT variables. */
-+    uint32_t count;            /* In: Buffer size;  Out: Used buffer size  */
-+};
-+typedef struct xen_sysctl_readconsole xen_sysctl_readconsole_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_readconsole_t);
-+
-+/* Get trace buffers machine base address */
-+#define XEN_SYSCTL_tbuf_op           2
-+struct xen_sysctl_tbuf_op {
-+    /* IN variables */
-+#define XEN_SYSCTL_TBUFOP_get_info     0
-+#define XEN_SYSCTL_TBUFOP_set_cpu_mask 1
-+#define XEN_SYSCTL_TBUFOP_set_evt_mask 2
-+#define XEN_SYSCTL_TBUFOP_set_size     3
-+#define XEN_SYSCTL_TBUFOP_enable       4
-+#define XEN_SYSCTL_TBUFOP_disable      5
-+    uint32_t cmd;
-+    /* IN/OUT variables */
-+    struct xenctl_cpumap cpu_mask;
-+    uint32_t             evt_mask;
-+    /* OUT variables */
-+    uint64_t buffer_mfn;
-+    uint32_t size;
-+};
-+typedef struct xen_sysctl_tbuf_op xen_sysctl_tbuf_op_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tbuf_op_t);
-+
-+/*
-+ * Get physical information about the host machine
-+ */
-+#define XEN_SYSCTL_physinfo          3
-+struct xen_sysctl_physinfo {
-+    uint32_t threads_per_core;
-+    uint32_t cores_per_socket;
-+    uint32_t sockets_per_node;
-+    uint32_t nr_nodes;
-+    uint32_t cpu_khz;
-+    uint64_t total_pages;
-+    uint64_t free_pages;
-+    uint64_t scrub_pages;
-+    uint32_t hw_cap[8];
-+};
-+typedef struct xen_sysctl_physinfo xen_sysctl_physinfo_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_physinfo_t);
-+
-+/*
-+ * Get the ID of the current scheduler.
-+ */
-+#define XEN_SYSCTL_sched_id          4
-+struct xen_sysctl_sched_id {
-+    /* OUT variable */
-+    uint32_t sched_id;
-+};
-+typedef struct xen_sysctl_sched_id xen_sysctl_sched_id_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_sched_id_t);
-+
-+/* Interface for controlling Xen software performance counters. */
-+#define XEN_SYSCTL_perfc_op          5
-+/* Sub-operations: */
-+#define XEN_SYSCTL_PERFCOP_reset 1   /* Reset all counters to zero. */
-+#define XEN_SYSCTL_PERFCOP_query 2   /* Get perfctr information. */
-+struct xen_sysctl_perfc_desc {
-+    char         name[80];             /* name of perf counter */
-+    uint32_t     nr_vals;              /* number of values for this counter */
-+};
-+typedef struct xen_sysctl_perfc_desc xen_sysctl_perfc_desc_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t);
-+typedef uint32_t xen_sysctl_perfc_val_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t);
-+
-+struct xen_sysctl_perfc_op {
-+    /* IN variables. */
-+    uint32_t       cmd;                /*  XEN_SYSCTL_PERFCOP_??? */
-+    /* OUT variables. */
-+    uint32_t       nr_counters;       /*  number of counters description  */
-+    uint32_t       nr_vals;           /*  number of values  */
-+    /* counter information (or NULL) */
-+    XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t) desc;
-+    /* counter values (or NULL) */
-+    XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t) val;
-+};
-+typedef struct xen_sysctl_perfc_op xen_sysctl_perfc_op_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_op_t);
-+
-+#define XEN_SYSCTL_getdomaininfolist 6
-+struct xen_sysctl_getdomaininfolist {
-+    /* IN variables. */
-+    domid_t               first_domain;
-+    uint32_t              max_domains;
-+    XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t) buffer;
-+    /* OUT variables. */
-+    uint32_t              num_domains;
-+};
-+typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t);
-+
-+struct xen_sysctl {
-+    uint32_t cmd;
-+    uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
-+    union {
-+        struct xen_sysctl_readconsole       readconsole;
-+        struct xen_sysctl_tbuf_op           tbuf_op;
-+        struct xen_sysctl_physinfo          physinfo;
-+        struct xen_sysctl_sched_id          sched_id;
-+        struct xen_sysctl_perfc_op          perfc_op;
-+        struct xen_sysctl_getdomaininfolist getdomaininfolist;
-+        uint8_t                             pad[128];
-+    } u;
-+};
-+typedef struct xen_sysctl xen_sysctl_t;
-+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_t);
-+
-+#endif /* __XEN_PUBLIC_SYSCTL_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/trace.h linux-2.6.16.33/include/xen/interface/trace.h
---- linux-2.6.16.33-noxen/include/xen/interface/trace.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/trace.h      2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,102 @@
-+/******************************************************************************
-+ * include/public/trace.h
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Mark Williamson, (C) 2004 Intel Research Cambridge
-+ * Copyright (C) 2005 Bin Ren
-+ */
-+
-+#ifndef __XEN_PUBLIC_TRACE_H__
-+#define __XEN_PUBLIC_TRACE_H__
-+
-+/* Trace classes */
-+#define TRC_CLS_SHIFT 16
-+#define TRC_GEN     0x0001f000    /* General trace            */
-+#define TRC_SCHED   0x0002f000    /* Xen Scheduler trace      */
-+#define TRC_DOM0OP  0x0004f000    /* Xen DOM0 operation trace */
-+#define TRC_VMX     0x0008f000    /* Xen VMX trace            */
-+#define TRC_MEM     0x0010f000    /* Xen memory trace         */
-+#define TRC_ALL     0xfffff000
-+
-+/* Trace subclasses */
-+#define TRC_SUBCLS_SHIFT 12
-+
-+/* trace subclasses for VMX */
-+#define TRC_VMXEXIT  0x00081000   /* VMX exit trace            */
-+#define TRC_VMXENTRY 0x00082000   /* VMX exit trace            */
-+#define TRC_VMXINTR  0x00084000   /* VMX interrupt trace       */
-+
-+/* Trace events per class */
-+#define TRC_LOST_RECORDS        (TRC_GEN + 1)
-+
-+#define TRC_SCHED_DOM_ADD       (TRC_SCHED +  1)
-+#define TRC_SCHED_DOM_REM       (TRC_SCHED +  2)
-+#define TRC_SCHED_SLEEP         (TRC_SCHED +  3)
-+#define TRC_SCHED_WAKE          (TRC_SCHED +  4)
-+#define TRC_SCHED_YIELD         (TRC_SCHED +  5)
-+#define TRC_SCHED_BLOCK         (TRC_SCHED +  6)
-+#define TRC_SCHED_SHUTDOWN      (TRC_SCHED +  7)
-+#define TRC_SCHED_CTL           (TRC_SCHED +  8)
-+#define TRC_SCHED_ADJDOM        (TRC_SCHED +  9)
-+#define TRC_SCHED_SWITCH        (TRC_SCHED + 10)
-+#define TRC_SCHED_S_TIMER_FN    (TRC_SCHED + 11)
-+#define TRC_SCHED_T_TIMER_FN    (TRC_SCHED + 12)
-+#define TRC_SCHED_DOM_TIMER_FN  (TRC_SCHED + 13)
-+#define TRC_SCHED_SWITCH_INFPREV (TRC_SCHED + 14)
-+#define TRC_SCHED_SWITCH_INFNEXT (TRC_SCHED + 15)
-+
-+#define TRC_MEM_PAGE_GRANT_MAP      (TRC_MEM + 1)
-+#define TRC_MEM_PAGE_GRANT_UNMAP    (TRC_MEM + 2)
-+#define TRC_MEM_PAGE_GRANT_TRANSFER (TRC_MEM + 3)
-+
-+/* trace events per subclass */
-+#define TRC_VMX_VMEXIT          (TRC_VMXEXIT + 1)
-+#define TRC_VMX_VMENTRY         (TRC_VMXENTRY + 1)
-+#define TRC_VMX_INTR            (TRC_VMXINTR + 1)
-+
-+
-+/* This structure represents a single trace buffer record. */
-+struct t_rec {
-+    uint64_t cycles;          /* cycle counter timestamp */
-+    uint32_t event;           /* event ID                */
-+    unsigned long data[5];    /* event data items        */
-+};
-+
-+/*
-+ * This structure contains the metadata for a single trace buffer.  The head
-+ * field, indexes into an array of struct t_rec's.
-+ */
-+struct t_buf {
-+    uint32_t cons;      /* Next item to be consumed by control tools. */
-+    uint32_t prod;      /* Next item to be produced by Xen.           */
-+    /* 'nr_recs' records follow immediately after the meta-data header.    */
-+};
-+
-+#endif /* __XEN_PUBLIC_TRACE_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/vcpu.h linux-2.6.16.33/include/xen/interface/vcpu.h
---- linux-2.6.16.33-noxen/include/xen/interface/vcpu.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/vcpu.h       2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,142 @@
-+/******************************************************************************
-+ * vcpu.h
-+ * 
-+ * VCPU initialisation, query, and hotplug.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_VCPU_H__
-+#define __XEN_PUBLIC_VCPU_H__
-+
-+/*
-+ * Prototype for this hypercall is:
-+ *  int vcpu_op(int cmd, int vcpuid, void *extra_args)
-+ * @cmd        == VCPUOP_??? (VCPU operation).
-+ * @vcpuid     == VCPU to operate on.
-+ * @extra_args == Operation-specific extra arguments (NULL if none).
-+ */
-+
-+/*
-+ * Initialise a VCPU. Each VCPU can be initialised only once. A 
-+ * newly-initialised VCPU will not run until it is brought up by VCPUOP_up.
-+ * 
-+ * @extra_arg == pointer to vcpu_guest_context structure containing initial
-+ *               state for the VCPU.
-+ */
-+#define VCPUOP_initialise           0
-+
-+/*
-+ * Bring up a VCPU. This makes the VCPU runnable. This operation will fail
-+ * if the VCPU has not been initialised (VCPUOP_initialise).
-+ */
-+#define VCPUOP_up                   1
-+
-+/*
-+ * Bring down a VCPU (i.e., make it non-runnable).
-+ * There are a few caveats that callers should observe:
-+ *  1. This operation may return, and VCPU_is_up may return false, before the
-+ *     VCPU stops running (i.e., the command is asynchronous). It is a good
-+ *     idea to ensure that the VCPU has entered a non-critical loop before
-+ *     bringing it down. Alternatively, this operation is guaranteed
-+ *     synchronous if invoked by the VCPU itself.
-+ *  2. After a VCPU is initialised, there is currently no way to drop all its
-+ *     references to domain memory. Even a VCPU that is down still holds
-+ *     memory references via its pagetable base pointer and GDT. It is good
-+ *     practise to move a VCPU onto an 'idle' or default page table, LDT and
-+ *     GDT before bringing it down.
-+ */
-+#define VCPUOP_down                 2
-+
-+/* Returns 1 if the given VCPU is up. */
-+#define VCPUOP_is_up                3
-+
-+/*
-+ * Return information about the state and running time of a VCPU.
-+ * @extra_arg == pointer to vcpu_runstate_info structure.
-+ */
-+#define VCPUOP_get_runstate_info    4
-+struct vcpu_runstate_info {
-+    /* VCPU's current state (RUNSTATE_*). */
-+    int      state;
-+    /* When was current state entered (system time, ns)? */
-+    uint64_t state_entry_time;
-+    /*
-+     * Time spent in each RUNSTATE_* (ns). The sum of these times is
-+     * guaranteed not to drift from system time.
-+     */
-+    uint64_t time[4];
-+};
-+typedef struct vcpu_runstate_info vcpu_runstate_info_t;
-+DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_t);
-+
-+/* VCPU is currently running on a physical CPU. */
-+#define RUNSTATE_running  0
-+
-+/* VCPU is runnable, but not currently scheduled on any physical CPU. */
-+#define RUNSTATE_runnable 1
-+
-+/* VCPU is blocked (a.k.a. idle). It is therefore not runnable. */
-+#define RUNSTATE_blocked  2
-+
-+/*
-+ * VCPU is not runnable, but it is not blocked.
-+ * This is a 'catch all' state for things like hotplug and pauses by the
-+ * system administrator (or for critical sections in the hypervisor).
-+ * RUNSTATE_blocked dominates this state (it is the preferred state).
-+ */
-+#define RUNSTATE_offline  3
-+
-+/*
-+ * Register a shared memory area from which the guest may obtain its own
-+ * runstate information without needing to execute a hypercall.
-+ * Notes:
-+ *  1. The registered address may be virtual or physical or guest handle,
-+ *     depending on the platform. Virtual address or guest handle should be
-+ *     registered on x86 systems.
-+ *  2. Only one shared area may be registered per VCPU. The shared area is
-+ *     updated by the hypervisor each time the VCPU is scheduled. Thus
-+ *     runstate.state will always be RUNSTATE_running and
-+ *     runstate.state_entry_time will indicate the system time at which the
-+ *     VCPU was last scheduled to run.
-+ * @extra_arg == pointer to vcpu_register_runstate_memory_area structure.
-+ */
-+#define VCPUOP_register_runstate_memory_area 5
-+struct vcpu_register_runstate_memory_area {
-+    union {
-+        XEN_GUEST_HANDLE(vcpu_runstate_info_t) h;
-+        struct vcpu_runstate_info *v;
-+        uint64_t p;
-+    } addr;
-+};
-+typedef struct vcpu_register_runstate_memory_area vcpu_register_runstate_memory_area_t;
-+
-+#endif /* __XEN_PUBLIC_VCPU_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/version.h linux-2.6.16.33/include/xen/interface/version.h
---- linux-2.6.16.33-noxen/include/xen/interface/version.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/version.h    2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,91 @@
-+/******************************************************************************
-+ * version.h
-+ * 
-+ * Xen version, type, and compile information.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2005, Nguyen Anh Quynh <aquynh@gmail.com>
-+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
-+ */
-+
-+#ifndef __XEN_PUBLIC_VERSION_H__
-+#define __XEN_PUBLIC_VERSION_H__
-+
-+/* NB. All ops return zero on success, except XENVER_{version,pagesize} */
-+
-+/* arg == NULL; returns major:minor (16:16). */
-+#define XENVER_version      0
-+
-+/* arg == xen_extraversion_t. */
-+#define XENVER_extraversion 1
-+typedef char xen_extraversion_t[16];
-+#define XEN_EXTRAVERSION_LEN (sizeof(xen_extraversion_t))
-+
-+/* arg == xen_compile_info_t. */
-+#define XENVER_compile_info 2
-+struct xen_compile_info {
-+    char compiler[64];
-+    char compile_by[16];
-+    char compile_domain[32];
-+    char compile_date[32];
-+};
-+typedef struct xen_compile_info xen_compile_info_t;
-+
-+#define XENVER_capabilities 3
-+typedef char xen_capabilities_info_t[1024];
-+#define XEN_CAPABILITIES_INFO_LEN (sizeof(xen_capabilities_info_t))
-+
-+#define XENVER_changeset 4
-+typedef char xen_changeset_info_t[64];
-+#define XEN_CHANGESET_INFO_LEN (sizeof(xen_changeset_info_t))
-+
-+#define XENVER_platform_parameters 5
-+struct xen_platform_parameters {
-+    unsigned long virt_start;
-+};
-+typedef struct xen_platform_parameters xen_platform_parameters_t;
-+
-+#define XENVER_get_features 6
-+struct xen_feature_info {
-+    unsigned int submap_idx;    /* IN: which 32-bit submap to return */
-+    uint32_t     submap;        /* OUT: 32-bit submap */
-+};
-+typedef struct xen_feature_info xen_feature_info_t;
-+
-+/* Declares the features reported by XENVER_get_features. */
-+#include "features.h"
-+
-+/* arg == NULL; returns host memory page size. */
-+#define XENVER_pagesize 7
-+
-+/* arg == xen_domain_handle_t. */
-+#define XENVER_guest_handle 8
-+
-+#endif /* __XEN_PUBLIC_VERSION_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/xen-compat.h linux-2.6.16.33/include/xen/interface/xen-compat.h
---- linux-2.6.16.33-noxen/include/xen/interface/xen-compat.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/xen-compat.h 2007-01-08 15:00:55.000000000 +0000
-@@ -0,0 +1,51 @@
-+/******************************************************************************
-+ * xen-compat.h
-+ * 
-+ * Guest OS interface to Xen.  Compatibility layer.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2006, Christian Limpach
-+ */
-+
-+#ifndef __XEN_PUBLIC_XEN_COMPAT_H__
-+#define __XEN_PUBLIC_XEN_COMPAT_H__
-+
-+#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030205
-+
-+#if defined(__XEN__) || defined(__XEN_TOOLS__)
-+/* Xen is built with matching headers and implements the latest interface. */
-+#define __XEN_INTERFACE_VERSION__ __XEN_LATEST_INTERFACE_VERSION__
-+#elif !defined(__XEN_INTERFACE_VERSION__)
-+/* Guests which do not specify a version get the legacy interface. */
-+#define __XEN_INTERFACE_VERSION__ 0x00000000
-+#endif
-+
-+#if __XEN_INTERFACE_VERSION__ > __XEN_LATEST_INTERFACE_VERSION__
-+#error "These header files do not support the requested interface version."
-+#endif
-+
-+/* Fields defined as a Xen guest handle since 0x00030205. */
-+#if __XEN_INTERFACE_VERSION__ >= 0x00030205
-+#define XEN_GUEST_HANDLE_00030205(type) XEN_GUEST_HANDLE(type)
-+#else
-+#define XEN_GUEST_HANDLE_00030205(type) type *
-+#endif
-+
-+#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/xen.h linux-2.6.16.33/include/xen/interface/xen.h
---- linux-2.6.16.33-noxen/include/xen/interface/xen.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/xen.h        2007-01-08 15:00:56.000000000 +0000
-@@ -0,0 +1,597 @@
-+/******************************************************************************
-+ * xen.h
-+ * 
-+ * Guest OS interface to Xen.
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (c) 2004, K A Fraser
-+ */
-+
-+#ifndef __XEN_PUBLIC_XEN_H__
-+#define __XEN_PUBLIC_XEN_H__
-+
-+#include "xen-compat.h"
-+
-+#if defined(__i386__) || defined(__x86_64__)
-+#include "arch-x86/xen.h"
-+#elif defined(__ia64__)
-+#include "arch-ia64.h"
-+#elif defined(__powerpc__)
-+#include "arch-powerpc.h"
-+#else
-+#error "Unsupported architecture"
-+#endif
-+
-+/*
-+ * HYPERCALLS
-+ */
-+
-+#define __HYPERVISOR_set_trap_table        0
-+#define __HYPERVISOR_mmu_update            1
-+#define __HYPERVISOR_set_gdt               2
-+#define __HYPERVISOR_stack_switch          3
-+#define __HYPERVISOR_set_callbacks         4
-+#define __HYPERVISOR_fpu_taskswitch        5
-+#define __HYPERVISOR_sched_op_compat       6 /* compat since 0x00030101 */
-+#define __HYPERVISOR_platform_op           7
-+#define __HYPERVISOR_set_debugreg          8
-+#define __HYPERVISOR_get_debugreg          9
-+#define __HYPERVISOR_update_descriptor    10
-+#define __HYPERVISOR_memory_op            12
-+#define __HYPERVISOR_multicall            13
-+#define __HYPERVISOR_update_va_mapping    14
-+#define __HYPERVISOR_set_timer_op         15
-+#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */
-+#define __HYPERVISOR_xen_version          17
-+#define __HYPERVISOR_console_io           18
-+#define __HYPERVISOR_physdev_op_compat    19 /* compat since 0x00030202 */
-+#define __HYPERVISOR_grant_table_op       20
-+#define __HYPERVISOR_vm_assist            21
-+#define __HYPERVISOR_update_va_mapping_otherdomain 22
-+#define __HYPERVISOR_iret                 23 /* x86 only */
-+#define __HYPERVISOR_vcpu_op              24
-+#define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
-+#define __HYPERVISOR_mmuext_op            26
-+#define __HYPERVISOR_acm_op               27
-+#define __HYPERVISOR_nmi_op               28
-+#define __HYPERVISOR_sched_op             29
-+#define __HYPERVISOR_callback_op          30
-+#define __HYPERVISOR_xenoprof_op          31
-+#define __HYPERVISOR_event_channel_op     32
-+#define __HYPERVISOR_physdev_op           33
-+#define __HYPERVISOR_hvm_op               34
-+#define __HYPERVISOR_sysctl               35
-+#define __HYPERVISOR_domctl               36
-+#define __HYPERVISOR_kexec_op             37
-+
-+/* Architecture-specific hypercall definitions. */
-+#define __HYPERVISOR_arch_0               48
-+#define __HYPERVISOR_arch_1               49
-+#define __HYPERVISOR_arch_2               50
-+#define __HYPERVISOR_arch_3               51
-+#define __HYPERVISOR_arch_4               52
-+#define __HYPERVISOR_arch_5               53
-+#define __HYPERVISOR_arch_6               54
-+#define __HYPERVISOR_arch_7               55
-+
-+/*
-+ * HYPERCALL COMPATIBILITY.
-+ */
-+
-+/* New sched_op hypercall introduced in 0x00030101. */
-+#if __XEN_INTERFACE_VERSION__ < 0x00030101
-+#undef __HYPERVISOR_sched_op
-+#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_compat
-+#endif
-+
-+/* New event-channel and physdev hypercalls introduced in 0x00030202. */
-+#if __XEN_INTERFACE_VERSION__ < 0x00030202
-+#undef __HYPERVISOR_event_channel_op
-+#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat
-+#undef __HYPERVISOR_physdev_op
-+#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat
-+#endif
-+
-+/* New platform_op hypercall introduced in 0x00030204. */
-+#if __XEN_INTERFACE_VERSION__ < 0x00030204
-+#define __HYPERVISOR_dom0_op __HYPERVISOR_platform_op
-+#endif
-+
-+/* 
-+ * VIRTUAL INTERRUPTS
-+ * 
-+ * Virtual interrupts that a guest OS may receive from Xen.
-+ * 
-+ * In the side comments, 'V.' denotes a per-VCPU VIRQ while 'G.' denotes a
-+ * global VIRQ. The former can be bound once per VCPU and cannot be re-bound.
-+ * The latter can be allocated only once per guest: they must initially be
-+ * allocated to VCPU0 but can subsequently be re-bound.
-+ */
-+#define VIRQ_TIMER      0  /* V. Timebase update, and/or requested timeout.  */
-+#define VIRQ_DEBUG      1  /* V. Request guest to dump debug info.           */
-+#define VIRQ_CONSOLE    2  /* G. (DOM0) Bytes received on emergency console. */
-+#define VIRQ_DOM_EXC    3  /* G. (DOM0) Exceptional event for some domain.   */
-+#define VIRQ_TBUF       4  /* G. (DOM0) Trace buffer has records available.  */
-+#define VIRQ_DEBUGGER   6  /* G. (DOM0) A domain has paused for debugging.   */
-+#define VIRQ_XENOPROF   7  /* V. XenOprofile interrupt: new sample available */
-+
-+/* Architecture-specific VIRQ definitions. */
-+#define VIRQ_ARCH_0    16
-+#define VIRQ_ARCH_1    17
-+#define VIRQ_ARCH_2    18
-+#define VIRQ_ARCH_3    19
-+#define VIRQ_ARCH_4    20
-+#define VIRQ_ARCH_5    21
-+#define VIRQ_ARCH_6    22
-+#define VIRQ_ARCH_7    23
-+
-+#define NR_VIRQS       24
-+
-+/*
-+ * MMU-UPDATE REQUESTS
-+ * 
-+ * HYPERVISOR_mmu_update() accepts a list of (ptr, val) pairs.
-+ * A foreigndom (FD) can be specified (or DOMID_SELF for none).
-+ * Where the FD has some effect, it is described below.
-+ * ptr[1:0] specifies the appropriate MMU_* command.
-+ * 
-+ * ptr[1:0] == MMU_NORMAL_PT_UPDATE:
-+ * Updates an entry in a page table. If updating an L1 table, and the new
-+ * table entry is valid/present, the mapped frame must belong to the FD, if
-+ * an FD has been specified. If attempting to map an I/O page then the
-+ * caller assumes the privilege of the FD.
-+ * FD == DOMID_IO: Permit /only/ I/O mappings, at the priv level of the caller.
-+ * FD == DOMID_XEN: Map restricted areas of Xen's heap space.
-+ * ptr[:2]  -- Machine address of the page-table entry to modify.
-+ * val      -- Value to write.
-+ * 
-+ * ptr[1:0] == MMU_MACHPHYS_UPDATE:
-+ * Updates an entry in the machine->pseudo-physical mapping table.
-+ * ptr[:2]  -- Machine address within the frame whose mapping to modify.
-+ *             The frame must belong to the FD, if one is specified.
-+ * val      -- Value to write into the mapping entry.
-+ */
-+#define MMU_NORMAL_PT_UPDATE     0 /* checked '*ptr = val'. ptr is MA.       */
-+#define MMU_MACHPHYS_UPDATE      1 /* ptr = MA of frame to modify entry for  */
-+
-+/*
-+ * MMU EXTENDED OPERATIONS
-+ * 
-+ * HYPERVISOR_mmuext_op() accepts a list of mmuext_op structures.
-+ * A foreigndom (FD) can be specified (or DOMID_SELF for none).
-+ * Where the FD has some effect, it is described below.
-+ * 
-+ * cmd: MMUEXT_(UN)PIN_*_TABLE
-+ * mfn: Machine frame number to be (un)pinned as a p.t. page.
-+ *      The frame must belong to the FD, if one is specified.
-+ * 
-+ * cmd: MMUEXT_NEW_BASEPTR
-+ * mfn: Machine frame number of new page-table base to install in MMU.
-+ * 
-+ * cmd: MMUEXT_NEW_USER_BASEPTR [x86/64 only]
-+ * mfn: Machine frame number of new page-table base to install in MMU
-+ *      when in user space.
-+ * 
-+ * cmd: MMUEXT_TLB_FLUSH_LOCAL
-+ * No additional arguments. Flushes local TLB.
-+ * 
-+ * cmd: MMUEXT_INVLPG_LOCAL
-+ * linear_addr: Linear address to be flushed from the local TLB.
-+ * 
-+ * cmd: MMUEXT_TLB_FLUSH_MULTI
-+ * vcpumask: Pointer to bitmap of VCPUs to be flushed.
-+ * 
-+ * cmd: MMUEXT_INVLPG_MULTI
-+ * linear_addr: Linear address to be flushed.
-+ * vcpumask: Pointer to bitmap of VCPUs to be flushed.
-+ * 
-+ * cmd: MMUEXT_TLB_FLUSH_ALL
-+ * No additional arguments. Flushes all VCPUs' TLBs.
-+ * 
-+ * cmd: MMUEXT_INVLPG_ALL
-+ * linear_addr: Linear address to be flushed from all VCPUs' TLBs.
-+ * 
-+ * cmd: MMUEXT_FLUSH_CACHE
-+ * No additional arguments. Writes back and flushes cache contents.
-+ * 
-+ * cmd: MMUEXT_SET_LDT
-+ * linear_addr: Linear address of LDT base (NB. must be page-aligned).
-+ * nr_ents: Number of entries in LDT.
-+ */
-+#define MMUEXT_PIN_L1_TABLE      0
-+#define MMUEXT_PIN_L2_TABLE      1
-+#define MMUEXT_PIN_L3_TABLE      2
-+#define MMUEXT_PIN_L4_TABLE      3
-+#define MMUEXT_UNPIN_TABLE       4
-+#define MMUEXT_NEW_BASEPTR       5
-+#define MMUEXT_TLB_FLUSH_LOCAL   6
-+#define MMUEXT_INVLPG_LOCAL      7
-+#define MMUEXT_TLB_FLUSH_MULTI   8
-+#define MMUEXT_INVLPG_MULTI      9
-+#define MMUEXT_TLB_FLUSH_ALL    10
-+#define MMUEXT_INVLPG_ALL       11
-+#define MMUEXT_FLUSH_CACHE      12
-+#define MMUEXT_SET_LDT          13
-+#define MMUEXT_NEW_USER_BASEPTR 15
-+
-+#ifndef __ASSEMBLY__
-+struct mmuext_op {
-+    unsigned int cmd;
-+    union {
-+        /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */
-+        xen_pfn_t     mfn;
-+        /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
-+        unsigned long linear_addr;
-+    } arg1;
-+    union {
-+        /* SET_LDT */
-+        unsigned int nr_ents;
-+        /* TLB_FLUSH_MULTI, INVLPG_MULTI */
-+        XEN_GUEST_HANDLE_00030205(void) vcpumask;
-+    } arg2;
-+};
-+typedef struct mmuext_op mmuext_op_t;
-+DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
-+#endif
-+
-+/* These are passed as 'flags' to update_va_mapping. They can be ORed. */
-+/* When specifying UVMF_MULTI, also OR in a pointer to a CPU bitmap.   */
-+/* UVMF_LOCAL is merely UVMF_MULTI with a NULL bitmap pointer.         */
-+#define UVMF_NONE               (0UL<<0) /* No flushing at all.   */
-+#define UVMF_TLB_FLUSH          (1UL<<0) /* Flush entire TLB(s).  */
-+#define UVMF_INVLPG             (2UL<<0) /* Flush only one entry. */
-+#define UVMF_FLUSHTYPE_MASK     (3UL<<0)
-+#define UVMF_MULTI              (0UL<<2) /* Flush subset of TLBs. */
-+#define UVMF_LOCAL              (0UL<<2) /* Flush local TLB.      */
-+#define UVMF_ALL                (1UL<<2) /* Flush all TLBs.       */
-+
-+/*
-+ * Commands to HYPERVISOR_console_io().
-+ */
-+#define CONSOLEIO_write         0
-+#define CONSOLEIO_read          1
-+
-+/*
-+ * Commands to HYPERVISOR_vm_assist().
-+ */
-+#define VMASST_CMD_enable                0
-+#define VMASST_CMD_disable               1
-+
-+/* x86/32 guests: simulate full 4GB segment limits. */
-+#define VMASST_TYPE_4gb_segments         0
-+
-+/* x86/32 guests: trap (vector 15) whenever above vmassist is used. */
-+#define VMASST_TYPE_4gb_segments_notify  1
-+
-+/*
-+ * x86 guests: support writes to bottom-level PTEs.
-+ * NB1. Page-directory entries cannot be written.
-+ * NB2. Guest must continue to remove all writable mappings of PTEs.
-+ */
-+#define VMASST_TYPE_writable_pagetables  2
-+
-+/* x86/PAE guests: support PDPTs above 4GB. */
-+#define VMASST_TYPE_pae_extended_cr3     3
-+
-+#define MAX_VMASST_TYPE                  3
-+
-+#ifndef __ASSEMBLY__
-+
-+typedef uint16_t domid_t;
-+
-+/* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */
-+#define DOMID_FIRST_RESERVED (0x7FF0U)
-+
-+/* DOMID_SELF is used in certain contexts to refer to oneself. */
-+#define DOMID_SELF (0x7FF0U)
-+
-+/*
-+ * DOMID_IO is used to restrict page-table updates to mapping I/O memory.
-+ * Although no Foreign Domain need be specified to map I/O pages, DOMID_IO
-+ * is useful to ensure that no mappings to the OS's own heap are accidentally
-+ * installed. (e.g., in Linux this could cause havoc as reference counts
-+ * aren't adjusted on the I/O-mapping code path).
-+ * This only makes sense in MMUEXT_SET_FOREIGNDOM, but in that context can
-+ * be specified by any calling domain.
-+ */
-+#define DOMID_IO   (0x7FF1U)
-+
-+/*
-+ * DOMID_XEN is used to allow privileged domains to map restricted parts of
-+ * Xen's heap space (e.g., the machine_to_phys table).
-+ * This only makes sense in MMUEXT_SET_FOREIGNDOM, and is only permitted if
-+ * the caller is privileged.
-+ */
-+#define DOMID_XEN  (0x7FF2U)
-+
-+/*
-+ * Send an array of these to HYPERVISOR_mmu_update().
-+ * NB. The fields are natural pointer/address size for this architecture.
-+ */
-+struct mmu_update {
-+    uint64_t ptr;       /* Machine address of PTE. */
-+    uint64_t val;       /* New contents of PTE.    */
-+};
-+typedef struct mmu_update mmu_update_t;
-+DEFINE_XEN_GUEST_HANDLE(mmu_update_t);
-+
-+/*
-+ * Send an array of these to HYPERVISOR_multicall().
-+ * NB. The fields are natural register size for this architecture.
-+ */
-+struct multicall_entry {
-+    unsigned long op, result;
-+    unsigned long args[6];
-+};
-+typedef struct multicall_entry multicall_entry_t;
-+DEFINE_XEN_GUEST_HANDLE(multicall_entry_t);
-+
-+/*
-+ * Event channel endpoints per domain:
-+ *  1024 if a long is 32 bits; 4096 if a long is 64 bits.
-+ */
-+#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
-+
-+struct vcpu_time_info {
-+    /*
-+     * Updates to the following values are preceded and followed by an
-+     * increment of 'version'. The guest can therefore detect updates by
-+     * looking for changes to 'version'. If the least-significant bit of
-+     * the version number is set then an update is in progress and the guest
-+     * must wait to read a consistent set of values.
-+     * The correct way to interact with the version number is similar to
-+     * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
-+     */
-+    uint32_t version;
-+    uint32_t pad0;
-+    uint64_t tsc_timestamp;   /* TSC at last update of time vals.  */
-+    uint64_t system_time;     /* Time, in nanosecs, since boot.    */
-+    /*
-+     * Current system time:
-+     *   system_time +
-+     *   ((((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul) >> 32)
-+     * CPU frequency (Hz):
-+     *   ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
-+     */
-+    uint32_t tsc_to_system_mul;
-+    int8_t   tsc_shift;
-+    int8_t   pad1[3];
-+}; /* 32 bytes */
-+typedef struct vcpu_time_info vcpu_time_info_t;
-+
-+struct vcpu_info {
-+    /*
-+     * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
-+     * a pending notification for a particular VCPU. It is then cleared 
-+     * by the guest OS /before/ checking for pending work, thus avoiding
-+     * a set-and-check race. Note that the mask is only accessed by Xen
-+     * on the CPU that is currently hosting the VCPU. This means that the
-+     * pending and mask flags can be updated by the guest without special
-+     * synchronisation (i.e., no need for the x86 LOCK prefix).
-+     * This may seem suboptimal because if the pending flag is set by
-+     * a different CPU then an IPI may be scheduled even when the mask
-+     * is set. However, note:
-+     *  1. The task of 'interrupt holdoff' is covered by the per-event-
-+     *     channel mask bits. A 'noisy' event that is continually being
-+     *     triggered can be masked at source at this very precise
-+     *     granularity.
-+     *  2. The main purpose of the per-VCPU mask is therefore to restrict
-+     *     reentrant execution: whether for concurrency control, or to
-+     *     prevent unbounded stack usage. Whatever the purpose, we expect
-+     *     that the mask will be asserted only for short periods at a time,
-+     *     and so the likelihood of a 'spurious' IPI is suitably small.
-+     * The mask is read before making an event upcall to the guest: a
-+     * non-zero mask therefore guarantees that the VCPU will not receive
-+     * an upcall activation. The mask is cleared when the VCPU requests
-+     * to block: this avoids wakeup-waiting races.
-+     */
-+    uint8_t evtchn_upcall_pending;
-+    uint8_t evtchn_upcall_mask;
-+    unsigned long evtchn_pending_sel;
-+    struct arch_vcpu_info arch;
-+    struct vcpu_time_info time;
-+}; /* 64 bytes (x86) */
-+typedef struct vcpu_info vcpu_info_t;
-+
-+/*
-+ * Xen/kernel shared data -- pointer provided in start_info.
-+ *
-+ * This structure is defined to be both smaller than a page, and the
-+ * only data on the shared page, but may vary in actual size even within
-+ * compatible Xen versions; guests should not rely on the size
-+ * of this structure remaining constant.
-+ */
-+struct shared_info {
-+    struct vcpu_info vcpu_info[MAX_VIRT_CPUS];
-+
-+    /*
-+     * A domain can create "event channels" on which it can send and receive
-+     * asynchronous event notifications. There are three classes of event that
-+     * are delivered by this mechanism:
-+     *  1. Bi-directional inter- and intra-domain connections. Domains must
-+     *     arrange out-of-band to set up a connection (usually by allocating
-+     *     an unbound 'listener' port and avertising that via a storage service
-+     *     such as xenstore).
-+     *  2. Physical interrupts. A domain with suitable hardware-access
-+     *     privileges can bind an event-channel port to a physical interrupt
-+     *     source.
-+     *  3. Virtual interrupts ('events'). A domain can bind an event-channel
-+     *     port to a virtual interrupt source, such as the virtual-timer
-+     *     device or the emergency console.
-+     * 
-+     * Event channels are addressed by a "port index". Each channel is
-+     * associated with two bits of information:
-+     *  1. PENDING -- notifies the domain that there is a pending notification
-+     *     to be processed. This bit is cleared by the guest.
-+     *  2. MASK -- if this bit is clear then a 0->1 transition of PENDING
-+     *     will cause an asynchronous upcall to be scheduled. This bit is only
-+     *     updated by the guest. It is read-only within Xen. If a channel
-+     *     becomes pending while the channel is masked then the 'edge' is lost
-+     *     (i.e., when the channel is unmasked, the guest must manually handle
-+     *     pending notifications as no upcall will be scheduled by Xen).
-+     * 
-+     * To expedite scanning of pending notifications, any 0->1 pending
-+     * transition on an unmasked channel causes a corresponding bit in a
-+     * per-vcpu selector word to be set. Each bit in the selector covers a
-+     * 'C long' in the PENDING bitfield array.
-+     */
-+    unsigned long evtchn_pending[sizeof(unsigned long) * 8];
-+    unsigned long evtchn_mask[sizeof(unsigned long) * 8];
-+
-+    /*
-+     * Wallclock time: updated only by control software. Guests should base
-+     * their gettimeofday() syscall on this wallclock-base value.
-+     */
-+    uint32_t wc_version;      /* Version counter: see vcpu_time_info_t. */
-+    uint32_t wc_sec;          /* Secs  00:00:00 UTC, Jan 1, 1970.  */
-+    uint32_t wc_nsec;         /* Nsecs 00:00:00 UTC, Jan 1, 1970.  */
-+
-+    struct arch_shared_info arch;
-+
-+};
-+typedef struct shared_info shared_info_t;
-+
-+/*
-+ * Start-of-day memory layout for the initial domain (DOM0):
-+ *  1. The domain is started within contiguous virtual-memory region.
-+ *  2. The contiguous region begins and ends on an aligned 4MB boundary.
-+ *  3. The region start corresponds to the load address of the OS image.
-+ *     If the load address is not 4MB aligned then the address is rounded down.
-+ *  4. This the order of bootstrap elements in the initial virtual region:
-+ *      a. relocated kernel image
-+ *      b. initial ram disk              [mod_start, mod_len]
-+ *      c. list of allocated page frames [mfn_list, nr_pages]
-+ *      d. start_info_t structure        [register ESI (x86)]
-+ *      e. bootstrap page tables         [pt_base, CR3 (x86)]
-+ *      f. bootstrap stack               [register ESP (x86)]
-+ *  5. Bootstrap elements are packed together, but each is 4kB-aligned.
-+ *  6. The initial ram disk may be omitted.
-+ *  7. The list of page frames forms a contiguous 'pseudo-physical' memory
-+ *     layout for the domain. In particular, the bootstrap virtual-memory
-+ *     region is a 1:1 mapping to the first section of the pseudo-physical map.
-+ *  8. All bootstrap elements are mapped read-writable for the guest OS. The
-+ *     only exception is the bootstrap page table, which is mapped read-only.
-+ *  9. There is guaranteed to be at least 512kB padding after the final
-+ *     bootstrap element. If necessary, the bootstrap virtual region is
-+ *     extended by an extra 4MB to ensure this.
-+ */
-+
-+#define MAX_GUEST_CMDLINE 1024
-+struct start_info {
-+    /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME.    */
-+    char magic[32];             /* "xen-<version>-<platform>".            */
-+    unsigned long nr_pages;     /* Total pages allocated to this domain.  */
-+    unsigned long shared_info;  /* MACHINE address of shared info struct. */
-+    uint32_t flags;             /* SIF_xxx flags.                         */
-+    xen_pfn_t store_mfn;        /* MACHINE page number of shared page.    */
-+    uint32_t store_evtchn;      /* Event channel for store communication. */
-+    union {
-+        struct {
-+            xen_pfn_t mfn;      /* MACHINE page number of console page.   */
-+            uint32_t  evtchn;   /* Event channel for console page.        */
-+        } domU;
-+        struct {
-+            uint32_t info_off;  /* Offset of console_info struct.         */
-+            uint32_t info_size; /* Size of console_info struct from start.*/
-+        } dom0;
-+    } console;
-+    /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME).     */
-+    unsigned long pt_base;      /* VIRTUAL address of page directory.     */
-+    unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames.       */
-+    unsigned long mfn_list;     /* VIRTUAL address of page-frame list.    */
-+    unsigned long mod_start;    /* VIRTUAL address of pre-loaded module.  */
-+    unsigned long mod_len;      /* Size (bytes) of pre-loaded module.     */
-+    int8_t cmd_line[MAX_GUEST_CMDLINE];
-+};
-+typedef struct start_info start_info_t;
-+
-+/* New console union for dom0 introduced in 0x00030203. */
-+#if __XEN_INTERFACE_VERSION__ < 0x00030203
-+#define console_mfn    console.domU.mfn
-+#define console_evtchn console.domU.evtchn
-+#endif
-+
-+/* These flags are passed in the 'flags' field of start_info_t. */
-+#define SIF_PRIVILEGED    (1<<0)  /* Is the domain privileged? */
-+#define SIF_INITDOMAIN    (1<<1)  /* Is this the initial control domain? */
-+
-+typedef struct dom0_vga_console_info {
-+    uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */
-+#define XEN_VGATYPE_TEXT_MODE_3 0x03
-+#define XEN_VGATYPE_VESA_LFB    0x23
-+
-+    union {
-+        struct {
-+            /* Font height, in pixels. */
-+            uint16_t font_height;
-+            /* Cursor location (column, row). */
-+            uint16_t cursor_x, cursor_y;
-+            /* Number of rows and columns (dimensions in characters). */
-+            uint16_t rows, columns;
-+        } text_mode_3;
-+
-+        struct {
-+            /* Width and height, in pixels. */
-+            uint16_t width, height;
-+            /* Bytes per scan line. */
-+            uint16_t bytes_per_line;
-+            /* Bits per pixel. */
-+            uint16_t bits_per_pixel;
-+            /* LFB physical address, and size (in units of 64kB). */
-+            uint32_t lfb_base;
-+            uint32_t lfb_size;
-+            /* RGB mask offsets and sizes, as defined by VBE 1.2+ */
-+            uint8_t  red_pos, red_size;
-+            uint8_t  green_pos, green_size;
-+            uint8_t  blue_pos, blue_size;
-+            uint8_t  rsvd_pos, rsvd_size;
-+        } vesa_lfb;
-+    } u;
-+} dom0_vga_console_info_t;
-+
-+typedef uint8_t xen_domain_handle_t[16];
-+
-+/* Turn a plain number into a C unsigned long constant. */
-+#define __mk_unsigned_long(x) x ## UL
-+#define mk_unsigned_long(x) __mk_unsigned_long(x)
-+
-+DEFINE_XEN_GUEST_HANDLE(uint8_t);
-+DEFINE_XEN_GUEST_HANDLE(uint16_t);
-+DEFINE_XEN_GUEST_HANDLE(uint32_t);
-+DEFINE_XEN_GUEST_HANDLE(uint64_t);
-+
-+#else /* __ASSEMBLY__ */
-+
-+/* In assembly code we cannot use C numeric constant suffixes. */
-+#define mk_unsigned_long(x) x
-+
-+#endif /* !__ASSEMBLY__ */
-+
-+#endif /* __XEN_PUBLIC_XEN_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/xencomm.h linux-2.6.16.33/include/xen/interface/xencomm.h
---- linux-2.6.16.33-noxen/include/xen/interface/xencomm.h      1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/xencomm.h    2007-01-08 15:00:56.000000000 +0000
-@@ -0,0 +1,41 @@
-+/*
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (C) IBM Corp. 2006
-+ */
-+
-+#ifndef _XEN_XENCOMM_H_
-+#define _XEN_XENCOMM_H_
-+
-+/* A xencomm descriptor is a scatter/gather list containing physical
-+ * addresses corresponding to a virtually contiguous memory area. The
-+ * hypervisor translates these physical addresses to machine addresses to copy
-+ * to and from the virtually contiguous area.
-+ */
-+
-+#define XENCOMM_MAGIC 0x58434F4D /* 'XCOM' */
-+#define XENCOMM_INVALID (~0UL)
-+
-+struct xencomm_desc {
-+    uint32_t magic;
-+    uint32_t nr_addrs; /* the number of entries in address[] */
-+    uint64_t address[0];
-+};
-+
-+#endif /* _XEN_XENCOMM_H_ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/interface/xenoprof.h linux-2.6.16.33/include/xen/interface/xenoprof.h
---- linux-2.6.16.33-noxen/include/xen/interface/xenoprof.h     1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/interface/xenoprof.h   2007-01-08 15:00:56.000000000 +0000
-@@ -0,0 +1,130 @@
-+/******************************************************************************
-+ * xenoprof.h
-+ * 
-+ * Interface for enabling system wide profiling based on hardware performance
-+ * counters
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (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.
-+ *
-+ * Copyright (C) 2005 Hewlett-Packard Co.
-+ * Written by Aravind Menon & Jose Renato Santos
-+ */
-+
-+#ifndef __XEN_PUBLIC_XENOPROF_H__
-+#define __XEN_PUBLIC_XENOPROF_H__
-+
-+#include "xen.h"
-+
-+/*
-+ * Commands to HYPERVISOR_xenoprof_op().
-+ */
-+#define XENOPROF_init                0
-+#define XENOPROF_reset_active_list   1
-+#define XENOPROF_reset_passive_list  2
-+#define XENOPROF_set_active          3
-+#define XENOPROF_set_passive         4
-+#define XENOPROF_reserve_counters    5
-+#define XENOPROF_counter             6
-+#define XENOPROF_setup_events        7
-+#define XENOPROF_enable_virq         8
-+#define XENOPROF_start               9
-+#define XENOPROF_stop               10
-+#define XENOPROF_disable_virq       11
-+#define XENOPROF_release_counters   12
-+#define XENOPROF_shutdown           13
-+#define XENOPROF_get_buffer         14
-+#define XENOPROF_last_op            14
-+
-+#define MAX_OPROF_EVENTS    32
-+#define MAX_OPROF_DOMAINS   25
-+#define XENOPROF_CPU_TYPE_SIZE 64
-+
-+/* Xenoprof performance events (not Xen events) */
-+struct event_log {
-+    uint64_t eip;
-+    uint8_t mode;
-+    uint8_t event;
-+};
-+
-+/* Xenoprof buffer shared between Xen and domain - 1 per VCPU */
-+struct xenoprof_buf {
-+    uint32_t event_head;
-+    uint32_t event_tail;
-+    uint32_t event_size;
-+    uint32_t vcpu_id;
-+    uint64_t xen_samples;
-+    uint64_t kernel_samples;
-+    uint64_t user_samples;
-+    uint64_t lost_samples;
-+    struct event_log event_log[1];
-+};
-+typedef struct xenoprof_buf xenoprof_buf_t;
-+DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t);
-+
-+struct xenoprof_init {
-+    int32_t  num_events;
-+    int32_t  is_primary;
-+    char cpu_type[XENOPROF_CPU_TYPE_SIZE];
-+};
-+typedef struct xenoprof_init xenoprof_init_t;
-+DEFINE_XEN_GUEST_HANDLE(xenoprof_init_t);
-+
-+struct xenoprof_get_buffer {
-+    int32_t  max_samples;
-+    int32_t  nbuf;
-+    int32_t  bufsize;
-+    uint64_t buf_gmaddr;
-+};
-+typedef struct xenoprof_get_buffer xenoprof_get_buffer_t;
-+DEFINE_XEN_GUEST_HANDLE(xenoprof_get_buffer_t);
-+
-+struct xenoprof_counter {
-+    uint32_t ind;
-+    uint64_t count;
-+    uint32_t enabled;
-+    uint32_t event;
-+    uint32_t hypervisor;
-+    uint32_t kernel;
-+    uint32_t user;
-+    uint64_t unit_mask;
-+};
-+typedef struct xenoprof_counter xenoprof_counter_t;
-+DEFINE_XEN_GUEST_HANDLE(xenoprof_counter_t);
-+
-+typedef struct xenoprof_passive {
-+    uint16_t domain_id;
-+    int32_t  max_samples;
-+    int32_t  nbuf;
-+    int32_t  bufsize;
-+    uint64_t buf_gmaddr;
-+} xenoprof_passive_t;
-+DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t);
-+
-+
-+#endif /* __XEN_PUBLIC_XENOPROF_H__ */
-+
-+/*
-+ * Local variables:
-+ * mode: C
-+ * c-set-style: "BSD"
-+ * c-basic-offset: 4
-+ * tab-width: 4
-+ * indent-tabs-mode: nil
-+ * End:
-+ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/pcifront.h linux-2.6.16.33/include/xen/pcifront.h
---- linux-2.6.16.33-noxen/include/xen/pcifront.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/pcifront.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,77 @@
-+/*
-+ * PCI Frontend - arch-dependendent declarations
-+ *
-+ *   Author: Ryan Wilson <hap9@epoch.ncsc.mil>
-+ */
-+#ifndef __XEN_ASM_PCIFRONT_H__
-+#define __XEN_ASM_PCIFRONT_H__
-+
-+#include <linux/config.h>
-+#include <linux/spinlock.h>
-+
-+#ifdef __KERNEL__
-+
-+#ifndef __ia64__
-+
-+struct pcifront_device;
-+struct pci_bus;
-+
-+struct pcifront_sd {
-+      int domain;
-+      struct pcifront_device *pdev;
-+};
-+
-+static inline struct pcifront_device *
-+pcifront_get_pdev(struct pcifront_sd *sd)
-+{
-+      return sd->pdev;
-+}
-+
-+static inline void pcifront_init_sd(struct pcifront_sd *sd, int domain,
-+                                  struct pcifront_device *pdev)
-+{
-+      sd->domain = domain;
-+      sd->pdev = pdev;
-+}
-+
-+#if defined(CONFIG_PCI_DOMAINS)
-+static inline int pci_domain_nr(struct pci_bus *bus)
-+{
-+      struct pcifront_sd *sd = bus->sysdata;
-+      return sd->domain;
-+}
-+static inline int pci_proc_domain(struct pci_bus *bus)
-+{
-+      return pci_domain_nr(bus);
-+}
-+#endif /* CONFIG_PCI_DOMAINS */
-+
-+#else /* __ia64__ */
-+
-+#include <asm/pci.h>
-+#define pcifront_sd pci_controller
-+
-+static inline struct pcifront_device *
-+pcifront_get_pdev(struct pcifront_sd *sd)
-+{
-+      return (struct pcifront_device *)sd->platform_data;
-+}
-+
-+static inline void pcifront_init_sd(struct pcifront_sd *sd, int domain,
-+                                  struct pcifront_device *pdev)
-+{
-+      sd->segment = domain;
-+      sd->acpi_handle = NULL;
-+      sd->iommu = NULL;
-+      sd->windows = 0;
-+      sd->window = NULL;
-+      sd->platform_data = pdev;
-+}
-+
-+#endif /* __ia64__ */
-+
-+extern spinlock_t pci_bus_lock;
-+
-+#endif /* __KERNEL__ */
-+
-+#endif /* __XEN_ASM_PCIFRONT_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/public/evtchn.h linux-2.6.16.33/include/xen/public/evtchn.h
---- linux-2.6.16.33-noxen/include/xen/public/evtchn.h  1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/public/evtchn.h        2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,88 @@
-+/******************************************************************************
-+ * evtchn.h
-+ * 
-+ * Interface to /dev/xen/evtchn.
-+ * 
-+ * Copyright (c) 2003-2005, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __LINUX_PUBLIC_EVTCHN_H__
-+#define __LINUX_PUBLIC_EVTCHN_H__
-+
-+/*
-+ * Bind a fresh port to VIRQ @virq.
-+ * Return allocated port.
-+ */
-+#define IOCTL_EVTCHN_BIND_VIRQ                                \
-+      _IOC(_IOC_NONE, 'E', 0, sizeof(struct ioctl_evtchn_bind_virq))
-+struct ioctl_evtchn_bind_virq {
-+      unsigned int virq;
-+};
-+
-+/*
-+ * Bind a fresh port to remote <@remote_domain, @remote_port>.
-+ * Return allocated port.
-+ */
-+#define IOCTL_EVTCHN_BIND_INTERDOMAIN                 \
-+      _IOC(_IOC_NONE, 'E', 1, sizeof(struct ioctl_evtchn_bind_interdomain))
-+struct ioctl_evtchn_bind_interdomain {
-+      unsigned int remote_domain, remote_port;
-+};
-+
-+/*
-+ * Allocate a fresh port for binding to @remote_domain.
-+ * Return allocated port.
-+ */
-+#define IOCTL_EVTCHN_BIND_UNBOUND_PORT                        \
-+      _IOC(_IOC_NONE, 'E', 2, sizeof(struct ioctl_evtchn_bind_unbound_port))
-+struct ioctl_evtchn_bind_unbound_port {
-+      unsigned int remote_domain;
-+};
-+
-+/*
-+ * Unbind previously allocated @port.
-+ */
-+#define IOCTL_EVTCHN_UNBIND                           \
-+      _IOC(_IOC_NONE, 'E', 3, sizeof(struct ioctl_evtchn_unbind))
-+struct ioctl_evtchn_unbind {
-+      unsigned int port;
-+};
-+
-+/*
-+ * Unbind previously allocated @port.
-+ */
-+#define IOCTL_EVTCHN_NOTIFY                           \
-+      _IOC(_IOC_NONE, 'E', 4, sizeof(struct ioctl_evtchn_notify))
-+struct ioctl_evtchn_notify {
-+      unsigned int port;
-+};
-+
-+/* Clear and reinitialise the event buffer. Clear error condition. */
-+#define IOCTL_EVTCHN_RESET                            \
-+      _IOC(_IOC_NONE, 'E', 5, 0)
-+
-+#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/public/privcmd.h linux-2.6.16.33/include/xen/public/privcmd.h
---- linux-2.6.16.33-noxen/include/xen/public/privcmd.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/public/privcmd.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,79 @@
-+/******************************************************************************
-+ * privcmd.h
-+ * 
-+ * Interface to /proc/xen/privcmd.
-+ * 
-+ * Copyright (c) 2003-2005, K A Fraser
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef __LINUX_PUBLIC_PRIVCMD_H__
-+#define __LINUX_PUBLIC_PRIVCMD_H__
-+
-+#include <linux/types.h>
-+
-+#ifndef __user
-+#define __user
-+#endif
-+
-+typedef struct privcmd_hypercall
-+{
-+      __u64 op;
-+      __u64 arg[5];
-+} privcmd_hypercall_t;
-+
-+typedef struct privcmd_mmap_entry {
-+      __u64 va;
-+      __u64 mfn;
-+      __u64 npages;
-+} privcmd_mmap_entry_t; 
-+
-+typedef struct privcmd_mmap {
-+      int num;
-+      domid_t dom; /* target domain */
-+      privcmd_mmap_entry_t __user *entry;
-+} privcmd_mmap_t; 
-+
-+typedef struct privcmd_mmapbatch {
-+      int num;     /* number of pages to populate */
-+      domid_t dom; /* target domain */
-+      __u64 addr;  /* virtual address */
-+      xen_pfn_t __user *arr; /* array of mfns - top nibble set on err */
-+} privcmd_mmapbatch_t; 
-+
-+/*
-+ * @cmd: IOCTL_PRIVCMD_HYPERCALL
-+ * @arg: &privcmd_hypercall_t
-+ * Return: Value returned from execution of the specified hypercall.
-+ */
-+#define IOCTL_PRIVCMD_HYPERCALL                                       \
-+      _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
-+#define IOCTL_PRIVCMD_MMAP                                    \
-+      _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
-+#define IOCTL_PRIVCMD_MMAPBATCH                                       \
-+      _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
-+
-+#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/xen_proc.h linux-2.6.16.33/include/xen/xen_proc.h
---- linux-2.6.16.33-noxen/include/xen/xen_proc.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/xen_proc.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,13 @@
-+
-+#ifndef __ASM_XEN_PROC_H__
-+#define __ASM_XEN_PROC_H__
-+
-+#include <linux/config.h>
-+#include <linux/proc_fs.h>
-+
-+extern struct proc_dir_entry *create_xen_proc_entry(
-+      const char *name, mode_t mode);
-+extern void remove_xen_proc_entry(
-+      const char *name);
-+
-+#endif /* __ASM_XEN_PROC_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/xenbus.h linux-2.6.16.33/include/xen/xenbus.h
---- linux-2.6.16.33-noxen/include/xen/xenbus.h 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/xenbus.h       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,307 @@
-+/******************************************************************************
-+ * xenbus.h
-+ *
-+ * Talks to Xen Store to figure out what devices we have.
-+ *
-+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
-+ * Copyright (C) 2005 XenSource Ltd.
-+ * 
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation; or, when distributed
-+ * separately from the Linux kernel or incorporated into other
-+ * software packages, subject to the following license:
-+ * 
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this source file (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy, modify,
-+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so, subject to
-+ * the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+
-+#ifndef _XEN_XENBUS_H
-+#define _XEN_XENBUS_H
-+
-+#include <linux/device.h>
-+#include <linux/notifier.h>
-+#include <linux/mutex.h>
-+#include <linux/completion.h>
-+#include <linux/init.h>
-+#include <xen/interface/xen.h>
-+#include <xen/interface/grant_table.h>
-+#include <xen/interface/io/xenbus.h>
-+#include <xen/interface/io/xs_wire.h>
-+
-+/* Register callback to watch this node. */
-+struct xenbus_watch
-+{
-+      struct list_head list;
-+
-+      /* Path being watched. */
-+      const char *node;
-+
-+      /* Callback (executed in a process context with no locks held). */
-+      void (*callback)(struct xenbus_watch *,
-+                       const char **vec, unsigned int len);
-+
-+      /* See XBWF_ definitions below. */
-+      unsigned long flags;
-+};
-+
-+/*
-+ * Execute callback in its own kthread. Useful if the callback is long
-+ * running or heavily serialised, to avoid taking out the main xenwatch thread
-+ * for a long period of time (or even unwittingly causing a deadlock).
-+ */
-+#define XBWF_new_thread       1
-+
-+/* A xenbus device. */
-+struct xenbus_device {
-+      const char *devicetype;
-+      const char *nodename;
-+      const char *otherend;
-+      int otherend_id;
-+      struct xenbus_watch otherend_watch;
-+      struct device dev;
-+      enum xenbus_state state;
-+      struct completion down;
-+};
-+
-+static inline struct xenbus_device *to_xenbus_device(struct device *dev)
-+{
-+      return container_of(dev, struct xenbus_device, dev);
-+}
-+
-+struct xenbus_device_id
-+{
-+      /* .../device/<device_type>/<identifier> */
-+      char devicetype[32];    /* General class of device. */
-+};
-+
-+/* A xenbus driver. */
-+struct xenbus_driver {
-+      char *name;
-+      struct module *owner;
-+      const struct xenbus_device_id *ids;
-+      int (*probe)(struct xenbus_device *dev,
-+                   const struct xenbus_device_id *id);
-+      void (*otherend_changed)(struct xenbus_device *dev,
-+                               enum xenbus_state backend_state);
-+      int (*remove)(struct xenbus_device *dev);
-+      int (*suspend)(struct xenbus_device *dev);
-+      int (*resume)(struct xenbus_device *dev);
-+      int (*uevent)(struct xenbus_device *, char **, int, char *, int);
-+      struct device_driver driver;
-+      int (*read_otherend_details)(struct xenbus_device *dev);
-+};
-+
-+static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)
-+{
-+      return container_of(drv, struct xenbus_driver, driver);
-+}
-+
-+int xenbus_register_frontend(struct xenbus_driver *drv);
-+int xenbus_register_backend(struct xenbus_driver *drv);
-+void xenbus_unregister_driver(struct xenbus_driver *drv);
-+
-+struct xenbus_transaction
-+{
-+      u32 id;
-+};
-+
-+/* Nil transaction ID. */
-+#define XBT_NIL ((struct xenbus_transaction) { 0 })
-+
-+char **xenbus_directory(struct xenbus_transaction t,
-+                      const char *dir, const char *node, unsigned int *num);
-+void *xenbus_read(struct xenbus_transaction t,
-+                const char *dir, const char *node, unsigned int *len);
-+int xenbus_write(struct xenbus_transaction t,
-+               const char *dir, const char *node, const char *string);
-+int xenbus_mkdir(struct xenbus_transaction t,
-+               const char *dir, const char *node);
-+int xenbus_exists(struct xenbus_transaction t,
-+                const char *dir, const char *node);
-+int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node);
-+int xenbus_transaction_start(struct xenbus_transaction *t);
-+int xenbus_transaction_end(struct xenbus_transaction t, int abort);
-+
-+/* Single read and scanf: returns -errno or num scanned if > 0. */
-+int xenbus_scanf(struct xenbus_transaction t,
-+               const char *dir, const char *node, const char *fmt, ...)
-+      __attribute__((format(scanf, 4, 5)));
-+
-+/* Single printf and write: returns -errno or 0. */
-+int xenbus_printf(struct xenbus_transaction t,
-+                const char *dir, const char *node, const char *fmt, ...)
-+      __attribute__((format(printf, 4, 5)));
-+
-+/* Generic read function: NULL-terminated triples of name,
-+ * sprintf-style type string, and pointer. Returns 0 or errno.*/
-+int xenbus_gather(struct xenbus_transaction t, const char *dir, ...);
-+
-+/* notifer routines for when the xenstore comes up */
-+int register_xenstore_notifier(struct notifier_block *nb);
-+void unregister_xenstore_notifier(struct notifier_block *nb);
-+
-+int register_xenbus_watch(struct xenbus_watch *watch);
-+void unregister_xenbus_watch(struct xenbus_watch *watch);
-+void xs_suspend(void);
-+void xs_resume(void);
-+
-+/* Used by xenbus_dev to borrow kernel's store connection. */
-+void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
-+
-+/* Called from xen core code. */
-+void xenbus_suspend(void);
-+void xenbus_resume(void);
-+
-+#define XENBUS_IS_ERR_READ(str) ({                    \
-+      if (!IS_ERR(str) && strlen(str) == 0) {         \
-+              kfree(str);                             \
-+              str = ERR_PTR(-ERANGE);                 \
-+      }                                               \
-+      IS_ERR(str);                                    \
-+})
-+
-+#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
-+
-+
-+/**
-+ * Register a watch on the given path, using the given xenbus_watch structure
-+ * for storage, and the given callback function as the callback.  Return 0 on
-+ * success, or -errno on error.  On success, the given path will be saved as
-+ * watch->node, and remains the caller's to free.  On error, watch->node will
-+ * be NULL, the device will switch to XenbusStateClosing, and the error will
-+ * be saved in the store.
-+ */
-+int xenbus_watch_path(struct xenbus_device *dev, const char *path,
-+                    struct xenbus_watch *watch,
-+                    void (*callback)(struct xenbus_watch *,
-+                                     const char **, unsigned int));
-+
-+
-+/**
-+ * Register a watch on the given path/path2, using the given xenbus_watch
-+ * structure for storage, and the given callback function as the callback.
-+ * Return 0 on success, or -errno on error.  On success, the watched path
-+ * (path/path2) will be saved as watch->node, and becomes the caller's to
-+ * kfree().  On error, watch->node will be NULL, so the caller has nothing to
-+ * free, the device will switch to XenbusStateClosing, and the error will be
-+ * saved in the store.
-+ */
-+int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
-+                     const char *path2, struct xenbus_watch *watch,
-+                     void (*callback)(struct xenbus_watch *,
-+                                      const char **, unsigned int));
-+
-+
-+/**
-+ * Advertise in the store a change of the given driver to the given new_state.
-+ * Return 0 on success, or -errno on error.  On error, the device will switch
-+ * to XenbusStateClosing, and the error will be saved in the store.
-+ */
-+int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state new_state);
-+
-+
-+/**
-+ * Grant access to the given ring_mfn to the peer of the given device.  Return
-+ * 0 on success, or -errno on error.  On error, the device will switch to
-+ * XenbusStateClosing, and the error will be saved in the store.
-+ */
-+int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
-+
-+
-+/**
-+ * Map a page of memory into this domain from another domain's grant table.
-+ * xenbus_map_ring_valloc allocates a page of virtual address space, maps the
-+ * page to that address, and sets *vaddr to that address.
-+ * xenbus_map_ring does not allocate the virtual address space (you must do
-+ * this yourself!). It only maps in the page to the specified address.
-+ * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h)
-+ * or -ENOMEM on error. If an error is returned, device will switch to
-+ * XenbusStateClosing and the error message will be saved in XenStore.
-+ */
-+struct vm_struct *xenbus_map_ring_valloc(struct xenbus_device *dev,
-+                                       int gnt_ref);
-+int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
-+                         grant_handle_t *handle, void *vaddr);
-+
-+
-+/**
-+ * Unmap a page of memory in this domain that was imported from another domain.
-+ * Use xenbus_unmap_ring_vfree if you mapped in your memory with
-+ * xenbus_map_ring_valloc (it will free the virtual address space).
-+ * Returns 0 on success and returns GNTST_* on error
-+ * (see xen/include/interface/grant_table.h).
-+ */
-+int xenbus_unmap_ring_vfree(struct xenbus_device *dev, struct vm_struct *);
-+int xenbus_unmap_ring(struct xenbus_device *dev,
-+                    grant_handle_t handle, void *vaddr);
-+
-+
-+/**
-+ * Allocate an event channel for the given xenbus_device, assigning the newly
-+ * created local port to *port.  Return 0 on success, or -errno on error.  On
-+ * error, the device will switch to XenbusStateClosing, and the error will be
-+ * saved in the store.
-+ */
-+int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
-+
-+
-+/**
-+ * Bind to an existing interdomain event channel in another domain. Returns 0
-+ * on success and stores the local port in *port. On error, returns -errno,
-+ * switches the device to XenbusStateClosing, and saves the error in XenStore.
-+ */
-+int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port);
-+
-+
-+/**
-+ * Free an existing event channel. Returns 0 on success or -errno on error.
-+ */
-+int xenbus_free_evtchn(struct xenbus_device *dev, int port);
-+
-+
-+/**
-+ * Return the state of the driver rooted at the given store path, or
-+ * XenbusStateUnknown if no state can be read.
-+ */
-+enum xenbus_state xenbus_read_driver_state(const char *path);
-+
-+
-+/***
-+ * Report the given negative errno into the store, along with the given
-+ * formatted message.
-+ */
-+void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
-+                    ...);
-+
-+
-+/***
-+ * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
-+ * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
-+ * closedown of this driver and its peer.
-+ */
-+void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
-+                    ...);
-+
-+int __init xenbus_dev_init(void);
-+
-+char *xenbus_strstate(enum xenbus_state state);
-+int xenbus_dev_is_online(struct xenbus_device *dev);
-+int xenbus_frontend_closed(struct xenbus_device *dev);
-+
-+#endif /* _XEN_XENBUS_H */
-diff -Nur linux-2.6.16.33-noxen/include/xen/xencons.h linux-2.6.16.33/include/xen/xencons.h
---- linux-2.6.16.33-noxen/include/xen/xencons.h        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/xencons.h      2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,19 @@
-+#ifndef __ASM_XENCONS_H__
-+#define __ASM_XENCONS_H__
-+
-+struct dom0_vga_console_info;
-+void dom0_init_screen_info(const struct dom0_vga_console_info *info);
-+
-+void xencons_force_flush(void);
-+void xencons_resume(void);
-+
-+/* Interrupt work hooks. Receive data, or kick data out. */
-+void xencons_rx(char *buf, unsigned len, struct pt_regs *regs);
-+void xencons_tx(void);
-+
-+int xencons_ring_init(void);
-+int xencons_ring_send(const char *data, unsigned len);
-+
-+void xencons_early_setup(void);
-+
-+#endif /* __ASM_XENCONS_H__ */
-diff -Nur linux-2.6.16.33-noxen/include/xen/xenoprof.h linux-2.6.16.33/include/xen/xenoprof.h
---- linux-2.6.16.33-noxen/include/xen/xenoprof.h       1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/include/xen/xenoprof.h     2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,42 @@
-+/******************************************************************************
-+ * xen/xenoprof.h
-+ *
-+ * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
-+ *                    VA Linux Systems Japan K.K.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+
-+#ifndef __XEN_XENOPROF_H__
-+#define __XEN_XENOPROF_H__
-+#ifdef CONFIG_XEN
-+
-+#include <asm/xenoprof.h>
-+
-+struct oprofile_operations;
-+int xenoprofile_init(struct oprofile_operations * ops);
-+void xenoprofile_exit(void);
-+
-+struct xenoprof_shared_buffer {
-+      char                                    *buffer;
-+      struct xenoprof_arch_shared_buffer      arch;
-+};
-+#else
-+#define xenoprofile_init(ops) (-ENOSYS)
-+#define xenoprofile_exit()    do { } while (0)
-+
-+#endif /* CONFIG_XEN */
-+#endif /* __XEN_XENOPROF_H__ */
-diff -Nur linux-2.6.16.33-noxen/kernel/Kconfig.preempt linux-2.6.16.33/kernel/Kconfig.preempt
---- linux-2.6.16.33-noxen/kernel/Kconfig.preempt       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/kernel/Kconfig.preempt     2007-01-08 15:00:46.000000000 +0000
-@@ -35,6 +35,7 @@
- config PREEMPT
-       bool "Preemptible Kernel (Low-Latency Desktop)"
-+      depends on !XEN
-       help
-         This option reduces the latency of the kernel by making
-         all kernel code (that is not executing in a critical section)
-diff -Nur linux-2.6.16.33-noxen/kernel/fork.c linux-2.6.16.33/kernel/fork.c
---- linux-2.6.16.33-noxen/kernel/fork.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/kernel/fork.c      2007-01-08 15:00:46.000000000 +0000
-@@ -274,6 +274,9 @@
-               if (retval)
-                       goto out;
-       }
-+#ifdef arch_dup_mmap
-+      arch_dup_mmap(mm, oldmm);
-+#endif
-       retval = 0;
- out:
-       up_write(&mm->mmap_sem);
-diff -Nur linux-2.6.16.33-noxen/kernel/irq/spurious.c linux-2.6.16.33/kernel/irq/spurious.c
---- linux-2.6.16.33-noxen/kernel/irq/spurious.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/kernel/irq/spurious.c      2007-01-08 15:00:46.000000000 +0000
-@@ -137,7 +137,8 @@
-                       struct pt_regs *regs)
- {
-       if (action_ret != IRQ_HANDLED) {
--              desc->irqs_unhandled++;
-+              if (!irq_ignore_unhandled(irq))
-+                      desc->irqs_unhandled++;
-               if (action_ret != IRQ_NONE)
-                       report_bad_irq(irq, desc, action_ret);
-       }
-diff -Nur linux-2.6.16.33-noxen/kernel/kexec.c linux-2.6.16.33/kernel/kexec.c
---- linux-2.6.16.33-noxen/kernel/kexec.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/kernel/kexec.c     2007-01-08 15:00:46.000000000 +0000
-@@ -403,7 +403,7 @@
-               pages = kimage_alloc_pages(GFP_KERNEL, order);
-               if (!pages)
-                       break;
--              pfn   = page_to_pfn(pages);
-+              pfn   = kexec_page_to_pfn(pages);
-               epfn  = pfn + count;
-               addr  = pfn << PAGE_SHIFT;
-               eaddr = epfn << PAGE_SHIFT;
-@@ -437,6 +437,7 @@
-       return pages;
- }
-+#ifndef CONFIG_XEN
- static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
-                                                     unsigned int order)
- {
-@@ -490,7 +491,7 @@
-               }
-               /* If I don't overlap any segments I have found my hole! */
-               if (i == image->nr_segments) {
--                      pages = pfn_to_page(hole_start >> PAGE_SHIFT);
-+                      pages = kexec_pfn_to_page(hole_start >> PAGE_SHIFT);
-                       break;
-               }
-       }
-@@ -517,6 +518,13 @@
-       return pages;
- }
-+#else /* !CONFIG_XEN */
-+struct page *kimage_alloc_control_pages(struct kimage *image,
-+                                       unsigned int order)
-+{
-+      return kimage_alloc_normal_control_pages(image, order);
-+}
-+#endif
- static int kimage_add_entry(struct kimage *image, kimage_entry_t entry)
- {
-@@ -532,7 +540,7 @@
-                       return -ENOMEM;
-               ind_page = page_address(page);
--              *image->entry = virt_to_phys(ind_page) | IND_INDIRECTION;
-+              *image->entry = kexec_virt_to_phys(ind_page) | IND_INDIRECTION;
-               image->entry = ind_page;
-               image->last_entry = ind_page +
-                                     ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1);
-@@ -593,13 +601,13 @@
- #define for_each_kimage_entry(image, ptr, entry) \
-       for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \
-               ptr = (entry & IND_INDIRECTION)? \
--                      phys_to_virt((entry & PAGE_MASK)): ptr +1)
-+                      kexec_phys_to_virt((entry & PAGE_MASK)): ptr +1)
- static void kimage_free_entry(kimage_entry_t entry)
- {
-       struct page *page;
--      page = pfn_to_page(entry >> PAGE_SHIFT);
-+      page = kexec_pfn_to_page(entry >> PAGE_SHIFT);
-       kimage_free_pages(page);
- }
-@@ -611,6 +619,10 @@
-       if (!image)
-               return;
-+#ifdef CONFIG_XEN
-+      xen_machine_kexec_unload(image);
-+#endif
-+
-       kimage_free_extra_pages(image);
-       for_each_kimage_entry(image, ptr, entry) {
-               if (entry & IND_INDIRECTION) {
-@@ -686,7 +698,7 @@
-        * have a match.
-        */
-       list_for_each_entry(page, &image->dest_pages, lru) {
--              addr = page_to_pfn(page) << PAGE_SHIFT;
-+              addr = kexec_page_to_pfn(page) << PAGE_SHIFT;
-               if (addr == destination) {
-                       list_del(&page->lru);
-                       return page;
-@@ -701,12 +713,12 @@
-               if (!page)
-                       return NULL;
-               /* If the page cannot be used file it away */
--              if (page_to_pfn(page) >
-+              if (kexec_page_to_pfn(page) >
-                               (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
-                       list_add(&page->lru, &image->unuseable_pages);
-                       continue;
-               }
--              addr = page_to_pfn(page) << PAGE_SHIFT;
-+              addr = kexec_page_to_pfn(page) << PAGE_SHIFT;
-               /* If it is the destination page we want use it */
-               if (addr == destination)
-@@ -729,7 +741,7 @@
-                       struct page *old_page;
-                       old_addr = *old & PAGE_MASK;
--                      old_page = pfn_to_page(old_addr >> PAGE_SHIFT);
-+                      old_page = kexec_pfn_to_page(old_addr >> PAGE_SHIFT);
-                       copy_highpage(page, old_page);
-                       *old = addr | (*old & ~PAGE_MASK);
-@@ -779,7 +791,7 @@
-                       result  = -ENOMEM;
-                       goto out;
-               }
--              result = kimage_add_page(image, page_to_pfn(page)
-+              result = kimage_add_page(image, kexec_page_to_pfn(page)
-                                                               << PAGE_SHIFT);
-               if (result < 0)
-                       goto out;
-@@ -811,6 +823,7 @@
-       return result;
- }
-+#ifndef CONFIG_XEN
- static int kimage_load_crash_segment(struct kimage *image,
-                                       struct kexec_segment *segment)
- {
-@@ -833,7 +846,7 @@
-               char *ptr;
-               size_t uchunk, mchunk;
--              page = pfn_to_page(maddr >> PAGE_SHIFT);
-+              page = kexec_pfn_to_page(maddr >> PAGE_SHIFT);
-               if (page == 0) {
-                       result  = -ENOMEM;
-                       goto out;
-@@ -881,6 +894,13 @@
-       return result;
- }
-+#else /* CONFIG_XEN */
-+static int kimage_load_segment(struct kimage *image,
-+                              struct kexec_segment *segment)
-+{
-+      return kimage_load_normal_segment(image, segment);
-+}
-+#endif
- /*
-  * Exec Kernel system call: for obvious reasons only root may call it.
-@@ -991,6 +1011,11 @@
-               if (result)
-                       goto out;
-       }
-+#ifdef CONFIG_XEN
-+      result = xen_machine_kexec_load(image);
-+      if (result)
-+              goto out;
-+#endif
-       /* Install the new kernel, and  Uninstall the old */
-       image = xchg(dest_image, image);
-@@ -1045,7 +1070,6 @@
-       struct kimage *image;
-       int locked;
--
-       /* Take the kexec_lock here to prevent sys_kexec_load
-        * running on one cpu from replacing the crash kernel
-        * we are using after a panic on a different cpu.
-diff -Nur linux-2.6.16.33-noxen/kernel/rcupdate.c linux-2.6.16.33/kernel/rcupdate.c
---- linux-2.6.16.33-noxen/kernel/rcupdate.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/kernel/rcupdate.c  2007-05-23 21:00:01.000000000 +0000
-@@ -485,6 +485,20 @@
-               __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu));
- }
-+/*
-+ * Check to see if any future RCU-related work will need to be done
-+ * by the current CPU, even if none need be done immediately, returning
-+ * 1 if so.  This function is part of the RCU implementation; it is -not-
-+ * an exported member of the RCU API.
-+ */
-+int rcu_needs_cpu(int cpu)
-+{
-+      struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
-+      struct rcu_data *rdp_bh = &per_cpu(rcu_bh_data, cpu);
-+
-+      return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu));
-+}
-+
- void rcu_check_callbacks(int cpu, int user)
- {
-       if (user || 
-diff -Nur linux-2.6.16.33-noxen/kernel/timer.c linux-2.6.16.33/kernel/timer.c
---- linux-2.6.16.33-noxen/kernel/timer.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/kernel/timer.c     2007-05-23 21:00:01.000000000 +0000
-@@ -555,6 +555,22 @@
-       }
-       spin_unlock(&base->t_base.lock);
-+      /*
-+       * It can happen that other CPUs service timer IRQs and increment
-+       * jiffies, but we have not yet got a local timer tick to process
-+       * the timer wheels.  In that case, the expiry time can be before
-+       * jiffies, but since the high-resolution timer here is relative to
-+       * jiffies, the default expression when high-resolution timers are
-+       * not active,
-+       *
-+       *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
-+       *
-+       * would falsely evaluate to true.  If that is the case, just
-+       * return jiffies so that we can immediately fire the local timer
-+       */
-+      if (time_before(expires, jiffies))
-+              return jiffies;
-+
-       if (time_before(hr_expires, expires))
-               return hr_expires;
-diff -Nur linux-2.6.16.33-noxen/lib/Makefile linux-2.6.16.33/lib/Makefile
---- linux-2.6.16.33-noxen/lib/Makefile 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/lib/Makefile       2007-01-08 15:00:46.000000000 +0000
-@@ -45,6 +45,7 @@
- obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
- obj-$(CONFIG_SWIOTLB) += swiotlb.o
-+swiotlb-$(CONFIG_XEN) := ../arch/i386/kernel/swiotlb.o
- hostprogs-y   := gen_crc32table
- clean-files   := crc32table.h
-diff -Nur linux-2.6.16.33-noxen/lib/vsprintf.c linux-2.6.16.33/lib/vsprintf.c
---- linux-2.6.16.33-noxen/lib/vsprintf.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/lib/vsprintf.c     2007-05-23 21:00:01.000000000 +0000
-@@ -187,49 +187,49 @@
-       size -= precision;
-       if (!(type&(ZEROPAD+LEFT))) {
-               while(size-->0) {
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = ' ';
-                       ++buf;
-               }
-       }
-       if (sign) {
--              if (buf <= end)
-+              if (buf < end)
-                       *buf = sign;
-               ++buf;
-       }
-       if (type & SPECIAL) {
-               if (base==8) {
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = '0';
-                       ++buf;
-               } else if (base==16) {
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = '0';
-                       ++buf;
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = digits[33];
-                       ++buf;
-               }
-       }
-       if (!(type & LEFT)) {
-               while (size-- > 0) {
--                      if (buf <= end)
-+                      if (buf < end)
-                               *buf = c;
-                       ++buf;
-               }
-       }
-       while (i < precision--) {
--              if (buf <= end)
-+              if (buf < end)
-                       *buf = '0';
-               ++buf;
-       }
-       while (i-- > 0) {
--              if (buf <= end)
-+              if (buf < end)
-                       *buf = tmp[i];
-               ++buf;
-       }
-       while (size-- > 0) {
--              if (buf <= end)
-+              if (buf < end)
-                       *buf = ' ';
-               ++buf;
-       }
-@@ -272,7 +272,8 @@
-                               /* 'z' changed to 'Z' --davidm 1/25/99 */
-                               /* 't' added for ptrdiff_t */
--      /* Reject out-of-range values early */
-+      /* Reject out-of-range values early.  Large positive sizes are
-+         used for unknown buffer sizes. */
-       if (unlikely((int) size < 0)) {
-               /* There can be only one.. */
-               static int warn = 1;
-@@ -282,16 +283,17 @@
-       }
-       str = buf;
--      end = buf + size - 1;
-+      end = buf + size;
--      if (end < buf - 1) {
--              end = ((void *) -1);
--              size = end - buf + 1;
-+      /* Make sure end is always >= buf */
-+      if (end < buf) {
-+              end = ((void *)-1);
-+              size = end - buf;
-       }
-       for (; *fmt ; ++fmt) {
-               if (*fmt != '%') {
--                      if (str <= end)
-+                      if (str < end)
-                               *str = *fmt;
-                       ++str;
-                       continue;
-@@ -357,17 +359,17 @@
-                       case 'c':
-                               if (!(flags & LEFT)) {
-                                       while (--field_width > 0) {
--                                              if (str <= end)
-+                                              if (str < end)
-                                                       *str = ' ';
-                                               ++str;
-                                       }
-                               }
-                               c = (unsigned char) va_arg(args, int);
--                              if (str <= end)
-+                              if (str < end)
-                                       *str = c;
-                               ++str;
-                               while (--field_width > 0) {
--                                      if (str <= end)
-+                                      if (str < end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-@@ -382,18 +384,18 @@
-                               if (!(flags & LEFT)) {
-                                       while (len < field_width--) {
--                                              if (str <= end)
-+                                              if (str < end)
-                                                       *str = ' ';
-                                               ++str;
-                                       }
-                               }
-                               for (i = 0; i < len; ++i) {
--                                      if (str <= end)
-+                                      if (str < end)
-                                               *str = *s;
-                                       ++str; ++s;
-                               }
-                               while (len < field_width--) {
--                                      if (str <= end)
-+                                      if (str < end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-@@ -426,7 +428,7 @@
-                               continue;
-                       case '%':
--                              if (str <= end)
-+                              if (str < end)
-                                       *str = '%';
-                               ++str;
-                               continue;
-@@ -449,11 +451,11 @@
-                               break;
-                       default:
--                              if (str <= end)
-+                              if (str < end)
-                                       *str = '%';
-                               ++str;
-                               if (*fmt) {
--                                      if (str <= end)
-+                                      if (str < end)
-                                               *str = *fmt;
-                                       ++str;
-                               } else {
-@@ -483,14 +485,13 @@
-               str = number(str, end, num, base,
-                               field_width, precision, flags);
-       }
--      if (str <= end)
--              *str = '\0';
--      else if (size > 0)
--              /* don't write out a null byte if the buf size is zero */
--              *end = '\0';
--      /* the trailing null byte doesn't count towards the total
--      * ++str;
--      */
-+      if (size > 0) {
-+              if (str < end)
-+                      *str = '\0';
-+              else
-+                      end[-1] = '\0';
-+      }
-+      /* the trailing null byte doesn't count towards the total */
-       return str-buf;
- }
-@@ -848,3 +849,26 @@
- }
- EXPORT_SYMBOL(sscanf);
-+
-+
-+/* Simplified asprintf. */
-+char *kasprintf(gfp_t gfp, const char *fmt, ...)
-+{
-+      va_list ap;
-+      unsigned int len;
-+      char *p;
-+
-+      va_start(ap, fmt);
-+      len = vsnprintf(NULL, 0, fmt, ap);
-+      va_end(ap);
-+
-+      p = kmalloc(len+1, gfp);
-+      if (!p)
-+              return NULL;
-+      va_start(ap, fmt);
-+      vsnprintf(p, len+1, fmt, ap);
-+      va_end(ap);
-+      return p;
-+}
-+
-+EXPORT_SYMBOL(kasprintf);
-diff -Nur linux-2.6.16.33-noxen/mm/Kconfig linux-2.6.16.33/mm/Kconfig
---- linux-2.6.16.33-noxen/mm/Kconfig   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/mm/Kconfig 2007-01-08 15:00:46.000000000 +0000
-@@ -126,11 +126,14 @@
- # Default to 4 for wider testing, though 8 might be more appropriate.
- # ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
- # PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes.
-+# XEN on x86 architecture uses the mapping field on pagetable pages to store a
-+# pointer to the destructor. This conflicts with pte_lock_deinit().
- #
- config SPLIT_PTLOCK_CPUS
-       int
-       default "4096" if ARM && !CPU_CACHE_VIPT
-       default "4096" if PARISC && !PA20
-+      default "4096" if X86_XEN || X86_64_XEN
-       default "4"
- #
-diff -Nur linux-2.6.16.33-noxen/mm/highmem.c linux-2.6.16.33/mm/highmem.c
---- linux-2.6.16.33-noxen/mm/highmem.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/mm/highmem.c       2007-01-08 15:00:46.000000000 +0000
-@@ -152,6 +152,17 @@
-       return vaddr;
- }
-+#ifdef CONFIG_XEN
-+void kmap_flush_unused(void)
-+{
-+      spin_lock(&kmap_lock);
-+      flush_all_zero_pkmaps();
-+      spin_unlock(&kmap_lock);
-+}
-+
-+EXPORT_SYMBOL(kmap_flush_unused);
-+#endif
-+
- void fastcall *kmap_high(struct page *page)
- {
-       unsigned long vaddr;
-diff -Nur linux-2.6.16.33-noxen/mm/memory.c linux-2.6.16.33/mm/memory.c
---- linux-2.6.16.33-noxen/mm/memory.c  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/mm/memory.c        2007-01-08 15:00:46.000000000 +0000
-@@ -405,7 +405,8 @@
-        * Remove this test eventually!
-        */
-       if (unlikely(!pfn_valid(pfn))) {
--              print_bad_pte(vma, pte, addr);
-+              if (!(vma->vm_flags & VM_RESERVED))
-+                      print_bad_pte(vma, pte, addr);
-               return NULL;
-       }
-@@ -881,6 +882,7 @@
-               tlb_finish_mmu(tlb, address, end);
-       return end;
- }
-+EXPORT_SYMBOL(zap_page_range);
- /*
-  * Do a quick page-table lookup for a single page.
-@@ -1020,6 +1022,26 @@
-                       continue;
-               }
-+#ifdef CONFIG_XEN
-+              if (vma && (vma->vm_flags & VM_FOREIGN)) {
-+                      struct page **map = vma->vm_private_data;
-+                      int offset = (start - vma->vm_start) >> PAGE_SHIFT;
-+                      if (map[offset] != NULL) {
-+                              if (pages) {
-+                                      struct page *page = map[offset];
-+                                      
-+                                      pages[i] = page;
-+                                      get_page(page);
-+                              }
-+                              if (vmas)
-+                                      vmas[i] = vma;
-+                              i++;
-+                              start += PAGE_SIZE;
-+                              len--;
-+                              continue;
-+                      }
-+              }
-+#endif
-               if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
-                               || !(vm_flags & vma->vm_flags))
-                       return i ? : -EFAULT;
-@@ -1359,6 +1381,102 @@
- }
- EXPORT_SYMBOL(remap_pfn_range);
-+#ifdef CONFIG_XEN
-+static inline int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
-+                                   unsigned long addr, unsigned long end,
-+                                   pte_fn_t fn, void *data)
-+{
-+      pte_t *pte;
-+      int err;
-+      struct page *pmd_page;
-+      spinlock_t *ptl;
-+
-+      pte = (mm == &init_mm) ?
-+              pte_alloc_kernel(pmd, addr) :
-+              pte_alloc_map_lock(mm, pmd, addr, &ptl);
-+      if (!pte)
-+              return -ENOMEM;
-+
-+      BUG_ON(pmd_huge(*pmd));
-+
-+      pmd_page = pmd_page(*pmd);
-+
-+      do {
-+              err = fn(pte, pmd_page, addr, data);
-+              if (err)
-+                      break;
-+      } while (pte++, addr += PAGE_SIZE, addr != end);
-+
-+      if (mm != &init_mm)
-+              pte_unmap_unlock(pte-1, ptl);
-+      return err;
-+}
-+
-+static inline int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
-+                                   unsigned long addr, unsigned long end,
-+                                   pte_fn_t fn, void *data)
-+{
-+      pmd_t *pmd;
-+      unsigned long next;
-+      int err;
-+
-+      pmd = pmd_alloc(mm, pud, addr);
-+      if (!pmd)
-+              return -ENOMEM;
-+      do {
-+              next = pmd_addr_end(addr, end);
-+              err = apply_to_pte_range(mm, pmd, addr, next, fn, data);
-+              if (err)
-+                      break;
-+      } while (pmd++, addr = next, addr != end);
-+      return err;
-+}
-+
-+static inline int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd,
-+                                   unsigned long addr, unsigned long end,
-+                                   pte_fn_t fn, void *data)
-+{
-+      pud_t *pud;
-+      unsigned long next;
-+      int err;
-+
-+      pud = pud_alloc(mm, pgd, addr);
-+      if (!pud)
-+              return -ENOMEM;
-+      do {
-+              next = pud_addr_end(addr, end);
-+              err = apply_to_pmd_range(mm, pud, addr, next, fn, data);
-+              if (err)
-+                      break;
-+      } while (pud++, addr = next, addr != end);
-+      return err;
-+}
-+
-+/*
-+ * Scan a region of virtual memory, filling in page tables as necessary
-+ * and calling a provided function on each leaf page table.
-+ */
-+int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
-+                      unsigned long size, pte_fn_t fn, void *data)
-+{
-+      pgd_t *pgd;
-+      unsigned long next;
-+      unsigned long end = addr + size;
-+      int err;
-+
-+      BUG_ON(addr >= end);
-+      pgd = pgd_offset(mm, addr);
-+      do {
-+              next = pgd_addr_end(addr, end);
-+              err = apply_to_pud_range(mm, pgd, addr, next, fn, data);
-+              if (err)
-+                      break;
-+      } while (pgd++, addr = next, addr != end);
-+      return err;
-+}
-+EXPORT_SYMBOL_GPL(apply_to_page_range);
-+#endif
-+
- /*
-  * handle_pte_fault chooses page fault handler according to an entry
-  * which was read non-atomically.  Before making any commitment, on
-diff -Nur linux-2.6.16.33-noxen/mm/mmap.c linux-2.6.16.33/mm/mmap.c
---- linux-2.6.16.33-noxen/mm/mmap.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/mm/mmap.c  2007-01-08 15:00:46.000000000 +0000
-@@ -1950,6 +1950,10 @@
-       unsigned long nr_accounted = 0;
-       unsigned long end;
-+#ifdef arch_exit_mmap
-+      arch_exit_mmap(mm);
-+#endif
-+
-       lru_add_drain();
-       flush_cache_mm(mm);
-       tlb = tlb_gather_mmu(mm, 1);
-diff -Nur linux-2.6.16.33-noxen/mm/page_alloc.c linux-2.6.16.33/mm/page_alloc.c
---- linux-2.6.16.33-noxen/mm/page_alloc.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/mm/page_alloc.c    2007-01-08 15:00:46.000000000 +0000
-@@ -422,7 +422,8 @@
-       int i;
-       int reserved = 0;
--      arch_free_page(page, order);
-+      if (arch_free_page(page, order))
-+              return;
-       if (!PageHighMem(page))
-               mutex_debug_check_no_locks_freed(page_address(page),
-                                                PAGE_SIZE<<order);
-@@ -716,7 +717,8 @@
-       struct per_cpu_pages *pcp;
-       unsigned long flags;
--      arch_free_page(page, 0);
-+      if (arch_free_page(page, 0))
-+              return;
-       if (PageAnon(page))
-               page->mapping = NULL;
-diff -Nur linux-2.6.16.33-noxen/net/atm/clip.c linux-2.6.16.33/net/atm/clip.c
---- linux-2.6.16.33-noxen/net/atm/clip.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/atm/clip.c     2007-05-23 21:00:01.000000000 +0000
-@@ -101,7 +101,7 @@
-               printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
-               return;
-       }
--      spin_lock_bh(&entry->neigh->dev->xmit_lock);    /* block clip_start_xmit() */
-+      netif_tx_lock_bh(entry->neigh->dev);    /* block clip_start_xmit() */
-       entry->neigh->used = jiffies;
-       for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
-               if (*walk == clip_vcc) {
-@@ -125,7 +125,7 @@
-       printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
-         "0x%p)\n",entry,clip_vcc);
- out:
--      spin_unlock_bh(&entry->neigh->dev->xmit_lock);
-+      netif_tx_unlock_bh(entry->neigh->dev);
- }
- /* The neighbour entry n->lock is held. */
-diff -Nur linux-2.6.16.33-noxen/net/bridge/br_device.c linux-2.6.16.33/net/bridge/br_device.c
---- linux-2.6.16.33-noxen/net/bridge/br_device.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/bridge/br_device.c     2007-05-23 21:00:01.000000000 +0000
-@@ -146,9 +146,9 @@
-       struct net_bridge *br = netdev_priv(dev);
-       if (data)
--              br->feature_mask |= NETIF_F_IP_CSUM;
-+              br->feature_mask |= NETIF_F_NO_CSUM;
-       else
--              br->feature_mask &= ~NETIF_F_IP_CSUM;
-+              br->feature_mask &= ~NETIF_F_ALL_CSUM;
-       br_features_recompute(br);
-       return 0;
-@@ -185,6 +185,6 @@
-       dev->set_mac_address = br_set_mac_address;
-       dev->priv_flags = IFF_EBRIDGE;
--      dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
--              | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
-+      dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
-+                      NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST;
- }
-diff -Nur linux-2.6.16.33-noxen/net/bridge/br_forward.c linux-2.6.16.33/net/bridge/br_forward.c
---- linux-2.6.16.33-noxen/net/bridge/br_forward.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/bridge/br_forward.c    2007-05-23 21:00:01.000000000 +0000
-@@ -32,7 +32,7 @@
- int br_dev_queue_push_xmit(struct sk_buff *skb)
- {
-       /* drop mtu oversized packets except tso */
--      if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
-+      if (skb->len > skb->dev->mtu && !skb_is_gso(skb))
-               kfree_skb(skb);
-       else {
- #ifdef CONFIG_BRIDGE_NETFILTER
-diff -Nur linux-2.6.16.33-noxen/net/bridge/br_if.c linux-2.6.16.33/net/bridge/br_if.c
---- linux-2.6.16.33-noxen/net/bridge/br_if.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/bridge/br_if.c 2007-05-23 21:00:01.000000000 +0000
-@@ -385,17 +385,28 @@
-       struct net_bridge_port *p;
-       unsigned long features, checksum;
--      features = br->feature_mask &~ NETIF_F_IP_CSUM;
--      checksum = br->feature_mask & NETIF_F_IP_CSUM;
-+      checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
-+      features = br->feature_mask & ~NETIF_F_ALL_CSUM;
-       list_for_each_entry(p, &br->port_list, list) {
--              if (!(p->dev->features 
--                    & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
-+              unsigned long feature = p->dev->features;
-+
-+              if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
-+                      checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
-+              if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
-+                      checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
-+              if (!(feature & NETIF_F_IP_CSUM))
-                       checksum = 0;
--              features &= p->dev->features;
-+
-+              if (feature & NETIF_F_GSO)
-+                      feature |= NETIF_F_TSO;
-+              feature |= NETIF_F_GSO;
-+
-+              features &= feature;
-       }
--      br->dev->features = features | checksum | NETIF_F_LLTX;
-+      br->dev->features = features | checksum | NETIF_F_LLTX |
-+                          NETIF_F_GSO_ROBUST;
- }
- /* called with RTNL */
-diff -Nur linux-2.6.16.33-noxen/net/bridge/br_netfilter.c linux-2.6.16.33/net/bridge/br_netfilter.c
---- linux-2.6.16.33-noxen/net/bridge/br_netfilter.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/bridge/br_netfilter.c  2007-05-23 21:00:01.000000000 +0000
-@@ -743,7 +743,7 @@
- {
-       if (skb->protocol == htons(ETH_P_IP) &&
-           skb->len > skb->dev->mtu &&
--          !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
-+          !skb_is_gso(skb))
-               return ip_fragment(skb, br_dev_queue_push_xmit);
-       else
-               return br_dev_queue_push_xmit(skb);
-diff -Nur linux-2.6.16.33-noxen/net/core/dev.c linux-2.6.16.33/net/core/dev.c
---- linux-2.6.16.33-noxen/net/core/dev.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/core/dev.c     2007-01-08 15:00:46.000000000 +0000
-@@ -115,6 +115,13 @@
- #include <net/iw_handler.h>
- #endif        /* CONFIG_NET_RADIO */
- #include <asm/current.h>
-+#include <linux/err.h>
-+
-+#ifdef CONFIG_XEN
-+#include <net/ip.h>
-+#include <linux/tcp.h>
-+#include <linux/udp.h>
-+#endif
- /*
-  *    The list of packet types we will receive (as opposed to discard)
-@@ -1032,7 +1039,7 @@
-  *    taps currently in use.
-  */
--void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
-+static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
- {
-       struct packet_type *ptype;
-@@ -1082,9 +1089,12 @@
-       unsigned int csum;
-       int ret = 0, offset = skb->h.raw - skb->data;
--      if (inward) {
--              skb->ip_summed = CHECKSUM_NONE;
--              goto out;
-+      if (inward)
-+              goto out_set_summed;
-+
-+      if (unlikely(skb_shinfo(skb)->gso_size)) {
-+              /* Let GSO fix up the checksum. */
-+              goto out_set_summed;
-       }
-       if (skb_cloned(skb)) {
-@@ -1101,11 +1111,65 @@
-       BUG_ON(skb->csum + 2 > offset);
-       *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
-+
-+out_set_summed:
-       skb->ip_summed = CHECKSUM_NONE;
- out:  
-       return ret;
- }
-+/**
-+ *    skb_gso_segment - Perform segmentation on skb.
-+ *    @skb: buffer to segment
-+ *    @features: features for the output path (see dev->features)
-+ *
-+ *    This function segments the given skb and returns a list of segments.
-+ *
-+ *    It may return NULL if the skb requires no segmentation.  This is
-+ *    only possible when GSO is used for verifying header integrity.
-+ */
-+struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
-+      struct packet_type *ptype;
-+      int type = skb->protocol;
-+      int err;
-+
-+      BUG_ON(skb_shinfo(skb)->frag_list);
-+
-+      skb->mac.raw = skb->data;
-+      skb->mac_len = skb->nh.raw - skb->data;
-+      __skb_pull(skb, skb->mac_len);
-+
-+      if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
-+              if (skb_header_cloned(skb) &&
-+                  (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
-+                      return ERR_PTR(err);
-+      }
-+
-+      rcu_read_lock();
-+      list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
-+              if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
-+                      if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
-+                              err = ptype->gso_send_check(skb);
-+                              segs = ERR_PTR(err);
-+                              if (err || skb_gso_ok(skb, features))
-+                                      break;
-+                              __skb_push(skb, skb->data - skb->nh.raw);
-+                      }
-+                      segs = ptype->gso_segment(skb, features);
-+                      break;
-+              }
-+      }
-+      rcu_read_unlock();
-+
-+      __skb_push(skb, skb->data - skb->mac.raw);
-+
-+      return segs;
-+}
-+
-+EXPORT_SYMBOL(skb_gso_segment);
-+
- /* Take action when hardware reception checksum errors are detected. */
- #ifdef CONFIG_BUG
- void netdev_rx_csum_fault(struct net_device *dev)
-@@ -1142,79 +1206,148 @@
- #define illegal_highdma(dev, skb)     (0)
- #endif
--/* Keep head the same: replace data */
--int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
-+struct dev_gso_cb {
-+      void (*destructor)(struct sk_buff *skb);
-+};
-+
-+#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
-+
-+static void dev_gso_skb_destructor(struct sk_buff *skb)
- {
--      unsigned int size;
--      u8 *data;
--      long offset;
--      struct skb_shared_info *ninfo;
--      int headerlen = skb->data - skb->head;
--      int expand = (skb->tail + skb->data_len) - skb->end;
--
--      if (skb_shared(skb))
--              BUG();
--
--      if (expand <= 0)
--              expand = 0;
--
--      size = skb->end - skb->head + expand;
--      size = SKB_DATA_ALIGN(size);
--      data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
--      if (!data)
--              return -ENOMEM;
--
--      /* Copy entire thing */
--      if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
--              BUG();
--
--      /* Set up shinfo */
--      ninfo = (struct skb_shared_info*)(data + size);
--      atomic_set(&ninfo->dataref, 1);
--      ninfo->tso_size = skb_shinfo(skb)->tso_size;
--      ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
--      ninfo->ufo_size = skb_shinfo(skb)->ufo_size;
--      ninfo->nr_frags = 0;
--      ninfo->frag_list = NULL;
--
--      /* Offset between the two in bytes */
--      offset = data - skb->head;
--
--      /* Free old data. */
--      skb_release_data(skb);
--
--      skb->head = data;
--      skb->end  = data + size;
--
--      /* Set up new pointers */
--      skb->h.raw   += offset;
--      skb->nh.raw  += offset;
--      skb->mac.raw += offset;
--      skb->tail    += offset;
--      skb->data    += offset;
-+      struct dev_gso_cb *cb;
-+
-+      do {
-+              struct sk_buff *nskb = skb->next;
--      /* We are no longer a clone, even if we were. */
--      skb->cloned    = 0;
-+              skb->next = nskb->next;
-+              nskb->next = NULL;
-+              kfree_skb(nskb);
-+      } while (skb->next);
-+
-+      cb = DEV_GSO_CB(skb);
-+      if (cb->destructor)
-+              cb->destructor(skb);
-+}
-+
-+/**
-+ *    dev_gso_segment - Perform emulated hardware segmentation on skb.
-+ *    @skb: buffer to segment
-+ *
-+ *    This function segments the given skb and stores the list of segments
-+ *    in skb->next.
-+ */
-+static int dev_gso_segment(struct sk_buff *skb)
-+{
-+      struct net_device *dev = skb->dev;
-+      struct sk_buff *segs;
-+      int features = dev->features & ~(illegal_highdma(dev, skb) ?
-+                                       NETIF_F_SG : 0);
-+
-+      segs = skb_gso_segment(skb, features);
-+
-+      /* Verifying header integrity only. */
-+      if (!segs)
-+              return 0;
-+
-+      if (unlikely(IS_ERR(segs)))
-+              return PTR_ERR(segs);
-+
-+      skb->next = segs;
-+      DEV_GSO_CB(skb)->destructor = skb->destructor;
-+      skb->destructor = dev_gso_skb_destructor;
--      skb->tail     += skb->data_len;
--      skb->data_len  = 0;
-+      return 0;
-+}
-+
-+int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      if (likely(!skb->next)) {
-+              if (netdev_nit)
-+                      dev_queue_xmit_nit(skb, dev);
-+
-+              if (netif_needs_gso(dev, skb)) {
-+                      if (unlikely(dev_gso_segment(skb)))
-+                              goto out_kfree_skb;
-+                      if (skb->next)
-+                              goto gso;
-+              }
-+
-+              return dev->hard_start_xmit(skb, dev);
-+      }
-+
-+gso:
-+      do {
-+              struct sk_buff *nskb = skb->next;
-+              int rc;
-+
-+              skb->next = nskb->next;
-+              nskb->next = NULL;
-+              rc = dev->hard_start_xmit(nskb, dev);
-+              if (unlikely(rc)) {
-+                      nskb->next = skb->next;
-+                      skb->next = nskb;
-+                      return rc;
-+              }
-+              if (unlikely(netif_queue_stopped(dev) && skb->next))
-+                      return NETDEV_TX_BUSY;
-+      } while (skb->next);
-+      
-+      skb->destructor = DEV_GSO_CB(skb)->destructor;
-+
-+out_kfree_skb:
-+      kfree_skb(skb);
-       return 0;
- }
- #define HARD_TX_LOCK(dev, cpu) {                      \
-       if ((dev->features & NETIF_F_LLTX) == 0) {      \
--              spin_lock(&dev->xmit_lock);             \
--              dev->xmit_lock_owner = cpu;             \
-+              netif_tx_lock(dev);                     \
-       }                                               \
- }
- #define HARD_TX_UNLOCK(dev) {                         \
-       if ((dev->features & NETIF_F_LLTX) == 0) {      \
--              dev->xmit_lock_owner = -1;              \
--              spin_unlock(&dev->xmit_lock);           \
-+              netif_tx_unlock(dev);                   \
-       }                                               \
- }
-+#ifdef CONFIG_XEN
-+inline int skb_checksum_setup(struct sk_buff *skb)
-+{
-+      if (skb->proto_csum_blank) {
-+              if (skb->protocol != htons(ETH_P_IP))
-+                      goto out;
-+              skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
-+              if (skb->h.raw >= skb->tail)
-+                      goto out;
-+              switch (skb->nh.iph->protocol) {
-+              case IPPROTO_TCP:
-+                      skb->csum = offsetof(struct tcphdr, check);
-+                      break;
-+              case IPPROTO_UDP:
-+                      skb->csum = offsetof(struct udphdr, check);
-+                      break;
-+              default:
-+                      if (net_ratelimit())
-+                              printk(KERN_ERR "Attempting to checksum a non-"
-+                                     "TCP/UDP packet, dropping a protocol"
-+                                     " %d packet", skb->nh.iph->protocol);
-+                      goto out;
-+              }
-+              if ((skb->h.raw + skb->csum + 2) > skb->tail)
-+                      goto out;
-+              skb->ip_summed = CHECKSUM_HW;
-+              skb->proto_csum_blank = 0;
-+      }
-+      return 0;
-+out:
-+      return -EPROTO;
-+}
-+#else
-+inline int skb_checksum_setup(struct sk_buff *skb) { return 0; }
-+#endif
-+
-+
- /**
-  *    dev_queue_xmit - transmit a buffer
-  *    @skb: buffer to transmit
-@@ -1247,9 +1380,19 @@
-       struct Qdisc *q;
-       int rc = -ENOMEM;
-+      /* If a checksum-deferred packet is forwarded to a device that needs a
-+       * checksum, correct the pointers and force checksumming.
-+       */
-+      if (skb_checksum_setup(skb))
-+              goto out_kfree_skb;
-+
-+      /* GSO will handle the following emulations directly. */
-+      if (netif_needs_gso(dev, skb))
-+              goto gso;
-+
-       if (skb_shinfo(skb)->frag_list &&
-           !(dev->features & NETIF_F_FRAGLIST) &&
--          __skb_linearize(skb, GFP_ATOMIC))
-+          __skb_linearize(skb))
-               goto out_kfree_skb;
-       /* Fragmented skb is linearized if device does not support SG,
-@@ -1258,25 +1401,26 @@
-        */
-       if (skb_shinfo(skb)->nr_frags &&
-           (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
--          __skb_linearize(skb, GFP_ATOMIC))
-+          __skb_linearize(skb))
-               goto out_kfree_skb;
-       /* If packet is not checksummed and device does not support
-        * checksumming for this protocol, complete checksumming here.
-        */
-       if (skb->ip_summed == CHECKSUM_HW &&
--          (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
-+          (!(dev->features & NETIF_F_GEN_CSUM) &&
-            (!(dev->features & NETIF_F_IP_CSUM) ||
-             skb->protocol != htons(ETH_P_IP))))
-               if (skb_checksum_help(skb, 0))
-                       goto out_kfree_skb;
-+gso:
-       spin_lock_prefetch(&dev->queue_lock);
-       /* Disable soft irqs for various locks below. Also 
-        * stops preemption for RCU. 
-        */
--      local_bh_disable(); 
-+      rcu_read_lock_bh(); 
-       /* Updates of qdisc are serialized by queue_lock. 
-        * The struct Qdisc which is pointed to by qdisc is now a 
-@@ -1310,8 +1454,8 @@
-       /* The device has no queue. Common case for software devices:
-          loopback, all the sorts of tunnels...
--         Really, it is unlikely that xmit_lock protection is necessary here.
--         (f.e. loopback and IP tunnels are clean ignoring statistics
-+         Really, it is unlikely that netif_tx_lock protection is necessary
-+         here.  (f.e. loopback and IP tunnels are clean ignoring statistics
-          counters.)
-          However, it is possible, that they rely on protection
-          made by us here.
-@@ -1327,11 +1471,8 @@
-                       HARD_TX_LOCK(dev, cpu);
-                       if (!netif_queue_stopped(dev)) {
--                              if (netdev_nit)
--                                      dev_queue_xmit_nit(skb, dev);
--
-                               rc = 0;
--                              if (!dev->hard_start_xmit(skb, dev)) {
-+                              if (!dev_hard_start_xmit(skb, dev)) {
-                                       HARD_TX_UNLOCK(dev);
-                                       goto out;
-                               }
-@@ -1350,13 +1491,13 @@
-       }
-       rc = -ENETDOWN;
--      local_bh_enable();
-+      rcu_read_unlock_bh();
- out_kfree_skb:
-       kfree_skb(skb);
-       return rc;
- out:
--      local_bh_enable();
-+      rcu_read_unlock_bh();
-       return rc;
- }
-@@ -1610,6 +1751,19 @@
-       }
- #endif
-+#ifdef CONFIG_XEN
-+      switch (skb->ip_summed) {
-+      case CHECKSUM_UNNECESSARY:
-+              skb->proto_data_valid = 1;
-+              break;
-+      case CHECKSUM_HW:
-+              /* XXX Implement me. */
-+      default:
-+              skb->proto_data_valid = 0;
-+              break;
-+      }
-+#endif
-+
-       list_for_each_entry_rcu(ptype, &ptype_all, list) {
-               if (!ptype->dev || ptype->dev == skb->dev) {
-                       if (pt_prev) 
-@@ -2671,7 +2825,7 @@
-       BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
-       spin_lock_init(&dev->queue_lock);
--      spin_lock_init(&dev->xmit_lock);
-+      spin_lock_init(&dev->_xmit_lock);
-       dev->xmit_lock_owner = -1;
- #ifdef CONFIG_NET_CLS_ACT
-       spin_lock_init(&dev->ingress_lock);
-@@ -2715,9 +2869,7 @@
-       /* Fix illegal SG+CSUM combinations. */
-       if ((dev->features & NETIF_F_SG) &&
--          !(dev->features & (NETIF_F_IP_CSUM |
--                             NETIF_F_NO_CSUM |
--                             NETIF_F_HW_CSUM))) {
-+          !(dev->features & NETIF_F_ALL_CSUM)) {
-               printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
-                      dev->name);
-               dev->features &= ~NETIF_F_SG;
-@@ -3269,7 +3421,6 @@
- EXPORT_SYMBOL(__dev_get_by_index);
- EXPORT_SYMBOL(__dev_get_by_name);
- EXPORT_SYMBOL(__dev_remove_pack);
--EXPORT_SYMBOL(__skb_linearize);
- EXPORT_SYMBOL(dev_valid_name);
- EXPORT_SYMBOL(dev_add_pack);
- EXPORT_SYMBOL(dev_alloc_name);
-@@ -3301,6 +3452,7 @@
- EXPORT_SYMBOL(net_enable_timestamp);
- EXPORT_SYMBOL(net_disable_timestamp);
- EXPORT_SYMBOL(dev_get_flags);
-+EXPORT_SYMBOL(skb_checksum_setup);
- #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
- EXPORT_SYMBOL(br_handle_frame_hook);
-diff -Nur linux-2.6.16.33-noxen/net/core/dev_mcast.c linux-2.6.16.33/net/core/dev_mcast.c
---- linux-2.6.16.33-noxen/net/core/dev_mcast.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/core/dev_mcast.c       2007-05-23 21:00:01.000000000 +0000
-@@ -62,7 +62,7 @@
-  *    Device mc lists are changed by bh at least if IPv6 is enabled,
-  *    so that it must be bh protected.
-  *
-- *    We block accesses to device mc filters with dev->xmit_lock.
-+ *    We block accesses to device mc filters with netif_tx_lock.
-  */
- /*
-@@ -93,9 +93,9 @@
- void dev_mc_upload(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       __dev_mc_upload(dev);
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- /*
-@@ -107,7 +107,7 @@
-       int err = 0;
-       struct dev_mc_list *dmi, **dmip;
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
-               /*
-@@ -139,13 +139,13 @@
-                        */
-                       __dev_mc_upload(dev);
-                       
--                      spin_unlock_bh(&dev->xmit_lock);
-+                      netif_tx_unlock_bh(dev);
-                       return 0;
-               }
-       }
-       err = -ENOENT;
- done:
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       return err;
- }
-@@ -160,7 +160,7 @@
-       dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
-               if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
-                   dmi->dmi_addrlen == alen) {
-@@ -176,7 +176,7 @@
-       }
-       if ((dmi = dmi1) == NULL) {
--              spin_unlock_bh(&dev->xmit_lock);
-+              netif_tx_unlock_bh(dev);
-               return -ENOMEM;
-       }
-       memcpy(dmi->dmi_addr, addr, alen);
-@@ -189,11 +189,11 @@
-       __dev_mc_upload(dev);
-       
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       return 0;
- done:
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       kfree(dmi1);
-       return err;
- }
-@@ -204,7 +204,7 @@
- void dev_mc_discard(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       
-       while (dev->mc_list != NULL) {
-               struct dev_mc_list *tmp = dev->mc_list;
-@@ -215,7 +215,7 @@
-       }
-       dev->mc_count = 0;
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- #ifdef CONFIG_PROC_FS
-@@ -250,7 +250,7 @@
-       struct dev_mc_list *m;
-       struct net_device *dev = v;
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       for (m = dev->mc_list; m; m = m->next) {
-               int i;
-@@ -262,7 +262,7 @@
-               seq_putc(seq, '\n');
-       }
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
-       return 0;
- }
-diff -Nur linux-2.6.16.33-noxen/net/core/ethtool.c linux-2.6.16.33/net/core/ethtool.c
---- linux-2.6.16.33-noxen/net/core/ethtool.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/core/ethtool.c 2007-05-23 21:00:01.000000000 +0000
-@@ -30,7 +30,7 @@
- u32 ethtool_op_get_tx_csum(struct net_device *dev)
- {
--      return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0;
-+      return (dev->features & NETIF_F_ALL_CSUM) != 0;
- }
- int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
-@@ -551,9 +551,7 @@
-               return -EFAULT;
-       if (edata.data && 
--          !(dev->features & (NETIF_F_IP_CSUM |
--                             NETIF_F_NO_CSUM |
--                             NETIF_F_HW_CSUM)))
-+          !(dev->features & NETIF_F_ALL_CSUM))
-               return -EINVAL;
-       return __ethtool_set_sg(dev, edata.data);
-@@ -561,7 +559,7 @@
- static int ethtool_get_tso(struct net_device *dev, char __user *useraddr)
- {
--      struct ethtool_value edata = { ETHTOOL_GTSO };
-+      struct ethtool_value edata = { ETHTOOL_GUFO };
-       if (!dev->ethtool_ops->get_tso)
-               return -EOPNOTSUPP;
-@@ -616,6 +614,29 @@
-       return dev->ethtool_ops->set_ufo(dev, edata.data);
- }
-+static int ethtool_get_gso(struct net_device *dev, char __user *useraddr)
-+{
-+      struct ethtool_value edata = { ETHTOOL_GGSO };
-+
-+      edata.data = dev->features & NETIF_F_GSO;
-+      if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+               return -EFAULT;
-+      return 0;
-+}
-+
-+static int ethtool_set_gso(struct net_device *dev, char __user *useraddr)
-+{
-+      struct ethtool_value edata;
-+
-+      if (copy_from_user(&edata, useraddr, sizeof(edata)))
-+              return -EFAULT;
-+      if (edata.data)
-+              dev->features |= NETIF_F_GSO;
-+      else
-+              dev->features &= ~NETIF_F_GSO;
-+      return 0;
-+}
-+
- static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
- {
-       struct ethtool_test test;
-@@ -907,6 +928,12 @@
-       case ETHTOOL_SUFO:
-               rc = ethtool_set_ufo(dev, useraddr);
-               break;
-+      case ETHTOOL_GGSO:
-+              rc = ethtool_get_gso(dev, useraddr);
-+              break;
-+      case ETHTOOL_SGSO:
-+              rc = ethtool_set_gso(dev, useraddr);
-+              break;
-       default:
-               rc =  -EOPNOTSUPP;
-       }
-diff -Nur linux-2.6.16.33-noxen/net/core/netpoll.c linux-2.6.16.33/net/core/netpoll.c
---- linux-2.6.16.33-noxen/net/core/netpoll.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/core/netpoll.c 2007-05-23 21:00:01.000000000 +0000
-@@ -273,24 +273,21 @@
-       do {
-               npinfo->tries--;
--              spin_lock(&np->dev->xmit_lock);
--              np->dev->xmit_lock_owner = smp_processor_id();
-+              netif_tx_lock(np->dev);
-               /*
-                * network drivers do not expect to be called if the queue is
-                * stopped.
-                */
-               if (netif_queue_stopped(np->dev)) {
--                      np->dev->xmit_lock_owner = -1;
--                      spin_unlock(&np->dev->xmit_lock);
-+                      netif_tx_unlock(np->dev);
-                       netpoll_poll(np);
-                       udelay(50);
-                       continue;
-               }
-               status = np->dev->hard_start_xmit(skb, np->dev);
--              np->dev->xmit_lock_owner = -1;
--              spin_unlock(&np->dev->xmit_lock);
-+              netif_tx_unlock(np->dev);
-               /* success */
-               if(!status) {
-diff -Nur linux-2.6.16.33-noxen/net/core/pktgen.c linux-2.6.16.33/net/core/pktgen.c
---- linux-2.6.16.33-noxen/net/core/pktgen.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/core/pktgen.c  2007-05-23 21:00:01.000000000 +0000
-@@ -2586,7 +2586,7 @@
-               }
-       }
-       
--      spin_lock_bh(&odev->xmit_lock);
-+      netif_tx_lock_bh(odev);
-       if (!netif_queue_stopped(odev)) {
-               atomic_inc(&(pkt_dev->skb->users));
-@@ -2631,7 +2631,7 @@
-               pkt_dev->next_tx_ns = 0;
-         }
--      spin_unlock_bh(&odev->xmit_lock);
-+      netif_tx_unlock_bh(odev);
-       
-       /* If pkt_dev->count is zero, then run forever */
-       if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
-diff -Nur linux-2.6.16.33-noxen/net/core/skbuff.c linux-2.6.16.33/net/core/skbuff.c
---- linux-2.6.16.33-noxen/net/core/skbuff.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/core/skbuff.c  2007-01-08 15:00:46.000000000 +0000
-@@ -132,6 +132,7 @@
-  *    Buffers may only be allocated from interrupts using a @gfp_mask of
-  *    %GFP_ATOMIC.
-  */
-+#ifndef CONFIG_HAVE_ARCH_ALLOC_SKB
- struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
-                           int fclone)
- {
-@@ -164,9 +165,9 @@
-       shinfo = skb_shinfo(skb);
-       atomic_set(&shinfo->dataref, 1);
-       shinfo->nr_frags  = 0;
--      shinfo->tso_size = 0;
--      shinfo->tso_segs = 0;
--      shinfo->ufo_size = 0;
-+      shinfo->gso_size = 0;
-+      shinfo->gso_segs = 0;
-+      shinfo->gso_type = 0;
-       shinfo->ip6_frag_id = 0;
-       shinfo->frag_list = NULL;
-@@ -186,6 +187,7 @@
-       skb = NULL;
-       goto out;
- }
-+#endif /* !CONFIG_HAVE_ARCH_ALLOC_SKB */
- /**
-  *    alloc_skb_from_cache    -       allocate a network buffer
-@@ -203,14 +205,18 @@
-  */
- struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
-                                    unsigned int size,
--                                   gfp_t gfp_mask)
-+                                   gfp_t gfp_mask,
-+                                   int fclone)
- {
-+      kmem_cache_t *cache;
-+      struct skb_shared_info *shinfo;
-       struct sk_buff *skb;
-       u8 *data;
-+      cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
-+
-       /* Get the HEAD */
--      skb = kmem_cache_alloc(skbuff_head_cache,
--                             gfp_mask & ~__GFP_DMA);
-+      skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA);
-       if (!skb)
-               goto out;
-@@ -227,17 +233,29 @@
-       skb->data = data;
-       skb->tail = data;
-       skb->end  = data + size;
-+      /* make sure we initialize shinfo sequentially */
-+      shinfo = skb_shinfo(skb);
-+      atomic_set(&shinfo->dataref, 1);
-+      shinfo->nr_frags  = 0;
-+      shinfo->gso_size = 0;
-+      shinfo->gso_segs = 0;
-+      shinfo->gso_type = 0;
-+      shinfo->ip6_frag_id = 0;
-+      shinfo->frag_list = NULL;
--      atomic_set(&(skb_shinfo(skb)->dataref), 1);
--      skb_shinfo(skb)->nr_frags  = 0;
--      skb_shinfo(skb)->tso_size = 0;
--      skb_shinfo(skb)->tso_segs = 0;
--      skb_shinfo(skb)->ufo_size = 0;
--      skb_shinfo(skb)->frag_list = NULL;
-+      if (fclone) {
-+              struct sk_buff *child = skb + 1;
-+              atomic_t *fclone_ref = (atomic_t *) (child + 1);
-+
-+              skb->fclone = SKB_FCLONE_ORIG;
-+              atomic_set(fclone_ref, 1);
-+
-+              child->fclone = SKB_FCLONE_UNAVAILABLE;
-+      }
- out:
-       return skb;
- nodata:
--      kmem_cache_free(skbuff_head_cache, skb);
-+      kmem_cache_free(cache, skb);
-       skb = NULL;
-       goto out;
- }
-@@ -414,6 +432,10 @@
-       C(local_df);
-       n->cloned = 1;
-       n->nohdr = 0;
-+#ifdef CONFIG_XEN
-+      C(proto_data_valid);
-+      C(proto_csum_blank);
-+#endif
-       C(pkt_type);
-       C(ip_summed);
-       C(priority);
-@@ -507,9 +529,9 @@
-       new->tc_index   = old->tc_index;
- #endif
-       atomic_set(&new->users, 1);
--      skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
--      skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
--      skb_shinfo(new)->ufo_size = skb_shinfo(old)->ufo_size;
-+      skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
-+      skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
-+      skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
- }
- /**
-@@ -1822,6 +1844,132 @@
-       return 0;
- }
-+/**
-+ *    skb_segment - Perform protocol segmentation on skb.
-+ *    @skb: buffer to segment
-+ *    @features: features for the output path (see dev->features)
-+ *
-+ *    This function performs segmentation on the given skb.  It returns
-+ *    the segment at the given position.  It returns NULL if there are
-+ *    no more segments to generate, or when an error is encountered.
-+ */
-+struct sk_buff *skb_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = NULL;
-+      struct sk_buff *tail = NULL;
-+      unsigned int mss = skb_shinfo(skb)->gso_size;
-+      unsigned int doffset = skb->data - skb->mac.raw;
-+      unsigned int offset = doffset;
-+      unsigned int headroom;
-+      unsigned int len;
-+      int sg = features & NETIF_F_SG;
-+      int nfrags = skb_shinfo(skb)->nr_frags;
-+      int err = -ENOMEM;
-+      int i = 0;
-+      int pos;
-+
-+      __skb_push(skb, doffset);
-+      headroom = skb_headroom(skb);
-+      pos = skb_headlen(skb);
-+
-+      do {
-+              struct sk_buff *nskb;
-+              skb_frag_t *frag;
-+              int hsize;
-+              int k;
-+              int size;
-+
-+              len = skb->len - offset;
-+              if (len > mss)
-+                      len = mss;
-+
-+              hsize = skb_headlen(skb) - offset;
-+              if (hsize < 0)
-+                      hsize = 0;
-+              if (hsize > len || !sg)
-+                      hsize = len;
-+
-+              nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
-+              if (unlikely(!nskb))
-+                      goto err;
-+
-+              if (segs)
-+                      tail->next = nskb;
-+              else
-+                      segs = nskb;
-+              tail = nskb;
-+
-+              nskb->dev = skb->dev;
-+              nskb->priority = skb->priority;
-+              nskb->protocol = skb->protocol;
-+              nskb->dst = dst_clone(skb->dst);
-+              memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
-+              nskb->pkt_type = skb->pkt_type;
-+              nskb->mac_len = skb->mac_len;
-+
-+              skb_reserve(nskb, headroom);
-+              nskb->mac.raw = nskb->data;
-+              nskb->nh.raw = nskb->data + skb->mac_len;
-+              nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
-+              memcpy(skb_put(nskb, doffset), skb->data, doffset);
-+
-+              if (!sg) {
-+                      nskb->csum = skb_copy_and_csum_bits(skb, offset,
-+                                                          skb_put(nskb, len),
-+                                                          len, 0);
-+                      continue;
-+              }
-+
-+              frag = skb_shinfo(nskb)->frags;
-+              k = 0;
-+
-+              nskb->ip_summed = CHECKSUM_HW;
-+              nskb->csum = skb->csum;
-+              memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
-+
-+              while (pos < offset + len) {
-+                      BUG_ON(i >= nfrags);
-+
-+                      *frag = skb_shinfo(skb)->frags[i];
-+                      get_page(frag->page);
-+                      size = frag->size;
-+
-+                      if (pos < offset) {
-+                              frag->page_offset += offset - pos;
-+                              frag->size -= offset - pos;
-+                      }
-+
-+                      k++;
-+
-+                      if (pos + size <= offset + len) {
-+                              i++;
-+                              pos += size;
-+                      } else {
-+                              frag->size -= pos + size - (offset + len);
-+                              break;
-+                      }
-+
-+                      frag++;
-+              }
-+
-+              skb_shinfo(nskb)->nr_frags = k;
-+              nskb->data_len = len - hsize;
-+              nskb->len += nskb->data_len;
-+              nskb->truesize += nskb->data_len;
-+      } while ((offset += len) < skb->len);
-+
-+      return segs;
-+
-+err:
-+      while ((skb = segs)) {
-+              segs = skb->next;
-+              kfree(skb);
-+      }
-+      return ERR_PTR(err);
-+}
-+
-+EXPORT_SYMBOL_GPL(skb_segment);
-+
- void __init skb_init(void)
- {
-       skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
-diff -Nur linux-2.6.16.33-noxen/net/core/skbuff.c~ linux-2.6.16.33/net/core/skbuff.c~
---- linux-2.6.16.33-noxen/net/core/skbuff.c~   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/net/core/skbuff.c~ 2007-05-23 21:00:01.000000000 +0000
-@@ -0,0 +1,2003 @@
-+/*
-+ *    Routines having to do with the 'struct sk_buff' memory handlers.
-+ *
-+ *    Authors:        Alan Cox <iiitac@pyr.swan.ac.uk>
-+ *                    Florian La Roche <rzsfl@rz.uni-sb.de>
-+ *
-+ *    Version:        $Id: skbuff.c,v 1.90 2001/11/07 05:56:19 davem Exp $
-+ *
-+ *    Fixes:
-+ *            Alan Cox        :       Fixed the worst of the load
-+ *                                    balancer bugs.
-+ *            Dave Platt      :       Interrupt stacking fix.
-+ *    Richard Kooijman        :       Timestamp fixes.
-+ *            Alan Cox        :       Changed buffer format.
-+ *            Alan Cox        :       destructor hook for AF_UNIX etc.
-+ *            Linus Torvalds  :       Better skb_clone.
-+ *            Alan Cox        :       Added skb_copy.
-+ *            Alan Cox        :       Added all the changed routines Linus
-+ *                                    only put in the headers
-+ *            Ray VanTassle   :       Fixed --skb->lock in free
-+ *            Alan Cox        :       skb_copy copy arp field
-+ *            Andi Kleen      :       slabified it.
-+ *            Robert Olsson   :       Removed skb_head_pool
-+ *
-+ *    NOTE:
-+ *            The __skb_ routines should be called with interrupts
-+ *    disabled, or you better be *real* sure that the operation is atomic
-+ *    with respect to whatever list is being frobbed (e.g. via lock_sock()
-+ *    or via disabling bottom half handlers, etc).
-+ *
-+ *    This program is free software; you can redistribute it and/or
-+ *    modify it under the terms of the GNU General Public License
-+ *    as published by the Free Software Foundation; either version
-+ *    2 of the License, or (at your option) any later version.
-+ */
-+
-+/*
-+ *    The functions in this file will not compile correctly with gcc 2.4.x
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/interrupt.h>
-+#include <linux/in.h>
-+#include <linux/inet.h>
-+#include <linux/slab.h>
-+#include <linux/netdevice.h>
-+#ifdef CONFIG_NET_CLS_ACT
-+#include <net/pkt_sched.h>
-+#endif
-+#include <linux/string.h>
-+#include <linux/skbuff.h>
-+#include <linux/cache.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/init.h>
-+#include <linux/highmem.h>
-+
-+#include <net/protocol.h>
-+#include <net/dst.h>
-+#include <net/sock.h>
-+#include <net/checksum.h>
-+#include <net/xfrm.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+
-+static kmem_cache_t *skbuff_head_cache __read_mostly;
-+static kmem_cache_t *skbuff_fclone_cache __read_mostly;
-+
-+/*
-+ *    Keep out-of-line to prevent kernel bloat.
-+ *    __builtin_return_address is not used because it is not always
-+ *    reliable.
-+ */
-+
-+/**
-+ *    skb_over_panic  -       private function
-+ *    @skb: buffer
-+ *    @sz: size
-+ *    @here: address
-+ *
-+ *    Out of line support code for skb_put(). Not user callable.
-+ */
-+void skb_over_panic(struct sk_buff *skb, int sz, void *here)
-+{
-+      printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p "
-+                        "data:%p tail:%p end:%p dev:%s\n",
-+             here, skb->len, sz, skb->head, skb->data, skb->tail, skb->end,
-+             skb->dev ? skb->dev->name : "<NULL>");
-+      BUG();
-+}
-+
-+/**
-+ *    skb_under_panic -       private function
-+ *    @skb: buffer
-+ *    @sz: size
-+ *    @here: address
-+ *
-+ *    Out of line support code for skb_push(). Not user callable.
-+ */
-+
-+void skb_under_panic(struct sk_buff *skb, int sz, void *here)
-+{
-+      printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p "
-+                        "data:%p tail:%p end:%p dev:%s\n",
-+             here, skb->len, sz, skb->head, skb->data, skb->tail, skb->end,
-+             skb->dev ? skb->dev->name : "<NULL>");
-+      BUG();
-+}
-+
-+/*    Allocate a new skbuff. We do this ourselves so we can fill in a few
-+ *    'private' fields and also do memory statistics to find all the
-+ *    [BEEP] leaks.
-+ *
-+ */
-+
-+/**
-+ *    __alloc_skb     -       allocate a network buffer
-+ *    @size: size to allocate
-+ *    @gfp_mask: allocation mask
-+ *    @fclone: allocate from fclone cache instead of head cache
-+ *            and allocate a cloned (child) skb
-+ *
-+ *    Allocate a new &sk_buff. The returned buffer has no headroom and a
-+ *    tail room of size bytes. The object has a reference count of one.
-+ *    The return is the buffer. On a failure the return is %NULL.
-+ *
-+ *    Buffers may only be allocated from interrupts using a @gfp_mask of
-+ *    %GFP_ATOMIC.
-+ */
-+struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
-+                          int fclone)
-+{
-+      kmem_cache_t *cache;
-+      struct skb_shared_info *shinfo;
-+      struct sk_buff *skb;
-+      u8 *data;
-+
-+      cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
-+
-+      /* Get the HEAD */
-+      skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA);
-+      if (!skb)
-+              goto out;
-+
-+      /* Get the DATA. Size must match skb_add_mtu(). */
-+      size = SKB_DATA_ALIGN(size);
-+      data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
-+      if (!data)
-+              goto nodata;
-+
-+      memset(skb, 0, offsetof(struct sk_buff, truesize));
-+      skb->truesize = size + sizeof(struct sk_buff);
-+      atomic_set(&skb->users, 1);
-+      skb->head = data;
-+      skb->data = data;
-+      skb->tail = data;
-+      skb->end  = data + size;
-+      /* make sure we initialize shinfo sequentially */
-+      shinfo = skb_shinfo(skb);
-+      atomic_set(&shinfo->dataref, 1);
-+      shinfo->nr_frags  = 0;
-+      shinfo->gso_size = 0;
-+      shinfo->gso_segs = 0;
-+      shinfo->gso_type = 0;
-+      shinfo->ip6_frag_id = 0;
-+      shinfo->frag_list = NULL;
-+
-+      if (fclone) {
-+              struct sk_buff *child = skb + 1;
-+              atomic_t *fclone_ref = (atomic_t *) (child + 1);
-+
-+              skb->fclone = SKB_FCLONE_ORIG;
-+              atomic_set(fclone_ref, 1);
-+
-+              child->fclone = SKB_FCLONE_UNAVAILABLE;
-+      }
-+out:
-+      return skb;
-+nodata:
-+      kmem_cache_free(cache, skb);
-+      skb = NULL;
-+      goto out;
-+}
-+
-+/**
-+ *    alloc_skb_from_cache    -       allocate a network buffer
-+ *    @cp: kmem_cache from which to allocate the data area
-+ *           (object size must be big enough for @size bytes + skb overheads)
-+ *    @size: size to allocate
-+ *    @gfp_mask: allocation mask
-+ *
-+ *    Allocate a new &sk_buff. The returned buffer has no headroom and
-+ *    tail room of size bytes. The object has a reference count of one.
-+ *    The return is the buffer. On a failure the return is %NULL.
-+ *
-+ *    Buffers may only be allocated from interrupts using a @gfp_mask of
-+ *    %GFP_ATOMIC.
-+ */
-+struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
-+                                   unsigned int size,
-+                                   gfp_t gfp_mask)
-+{
-+      struct sk_buff *skb;
-+      u8 *data;
-+
-+      /* Get the HEAD */
-+      skb = kmem_cache_alloc(skbuff_head_cache,
-+                             gfp_mask & ~__GFP_DMA);
-+      if (!skb)
-+              goto out;
-+
-+      /* Get the DATA. */
-+      size = SKB_DATA_ALIGN(size);
-+      data = kmem_cache_alloc(cp, gfp_mask);
-+      if (!data)
-+              goto nodata;
-+
-+      memset(skb, 0, offsetof(struct sk_buff, truesize));
-+      skb->truesize = size + sizeof(struct sk_buff);
-+      atomic_set(&skb->users, 1);
-+      skb->head = data;
-+      skb->data = data;
-+      skb->tail = data;
-+      skb->end  = data + size;
-+
-+      atomic_set(&(skb_shinfo(skb)->dataref), 1);
-+      skb_shinfo(skb)->nr_frags  = 0;
-+      skb_shinfo(skb)->gso_size = 0;
-+      skb_shinfo(skb)->gso_segs = 0;
-+      skb_shinfo(skb)->gso_type = 0;
-+      skb_shinfo(skb)->frag_list = NULL;
-+out:
-+      return skb;
-+nodata:
-+      kmem_cache_free(skbuff_head_cache, skb);
-+      skb = NULL;
-+      goto out;
-+}
-+
-+
-+static void skb_drop_list(struct sk_buff **listp)
-+{
-+      struct sk_buff *list = *listp;
-+
-+      *listp = NULL;
-+
-+      do {
-+              struct sk_buff *this = list;
-+              list = list->next;
-+              kfree_skb(this);
-+      } while (list);
-+}
-+
-+static inline void skb_drop_fraglist(struct sk_buff *skb)
-+{
-+      skb_drop_list(&skb_shinfo(skb)->frag_list);
-+}
-+
-+static void skb_clone_fraglist(struct sk_buff *skb)
-+{
-+      struct sk_buff *list;
-+
-+      for (list = skb_shinfo(skb)->frag_list; list; list = list->next)
-+              skb_get(list);
-+}
-+
-+void skb_release_data(struct sk_buff *skb)
-+{
-+      if (!skb->cloned ||
-+          !atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1,
-+                             &skb_shinfo(skb)->dataref)) {
-+              if (skb_shinfo(skb)->nr_frags) {
-+                      int i;
-+                      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-+                              put_page(skb_shinfo(skb)->frags[i].page);
-+              }
-+
-+              if (skb_shinfo(skb)->frag_list)
-+                      skb_drop_fraglist(skb);
-+
-+              kfree(skb->head);
-+      }
-+}
-+
-+/*
-+ *    Free an skbuff by memory without cleaning the state.
-+ */
-+void kfree_skbmem(struct sk_buff *skb)
-+{
-+      struct sk_buff *other;
-+      atomic_t *fclone_ref;
-+
-+      skb_release_data(skb);
-+      switch (skb->fclone) {
-+      case SKB_FCLONE_UNAVAILABLE:
-+              kmem_cache_free(skbuff_head_cache, skb);
-+              break;
-+
-+      case SKB_FCLONE_ORIG:
-+              fclone_ref = (atomic_t *) (skb + 2);
-+              if (atomic_dec_and_test(fclone_ref))
-+                      kmem_cache_free(skbuff_fclone_cache, skb);
-+              break;
-+
-+      case SKB_FCLONE_CLONE:
-+              fclone_ref = (atomic_t *) (skb + 1);
-+              other = skb - 1;
-+
-+              /* The clone portion is available for
-+               * fast-cloning again.
-+               */
-+              skb->fclone = SKB_FCLONE_UNAVAILABLE;
-+
-+              if (atomic_dec_and_test(fclone_ref))
-+                      kmem_cache_free(skbuff_fclone_cache, other);
-+              break;
-+      };
-+}
-+
-+/**
-+ *    __kfree_skb - private function
-+ *    @skb: buffer
-+ *
-+ *    Free an sk_buff. Release anything attached to the buffer.
-+ *    Clean the state. This is an internal helper function. Users should
-+ *    always call kfree_skb
-+ */
-+
-+void __kfree_skb(struct sk_buff *skb)
-+{
-+      dst_release(skb->dst);
-+#ifdef CONFIG_XFRM
-+      secpath_put(skb->sp);
-+#endif
-+      if (skb->destructor) {
-+              WARN_ON(in_irq());
-+              skb->destructor(skb);
-+      }
-+#ifdef CONFIG_NETFILTER
-+      nf_conntrack_put(skb->nfct);
-+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-+      nf_conntrack_put_reasm(skb->nfct_reasm);
-+#endif
-+#ifdef CONFIG_BRIDGE_NETFILTER
-+      nf_bridge_put(skb->nf_bridge);
-+#endif
-+#endif
-+/* XXX: IS this still necessary? - JHS */
-+#ifdef CONFIG_NET_SCHED
-+      skb->tc_index = 0;
-+#ifdef CONFIG_NET_CLS_ACT
-+      skb->tc_verd = 0;
-+#endif
-+#endif
-+
-+      kfree_skbmem(skb);
-+}
-+
-+/**
-+ *    skb_clone       -       duplicate an sk_buff
-+ *    @skb: buffer to clone
-+ *    @gfp_mask: allocation priority
-+ *
-+ *    Duplicate an &sk_buff. The new one is not owned by a socket. Both
-+ *    copies share the same packet data but not structure. The new
-+ *    buffer has a reference count of 1. If the allocation fails the
-+ *    function returns %NULL otherwise the new buffer is returned.
-+ *
-+ *    If this function is called from an interrupt gfp_mask() must be
-+ *    %GFP_ATOMIC.
-+ */
-+
-+struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
-+{
-+      struct sk_buff *n;
-+
-+      n = skb + 1;
-+      if (skb->fclone == SKB_FCLONE_ORIG &&
-+          n->fclone == SKB_FCLONE_UNAVAILABLE) {
-+              atomic_t *fclone_ref = (atomic_t *) (n + 1);
-+              n->fclone = SKB_FCLONE_CLONE;
-+              atomic_inc(fclone_ref);
-+      } else {
-+              n = kmem_cache_alloc(skbuff_head_cache, gfp_mask);
-+              if (!n)
-+                      return NULL;
-+              n->fclone = SKB_FCLONE_UNAVAILABLE;
-+      }
-+
-+#define C(x) n->x = skb->x
-+
-+      n->next = n->prev = NULL;
-+      n->sk = NULL;
-+      C(tstamp);
-+      C(dev);
-+      C(h);
-+      C(nh);
-+      C(mac);
-+      C(dst);
-+      dst_clone(skb->dst);
-+      C(sp);
-+#ifdef CONFIG_INET
-+      secpath_get(skb->sp);
-+#endif
-+      memcpy(n->cb, skb->cb, sizeof(skb->cb));
-+      C(len);
-+      C(data_len);
-+      C(csum);
-+      C(local_df);
-+      n->cloned = 1;
-+      n->nohdr = 0;
-+      C(pkt_type);
-+      C(ip_summed);
-+      C(priority);
-+#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
-+      C(ipvs_property);
-+#endif
-+      C(protocol);
-+      n->destructor = NULL;
-+#ifdef CONFIG_NETFILTER
-+      C(nfmark);
-+      C(nfct);
-+      nf_conntrack_get(skb->nfct);
-+      C(nfctinfo);
-+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-+      C(nfct_reasm);
-+      nf_conntrack_get_reasm(skb->nfct_reasm);
-+#endif
-+#ifdef CONFIG_BRIDGE_NETFILTER
-+      C(nf_bridge);
-+      nf_bridge_get(skb->nf_bridge);
-+#endif
-+#endif /*CONFIG_NETFILTER*/
-+#ifdef CONFIG_NET_SCHED
-+      C(tc_index);
-+#ifdef CONFIG_NET_CLS_ACT
-+      n->tc_verd = SET_TC_VERD(skb->tc_verd,0);
-+      n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
-+      n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
-+      C(input_dev);
-+#endif
-+
-+#endif
-+      C(truesize);
-+      atomic_set(&n->users, 1);
-+      C(head);
-+      C(data);
-+      C(tail);
-+      C(end);
-+
-+      atomic_inc(&(skb_shinfo(skb)->dataref));
-+      skb->cloned = 1;
-+
-+      return n;
-+}
-+
-+static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
-+{
-+      /*
-+       *      Shift between the two data areas in bytes
-+       */
-+      unsigned long offset = new->data - old->data;
-+
-+      new->sk         = NULL;
-+      new->dev        = old->dev;
-+      new->priority   = old->priority;
-+      new->protocol   = old->protocol;
-+      new->dst        = dst_clone(old->dst);
-+#ifdef CONFIG_INET
-+      new->sp         = secpath_get(old->sp);
-+#endif
-+      new->h.raw      = old->h.raw + offset;
-+      new->nh.raw     = old->nh.raw + offset;
-+      new->mac.raw    = old->mac.raw + offset;
-+      memcpy(new->cb, old->cb, sizeof(old->cb));
-+      new->local_df   = old->local_df;
-+      new->fclone     = SKB_FCLONE_UNAVAILABLE;
-+      new->pkt_type   = old->pkt_type;
-+      new->tstamp     = old->tstamp;
-+      new->destructor = NULL;
-+#ifdef CONFIG_NETFILTER
-+      new->nfmark     = old->nfmark;
-+      new->nfct       = old->nfct;
-+      nf_conntrack_get(old->nfct);
-+      new->nfctinfo   = old->nfctinfo;
-+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-+      new->nfct_reasm = old->nfct_reasm;
-+      nf_conntrack_get_reasm(old->nfct_reasm);
-+#endif
-+#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
-+      new->ipvs_property = old->ipvs_property;
-+#endif
-+#ifdef CONFIG_BRIDGE_NETFILTER
-+      new->nf_bridge  = old->nf_bridge;
-+      nf_bridge_get(old->nf_bridge);
-+#endif
-+#endif
-+#ifdef CONFIG_NET_SCHED
-+#ifdef CONFIG_NET_CLS_ACT
-+      new->tc_verd = old->tc_verd;
-+#endif
-+      new->tc_index   = old->tc_index;
-+#endif
-+      atomic_set(&new->users, 1);
-+      skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
-+      skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
-+      skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
-+}
-+
-+/**
-+ *    skb_copy        -       create private copy of an sk_buff
-+ *    @skb: buffer to copy
-+ *    @gfp_mask: allocation priority
-+ *
-+ *    Make a copy of both an &sk_buff and its data. This is used when the
-+ *    caller wishes to modify the data and needs a private copy of the
-+ *    data to alter. Returns %NULL on failure or the pointer to the buffer
-+ *    on success. The returned buffer has a reference count of 1.
-+ *
-+ *    As by-product this function converts non-linear &sk_buff to linear
-+ *    one, so that &sk_buff becomes completely private and caller is allowed
-+ *    to modify all the data of returned buffer. This means that this
-+ *    function is not recommended for use in circumstances when only
-+ *    header is going to be modified. Use pskb_copy() instead.
-+ */
-+
-+struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
-+{
-+      int headerlen = skb->data - skb->head;
-+      /*
-+       *      Allocate the copy buffer
-+       */
-+      struct sk_buff *n = alloc_skb(skb->end - skb->head + skb->data_len,
-+                                    gfp_mask);
-+      if (!n)
-+              return NULL;
-+
-+      /* Set the data pointer */
-+      skb_reserve(n, headerlen);
-+      /* Set the tail pointer and length */
-+      skb_put(n, skb->len);
-+      n->csum      = skb->csum;
-+      n->ip_summed = skb->ip_summed;
-+
-+      if (skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len))
-+              BUG();
-+
-+      copy_skb_header(n, skb);
-+      return n;
-+}
-+
-+
-+/**
-+ *    pskb_copy       -       create copy of an sk_buff with private head.
-+ *    @skb: buffer to copy
-+ *    @gfp_mask: allocation priority
-+ *
-+ *    Make a copy of both an &sk_buff and part of its data, located
-+ *    in header. Fragmented data remain shared. This is used when
-+ *    the caller wishes to modify only header of &sk_buff and needs
-+ *    private copy of the header to alter. Returns %NULL on failure
-+ *    or the pointer to the buffer on success.
-+ *    The returned buffer has a reference count of 1.
-+ */
-+
-+struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
-+{
-+      /*
-+       *      Allocate the copy buffer
-+       */
-+      struct sk_buff *n = alloc_skb(skb->end - skb->head, gfp_mask);
-+
-+      if (!n)
-+              goto out;
-+
-+      /* Set the data pointer */
-+      skb_reserve(n, skb->data - skb->head);
-+      /* Set the tail pointer and length */
-+      skb_put(n, skb_headlen(skb));
-+      /* Copy the bytes */
-+      memcpy(n->data, skb->data, n->len);
-+      n->csum      = skb->csum;
-+      n->ip_summed = skb->ip_summed;
-+
-+      n->truesize += skb->data_len;
-+      n->data_len  = skb->data_len;
-+      n->len       = skb->len;
-+
-+      if (skb_shinfo(skb)->nr_frags) {
-+              int i;
-+
-+              for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+                      skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i];
-+                      get_page(skb_shinfo(n)->frags[i].page);
-+              }
-+              skb_shinfo(n)->nr_frags = i;
-+      }
-+
-+      if (skb_shinfo(skb)->frag_list) {
-+              skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list;
-+              skb_clone_fraglist(n);
-+      }
-+
-+      copy_skb_header(n, skb);
-+out:
-+      return n;
-+}
-+
-+/**
-+ *    pskb_expand_head - reallocate header of &sk_buff
-+ *    @skb: buffer to reallocate
-+ *    @nhead: room to add at head
-+ *    @ntail: room to add at tail
-+ *    @gfp_mask: allocation priority
-+ *
-+ *    Expands (or creates identical copy, if &nhead and &ntail are zero)
-+ *    header of skb. &sk_buff itself is not changed. &sk_buff MUST have
-+ *    reference count of 1. Returns zero in the case of success or error,
-+ *    if expansion failed. In the last case, &sk_buff is not changed.
-+ *
-+ *    All the pointers pointing into skb header may change and must be
-+ *    reloaded after call to this function.
-+ */
-+
-+int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
-+                   gfp_t gfp_mask)
-+{
-+      int i;
-+      u8 *data;
-+      int size = nhead + (skb->end - skb->head) + ntail;
-+      long off;
-+
-+      if (skb_shared(skb))
-+              BUG();
-+
-+      size = SKB_DATA_ALIGN(size);
-+
-+      data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
-+      if (!data)
-+              goto nodata;
-+
-+      /* Copy only real data... and, alas, header. This should be
-+       * optimized for the cases when header is void. */
-+      memcpy(data + nhead, skb->head, skb->tail - skb->head);
-+      memcpy(data + size, skb->end, sizeof(struct skb_shared_info));
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-+              get_page(skb_shinfo(skb)->frags[i].page);
-+
-+      if (skb_shinfo(skb)->frag_list)
-+              skb_clone_fraglist(skb);
-+
-+      skb_release_data(skb);
-+
-+      off = (data + nhead) - skb->head;
-+
-+      skb->head     = data;
-+      skb->end      = data + size;
-+      skb->data    += off;
-+      skb->tail    += off;
-+      skb->mac.raw += off;
-+      skb->h.raw   += off;
-+      skb->nh.raw  += off;
-+      skb->cloned   = 0;
-+      skb->nohdr    = 0;
-+      atomic_set(&skb_shinfo(skb)->dataref, 1);
-+      return 0;
-+
-+nodata:
-+      return -ENOMEM;
-+}
-+
-+/* Make private copy of skb with writable head and some headroom */
-+
-+struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom)
-+{
-+      struct sk_buff *skb2;
-+      int delta = headroom - skb_headroom(skb);
-+
-+      if (delta <= 0)
-+              skb2 = pskb_copy(skb, GFP_ATOMIC);
-+      else {
-+              skb2 = skb_clone(skb, GFP_ATOMIC);
-+              if (skb2 && pskb_expand_head(skb2, SKB_DATA_ALIGN(delta), 0,
-+                                           GFP_ATOMIC)) {
-+                      kfree_skb(skb2);
-+                      skb2 = NULL;
-+              }
-+      }
-+      return skb2;
-+}
-+
-+
-+/**
-+ *    skb_copy_expand -       copy and expand sk_buff
-+ *    @skb: buffer to copy
-+ *    @newheadroom: new free bytes at head
-+ *    @newtailroom: new free bytes at tail
-+ *    @gfp_mask: allocation priority
-+ *
-+ *    Make a copy of both an &sk_buff and its data and while doing so
-+ *    allocate additional space.
-+ *
-+ *    This is used when the caller wishes to modify the data and needs a
-+ *    private copy of the data to alter as well as more space for new fields.
-+ *    Returns %NULL on failure or the pointer to the buffer
-+ *    on success. The returned buffer has a reference count of 1.
-+ *
-+ *    You must pass %GFP_ATOMIC as the allocation priority if this function
-+ *    is called from an interrupt.
-+ *
-+ *    BUG ALERT: ip_summed is not copied. Why does this work? Is it used
-+ *    only by netfilter in the cases when checksum is recalculated? --ANK
-+ */
-+struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
-+                              int newheadroom, int newtailroom,
-+                              gfp_t gfp_mask)
-+{
-+      /*
-+       *      Allocate the copy buffer
-+       */
-+      struct sk_buff *n = alloc_skb(newheadroom + skb->len + newtailroom,
-+                                    gfp_mask);
-+      int head_copy_len, head_copy_off;
-+
-+      if (!n)
-+              return NULL;
-+
-+      skb_reserve(n, newheadroom);
-+
-+      /* Set the tail pointer and length */
-+      skb_put(n, skb->len);
-+
-+      head_copy_len = skb_headroom(skb);
-+      head_copy_off = 0;
-+      if (newheadroom <= head_copy_len)
-+              head_copy_len = newheadroom;
-+      else
-+              head_copy_off = newheadroom - head_copy_len;
-+
-+      /* Copy the linear header and data. */
-+      if (skb_copy_bits(skb, -head_copy_len, n->head + head_copy_off,
-+                        skb->len + head_copy_len))
-+              BUG();
-+
-+      copy_skb_header(n, skb);
-+
-+      return n;
-+}
-+
-+/**
-+ *    skb_pad                 -       zero pad the tail of an skb
-+ *    @skb: buffer to pad
-+ *    @pad: space to pad
-+ *
-+ *    Ensure that a buffer is followed by a padding area that is zero
-+ *    filled. Used by network drivers which may DMA or transfer data
-+ *    beyond the buffer end onto the wire.
-+ *
-+ *    May return NULL in out of memory cases.
-+ */
-+ 
-+struct sk_buff *skb_pad(struct sk_buff *skb, int pad)
-+{
-+      struct sk_buff *nskb;
-+      
-+      /* If the skbuff is non linear tailroom is always zero.. */
-+      if (skb_tailroom(skb) >= pad) {
-+              memset(skb->data+skb->len, 0, pad);
-+              return skb;
-+      }
-+      
-+      nskb = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb) + pad, GFP_ATOMIC);
-+      kfree_skb(skb);
-+      if (nskb)
-+              memset(nskb->data+nskb->len, 0, pad);
-+      return nskb;
-+}     
-+ 
-+/* Trims skb to length len. It can change skb pointers.
-+ */
-+
-+int ___pskb_trim(struct sk_buff *skb, unsigned int len)
-+{
-+      struct sk_buff **fragp;
-+      struct sk_buff *frag;
-+      int offset = skb_headlen(skb);
-+      int nfrags = skb_shinfo(skb)->nr_frags;
-+      int i;
-+      int err;
-+
-+      if (skb_cloned(skb) &&
-+          unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))))
-+              return err;
-+
-+      i = 0;
-+      if (offset >= len)
-+              goto drop_pages;
-+
-+      for (; i < nfrags; i++) {
-+              int end = offset + skb_shinfo(skb)->frags[i].size;
-+
-+              if (end < len) {
-+                      offset = end;
-+                      continue;
-+              }
-+
-+              skb_shinfo(skb)->frags[i++].size = len - offset;
-+
-+drop_pages:
-+              skb_shinfo(skb)->nr_frags = i;
-+
-+              for (; i < nfrags; i++)
-+                      put_page(skb_shinfo(skb)->frags[i].page);
-+
-+              if (skb_shinfo(skb)->frag_list)
-+                      skb_drop_fraglist(skb);
-+              goto done;
-+      }
-+
-+      for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp);
-+           fragp = &frag->next) {
-+              int end = offset + frag->len;
-+
-+              if (skb_shared(frag)) {
-+                      struct sk_buff *nfrag;
-+
-+                      nfrag = skb_clone(frag, GFP_ATOMIC);
-+                      if (unlikely(!nfrag))
-+                              return -ENOMEM;
-+
-+                      nfrag->next = frag->next;
-+                      kfree_skb(frag);
-+                      frag = nfrag;
-+                      *fragp = frag;
-+              }
-+
-+              if (end < len) {
-+                      offset = end;
-+                      continue;
-+              }
-+
-+              if (end > len &&
-+                  unlikely((err = pskb_trim(frag, len - offset))))
-+                      return err;
-+
-+              if (frag->next)
-+                      skb_drop_list(&frag->next);
-+              break;
-+      }
-+
-+done:
-+      if (len > skb_headlen(skb)) {
-+              skb->data_len -= skb->len - len;
-+              skb->len       = len;
-+      } else {
-+              skb->len       = len;
-+              skb->data_len  = 0;
-+              skb->tail      = skb->data + len;
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ *    __pskb_pull_tail - advance tail of skb header
-+ *    @skb: buffer to reallocate
-+ *    @delta: number of bytes to advance tail
-+ *
-+ *    The function makes a sense only on a fragmented &sk_buff,
-+ *    it expands header moving its tail forward and copying necessary
-+ *    data from fragmented part.
-+ *
-+ *    &sk_buff MUST have reference count of 1.
-+ *
-+ *    Returns %NULL (and &sk_buff does not change) if pull failed
-+ *    or value of new tail of skb in the case of success.
-+ *
-+ *    All the pointers pointing into skb header may change and must be
-+ *    reloaded after call to this function.
-+ */
-+
-+/* Moves tail of skb head forward, copying data from fragmented part,
-+ * when it is necessary.
-+ * 1. It may fail due to malloc failure.
-+ * 2. It may change skb pointers.
-+ *
-+ * It is pretty complicated. Luckily, it is called only in exceptional cases.
-+ */
-+unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta)
-+{
-+      /* If skb has not enough free space at tail, get new one
-+       * plus 128 bytes for future expansions. If we have enough
-+       * room at tail, reallocate without expansion only if skb is cloned.
-+       */
-+      int i, k, eat = (skb->tail + delta) - skb->end;
-+
-+      if (eat > 0 || skb_cloned(skb)) {
-+              if (pskb_expand_head(skb, 0, eat > 0 ? eat + 128 : 0,
-+                                   GFP_ATOMIC))
-+                      return NULL;
-+      }
-+
-+      if (skb_copy_bits(skb, skb_headlen(skb), skb->tail, delta))
-+              BUG();
-+
-+      /* Optimization: no fragments, no reasons to preestimate
-+       * size of pulled pages. Superb.
-+       */
-+      if (!skb_shinfo(skb)->frag_list)
-+              goto pull_pages;
-+
-+      /* Estimate size of pulled pages. */
-+      eat = delta;
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              if (skb_shinfo(skb)->frags[i].size >= eat)
-+                      goto pull_pages;
-+              eat -= skb_shinfo(skb)->frags[i].size;
-+      }
-+
-+      /* If we need update frag list, we are in troubles.
-+       * Certainly, it possible to add an offset to skb data,
-+       * but taking into account that pulling is expected to
-+       * be very rare operation, it is worth to fight against
-+       * further bloating skb head and crucify ourselves here instead.
-+       * Pure masohism, indeed. 8)8)
-+       */
-+      if (eat) {
-+              struct sk_buff *list = skb_shinfo(skb)->frag_list;
-+              struct sk_buff *clone = NULL;
-+              struct sk_buff *insp = NULL;
-+
-+              do {
-+                      BUG_ON(!list);
-+
-+                      if (list->len <= eat) {
-+                              /* Eaten as whole. */
-+                              eat -= list->len;
-+                              list = list->next;
-+                              insp = list;
-+                      } else {
-+                              /* Eaten partially. */
-+
-+                              if (skb_shared(list)) {
-+                                      /* Sucks! We need to fork list. :-( */
-+                                      clone = skb_clone(list, GFP_ATOMIC);
-+                                      if (!clone)
-+                                              return NULL;
-+                                      insp = list->next;
-+                                      list = clone;
-+                              } else {
-+                                      /* This may be pulled without
-+                                       * problems. */
-+                                      insp = list;
-+                              }
-+                              if (!pskb_pull(list, eat)) {
-+                                      if (clone)
-+                                              kfree_skb(clone);
-+                                      return NULL;
-+                              }
-+                              break;
-+                      }
-+              } while (eat);
-+
-+              /* Free pulled out fragments. */
-+              while ((list = skb_shinfo(skb)->frag_list) != insp) {
-+                      skb_shinfo(skb)->frag_list = list->next;
-+                      kfree_skb(list);
-+              }
-+              /* And insert new clone at head. */
-+              if (clone) {
-+                      clone->next = list;
-+                      skb_shinfo(skb)->frag_list = clone;
-+              }
-+      }
-+      /* Success! Now we may commit changes to skb data. */
-+
-+pull_pages:
-+      eat = delta;
-+      k = 0;
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              if (skb_shinfo(skb)->frags[i].size <= eat) {
-+                      put_page(skb_shinfo(skb)->frags[i].page);
-+                      eat -= skb_shinfo(skb)->frags[i].size;
-+              } else {
-+                      skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i];
-+                      if (eat) {
-+                              skb_shinfo(skb)->frags[k].page_offset += eat;
-+                              skb_shinfo(skb)->frags[k].size -= eat;
-+                              eat = 0;
-+                      }
-+                      k++;
-+              }
-+      }
-+      skb_shinfo(skb)->nr_frags = k;
-+
-+      skb->tail     += delta;
-+      skb->data_len -= delta;
-+
-+      return skb->tail;
-+}
-+
-+/* Copy some data bits from skb to kernel buffer. */
-+
-+int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
-+{
-+      int i, copy;
-+      int start = skb_headlen(skb);
-+
-+      if (offset > (int)skb->len - len)
-+              goto fault;
-+
-+      /* Copy header. */
-+      if ((copy = start - offset) > 0) {
-+              if (copy > len)
-+                      copy = len;
-+              memcpy(to, skb->data + offset, copy);
-+              if ((len -= copy) == 0)
-+                      return 0;
-+              offset += copy;
-+              to     += copy;
-+      }
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              int end;
-+
-+              BUG_TRAP(start <= offset + len);
-+
-+              end = start + skb_shinfo(skb)->frags[i].size;
-+              if ((copy = end - offset) > 0) {
-+                      u8 *vaddr;
-+
-+                      if (copy > len)
-+                              copy = len;
-+
-+                      vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
-+                      memcpy(to,
-+                             vaddr + skb_shinfo(skb)->frags[i].page_offset+
-+                             offset - start, copy);
-+                      kunmap_skb_frag(vaddr);
-+
-+                      if ((len -= copy) == 0)
-+                              return 0;
-+                      offset += copy;
-+                      to     += copy;
-+              }
-+              start = end;
-+      }
-+
-+      if (skb_shinfo(skb)->frag_list) {
-+              struct sk_buff *list = skb_shinfo(skb)->frag_list;
-+
-+              for (; list; list = list->next) {
-+                      int end;
-+
-+                      BUG_TRAP(start <= offset + len);
-+
-+                      end = start + list->len;
-+                      if ((copy = end - offset) > 0) {
-+                              if (copy > len)
-+                                      copy = len;
-+                              if (skb_copy_bits(list, offset - start,
-+                                                to, copy))
-+                                      goto fault;
-+                              if ((len -= copy) == 0)
-+                                      return 0;
-+                              offset += copy;
-+                              to     += copy;
-+                      }
-+                      start = end;
-+              }
-+      }
-+      if (!len)
-+              return 0;
-+
-+fault:
-+      return -EFAULT;
-+}
-+
-+/**
-+ *    skb_store_bits - store bits from kernel buffer to skb
-+ *    @skb: destination buffer
-+ *    @offset: offset in destination
-+ *    @from: source buffer
-+ *    @len: number of bytes to copy
-+ *
-+ *    Copy the specified number of bytes from the source buffer to the
-+ *    destination skb.  This function handles all the messy bits of
-+ *    traversing fragment lists and such.
-+ */
-+
-+int skb_store_bits(const struct sk_buff *skb, int offset, void *from, int len)
-+{
-+      int i, copy;
-+      int start = skb_headlen(skb);
-+
-+      if (offset > (int)skb->len - len)
-+              goto fault;
-+
-+      if ((copy = start - offset) > 0) {
-+              if (copy > len)
-+                      copy = len;
-+              memcpy(skb->data + offset, from, copy);
-+              if ((len -= copy) == 0)
-+                      return 0;
-+              offset += copy;
-+              from += copy;
-+      }
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+              int end;
-+
-+              BUG_TRAP(start <= offset + len);
-+
-+              end = start + frag->size;
-+              if ((copy = end - offset) > 0) {
-+                      u8 *vaddr;
-+
-+                      if (copy > len)
-+                              copy = len;
-+
-+                      vaddr = kmap_skb_frag(frag);
-+                      memcpy(vaddr + frag->page_offset + offset - start,
-+                             from, copy);
-+                      kunmap_skb_frag(vaddr);
-+
-+                      if ((len -= copy) == 0)
-+                              return 0;
-+                      offset += copy;
-+                      from += copy;
-+              }
-+              start = end;
-+      }
-+
-+      if (skb_shinfo(skb)->frag_list) {
-+              struct sk_buff *list = skb_shinfo(skb)->frag_list;
-+
-+              for (; list; list = list->next) {
-+                      int end;
-+
-+                      BUG_TRAP(start <= offset + len);
-+
-+                      end = start + list->len;
-+                      if ((copy = end - offset) > 0) {
-+                              if (copy > len)
-+                                      copy = len;
-+                              if (skb_store_bits(list, offset - start,
-+                                                 from, copy))
-+                                      goto fault;
-+                              if ((len -= copy) == 0)
-+                                      return 0;
-+                              offset += copy;
-+                              from += copy;
-+                      }
-+                      start = end;
-+              }
-+      }
-+      if (!len)
-+              return 0;
-+
-+fault:
-+      return -EFAULT;
-+}
-+
-+EXPORT_SYMBOL(skb_store_bits);
-+
-+/* Checksum skb data. */
-+
-+unsigned int skb_checksum(const struct sk_buff *skb, int offset,
-+                        int len, unsigned int csum)
-+{
-+      int start = skb_headlen(skb);
-+      int i, copy = start - offset;
-+      int pos = 0;
-+
-+      /* Checksum header. */
-+      if (copy > 0) {
-+              if (copy > len)
-+                      copy = len;
-+              csum = csum_partial(skb->data + offset, copy, csum);
-+              if ((len -= copy) == 0)
-+                      return csum;
-+              offset += copy;
-+              pos     = copy;
-+      }
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              int end;
-+
-+              BUG_TRAP(start <= offset + len);
-+
-+              end = start + skb_shinfo(skb)->frags[i].size;
-+              if ((copy = end - offset) > 0) {
-+                      unsigned int csum2;
-+                      u8 *vaddr;
-+                      skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+
-+                      if (copy > len)
-+                              copy = len;
-+                      vaddr = kmap_skb_frag(frag);
-+                      csum2 = csum_partial(vaddr + frag->page_offset +
-+                                           offset - start, copy, 0);
-+                      kunmap_skb_frag(vaddr);
-+                      csum = csum_block_add(csum, csum2, pos);
-+                      if (!(len -= copy))
-+                              return csum;
-+                      offset += copy;
-+                      pos    += copy;
-+              }
-+              start = end;
-+      }
-+
-+      if (skb_shinfo(skb)->frag_list) {
-+              struct sk_buff *list = skb_shinfo(skb)->frag_list;
-+
-+              for (; list; list = list->next) {
-+                      int end;
-+
-+                      BUG_TRAP(start <= offset + len);
-+
-+                      end = start + list->len;
-+                      if ((copy = end - offset) > 0) {
-+                              unsigned int csum2;
-+                              if (copy > len)
-+                                      copy = len;
-+                              csum2 = skb_checksum(list, offset - start,
-+                                                   copy, 0);
-+                              csum = csum_block_add(csum, csum2, pos);
-+                              if ((len -= copy) == 0)
-+                                      return csum;
-+                              offset += copy;
-+                              pos    += copy;
-+                      }
-+                      start = end;
-+              }
-+      }
-+      BUG_ON(len);
-+
-+      return csum;
-+}
-+
-+/* Both of above in one bottle. */
-+
-+unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
-+                                  u8 *to, int len, unsigned int csum)
-+{
-+      int start = skb_headlen(skb);
-+      int i, copy = start - offset;
-+      int pos = 0;
-+
-+      /* Copy header. */
-+      if (copy > 0) {
-+              if (copy > len)
-+                      copy = len;
-+              csum = csum_partial_copy_nocheck(skb->data + offset, to,
-+                                               copy, csum);
-+              if ((len -= copy) == 0)
-+                      return csum;
-+              offset += copy;
-+              to     += copy;
-+              pos     = copy;
-+      }
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+              int end;
-+
-+              BUG_TRAP(start <= offset + len);
-+
-+              end = start + skb_shinfo(skb)->frags[i].size;
-+              if ((copy = end - offset) > 0) {
-+                      unsigned int csum2;
-+                      u8 *vaddr;
-+                      skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+
-+                      if (copy > len)
-+                              copy = len;
-+                      vaddr = kmap_skb_frag(frag);
-+                      csum2 = csum_partial_copy_nocheck(vaddr +
-+                                                        frag->page_offset +
-+                                                        offset - start, to,
-+                                                        copy, 0);
-+                      kunmap_skb_frag(vaddr);
-+                      csum = csum_block_add(csum, csum2, pos);
-+                      if (!(len -= copy))
-+                              return csum;
-+                      offset += copy;
-+                      to     += copy;
-+                      pos    += copy;
-+              }
-+              start = end;
-+      }
-+
-+      if (skb_shinfo(skb)->frag_list) {
-+              struct sk_buff *list = skb_shinfo(skb)->frag_list;
-+
-+              for (; list; list = list->next) {
-+                      unsigned int csum2;
-+                      int end;
-+
-+                      BUG_TRAP(start <= offset + len);
-+
-+                      end = start + list->len;
-+                      if ((copy = end - offset) > 0) {
-+                              if (copy > len)
-+                                      copy = len;
-+                              csum2 = skb_copy_and_csum_bits(list,
-+                                                             offset - start,
-+                                                             to, copy, 0);
-+                              csum = csum_block_add(csum, csum2, pos);
-+                              if ((len -= copy) == 0)
-+                                      return csum;
-+                              offset += copy;
-+                              to     += copy;
-+                              pos    += copy;
-+                      }
-+                      start = end;
-+              }
-+      }
-+      BUG_ON(len);
-+      return csum;
-+}
-+
-+void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
-+{
-+      unsigned int csum;
-+      long csstart;
-+
-+      if (skb->ip_summed == CHECKSUM_HW)
-+              csstart = skb->h.raw - skb->data;
-+      else
-+              csstart = skb_headlen(skb);
-+
-+      BUG_ON(csstart > skb_headlen(skb));
-+
-+      memcpy(to, skb->data, csstart);
-+
-+      csum = 0;
-+      if (csstart != skb->len)
-+              csum = skb_copy_and_csum_bits(skb, csstart, to + csstart,
-+                                            skb->len - csstart, 0);
-+
-+      if (skb->ip_summed == CHECKSUM_HW) {
-+              long csstuff = csstart + skb->csum;
-+
-+              *((unsigned short *)(to + csstuff)) = csum_fold(csum);
-+      }
-+}
-+
-+/**
-+ *    skb_dequeue - remove from the head of the queue
-+ *    @list: list to dequeue from
-+ *
-+ *    Remove the head of the list. The list lock is taken so the function
-+ *    may be used safely with other locking list functions. The head item is
-+ *    returned or %NULL if the list is empty.
-+ */
-+
-+struct sk_buff *skb_dequeue(struct sk_buff_head *list)
-+{
-+      unsigned long flags;
-+      struct sk_buff *result;
-+
-+      spin_lock_irqsave(&list->lock, flags);
-+      result = __skb_dequeue(list);
-+      spin_unlock_irqrestore(&list->lock, flags);
-+      return result;
-+}
-+
-+/**
-+ *    skb_dequeue_tail - remove from the tail of the queue
-+ *    @list: list to dequeue from
-+ *
-+ *    Remove the tail of the list. The list lock is taken so the function
-+ *    may be used safely with other locking list functions. The tail item is
-+ *    returned or %NULL if the list is empty.
-+ */
-+struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
-+{
-+      unsigned long flags;
-+      struct sk_buff *result;
-+
-+      spin_lock_irqsave(&list->lock, flags);
-+      result = __skb_dequeue_tail(list);
-+      spin_unlock_irqrestore(&list->lock, flags);
-+      return result;
-+}
-+
-+/**
-+ *    skb_queue_purge - empty a list
-+ *    @list: list to empty
-+ *
-+ *    Delete all buffers on an &sk_buff list. Each buffer is removed from
-+ *    the list and one reference dropped. This function takes the list
-+ *    lock and is atomic with respect to other list locking functions.
-+ */
-+void skb_queue_purge(struct sk_buff_head *list)
-+{
-+      struct sk_buff *skb;
-+      while ((skb = skb_dequeue(list)) != NULL)
-+              kfree_skb(skb);
-+}
-+
-+/**
-+ *    skb_queue_head - queue a buffer at the list head
-+ *    @list: list to use
-+ *    @newsk: buffer to queue
-+ *
-+ *    Queue a buffer at the start of the list. This function takes the
-+ *    list lock and can be used safely with other locking &sk_buff functions
-+ *    safely.
-+ *
-+ *    A buffer cannot be placed on two lists at the same time.
-+ */
-+void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&list->lock, flags);
-+      __skb_queue_head(list, newsk);
-+      spin_unlock_irqrestore(&list->lock, flags);
-+}
-+
-+/**
-+ *    skb_queue_tail - queue a buffer at the list tail
-+ *    @list: list to use
-+ *    @newsk: buffer to queue
-+ *
-+ *    Queue a buffer at the tail of the list. This function takes the
-+ *    list lock and can be used safely with other locking &sk_buff functions
-+ *    safely.
-+ *
-+ *    A buffer cannot be placed on two lists at the same time.
-+ */
-+void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&list->lock, flags);
-+      __skb_queue_tail(list, newsk);
-+      spin_unlock_irqrestore(&list->lock, flags);
-+}
-+
-+/**
-+ *    skb_unlink      -       remove a buffer from a list
-+ *    @skb: buffer to remove
-+ *    @list: list to use
-+ *
-+ *    Remove a packet from a list. The list locks are taken and this
-+ *    function is atomic with respect to other list locked calls
-+ *
-+ *    You must know what list the SKB is on.
-+ */
-+void skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&list->lock, flags);
-+      __skb_unlink(skb, list);
-+      spin_unlock_irqrestore(&list->lock, flags);
-+}
-+
-+/**
-+ *    skb_append      -       append a buffer
-+ *    @old: buffer to insert after
-+ *    @newsk: buffer to insert
-+ *    @list: list to use
-+ *
-+ *    Place a packet after a given packet in a list. The list locks are taken
-+ *    and this function is atomic with respect to other list locked calls.
-+ *    A buffer cannot be placed on two lists at the same time.
-+ */
-+void skb_append(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&list->lock, flags);
-+      __skb_append(old, newsk, list);
-+      spin_unlock_irqrestore(&list->lock, flags);
-+}
-+
-+
-+/**
-+ *    skb_insert      -       insert a buffer
-+ *    @old: buffer to insert before
-+ *    @newsk: buffer to insert
-+ *    @list: list to use
-+ *
-+ *    Place a packet before a given packet in a list. The list locks are
-+ *    taken and this function is atomic with respect to other list locked
-+ *    calls.
-+ *
-+ *    A buffer cannot be placed on two lists at the same time.
-+ */
-+void skb_insert(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list)
-+{
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&list->lock, flags);
-+      __skb_insert(newsk, old->prev, old, list);
-+      spin_unlock_irqrestore(&list->lock, flags);
-+}
-+
-+#if 0
-+/*
-+ *    Tune the memory allocator for a new MTU size.
-+ */
-+void skb_add_mtu(int mtu)
-+{
-+      /* Must match allocation in alloc_skb */
-+      mtu = SKB_DATA_ALIGN(mtu) + sizeof(struct skb_shared_info);
-+
-+      kmem_add_cache_size(mtu);
-+}
-+#endif
-+
-+static inline void skb_split_inside_header(struct sk_buff *skb,
-+                                         struct sk_buff* skb1,
-+                                         const u32 len, const int pos)
-+{
-+      int i;
-+
-+      memcpy(skb_put(skb1, pos - len), skb->data + len, pos - len);
-+
-+      /* And move data appendix as is. */
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-+              skb_shinfo(skb1)->frags[i] = skb_shinfo(skb)->frags[i];
-+
-+      skb_shinfo(skb1)->nr_frags = skb_shinfo(skb)->nr_frags;
-+      skb_shinfo(skb)->nr_frags  = 0;
-+      skb1->data_len             = skb->data_len;
-+      skb1->len                  += skb1->data_len;
-+      skb->data_len              = 0;
-+      skb->len                   = len;
-+      skb->tail                  = skb->data + len;
-+}
-+
-+static inline void skb_split_no_header(struct sk_buff *skb,
-+                                     struct sk_buff* skb1,
-+                                     const u32 len, int pos)
-+{
-+      int i, k = 0;
-+      const int nfrags = skb_shinfo(skb)->nr_frags;
-+
-+      skb_shinfo(skb)->nr_frags = 0;
-+      skb1->len                 = skb1->data_len = skb->len - len;
-+      skb->len                  = len;
-+      skb->data_len             = len - pos;
-+
-+      for (i = 0; i < nfrags; i++) {
-+              int size = skb_shinfo(skb)->frags[i].size;
-+
-+              if (pos + size > len) {
-+                      skb_shinfo(skb1)->frags[k] = skb_shinfo(skb)->frags[i];
-+
-+                      if (pos < len) {
-+                              /* Split frag.
-+                               * We have two variants in this case:
-+                               * 1. Move all the frag to the second
-+                               *    part, if it is possible. F.e.
-+                               *    this approach is mandatory for TUX,
-+                               *    where splitting is expensive.
-+                               * 2. Split is accurately. We make this.
-+                               */
-+                              get_page(skb_shinfo(skb)->frags[i].page);
-+                              skb_shinfo(skb1)->frags[0].page_offset += len - pos;
-+                              skb_shinfo(skb1)->frags[0].size -= len - pos;
-+                              skb_shinfo(skb)->frags[i].size  = len - pos;
-+                              skb_shinfo(skb)->nr_frags++;
-+                      }
-+                      k++;
-+              } else
-+                      skb_shinfo(skb)->nr_frags++;
-+              pos += size;
-+      }
-+      skb_shinfo(skb1)->nr_frags = k;
-+}
-+
-+/**
-+ * skb_split - Split fragmented skb to two parts at length len.
-+ * @skb: the buffer to split
-+ * @skb1: the buffer to receive the second part
-+ * @len: new length for skb
-+ */
-+void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len)
-+{
-+      int pos = skb_headlen(skb);
-+
-+      if (len < pos)  /* Split line is inside header. */
-+              skb_split_inside_header(skb, skb1, len, pos);
-+      else            /* Second chunk has no header, nothing to copy. */
-+              skb_split_no_header(skb, skb1, len, pos);
-+}
-+
-+/**
-+ * skb_prepare_seq_read - Prepare a sequential read of skb data
-+ * @skb: the buffer to read
-+ * @from: lower offset of data to be read
-+ * @to: upper offset of data to be read
-+ * @st: state variable
-+ *
-+ * Initializes the specified state variable. Must be called before
-+ * invoking skb_seq_read() for the first time.
-+ */
-+void skb_prepare_seq_read(struct sk_buff *skb, unsigned int from,
-+                        unsigned int to, struct skb_seq_state *st)
-+{
-+      st->lower_offset = from;
-+      st->upper_offset = to;
-+      st->root_skb = st->cur_skb = skb;
-+      st->frag_idx = st->stepped_offset = 0;
-+      st->frag_data = NULL;
-+}
-+
-+/**
-+ * skb_seq_read - Sequentially read skb data
-+ * @consumed: number of bytes consumed by the caller so far
-+ * @data: destination pointer for data to be returned
-+ * @st: state variable
-+ *
-+ * Reads a block of skb data at &consumed relative to the
-+ * lower offset specified to skb_prepare_seq_read(). Assigns
-+ * the head of the data block to &data and returns the length
-+ * of the block or 0 if the end of the skb data or the upper
-+ * offset has been reached.
-+ *
-+ * The caller is not required to consume all of the data
-+ * returned, i.e. &consumed is typically set to the number
-+ * of bytes already consumed and the next call to
-+ * skb_seq_read() will return the remaining part of the block.
-+ *
-+ * Note: The size of each block of data returned can be arbitary,
-+ *       this limitation is the cost for zerocopy seqeuental
-+ *       reads of potentially non linear data.
-+ *
-+ * Note: Fragment lists within fragments are not implemented
-+ *       at the moment, state->root_skb could be replaced with
-+ *       a stack for this purpose.
-+ */
-+unsigned int skb_seq_read(unsigned int consumed, const u8 **data,
-+                        struct skb_seq_state *st)
-+{
-+      unsigned int block_limit, abs_offset = consumed + st->lower_offset;
-+      skb_frag_t *frag;
-+
-+      if (unlikely(abs_offset >= st->upper_offset))
-+              return 0;
-+
-+next_skb:
-+      block_limit = skb_headlen(st->cur_skb);
-+
-+      if (abs_offset < block_limit) {
-+              *data = st->cur_skb->data + abs_offset;
-+              return block_limit - abs_offset;
-+      }
-+
-+      if (st->frag_idx == 0 && !st->frag_data)
-+              st->stepped_offset += skb_headlen(st->cur_skb);
-+
-+      while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) {
-+              frag = &skb_shinfo(st->cur_skb)->frags[st->frag_idx];
-+              block_limit = frag->size + st->stepped_offset;
-+
-+              if (abs_offset < block_limit) {
-+                      if (!st->frag_data)
-+                              st->frag_data = kmap_skb_frag(frag);
-+
-+                      *data = (u8 *) st->frag_data + frag->page_offset +
-+                              (abs_offset - st->stepped_offset);
-+
-+                      return block_limit - abs_offset;
-+              }
-+
-+              if (st->frag_data) {
-+                      kunmap_skb_frag(st->frag_data);
-+                      st->frag_data = NULL;
-+              }
-+
-+              st->frag_idx++;
-+              st->stepped_offset += frag->size;
-+      }
-+
-+      if (st->cur_skb->next) {
-+              st->cur_skb = st->cur_skb->next;
-+              st->frag_idx = 0;
-+              goto next_skb;
-+      } else if (st->root_skb == st->cur_skb &&
-+                 skb_shinfo(st->root_skb)->frag_list) {
-+              st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
-+              goto next_skb;
-+      }
-+
-+      return 0;
-+}
-+
-+/**
-+ * skb_abort_seq_read - Abort a sequential read of skb data
-+ * @st: state variable
-+ *
-+ * Must be called if skb_seq_read() was not called until it
-+ * returned 0.
-+ */
-+void skb_abort_seq_read(struct skb_seq_state *st)
-+{
-+      if (st->frag_data)
-+              kunmap_skb_frag(st->frag_data);
-+}
-+
-+#define TS_SKB_CB(state)      ((struct skb_seq_state *) &((state)->cb))
-+
-+static unsigned int skb_ts_get_next_block(unsigned int offset, const u8 **text,
-+                                        struct ts_config *conf,
-+                                        struct ts_state *state)
-+{
-+      return skb_seq_read(offset, text, TS_SKB_CB(state));
-+}
-+
-+static void skb_ts_finish(struct ts_config *conf, struct ts_state *state)
-+{
-+      skb_abort_seq_read(TS_SKB_CB(state));
-+}
-+
-+/**
-+ * skb_find_text - Find a text pattern in skb data
-+ * @skb: the buffer to look in
-+ * @from: search offset
-+ * @to: search limit
-+ * @config: textsearch configuration
-+ * @state: uninitialized textsearch state variable
-+ *
-+ * Finds a pattern in the skb data according to the specified
-+ * textsearch configuration. Use textsearch_next() to retrieve
-+ * subsequent occurrences of the pattern. Returns the offset
-+ * to the first occurrence or UINT_MAX if no match was found.
-+ */
-+unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
-+                         unsigned int to, struct ts_config *config,
-+                         struct ts_state *state)
-+{
-+      config->get_next_block = skb_ts_get_next_block;
-+      config->finish = skb_ts_finish;
-+
-+      skb_prepare_seq_read(skb, from, to, TS_SKB_CB(state));
-+
-+      return textsearch_find(config, state);
-+}
-+
-+/**
-+ * skb_append_datato_frags: - append the user data to a skb
-+ * @sk: sock  structure
-+ * @skb: skb structure to be appened with user data.
-+ * @getfrag: call back function to be used for getting the user data
-+ * @from: pointer to user message iov
-+ * @length: length of the iov message
-+ *
-+ * Description: This procedure append the user data in the fragment part
-+ * of the skb if any page alloc fails user this procedure returns  -ENOMEM
-+ */
-+int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
-+                      int (*getfrag)(void *from, char *to, int offset,
-+                                      int len, int odd, struct sk_buff *skb),
-+                      void *from, int length)
-+{
-+      int frg_cnt = 0;
-+      skb_frag_t *frag = NULL;
-+      struct page *page = NULL;
-+      int copy, left;
-+      int offset = 0;
-+      int ret;
-+
-+      do {
-+              /* Return error if we don't have space for new frag */
-+              frg_cnt = skb_shinfo(skb)->nr_frags;
-+              if (frg_cnt >= MAX_SKB_FRAGS)
-+                      return -EFAULT;
-+
-+              /* allocate a new page for next frag */
-+              page = alloc_pages(sk->sk_allocation, 0);
-+
-+              /* If alloc_page fails just return failure and caller will
-+               * free previous allocated pages by doing kfree_skb()
-+               */
-+              if (page == NULL)
-+                      return -ENOMEM;
-+
-+              /* initialize the next frag */
-+              sk->sk_sndmsg_page = page;
-+              sk->sk_sndmsg_off = 0;
-+              skb_fill_page_desc(skb, frg_cnt, page, 0, 0);
-+              skb->truesize += PAGE_SIZE;
-+              atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
-+
-+              /* get the new initialized frag */
-+              frg_cnt = skb_shinfo(skb)->nr_frags;
-+              frag = &skb_shinfo(skb)->frags[frg_cnt - 1];
-+
-+              /* copy the user data to page */
-+              left = PAGE_SIZE - frag->page_offset;
-+              copy = (length > left)? left : length;
-+
-+              ret = getfrag(from, (page_address(frag->page) +
-+                          frag->page_offset + frag->size),
-+                          offset, copy, 0, skb);
-+              if (ret < 0)
-+                      return -EFAULT;
-+
-+              /* copy was successful so update the size parameters */
-+              sk->sk_sndmsg_off += copy;
-+              frag->size += copy;
-+              skb->len += copy;
-+              skb->data_len += copy;
-+              offset += copy;
-+              length -= copy;
-+
-+      } while (length > 0);
-+
-+      return 0;
-+}
-+
-+/**
-+ *    skb_segment - Perform protocol segmentation on skb.
-+ *    @skb: buffer to segment
-+ *    @features: features for the output path (see dev->features)
-+ *
-+ *    This function performs segmentation on the given skb.  It returns
-+ *    the segment at the given position.  It returns NULL if there are
-+ *    no more segments to generate, or when an error is encountered.
-+ */
-+struct sk_buff *skb_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = NULL;
-+      struct sk_buff *tail = NULL;
-+      unsigned int mss = skb_shinfo(skb)->gso_size;
-+      unsigned int doffset = skb->data - skb->mac.raw;
-+      unsigned int offset = doffset;
-+      unsigned int headroom;
-+      unsigned int len;
-+      int sg = features & NETIF_F_SG;
-+      int nfrags = skb_shinfo(skb)->nr_frags;
-+      int err = -ENOMEM;
-+      int i = 0;
-+      int pos;
-+
-+      __skb_push(skb, doffset);
-+      headroom = skb_headroom(skb);
-+      pos = skb_headlen(skb);
-+
-+      do {
-+              struct sk_buff *nskb;
-+              skb_frag_t *frag;
-+              int hsize, nsize;
-+              int k;
-+              int size;
-+
-+              len = skb->len - offset;
-+              if (len > mss)
-+                      len = mss;
-+
-+              hsize = skb_headlen(skb) - offset;
-+              if (hsize < 0)
-+                      hsize = 0;
-+              nsize = hsize + doffset;
-+              if (nsize > len + doffset || !sg)
-+                      nsize = len + doffset;
-+
-+              nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
-+              if (unlikely(!nskb))
-+                      goto err;
-+
-+              if (segs)
-+                      tail->next = nskb;
-+              else
-+                      segs = nskb;
-+              tail = nskb;
-+
-+              nskb->dev = skb->dev;
-+              nskb->priority = skb->priority;
-+              nskb->protocol = skb->protocol;
-+              nskb->dst = dst_clone(skb->dst);
-+              memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
-+              nskb->pkt_type = skb->pkt_type;
-+              nskb->mac_len = skb->mac_len;
-+
-+              skb_reserve(nskb, headroom);
-+              nskb->mac.raw = nskb->data;
-+              nskb->nh.raw = nskb->data + skb->mac_len;
-+              nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
-+              memcpy(skb_put(nskb, doffset), skb->data, doffset);
-+
-+              if (!sg) {
-+                      nskb->csum = skb_copy_and_csum_bits(skb, offset,
-+                                                          skb_put(nskb, len),
-+                                                          len, 0);
-+                      continue;
-+              }
-+
-+              frag = skb_shinfo(nskb)->frags;
-+              k = 0;
-+
-+              nskb->ip_summed = CHECKSUM_HW;
-+              nskb->csum = skb->csum;
-+              memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
-+
-+              while (pos < offset + len) {
-+                      BUG_ON(i >= nfrags);
-+
-+                      *frag = skb_shinfo(skb)->frags[i];
-+                      get_page(frag->page);
-+                      size = frag->size;
-+
-+                      if (pos < offset) {
-+                              frag->page_offset += offset - pos;
-+                              frag->size -= offset - pos;
-+                      }
-+
-+                      k++;
-+
-+                      if (pos + size <= offset + len) {
-+                              i++;
-+                              pos += size;
-+                      } else {
-+                              frag->size -= pos + size - (offset + len);
-+                              break;
-+                      }
-+
-+                      frag++;
-+              }
-+
-+              skb_shinfo(nskb)->nr_frags = k;
-+              nskb->data_len = len - hsize;
-+              nskb->len += nskb->data_len;
-+              nskb->truesize += nskb->data_len;
-+      } while ((offset += len) < skb->len);
-+
-+      return segs;
-+
-+err:
-+      while ((skb = segs)) {
-+              segs = skb->next;
-+              kfree(skb);
-+      }
-+      return ERR_PTR(err);
-+}
-+
-+EXPORT_SYMBOL_GPL(skb_segment);
-+
-+void __init skb_init(void)
-+{
-+      skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
-+                                            sizeof(struct sk_buff),
-+                                            0,
-+                                            SLAB_HWCACHE_ALIGN,
-+                                            NULL, NULL);
-+      if (!skbuff_head_cache)
-+              panic("cannot create skbuff cache");
-+
-+      skbuff_fclone_cache = kmem_cache_create("skbuff_fclone_cache",
-+                                              (2*sizeof(struct sk_buff)) +
-+                                              sizeof(atomic_t),
-+                                              0,
-+                                              SLAB_HWCACHE_ALIGN,
-+                                              NULL, NULL);
-+      if (!skbuff_fclone_cache)
-+              panic("cannot create skbuff cache");
-+}
-+
-+EXPORT_SYMBOL(___pskb_trim);
-+EXPORT_SYMBOL(__kfree_skb);
-+EXPORT_SYMBOL(__pskb_pull_tail);
-+EXPORT_SYMBOL(__alloc_skb);
-+EXPORT_SYMBOL(pskb_copy);
-+EXPORT_SYMBOL(pskb_expand_head);
-+EXPORT_SYMBOL(skb_checksum);
-+EXPORT_SYMBOL(skb_clone);
-+EXPORT_SYMBOL(skb_clone_fraglist);
-+EXPORT_SYMBOL(skb_copy);
-+EXPORT_SYMBOL(skb_copy_and_csum_bits);
-+EXPORT_SYMBOL(skb_copy_and_csum_dev);
-+EXPORT_SYMBOL(skb_copy_bits);
-+EXPORT_SYMBOL(skb_copy_expand);
-+EXPORT_SYMBOL(skb_over_panic);
-+EXPORT_SYMBOL(skb_pad);
-+EXPORT_SYMBOL(skb_realloc_headroom);
-+EXPORT_SYMBOL(skb_under_panic);
-+EXPORT_SYMBOL(skb_dequeue);
-+EXPORT_SYMBOL(skb_dequeue_tail);
-+EXPORT_SYMBOL(skb_insert);
-+EXPORT_SYMBOL(skb_queue_purge);
-+EXPORT_SYMBOL(skb_queue_head);
-+EXPORT_SYMBOL(skb_queue_tail);
-+EXPORT_SYMBOL(skb_unlink);
-+EXPORT_SYMBOL(skb_append);
-+EXPORT_SYMBOL(skb_split);
-+EXPORT_SYMBOL(skb_prepare_seq_read);
-+EXPORT_SYMBOL(skb_seq_read);
-+EXPORT_SYMBOL(skb_abort_seq_read);
-+EXPORT_SYMBOL(skb_find_text);
-+EXPORT_SYMBOL(skb_append_datato_frags);
-diff -Nur linux-2.6.16.33-noxen/net/decnet/dn_nsp_in.c linux-2.6.16.33/net/decnet/dn_nsp_in.c
---- linux-2.6.16.33-noxen/net/decnet/dn_nsp_in.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/decnet/dn_nsp_in.c     2007-05-23 21:00:01.000000000 +0000
-@@ -801,8 +801,7 @@
-                * We linearize everything except data segments here.
-                */
-               if (cb->nsp_flags & ~0x60) {
--                      if (unlikely(skb_is_nonlinear(skb)) &&
--                          skb_linearize(skb, GFP_ATOMIC) != 0)
-+                      if (unlikely(skb_linearize(skb)))
-                               goto free_out;
-               }
-diff -Nur linux-2.6.16.33-noxen/net/decnet/dn_route.c linux-2.6.16.33/net/decnet/dn_route.c
---- linux-2.6.16.33-noxen/net/decnet/dn_route.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/decnet/dn_route.c      2007-05-23 21:00:01.000000000 +0000
-@@ -629,8 +629,7 @@
-                       padlen);
-         if (flags & DN_RT_PKT_CNTL) {
--              if (unlikely(skb_is_nonlinear(skb)) &&
--                  skb_linearize(skb, GFP_ATOMIC) != 0)
-+              if (unlikely(skb_linearize(skb)))
-                       goto dump_it;
-                 switch(flags & DN_RT_CNTL_MSK) {
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/af_inet.c linux-2.6.16.33/net/ipv4/af_inet.c
---- linux-2.6.16.33-noxen/net/ipv4/af_inet.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/af_inet.c 2007-05-23 21:00:01.000000000 +0000
-@@ -68,6 +68,7 @@
-  */
- #include <linux/config.h>
-+#include <linux/err.h>
- #include <linux/errno.h>
- #include <linux/types.h>
- #include <linux/socket.h>
-@@ -1084,6 +1085,88 @@
- EXPORT_SYMBOL(inet_sk_rebuild_header);
-+static int inet_gso_send_check(struct sk_buff *skb)
-+{
-+      struct iphdr *iph;
-+      struct net_protocol *ops;
-+      int proto;
-+      int ihl;
-+      int err = -EINVAL;
-+
-+      if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
-+              goto out;
-+
-+      iph = skb->nh.iph;
-+      ihl = iph->ihl * 4;
-+      if (ihl < sizeof(*iph))
-+              goto out;
-+
-+      if (unlikely(!pskb_may_pull(skb, ihl)))
-+              goto out;
-+
-+      skb->h.raw = __skb_pull(skb, ihl);
-+      iph = skb->nh.iph;
-+      proto = iph->protocol & (MAX_INET_PROTOS - 1);
-+      err = -EPROTONOSUPPORT;
-+
-+      rcu_read_lock();
-+      ops = rcu_dereference(inet_protos[proto]);
-+      if (likely(ops && ops->gso_send_check))
-+              err = ops->gso_send_check(skb);
-+      rcu_read_unlock();
-+
-+out:
-+      return err;
-+}
-+
-+static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = ERR_PTR(-EINVAL);
-+      struct iphdr *iph;
-+      struct net_protocol *ops;
-+      int proto;
-+      int ihl;
-+      int id;
-+
-+      if (!pskb_may_pull(skb, sizeof(*iph)))
-+              goto out;
-+
-+      iph = skb->nh.iph;
-+      ihl = iph->ihl * 4;
-+      if (ihl < sizeof(*iph))
-+              goto out;
-+
-+      if (!pskb_may_pull(skb, ihl))
-+              goto out;
-+
-+      skb->h.raw = __skb_pull(skb, ihl);
-+      iph = skb->nh.iph;
-+      id = ntohs(iph->id);
-+      proto = iph->protocol & (MAX_INET_PROTOS - 1);
-+      segs = ERR_PTR(-EPROTONOSUPPORT);
-+
-+      rcu_read_lock();
-+      ops = rcu_dereference(inet_protos[proto]);
-+      if (ops && ops->gso_segment)
-+              segs = ops->gso_segment(skb, features);
-+      rcu_read_unlock();
-+
-+      if (!segs || unlikely(IS_ERR(segs)))
-+              goto out;
-+
-+      skb = segs;
-+      do {
-+              iph = skb->nh.iph;
-+              iph->id = htons(id++);
-+              iph->tot_len = htons(skb->len - skb->mac_len);
-+              iph->check = 0;
-+              iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
-+      } while ((skb = skb->next));
-+
-+out:
-+      return segs;
-+}
-+
- #ifdef CONFIG_IP_MULTICAST
- static struct net_protocol igmp_protocol = {
-       .handler =      igmp_rcv,
-@@ -1093,6 +1176,8 @@
- static struct net_protocol tcp_protocol = {
-       .handler =      tcp_v4_rcv,
-       .err_handler =  tcp_v4_err,
-+      .gso_send_check = tcp_v4_gso_send_check,
-+      .gso_segment =  tcp_tso_segment,
-       .no_policy =    1,
- };
-@@ -1138,6 +1223,8 @@
- static struct packet_type ip_packet_type = {
-       .type = __constant_htons(ETH_P_IP),
-       .func = ip_rcv,
-+      .gso_send_check = inet_gso_send_check,
-+      .gso_segment = inet_gso_segment,
- };
- static int __init inet_init(void)
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/ip_output.c linux-2.6.16.33/net/ipv4/ip_output.c
---- linux-2.6.16.33-noxen/net/ipv4/ip_output.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/ip_output.c       2007-05-23 21:00:01.000000000 +0000
-@@ -210,8 +210,7 @@
-               return dst_output(skb);
-       }
- #endif
--      if (skb->len > dst_mtu(skb->dst) &&
--          !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
-+      if (skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb))
-               return ip_fragment(skb, ip_finish_output2);
-       else
-               return ip_finish_output2(skb);
-@@ -362,7 +361,7 @@
-       }
-       ip_select_ident_more(iph, &rt->u.dst, sk,
--                           (skb_shinfo(skb)->tso_segs ?: 1) - 1);
-+                           (skb_shinfo(skb)->gso_segs ?: 1) - 1);
-       /* Add an IP checksum. */
-       ip_send_check(iph);
-@@ -743,7 +742,8 @@
-                              (length - transhdrlen));
-       if (!err) {
-               /* specify the length of each IP datagram fragment*/
--              skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
-+              skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
-+              skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
-               __skb_queue_tail(&sk->sk_write_queue, skb);
-               return 0;
-@@ -839,7 +839,7 @@
-        */
-       if (transhdrlen &&
-           length + fragheaderlen <= mtu &&
--          rt->u.dst.dev->features&(NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) &&
-+          rt->u.dst.dev->features & NETIF_F_ALL_CSUM &&
-           !exthdrlen)
-               csummode = CHECKSUM_HW;
-@@ -1086,14 +1086,16 @@
-       inet->cork.length += size;
-       if ((sk->sk_protocol == IPPROTO_UDP) &&
--          (rt->u.dst.dev->features & NETIF_F_UFO))
--              skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
-+          (rt->u.dst.dev->features & NETIF_F_UFO)) {
-+              skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
-+              skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
-+      }
-       while (size > 0) {
-               int i;
--              if (skb_shinfo(skb)->ufo_size)
-+              if (skb_is_gso(skb))
-                       len = size;
-               else {
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/ipcomp.c linux-2.6.16.33/net/ipv4/ipcomp.c
---- linux-2.6.16.33-noxen/net/ipv4/ipcomp.c    2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/ipcomp.c  2007-05-23 21:00:01.000000000 +0000
-@@ -84,7 +84,7 @@
-                         struct xfrm_decap_state *decap, struct sk_buff *skb)
- {
-       u8 nexthdr;
--      int err = 0;
-+      int err = -ENOMEM;
-       struct iphdr *iph;
-       union {
-               struct iphdr    iph;
-@@ -92,11 +92,8 @@
-       } tmp_iph;
--      if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
--          skb_linearize(skb, GFP_ATOMIC) != 0) {
--              err = -ENOMEM;
-+      if (skb_linearize_cow(skb))
-               goto out;
--      }
-       skb->ip_summed = CHECKSUM_NONE;
-@@ -171,10 +168,8 @@
-               goto out_ok;
-       }
--      if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
--          skb_linearize(skb, GFP_ATOMIC) != 0) {
-+      if (skb_linearize_cow(skb))
-               goto out_ok;
--      }
-       
-       err = ipcomp_compress(x, skb);
-       iph = skb->nh.iph;
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/netfilter/ip_nat_proto_tcp.c linux-2.6.16.33/net/ipv4/netfilter/ip_nat_proto_tcp.c
---- linux-2.6.16.33-noxen/net/ipv4/netfilter/ip_nat_proto_tcp.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/netfilter/ip_nat_proto_tcp.c      2007-05-23 21:00:01.000000000 +0000
-@@ -129,7 +129,12 @@
-       if (hdrsize < sizeof(*hdr))
-               return 1;
--      hdr->check = ip_nat_cheat_check(~oldip, newip,
-+#ifdef CONFIG_XEN
-+      if ((*pskb)->proto_csum_blank)
-+              hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+      else
-+#endif
-+              hdr->check = ip_nat_cheat_check(~oldip, newip,
-                                       ip_nat_cheat_check(oldport ^ 0xFFFF,
-                                                          newport,
-                                                          hdr->check));
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/netfilter/ip_nat_proto_udp.c linux-2.6.16.33/net/ipv4/netfilter/ip_nat_proto_udp.c
---- linux-2.6.16.33-noxen/net/ipv4/netfilter/ip_nat_proto_udp.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/netfilter/ip_nat_proto_udp.c      2007-05-23 21:00:01.000000000 +0000
-@@ -113,11 +113,17 @@
-               newport = tuple->dst.u.udp.port;
-               portptr = &hdr->dest;
-       }
--      if (hdr->check) /* 0 is a special case meaning no checksum */
--              hdr->check = ip_nat_cheat_check(~oldip, newip,
-+      if (hdr->check) { /* 0 is a special case meaning no checksum */
-+#ifdef CONFIG_XEN
-+              if ((*pskb)->proto_csum_blank)
-+                      hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+              else
-+#endif
-+                      hdr->check = ip_nat_cheat_check(~oldip, newip,
-                                       ip_nat_cheat_check(*portptr ^ 0xFFFF,
-                                                          newport,
-                                                          hdr->check));
-+      }
-       *portptr = newport;
-       return 1;
- }
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/tcp.c linux-2.6.16.33/net/ipv4/tcp.c
---- linux-2.6.16.33-noxen/net/ipv4/tcp.c       2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/tcp.c     2007-05-23 21:00:01.000000000 +0000
-@@ -257,6 +257,7 @@
- #include <linux/fs.h>
- #include <linux/random.h>
- #include <linux/bootmem.h>
-+#include <linux/err.h>
- #include <net/icmp.h>
- #include <net/tcp.h>
-@@ -570,7 +571,7 @@
-               skb->ip_summed = CHECKSUM_HW;
-               tp->write_seq += copy;
-               TCP_SKB_CB(skb)->end_seq += copy;
--              skb_shinfo(skb)->tso_segs = 0;
-+              skb_shinfo(skb)->gso_segs = 0;
-               if (!copied)
-                       TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;
-@@ -621,14 +622,10 @@
-       ssize_t res;
-       struct sock *sk = sock->sk;
--#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
--
-       if (!(sk->sk_route_caps & NETIF_F_SG) ||
--          !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS))
-+          !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
-               return sock_no_sendpage(sock, page, offset, size, flags);
--#undef TCP_ZC_CSUM_FLAGS
--
-       lock_sock(sk);
-       TCP_CHECK_TIMER(sk);
-       res = do_tcp_sendpages(sk, &page, offset, size, flags);
-@@ -725,9 +722,7 @@
-                               /*
-                                * Check whether we can use HW checksum.
-                                */
--                              if (sk->sk_route_caps &
--                                  (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM |
--                                   NETIF_F_HW_CSUM))
-+                              if (sk->sk_route_caps & NETIF_F_ALL_CSUM)
-                                       skb->ip_summed = CHECKSUM_HW;
-                               skb_entail(sk, tp, skb);
-@@ -823,7 +818,7 @@
-                       tp->write_seq += copy;
-                       TCP_SKB_CB(skb)->end_seq += copy;
--                      skb_shinfo(skb)->tso_segs = 0;
-+                      skb_shinfo(skb)->gso_segs = 0;
-                       from += copy;
-                       copied += copy;
-@@ -2026,6 +2021,77 @@
- }
-+struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
-+{
-+      struct sk_buff *segs = ERR_PTR(-EINVAL);
-+      struct tcphdr *th;
-+      unsigned thlen;
-+      unsigned int seq;
-+      unsigned int delta;
-+      unsigned int oldlen;
-+      unsigned int len;
-+
-+      if (!pskb_may_pull(skb, sizeof(*th)))
-+              goto out;
-+
-+      th = skb->h.th;
-+      thlen = th->doff * 4;
-+      if (thlen < sizeof(*th))
-+              goto out;
-+
-+      if (!pskb_may_pull(skb, thlen))
-+              goto out;
-+
-+      oldlen = (u16)~skb->len;
-+      __skb_pull(skb, thlen);
-+
-+      if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
-+              /* Packet is from an untrusted source, reset gso_segs. */
-+              int mss = skb_shinfo(skb)->gso_size;
-+
-+              skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
-+
-+              segs = NULL;
-+              goto out;
-+      }
-+
-+      segs = skb_segment(skb, features);
-+      if (IS_ERR(segs))
-+              goto out;
-+
-+      len = skb_shinfo(skb)->gso_size;
-+      delta = htonl(oldlen + (thlen + len));
-+
-+      skb = segs;
-+      th = skb->h.th;
-+      seq = ntohl(th->seq);
-+
-+      do {
-+              th->fin = th->psh = 0;
-+
-+              th->check = ~csum_fold(th->check + delta);
-+              if (skb->ip_summed != CHECKSUM_HW)
-+                      th->check = csum_fold(csum_partial(skb->h.raw, thlen,
-+                                                         skb->csum));
-+
-+              seq += len;
-+              skb = skb->next;
-+              th = skb->h.th;
-+
-+              th->seq = htonl(seq);
-+              th->cwr = 0;
-+      } while (skb->next);
-+
-+      delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len);
-+      th->check = ~csum_fold(th->check + delta);
-+      if (skb->ip_summed != CHECKSUM_HW)
-+              th->check = csum_fold(csum_partial(skb->h.raw, thlen,
-+                                                 skb->csum));
-+
-+out:
-+      return segs;
-+}
-+
- extern void __skb_cb_too_small_for_tcp(int, int);
- extern struct tcp_congestion_ops tcp_reno;
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/tcp_input.c linux-2.6.16.33/net/ipv4/tcp_input.c
---- linux-2.6.16.33-noxen/net/ipv4/tcp_input.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/tcp_input.c       2007-05-23 21:00:01.000000000 +0000
-@@ -127,7 +127,7 @@
-       /* skb->len may jitter because of SACKs, even if peer
-        * sends good full-sized frames.
-        */
--      len = skb->len;
-+      len = skb_shinfo(skb)->gso_size ?: skb->len;
-       if (len >= icsk->icsk_ack.rcv_mss) {
-               icsk->icsk_ack.rcv_mss = len;
-       } else {
-@@ -1072,7 +1072,7 @@
-                               else
-                                       pkt_len = (end_seq -
-                                                  TCP_SKB_CB(skb)->seq);
--                              if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->tso_size))
-+                              if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->gso_size))
-                                       break;
-                               pcount = tcp_skb_pcount(skb);
-                       }
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/tcp_ipv4.c linux-2.6.16.33/net/ipv4/tcp_ipv4.c
---- linux-2.6.16.33-noxen/net/ipv4/tcp_ipv4.c  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/tcp_ipv4.c        2007-05-23 21:00:01.000000000 +0000
-@@ -495,6 +495,24 @@
-       }
- }
-+int tcp_v4_gso_send_check(struct sk_buff *skb)
-+{
-+      struct iphdr *iph;
-+      struct tcphdr *th;
-+
-+      if (!pskb_may_pull(skb, sizeof(*th)))
-+              return -EINVAL;
-+
-+      iph = skb->nh.iph;
-+      th = skb->h.th;
-+
-+      th->check = 0;
-+      th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0);
-+      skb->csum = offsetof(struct tcphdr, check);
-+      skb->ip_summed = CHECKSUM_HW;
-+      return 0;
-+}
-+
- /*
-  *    This routine will send an RST to the other tcp.
-  *
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/tcp_output.c linux-2.6.16.33/net/ipv4/tcp_output.c
---- linux-2.6.16.33-noxen/net/ipv4/tcp_output.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/tcp_output.c      2007-05-23 21:00:01.000000000 +0000
-@@ -497,15 +497,17 @@
-               /* Avoid the costly divide in the normal
-                * non-TSO case.
-                */
--              skb_shinfo(skb)->tso_segs = 1;
--              skb_shinfo(skb)->tso_size = 0;
-+              skb_shinfo(skb)->gso_segs = 1;
-+              skb_shinfo(skb)->gso_size = 0;
-+              skb_shinfo(skb)->gso_type = 0;
-       } else {
-               unsigned int factor;
-               factor = skb->len + (mss_now - 1);
-               factor /= mss_now;
--              skb_shinfo(skb)->tso_segs = factor;
--              skb_shinfo(skb)->tso_size = mss_now;
-+              skb_shinfo(skb)->gso_segs = factor;
-+              skb_shinfo(skb)->gso_size = mss_now;
-+              skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
-       }
- }
-@@ -850,7 +852,7 @@
-       if (!tso_segs ||
-           (tso_segs > 1 &&
--           skb_shinfo(skb)->tso_size != mss_now)) {
-+           tcp_skb_mss(skb) != mss_now)) {
-               tcp_set_skb_tso_segs(sk, skb, mss_now);
-               tso_segs = tcp_skb_pcount(skb);
-       }
-@@ -1510,8 +1512,9 @@
-          tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
-               if (!pskb_trim(skb, 0)) {
-                       TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1;
--                      skb_shinfo(skb)->tso_segs = 1;
--                      skb_shinfo(skb)->tso_size = 0;
-+                      skb_shinfo(skb)->gso_segs = 1;
-+                      skb_shinfo(skb)->gso_size = 0;
-+                      skb_shinfo(skb)->gso_type = 0;
-                       skb->ip_summed = CHECKSUM_NONE;
-                       skb->csum = 0;
-               }
-@@ -1716,8 +1719,9 @@
-               skb->csum = 0;
-               TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
-               TCP_SKB_CB(skb)->sacked = 0;
--              skb_shinfo(skb)->tso_segs = 1;
--              skb_shinfo(skb)->tso_size = 0;
-+              skb_shinfo(skb)->gso_segs = 1;
-+              skb_shinfo(skb)->gso_size = 0;
-+              skb_shinfo(skb)->gso_type = 0;
-               /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
-               TCP_SKB_CB(skb)->seq = tp->write_seq;
-@@ -1749,8 +1753,9 @@
-       skb->csum = 0;
-       TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
-       TCP_SKB_CB(skb)->sacked = 0;
--      skb_shinfo(skb)->tso_segs = 1;
--      skb_shinfo(skb)->tso_size = 0;
-+      skb_shinfo(skb)->gso_segs = 1;
-+      skb_shinfo(skb)->gso_size = 0;
-+      skb_shinfo(skb)->gso_type = 0;
-       /* Send it off. */
-       TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp);
-@@ -1833,8 +1838,9 @@
-       TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn;
-       TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
-       TCP_SKB_CB(skb)->sacked = 0;
--      skb_shinfo(skb)->tso_segs = 1;
--      skb_shinfo(skb)->tso_size = 0;
-+      skb_shinfo(skb)->gso_segs = 1;
-+      skb_shinfo(skb)->gso_size = 0;
-+      skb_shinfo(skb)->gso_type = 0;
-       th->seq = htonl(TCP_SKB_CB(skb)->seq);
-       th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1);
-       if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
-@@ -1937,8 +1943,9 @@
-       TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN;
-       TCP_ECN_send_syn(sk, tp, buff);
-       TCP_SKB_CB(buff)->sacked = 0;
--      skb_shinfo(buff)->tso_segs = 1;
--      skb_shinfo(buff)->tso_size = 0;
-+      skb_shinfo(buff)->gso_segs = 1;
-+      skb_shinfo(buff)->gso_size = 0;
-+      skb_shinfo(buff)->gso_type = 0;
-       buff->csum = 0;
-       TCP_SKB_CB(buff)->seq = tp->write_seq++;
-       TCP_SKB_CB(buff)->end_seq = tp->write_seq;
-@@ -2042,8 +2049,9 @@
-               buff->csum = 0;
-               TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK;
-               TCP_SKB_CB(buff)->sacked = 0;
--              skb_shinfo(buff)->tso_segs = 1;
--              skb_shinfo(buff)->tso_size = 0;
-+              skb_shinfo(buff)->gso_segs = 1;
-+              skb_shinfo(buff)->gso_size = 0;
-+              skb_shinfo(buff)->gso_type = 0;
-               /* Send it off, this clears delayed acks for us. */
-               TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk, tp);
-@@ -2078,8 +2086,9 @@
-       skb->csum = 0;
-       TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
-       TCP_SKB_CB(skb)->sacked = urgent;
--      skb_shinfo(skb)->tso_segs = 1;
--      skb_shinfo(skb)->tso_size = 0;
-+      skb_shinfo(skb)->gso_segs = 1;
-+      skb_shinfo(skb)->gso_size = 0;
-+      skb_shinfo(skb)->gso_type = 0;
-       /* Use a previous sequence.  This should cause the other
-        * end to send an ack.  Don't queue or clone SKB, just
-diff -Nur linux-2.6.16.33-noxen/net/ipv4/xfrm4_output.c linux-2.6.16.33/net/ipv4/xfrm4_output.c
---- linux-2.6.16.33-noxen/net/ipv4/xfrm4_output.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv4/xfrm4_output.c    2007-05-23 21:00:01.000000000 +0000
-@@ -9,6 +9,8 @@
-  */
- #include <linux/compiler.h>
-+#include <linux/if_ether.h>
-+#include <linux/kernel.h>
- #include <linux/skbuff.h>
- #include <linux/spinlock.h>
- #include <linux/netfilter_ipv4.h>
-@@ -17,6 +19,8 @@
- #include <net/xfrm.h>
- #include <net/icmp.h>
-+extern int skb_checksum_setup(struct sk_buff *skb);
-+
- /* Add encapsulation header.
-  *
-  * In transport mode, the IP header will be moved forward to make space
-@@ -103,6 +107,10 @@
-       struct xfrm_state *x = dst->xfrm;
-       int err;
-       
-+      err = skb_checksum_setup(skb);
-+      if (err)
-+              goto error_nolock;
-+
-       if (skb->ip_summed == CHECKSUM_HW) {
-               err = skb_checksum_help(skb, 0);
-               if (err)
-@@ -152,16 +160,10 @@
-       goto out_exit;
- }
--static int xfrm4_output_finish(struct sk_buff *skb)
-+static int xfrm4_output_finish2(struct sk_buff *skb)
- {
-       int err;
--#ifdef CONFIG_NETFILTER
--      if (!skb->dst->xfrm) {
--              IPCB(skb)->flags |= IPSKB_REROUTED;
--              return dst_output(skb);
--      }
--#endif
-       while (likely((err = xfrm4_output_one(skb)) == 0)) {
-               nf_reset(skb);
-@@ -174,7 +176,7 @@
-                       return dst_output(skb);
-               err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL,
--                            skb->dst->dev, xfrm4_output_finish);
-+                            skb->dst->dev, xfrm4_output_finish2);
-               if (unlikely(err != 1))
-                       break;
-       }
-@@ -182,6 +184,48 @@
-       return err;
- }
-+static int xfrm4_output_finish(struct sk_buff *skb)
-+{
-+      struct sk_buff *segs;
-+
-+#ifdef CONFIG_NETFILTER
-+      if (!skb->dst->xfrm) {
-+              IPCB(skb)->flags |= IPSKB_REROUTED;
-+              return dst_output(skb);
-+      }
-+#endif
-+
-+      if (!skb_is_gso(skb))
-+              return xfrm4_output_finish2(skb);
-+
-+      skb->protocol = htons(ETH_P_IP);
-+      segs = skb_gso_segment(skb, 0);
-+      kfree_skb(skb);
-+      if (unlikely(IS_ERR(segs)))
-+              return PTR_ERR(segs);
-+
-+      do {
-+              struct sk_buff *nskb = segs->next;
-+              int err;
-+
-+              segs->next = NULL;
-+              err = xfrm4_output_finish2(segs);
-+
-+              if (unlikely(err)) {
-+                      while ((segs = nskb)) {
-+                              nskb = segs->next;
-+                              segs->next = NULL;
-+                              kfree_skb(segs);
-+                      }
-+                      return err;
-+              }
-+
-+              segs = nskb;
-+      } while (segs);
-+
-+      return 0;
-+}
-+
- int xfrm4_output(struct sk_buff *skb)
- {
-       return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
-diff -Nur linux-2.6.16.33-noxen/net/ipv6/addrconf.c linux-2.6.16.33/net/ipv6/addrconf.c
---- linux-2.6.16.33-noxen/net/ipv6/addrconf.c  2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv6/addrconf.c        2007-05-23 21:00:01.000000000 +0000
-@@ -2471,6 +2471,7 @@
-       spin_lock_bh(&ifp->lock);
-       if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
-+          !(dev->flags&IFF_MULTICAST) ||
-           !(ifp->flags&IFA_F_TENTATIVE)) {
-               ifp->flags &= ~IFA_F_TENTATIVE;
-               spin_unlock_bh(&ifp->lock);
-@@ -2555,6 +2556,7 @@
-       if (ifp->idev->cnf.forwarding == 0 &&
-           ifp->idev->cnf.rtr_solicits > 0 &&
-           (dev->flags&IFF_LOOPBACK) == 0 &&
-+          (dev->flags & IFF_MULTICAST) &&
-           (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
-               struct in6_addr all_routers;
-diff -Nur linux-2.6.16.33-noxen/net/ipv6/ip6_output.c linux-2.6.16.33/net/ipv6/ip6_output.c
---- linux-2.6.16.33-noxen/net/ipv6/ip6_output.c        2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv6/ip6_output.c      2007-05-23 21:00:01.000000000 +0000
-@@ -147,7 +147,7 @@
- int ip6_output(struct sk_buff *skb)
- {
--      if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) ||
-+      if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) ||
-                               dst_allfrag(skb->dst))
-               return ip6_fragment(skb, ip6_output2);
-       else
-@@ -829,8 +829,9 @@
-               struct frag_hdr fhdr;
-               /* specify the length of each IP datagram fragment*/
--              skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - 
--                                              sizeof(struct frag_hdr);
-+              skb_shinfo(skb)->gso_size = mtu - fragheaderlen - 
-+                                          sizeof(struct frag_hdr);
-+              skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
-               ipv6_select_ident(skb, &fhdr);
-               skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
-               __skb_queue_tail(&sk->sk_write_queue, skb);
-diff -Nur linux-2.6.16.33-noxen/net/ipv6/ipcomp6.c linux-2.6.16.33/net/ipv6/ipcomp6.c
---- linux-2.6.16.33-noxen/net/ipv6/ipcomp6.c   2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv6/ipcomp6.c 2007-05-23 21:00:01.000000000 +0000
-@@ -64,7 +64,7 @@
- static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
- {
--      int err = 0;
-+      int err = -ENOMEM;
-       u8 nexthdr = 0;
-       int hdr_len = skb->h.raw - skb->nh.raw;
-       unsigned char *tmp_hdr = NULL;
-@@ -75,11 +75,8 @@
-       struct crypto_tfm *tfm;
-       int cpu;
--      if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
--              skb_linearize(skb, GFP_ATOMIC) != 0) {
--              err = -ENOMEM;
-+      if (skb_linearize_cow(skb))
-               goto out;
--      }
-       skb->ip_summed = CHECKSUM_NONE;
-@@ -158,10 +155,8 @@
-               goto out_ok;
-       }
--      if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
--              skb_linearize(skb, GFP_ATOMIC) != 0) {
-+      if (skb_linearize_cow(skb))
-               goto out_ok;
--      }
-       /* compression */
-       plen = skb->len - hdr_len;
-diff -Nur linux-2.6.16.33-noxen/net/ipv6/xfrm6_output.c linux-2.6.16.33/net/ipv6/xfrm6_output.c
---- linux-2.6.16.33-noxen/net/ipv6/xfrm6_output.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/ipv6/xfrm6_output.c    2007-05-23 21:00:01.000000000 +0000
-@@ -151,7 +151,7 @@
-       goto out_exit;
- }
--static int xfrm6_output_finish(struct sk_buff *skb)
-+static int xfrm6_output_finish2(struct sk_buff *skb)
- {
-       int err;
-@@ -167,7 +167,7 @@
-                       return dst_output(skb);
-               err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL,
--                            skb->dst->dev, xfrm6_output_finish);
-+                            skb->dst->dev, xfrm6_output_finish2);
-               if (unlikely(err != 1))
-                       break;
-       }
-@@ -175,6 +175,41 @@
-       return err;
- }
-+static int xfrm6_output_finish(struct sk_buff *skb)
-+{
-+      struct sk_buff *segs;
-+
-+      if (!skb_is_gso(skb))
-+              return xfrm6_output_finish2(skb);
-+
-+      skb->protocol = htons(ETH_P_IP);
-+      segs = skb_gso_segment(skb, 0);
-+      kfree_skb(skb);
-+      if (unlikely(IS_ERR(segs)))
-+              return PTR_ERR(segs);
-+
-+      do {
-+              struct sk_buff *nskb = segs->next;
-+              int err;
-+
-+              segs->next = NULL;
-+              err = xfrm6_output_finish2(segs);
-+
-+              if (unlikely(err)) {
-+                      while ((segs = nskb)) {
-+                              nskb = segs->next;
-+                              segs->next = NULL;
-+                              kfree_skb(segs);
-+                      }
-+                      return err;
-+              }
-+
-+              segs = nskb;
-+      } while (segs);
-+
-+      return 0;
-+}
-+
- int xfrm6_output(struct sk_buff *skb)
- {
-       return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
-diff -Nur linux-2.6.16.33-noxen/net/sched/sch_generic.c linux-2.6.16.33/net/sched/sch_generic.c
---- linux-2.6.16.33-noxen/net/sched/sch_generic.c      2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/sched/sch_generic.c    2007-05-23 21:00:01.000000000 +0000
-@@ -72,9 +72,9 @@
-    dev->queue_lock serializes queue accesses for this device
-    AND dev->qdisc pointer itself.
--   dev->xmit_lock serializes accesses to device driver.
-+   netif_tx_lock serializes accesses to device driver.
--   dev->queue_lock and dev->xmit_lock are mutually exclusive,
-+   dev->queue_lock and netif_tx_lock are mutually exclusive,
-    if one is grabbed, another must be free.
-  */
-@@ -90,14 +90,17 @@
-    NOTE: Called under dev->queue_lock with locally disabled BH.
- */
--int qdisc_restart(struct net_device *dev)
-+static inline int qdisc_restart(struct net_device *dev)
- {
-       struct Qdisc *q = dev->qdisc;
-       struct sk_buff *skb;
-       /* Dequeue packet */
--      if ((skb = q->dequeue(q)) != NULL) {
-+      if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
-               unsigned nolock = (dev->features & NETIF_F_LLTX);
-+
-+              dev->gso_skb = NULL;
-+
-               /*
-                * When the driver has LLTX set it does its own locking
-                * in start_xmit. No need to add additional overhead by
-@@ -108,7 +111,7 @@
-                * will be requeued.
-                */
-               if (!nolock) {
--                      if (!spin_trylock(&dev->xmit_lock)) {
-+                      if (!netif_tx_trylock(dev)) {
-                       collision:
-                               /* So, someone grabbed the driver. */
-                               
-@@ -126,8 +129,6 @@
-                               __get_cpu_var(netdev_rx_stat).cpu_collision++;
-                               goto requeue;
-                       }
--                      /* Remember that the driver is grabbed by us. */
--                      dev->xmit_lock_owner = smp_processor_id();
-               }
-               
-               {
-@@ -136,14 +137,11 @@
-                       if (!netif_queue_stopped(dev)) {
-                               int ret;
--                              if (netdev_nit)
--                                      dev_queue_xmit_nit(skb, dev);
--                              ret = dev->hard_start_xmit(skb, dev);
-+                              ret = dev_hard_start_xmit(skb, dev);
-                               if (ret == NETDEV_TX_OK) { 
-                                       if (!nolock) {
--                                              dev->xmit_lock_owner = -1;
--                                              spin_unlock(&dev->xmit_lock);
-+                                              netif_tx_unlock(dev);
-                                       }
-                                       spin_lock(&dev->queue_lock);
-                                       return -1;
-@@ -157,8 +155,7 @@
-                       /* NETDEV_TX_BUSY - we need to requeue */
-                       /* Release the driver */
-                       if (!nolock) { 
--                              dev->xmit_lock_owner = -1;
--                              spin_unlock(&dev->xmit_lock);
-+                              netif_tx_unlock(dev);
-                       } 
-                       spin_lock(&dev->queue_lock);
-                       q = dev->qdisc;
-@@ -175,7 +172,10 @@
-                */
- requeue:
--              q->ops->requeue(skb, q);
-+              if (skb->next)
-+                      dev->gso_skb = skb;
-+              else
-+                      q->ops->requeue(skb, q);
-               netif_schedule(dev);
-               return 1;
-       }
-@@ -183,11 +183,23 @@
-       return q->q.qlen;
- }
-+void __qdisc_run(struct net_device *dev)
-+{
-+      if (unlikely(dev->qdisc == &noop_qdisc))
-+              goto out;
-+
-+      while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
-+              /* NOTHING */;
-+
-+out:
-+      clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
-+}
-+
- static void dev_watchdog(unsigned long arg)
- {
-       struct net_device *dev = (struct net_device *)arg;
--      spin_lock(&dev->xmit_lock);
-+      netif_tx_lock(dev);
-       if (dev->qdisc != &noop_qdisc) {
-               if (netif_device_present(dev) &&
-                   netif_running(dev) &&
-@@ -201,7 +213,7 @@
-                               dev_hold(dev);
-               }
-       }
--      spin_unlock(&dev->xmit_lock);
-+      netif_tx_unlock(dev);
-       dev_put(dev);
- }
-@@ -225,17 +237,17 @@
- static void dev_watchdog_up(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       __netdev_watchdog_up(dev);
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- static void dev_watchdog_down(struct net_device *dev)
- {
--      spin_lock_bh(&dev->xmit_lock);
-+      netif_tx_lock_bh(dev);
-       if (del_timer(&dev->watchdog_timer))
-               __dev_put(dev);
--      spin_unlock_bh(&dev->xmit_lock);
-+      netif_tx_unlock_bh(dev);
- }
- void netif_carrier_on(struct net_device *dev)
-@@ -577,10 +589,17 @@
-       dev_watchdog_down(dev);
--      while (test_bit(__LINK_STATE_SCHED, &dev->state))
-+      /* Wait for outstanding dev_queue_xmit calls. */
-+      synchronize_rcu();
-+
-+      /* Wait for outstanding qdisc_run calls. */
-+      while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
-               yield();
--      spin_unlock_wait(&dev->xmit_lock);
-+      if (dev->gso_skb) {
-+              kfree_skb(dev->gso_skb);
-+              dev->gso_skb = NULL;
-+      }
- }
- void dev_init_scheduler(struct net_device *dev)
-@@ -622,6 +641,5 @@
- EXPORT_SYMBOL(qdisc_alloc);
- EXPORT_SYMBOL(qdisc_destroy);
- EXPORT_SYMBOL(qdisc_reset);
--EXPORT_SYMBOL(qdisc_restart);
- EXPORT_SYMBOL(qdisc_lock_tree);
- EXPORT_SYMBOL(qdisc_unlock_tree);
-diff -Nur linux-2.6.16.33-noxen/net/sched/sch_teql.c linux-2.6.16.33/net/sched/sch_teql.c
---- linux-2.6.16.33-noxen/net/sched/sch_teql.c 2006-11-22 18:06:31.000000000 +0000
-+++ linux-2.6.16.33/net/sched/sch_teql.c       2007-05-23 21:00:01.000000000 +0000
-@@ -302,20 +302,17 @@
-               switch (teql_resolve(skb, skb_res, slave)) {
-               case 0:
--                      if (spin_trylock(&slave->xmit_lock)) {
--                              slave->xmit_lock_owner = smp_processor_id();
-+                      if (netif_tx_trylock(slave)) {
-                               if (!netif_queue_stopped(slave) &&
-                                   slave->hard_start_xmit(skb, slave) == 0) {
--                                      slave->xmit_lock_owner = -1;
--                                      spin_unlock(&slave->xmit_lock);
-+                                      netif_tx_unlock(slave);
-                                       master->slaves = NEXT_SLAVE(q);
-                                       netif_wake_queue(dev);
-                                       master->stats.tx_packets++;
-                                       master->stats.tx_bytes += len;
-                                       return 0;
-                               }
--                              slave->xmit_lock_owner = -1;
--                              spin_unlock(&slave->xmit_lock);
-+                              netif_tx_unlock(slave);
-                       }
-                       if (netif_queue_stopped(dev))
-                               busy = 1;
-diff -Nur linux-2.6.16.33-noxen/scripts/Makefile.xen linux-2.6.16.33/scripts/Makefile.xen
---- linux-2.6.16.33-noxen/scripts/Makefile.xen 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.16.33/scripts/Makefile.xen       2007-01-08 15:00:46.000000000 +0000
-@@ -0,0 +1,14 @@
-+
-+# cherrypickxen($1 = allobj)
-+cherrypickxen = $(foreach var, $(1), \
-+              $(shell o=$(var); \
-+                      c=$${o%.o}-xen.c; \
-+                      s=$${o%.o}-xen.S; \
-+                      oxen=$${o%.o}-xen.o; \
-+                      [ -f $(srctree)/$(src)/$${c} ] || \
-+                         [ -f $(srctree)/$(src)/$${s} ] \
-+                              && echo $$oxen \
-+                              || echo $(var) ) \
-+        )
-+# filterxen($1 = allobj, $2 = noobjs)
-+filterxen = $(filter-out $(2), $(1))
diff --git a/src/patches/xen-3.0.4-layer7-fix.patch b/src/patches/xen-3.0.4-layer7-fix.patch
deleted file mode 100644 (file)
index 193a2f7..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
---- ipt_layer7.c~      2007-05-25 13:57:38.000000000 +0200
-+++ ipt_layer7.c       2007-05-25 13:58:43.000000000 +0200
-@@ -368,13 +368,13 @@
-               return (pattern_result ^ info->invert);
-       }
--      if(skb_is_nonlinear(skb)){
--              if(skb_linearize(skb, GFP_ATOMIC) != 0){
-+//    if(skb_is_nonlinear(skb)){
-+              if(skb_linearize(skb/*, GFP_ATOMIC */) != 0){
-                       if (net_ratelimit()) 
-                               printk(KERN_ERR "layer7: failed to linearize packet, bailing.\n");
-                       return info->invert;
-               }
--      }
-+//    }
-       
-       /* now that the skb is linearized, it's safe to set these. */
-       app_data = skb->data + app_data_offset(skb);
diff --git a/src/patches/xen-3.0.4-netfilter-fix.patch b/src/patches/xen-3.0.4-netfilter-fix.patch
deleted file mode 100644 (file)
index 830c84d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- ipt_REJECT.c~      2007-05-25 13:59:33.000000000 +0200
-+++ ipt_REJECT.c       2007-05-25 13:00:17.000000000 +0200
-@@ -159,8 +159,8 @@
-       nskb->nf_bridge = NULL;
- #endif
--      skb_shinfo(nskb)->tso_size = 0;
--      skb_shinfo(nskb)->tso_segs = 0;
-+      skb_shinfo(nskb)->gso_size = 0;
-+      skb_shinfo(nskb)->gso_segs = 0;
-       tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);