[kernel] r7284 - in dists/trunk/linux-2.6/debian/patches: . series

Bastian Blank waldi at costa.debian.org
Thu Aug 31 21:23:06 UTC 2006


Author: waldi
Date: Thu Aug 31 21:22:06 2006
New Revision: 7284

Added:
   dists/trunk/linux-2.6/debian/patches/series/0experimental.1-extra
   dists/trunk/linux-2.6/debian/patches/xen-fedora-35757.patch
      - copied, changed from r7158, /dists/sid/linux-2.6/debian/patches/xen-fedora-28927.patch

Log:
* debian/patches/series/0experimental.1-extra: Add xen-fedora-35757.patch.
* debian/patches/xen-fedora-35757.patch: Add.


Added: dists/trunk/linux-2.6/debian/patches/series/0experimental.1-extra
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/series/0experimental.1-extra	Thu Aug 31 21:22:06 2006
@@ -0,0 +1 @@
++ xen-fedora-35757.patch *_xen *_xen-vserver

Copied: dists/trunk/linux-2.6/debian/patches/xen-fedora-35757.patch (from r7158, /dists/sid/linux-2.6/debian/patches/xen-fedora-28927.patch)
==============================================================================
--- /dists/sid/linux-2.6/debian/patches/xen-fedora-28927.patch	(original)
+++ dists/trunk/linux-2.6/debian/patches/xen-fedora-35757.patch	Thu Aug 31 21:22:06 2006
@@ -1,6 +1,685 @@
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/boot-xen/Makefile linux-2.6.17-xen/arch/i386/boot-xen/Makefile
---- linux-2.6.17/arch/i386/boot-xen/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/boot-xen/Makefile	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/common/sa1111.c linux-2.6.18-rc5-xen/arch/arm/common/sa1111.c
+--- linux-2.6.18-rc5/arch/arm/common/sa1111.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/common/sa1111.c	2006-09-01 00:09:08.000000000 +0200
+@@ -618,7 +618,7 @@
+ {
+ 	struct sa1111 *sachip;
+ 	unsigned long id;
+-	unsigned int has_devs, val;
++	unsigned int has_devs;
+ 	int i, ret = -ENODEV;
+ 
+ 	sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
+@@ -669,6 +669,9 @@
+ 	sa1111_wake(sachip);
+ 
+ #ifdef CONFIG_ARCH_SA1100
++	{
++	unsigned int val;
++
+ 	/*
+ 	 * The SDRAM configuration of the SA1110 and the SA1111 must
+ 	 * match.  This is very important to ensure that SA1111 accesses
+@@ -692,6 +695,7 @@
+ 	 * Enable the SA1110 memory bus request and grant signals.
+ 	 */
+ 	sa1110_mb_enable();
++	}
+ #endif
+ 
+ 	/*
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/kernel/isa.c linux-2.6.18-rc5-xen/arch/arm/kernel/isa.c
+--- linux-2.6.18-rc5/arch/arm/kernel/isa.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/kernel/isa.c	2006-09-01 00:09:08.000000000 +0200
+@@ -3,21 +3,14 @@
+  *
+  *  Copyright (C) 1999 Phil Blundell
+  *
+- *  ISA shared memory and I/O port support
+- */
+-
+-/*
+  * 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.
++ *
++ *  ISA shared memory and I/O port support, and is required to support
++ *  iopl, inb, outb and friends in userspace via glibc emulation.
+  */
+-
+-/* 
+- * Nothing about this is actually ARM specific.  One day we could move
+- * it into kernel/resource.c or some place like that.  
+- */
+-
+ #include <linux/stddef.h>
+ #include <linux/types.h>
+ #include <linux/fs.h>
+@@ -27,21 +20,49 @@
+ static unsigned int isa_membase, isa_portbase, isa_portshift;
+ 
+ static ctl_table ctl_isa_vars[4] = {
+-	{BUS_ISA_MEM_BASE, "membase", &isa_membase, 
+-	 sizeof(isa_membase), 0444, NULL, &proc_dointvec},
+-	{BUS_ISA_PORT_BASE, "portbase", &isa_portbase, 
+-	 sizeof(isa_portbase), 0444, NULL, &proc_dointvec},
+-	{BUS_ISA_PORT_SHIFT, "portshift", &isa_portshift, 
+-	 sizeof(isa_portshift), 0444, NULL, &proc_dointvec},
+-	{0}
++	{
++		.ctl_name	= BUS_ISA_MEM_BASE,
++		.procname	= "membase",
++		.data		= &isa_membase, 
++		.maxlen		= sizeof(isa_membase),
++		.mode		= 0444,
++		.proc_handler	= &proc_dointvec,
++	}, {
++		.ctl_name	= BUS_ISA_PORT_BASE,
++		.procname	= "portbase",
++		.data		= &isa_portbase, 
++		.maxlen		= sizeof(isa_portbase),
++		.mode		= 0444,
++		.proc_handler	= &proc_dointvec,
++	}, {
++		.ctl_name	= BUS_ISA_PORT_SHIFT,
++		.procname	= "portshift",
++		.data		= &isa_portshift, 
++		.maxlen		= sizeof(isa_portshift),
++		.mode		= 0444,
++		.proc_handler	= &proc_dointvec,
++	}, {0}
+ };
+ 
+ static struct ctl_table_header *isa_sysctl_header;
+ 
+-static ctl_table ctl_isa[2] = {{CTL_BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars},
+-			       {0}};
+-static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa},
+-			       {0}};
++static ctl_table ctl_isa[2] = {
++	{
++		.ctl_name	= CTL_BUS_ISA,
++		.procname	= "isa",
++		.mode		= 0555,
++		.child		= ctl_isa_vars,
++	}, {0}
++};
++
++static ctl_table ctl_bus[2] = {
++	{
++		.ctl_name	= CTL_BUS,
++		.procname	= "bus",
++		.mode		= 0555,
++		.child		= ctl_isa,
++	}, {0}
++};
+ 
+ void __init
+ register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift)
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/kernel/Makefile linux-2.6.18-rc5-xen/arch/arm/kernel/Makefile
+--- linux-2.6.18-rc5/arch/arm/kernel/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/kernel/Makefile	2006-09-01 00:09:08.000000000 +0200
+@@ -13,12 +13,11 @@
+ obj-$(CONFIG_APM)		+= apm.o
+ obj-$(CONFIG_ISA_DMA_API)	+= dma.o
+ obj-$(CONFIG_ARCH_ACORN)	+= ecard.o 
+-obj-$(CONFIG_FOOTBRIDGE)	+= isa.o
+ obj-$(CONFIG_FIQ)		+= fiq.o
+ obj-$(CONFIG_MODULES)		+= armksyms.o module.o
+ obj-$(CONFIG_ARTHUR)		+= arthur.o
+ obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
+-obj-$(CONFIG_PCI)		+= bios32.o
++obj-$(CONFIG_PCI)		+= bios32.o isa.o
+ obj-$(CONFIG_SMP)		+= smp.o
+ obj-$(CONFIG_OABI_COMPAT)	+= sys_oabi-compat.o
+ 
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/mach-footbridge/dc21285.c linux-2.6.18-rc5-xen/arch/arm/mach-footbridge/dc21285.c
+--- linux-2.6.18-rc5/arch/arm/mach-footbridge/dc21285.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/mach-footbridge/dc21285.c	2006-09-01 00:09:08.000000000 +0200
+@@ -35,7 +35,6 @@
+ 
+ extern int setup_arm_irq(int, struct irqaction *);
+ extern void pcibios_report_status(u_int status_mask, int warn);
+-extern void register_isa_ports(unsigned int, unsigned int, unsigned int);
+ 
+ static unsigned long
+ dc21285_base_address(struct pci_bus *bus, unsigned int devfn)
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/mach-integrator/pci_v3.c linux-2.6.18-rc5-xen/arch/arm/mach-integrator/pci_v3.c
+--- linux-2.6.18-rc5/arch/arm/mach-integrator/pci_v3.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/mach-integrator/pci_v3.c	2006-09-01 00:09:08.000000000 +0200
+@@ -600,4 +600,6 @@
+ 		printk(KERN_ERR "PCI: unable to grab local bus timeout "
+ 		       "interrupt: %d\n", ret);
+ #endif
++
++	register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
+ }
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/mach-pxa/corgi_ssp.c linux-2.6.18-rc5-xen/arch/arm/mach-pxa/corgi_ssp.c
+--- linux-2.6.18-rc5/arch/arm/mach-pxa/corgi_ssp.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/mach-pxa/corgi_ssp.c	2006-09-01 00:09:08.000000000 +0200
+@@ -47,14 +47,15 @@
+  */
+ unsigned long corgi_ssp_ads7846_putget(ulong data)
+ {
+-	unsigned long ret,flag;
++	unsigned long flag;
++	u32 ret = 0;
+ 
+ 	spin_lock_irqsave(&corgi_ssp_lock, flag);
+ 	if (ssp_machinfo->cs_ads7846 >= 0)
+ 		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+ 
+ 	ssp_write_word(&corgi_ssp_dev,data);
+-	ret = ssp_read_word(&corgi_ssp_dev);
++ 	ssp_read_word(&corgi_ssp_dev, &ret);
+ 
+ 	if (ssp_machinfo->cs_ads7846 >= 0)
+ 		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
+@@ -88,7 +89,9 @@
+ 
+ unsigned long corgi_ssp_ads7846_get(void)
+ {
+-	return ssp_read_word(&corgi_ssp_dev);
++	u32 ret = 0;
++	ssp_read_word(&corgi_ssp_dev, &ret);
++	return ret;
+ }
+ 
+ EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
+@@ -104,6 +107,7 @@
+ unsigned long corgi_ssp_dac_put(ulong data)
+ {
+ 	unsigned long flag, sscr1 = SSCR1_SPH;
++	u32 tmp;
+ 
+ 	spin_lock_irqsave(&corgi_ssp_lock, flag);
+ 
+@@ -118,7 +122,7 @@
+ 		GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
+ 	ssp_write_word(&corgi_ssp_dev,data);
+ 	/* Read null data back from device to prevent SSP overflow */
+-	ssp_read_word(&corgi_ssp_dev);
++	ssp_read_word(&corgi_ssp_dev, &tmp);
+ 	if (ssp_machinfo->cs_lcdcon >= 0)
+ 		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
+ 
+@@ -150,7 +154,7 @@
+ int corgi_ssp_max1111_get(ulong data)
+ {
+ 	unsigned long flag;
+-	int voltage,voltage1,voltage2;
++	long voltage = 0, voltage1 = 0, voltage2 = 0;
+ 
+ 	spin_lock_irqsave(&corgi_ssp_lock, flag);
+ 	if (ssp_machinfo->cs_max1111 >= 0)
+@@ -163,15 +167,15 @@
+ 
+ 	/* TB1/RB1 */
+ 	ssp_write_word(&corgi_ssp_dev,data);
+-	ssp_read_word(&corgi_ssp_dev); /* null read */
++	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
+ 
+ 	/* TB12/RB2 */
+ 	ssp_write_word(&corgi_ssp_dev,0);
+-	voltage1=ssp_read_word(&corgi_ssp_dev);
++	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
+ 
+ 	/* TB13/RB3*/
+ 	ssp_write_word(&corgi_ssp_dev,0);
+-	voltage2=ssp_read_word(&corgi_ssp_dev);
++	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
+ 
+ 	ssp_disable(&corgi_ssp_dev);
+ 	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/mach-pxa/ssp.c linux-2.6.18-rc5-xen/arch/arm/mach-pxa/ssp.c
+--- linux-2.6.18-rc5/arch/arm/mach-pxa/ssp.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/mach-pxa/ssp.c	2006-09-01 00:09:08.000000000 +0200
+@@ -40,6 +40,8 @@
+ 
+ #define PXA_SSP_PORTS 	3
+ 
++#define TIMEOUT 100000
++
+ struct ssp_info_ {
+ 	int irq;
+ 	u32 clock;
+@@ -92,13 +94,18 @@
+  * The caller is expected to perform the necessary locking.
+  *
+  * Returns:
+- *   %-ETIMEDOUT	timeout occurred (for future)
++ *   %-ETIMEDOUT	timeout occurred
+  *   0			success
+  */
+ int ssp_write_word(struct ssp_dev *dev, u32 data)
+ {
+-	while (!(SSSR_P(dev->port) & SSSR_TNF))
++	int timeout = TIMEOUT;
++
++	while (!(SSSR_P(dev->port) & SSSR_TNF)) {
++	        if (!--timeout)
++	        	return -ETIMEDOUT;
+ 		cpu_relax();
++	}
+ 
+ 	SSDR_P(dev->port) = data;
+ 
+@@ -117,15 +124,21 @@
+  * The caller is expected to perform the necessary locking.
+  *
+  * Returns:
+- *   %-ETIMEDOUT	timeout occurred (for future)
++ *   %-ETIMEDOUT	timeout occurred
+  *   32-bit data	success
+  */
+-int ssp_read_word(struct ssp_dev *dev)
++int ssp_read_word(struct ssp_dev *dev, u32 *data)
+ {
+-	while (!(SSSR_P(dev->port) & SSSR_RNE))
++	int timeout = TIMEOUT;
++
++	while (!(SSSR_P(dev->port) & SSSR_RNE)) {
++	        if (!--timeout)
++	        	return -ETIMEDOUT;
+ 		cpu_relax();
++	}
+ 
+-	return SSDR_P(dev->port);
++	*data = SSDR_P(dev->port);
++	return 0;
+ }
+ 
+ /**
+@@ -136,13 +149,21 @@
+  *
+  * The caller is expected to perform the necessary locking.
+  */
+-void ssp_flush(struct ssp_dev *dev)
++int ssp_flush(struct ssp_dev *dev)
+ {
++	int timeout = TIMEOUT * 2;
++
+ 	do {
+ 		while (SSSR_P(dev->port) & SSSR_RNE) {
++		        if (!--timeout)
++		        	return -ETIMEDOUT;
+ 			(void) SSDR_P(dev->port);
+ 		}
++	        if (!--timeout)
++	        	return -ETIMEDOUT;
+ 	} while (SSSR_P(dev->port) & SSSR_BSY);
++
++	return 0;
+ }
+ 
+ /**
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/mach-sa1100/ssp.c linux-2.6.18-rc5-xen/arch/arm/mach-sa1100/ssp.c
+--- linux-2.6.18-rc5/arch/arm/mach-sa1100/ssp.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/mach-sa1100/ssp.c	2006-09-01 00:09:08.000000000 +0200
+@@ -23,6 +23,8 @@
+ #include <asm/hardware.h>
+ #include <asm/hardware/ssp.h>
+ 
++#define TIMEOUT 100000
++
+ static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	unsigned int status = Ser4SSSR;
+@@ -47,18 +49,27 @@
+  * The caller is expected to perform the necessary locking.
+  *
+  * Returns:
+- *   %-ETIMEDOUT	timeout occurred (for future)
++ *   %-ETIMEDOUT	timeout occurred
+  *   0			success
+  */
+ int ssp_write_word(u16 data)
+ {
+-	while (!(Ser4SSSR & SSSR_TNF))
++	int timeout = TIMEOUT;
++
++	while (!(Ser4SSSR & SSSR_TNF)) {
++	        if (!--timeout)
++	        	return -ETIMEDOUT;
+ 		cpu_relax();
++	}
+ 
+ 	Ser4SSDR = data;
+ 
+-	while (!(Ser4SSSR & SSSR_BSY))
++	timeout = TIMEOUT;
++	while (!(Ser4SSSR & SSSR_BSY)) {
++	        if (!--timeout)
++	        	return -ETIMEDOUT;
+ 		cpu_relax();
++	}
+ 
+ 	return 0;
+ }
+@@ -75,15 +86,22 @@
+  * The caller is expected to perform the necessary locking.
+  *
+  * Returns:
+- *   %-ETIMEDOUT	timeout occurred (for future)
++ *   %-ETIMEDOUT	timeout occurred
+  *   16-bit data	success
+  */
+-int ssp_read_word(void)
++int ssp_read_word(u16 *data)
+ {
+-	while (!(Ser4SSSR & SSSR_RNE))
++	int timeout = TIMEOUT;
++
++	while (!(Ser4SSSR & SSSR_RNE)) {
++	        if (!--timeout)
++	        	return -ETIMEDOUT;
+ 		cpu_relax();
++	}
++
++	*data = (u16)Ser4SSDR;
+ 
+-	return Ser4SSDR;
++	return 0;
+ }
+ 
+ /**
+@@ -93,14 +111,26 @@
+  * is empty.
+  *
+  * The caller is expected to perform the necessary locking.
++ *
++ * Returns:
++ *   %-ETIMEDOUT	timeout occurred
++ *   0			success
+  */
+-void ssp_flush(void)
++int ssp_flush(void)
+ {
++	int timeout = TIMEOUT * 2;
++
+ 	do {
+ 		while (Ser4SSSR & SSSR_RNE) {
++		        if (!--timeout)
++		        	return -ETIMEDOUT;
+ 			(void) Ser4SSDR;
+ 		}
++	        if (!--timeout)
++	        	return -ETIMEDOUT;
+ 	} while (Ser4SSSR & SSSR_BSY);
++
++	return 0;
+ }
+ 
+ /**
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/Makefile linux-2.6.18-rc5-xen/arch/arm/Makefile
+--- linux-2.6.18-rc5/arch/arm/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/Makefile	2006-09-01 00:09:08.000000000 +0200
+@@ -47,7 +47,8 @@
+ # testing for a specific architecture or later rather impossible.
+ arch-$(CONFIG_CPU_32v6)		:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
+ arch-$(CONFIG_CPU_32v6K)	:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
+-arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4)
++arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
++arch-$(CONFIG_CPU_32v4T)	:=-D__LINUX_ARM_ARCH__=4 -march=armv4t
+ arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
+ arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
+ 
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/mm/Kconfig linux-2.6.18-rc5-xen/arch/arm/mm/Kconfig
+--- linux-2.6.18-rc5/arch/arm/mm/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/mm/Kconfig	2006-09-01 00:09:08.000000000 +0200
+@@ -46,7 +46,7 @@
+ config CPU_ARM720T
+ 	bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR
+ 	default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
+-	select CPU_32v4
++	select CPU_32v4T
+ 	select CPU_ABRT_LV4T
+ 	select CPU_CACHE_V4
+ 	select CPU_CACHE_VIVT
+@@ -64,7 +64,7 @@
+ 	bool "Support ARM920T processor"
+ 	depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
+ 	default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
+-	select CPU_32v4
++	select CPU_32v4T
+ 	select CPU_ABRT_EV4T
+ 	select CPU_CACHE_V4WT
+ 	select CPU_CACHE_VIVT
+@@ -85,7 +85,7 @@
+ 	bool "Support ARM922T processor" if ARCH_INTEGRATOR
+ 	depends on ARCH_LH7A40X || ARCH_INTEGRATOR
+ 	default y if ARCH_LH7A40X
+-	select CPU_32v4
++	select CPU_32v4T
+ 	select CPU_ABRT_EV4T
+ 	select CPU_CACHE_V4WT
+ 	select CPU_CACHE_VIVT
+@@ -104,7 +104,7 @@
+  	bool "Support ARM925T processor" if ARCH_OMAP1
+  	depends on ARCH_OMAP15XX
+  	default y if ARCH_OMAP15XX
+-	select CPU_32v4
++	select CPU_32v4T
+ 	select CPU_ABRT_EV4T
+ 	select CPU_CACHE_V4WT
+ 	select CPU_CACHE_VIVT
+@@ -285,6 +285,11 @@
+ 	select TLS_REG_EMUL if SMP || !MMU
+ 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ 
++config CPU_32v4T
++	bool
++	select TLS_REG_EMUL if SMP || !MMU
++	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
++
+ config CPU_32v5
+ 	bool
+ 	select TLS_REG_EMUL if SMP || !MMU
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/vfp/vfpdouble.c linux-2.6.18-rc5-xen/arch/arm/vfp/vfpdouble.c
+--- linux-2.6.18-rc5/arch/arm/vfp/vfpdouble.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/vfp/vfpdouble.c	2006-09-01 00:09:08.000000000 +0200
+@@ -465,7 +465,7 @@
+ 	 */
+ 	if (tm & (VFP_INFINITY|VFP_NAN)) {
+ 		vsd.exponent = 255;
+-		if (tm & VFP_NAN)
++		if (tm == VFP_QNAN)
+ 			vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
+ 		goto pack_nan;
+ 	} else if (tm & VFP_ZERO)
+@@ -1127,7 +1127,7 @@
+ {
+ 	u32 op = inst & FOP_MASK;
+ 	u32 exceptions = 0;
+-	unsigned int dd = vfp_get_dd(inst);
++	unsigned int dest;
+ 	unsigned int dn = vfp_get_dn(inst);
+ 	unsigned int dm = vfp_get_dm(inst);
+ 	unsigned int vecitr, veclen, vecstride;
+@@ -1137,10 +1137,20 @@
+ 	vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2;
+ 
+ 	/*
++	 * fcvtds takes an sN register number as destination, not dN.
++	 * It also always operates on scalars.
++	 */
++	if ((inst & FEXT_MASK) == FEXT_FCVT) {
++		veclen = 0;
++		dest = vfp_get_sd(inst);
++	} else
++		dest = vfp_get_dd(inst);
++
++	/*
+ 	 * If destination bank is zero, vector length is always '1'.
+ 	 * ARM DDI0100F C5.1.3, C5.3.2.
+ 	 */
+-	if (FREG_BANK(dd) == 0)
++	if (FREG_BANK(dest) == 0)
+ 		veclen = 0;
+ 
+ 	pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
+@@ -1153,16 +1163,20 @@
+ 	for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
+ 		u32 except;
+ 
+-		if (op == FOP_EXT)
++		if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
++			pr_debug("VFP: itr%d (s%u) = op[%u] (d%u)\n",
++				 vecitr >> FPSCR_LENGTH_BIT,
++				 dest, dn, dm);
++		else if (op == FOP_EXT)
+ 			pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n",
+ 				 vecitr >> FPSCR_LENGTH_BIT,
+-				 dd, dn, dm);
++				 dest, dn, dm);
+ 		else
+ 			pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n",
+ 				 vecitr >> FPSCR_LENGTH_BIT,
+-				 dd, dn, FOP_TO_IDX(op), dm);
++				 dest, dn, FOP_TO_IDX(op), dm);
+ 
+-		except = fop(dd, dn, dm, fpscr);
++		except = fop(dest, dn, dm, fpscr);
+ 		pr_debug("VFP: itr%d: exceptions=%08x\n",
+ 			 vecitr >> FPSCR_LENGTH_BIT, except);
+ 
+@@ -1180,7 +1194,7 @@
+ 		 * we encounter an exception.  We continue.
+ 		 */
+ 
+-		dd = FREG_BANK(dd) + ((FREG_IDX(dd) + vecstride) & 6);
++		dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6);
+ 		dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6);
+ 		if (FREG_BANK(dm) != 0)
+ 			dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/vfp/vfp.h linux-2.6.18-rc5-xen/arch/arm/vfp/vfp.h
+--- linux-2.6.18-rc5/arch/arm/vfp/vfp.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/vfp/vfp.h	2006-09-01 00:09:08.000000000 +0200
+@@ -353,3 +353,11 @@
+  * A special flag to tell the normalisation code not to normalise.
+  */
+ #define VFP_NAN_FLAG	0x100
++
++/*
++ * A bit pattern used to indicate the initial (unset) value of the
++ * exception mask, in case nothing handles an instruction.  This
++ * doesn't include the NAN flag, which get masked out before
++ * we check for an error.
++ */
++#define VFP_EXCEPTION_ERROR	((u32)-1 & ~VFP_NAN_FLAG)
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/vfp/vfpmodule.c linux-2.6.18-rc5-xen/arch/arm/vfp/vfpmodule.c
+--- linux-2.6.18-rc5/arch/arm/vfp/vfpmodule.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/vfp/vfpmodule.c	2006-09-01 00:09:08.000000000 +0200
+@@ -131,7 +131,7 @@
+ 
+ 	pr_debug("VFP: raising exceptions %08x\n", exceptions);
+ 
+-	if (exceptions == (u32)-1) {
++	if (exceptions == VFP_EXCEPTION_ERROR) {
+ 		vfp_panic("unhandled bounce");
+ 		vfp_raise_sigfpe(0, regs);
+ 		return;
+@@ -170,7 +170,7 @@
+  */
+ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
+ {
+-	u32 exceptions = (u32)-1;
++	u32 exceptions = VFP_EXCEPTION_ERROR;
+ 
+ 	pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr);
+ 
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/arm/vfp/vfpsingle.c linux-2.6.18-rc5-xen/arch/arm/vfp/vfpsingle.c
+--- linux-2.6.18-rc5/arch/arm/vfp/vfpsingle.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/arm/vfp/vfpsingle.c	2006-09-01 00:09:08.000000000 +0200
+@@ -506,7 +506,7 @@
+ 	 */
+ 	if (tm & (VFP_INFINITY|VFP_NAN)) {
+ 		vdd.exponent = 2047;
+-		if (tm & VFP_NAN)
++		if (tm == VFP_QNAN)
+ 			vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
+ 		goto pack_nan;
+ 	} else if (tm & VFP_ZERO)
+@@ -514,10 +514,6 @@
+ 	else
+ 		vdd.exponent = vsm.exponent + (1023 - 127);
+ 
+-	/*
+-	 * Technically, if bit 0 of dd is set, this is an invalid
+-	 * instruction.  However, we ignore this for efficiency.
+-	 */
+ 	return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd");
+ 
+  pack_nan:
+@@ -1174,7 +1170,7 @@
+ {
+ 	u32 op = inst & FOP_MASK;
+ 	u32 exceptions = 0;
+-	unsigned int sd = vfp_get_sd(inst);
++	unsigned int dest;
+ 	unsigned int sn = vfp_get_sn(inst);
+ 	unsigned int sm = vfp_get_sm(inst);
+ 	unsigned int vecitr, veclen, vecstride;
+@@ -1184,10 +1180,22 @@
+ 	vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK);
+ 
+ 	/*
++	 * fcvtsd takes a dN register number as destination, not sN.
++	 * Technically, if bit 0 of dd is set, this is an invalid
++	 * instruction.  However, we ignore this for efficiency.
++	 * It also only operates on scalars.
++	 */
++	if ((inst & FEXT_MASK) == FEXT_FCVT) {
++		veclen = 0;
++		dest = vfp_get_dd(inst);
++	} else
++		dest = vfp_get_sd(inst);
++
++	/*
+ 	 * If destination bank is zero, vector length is always '1'.
+ 	 * ARM DDI0100F C5.1.3, C5.3.2.
+ 	 */
+-	if (FREG_BANK(sd) == 0)
++	if (FREG_BANK(dest) == 0)
+ 		veclen = 0;
+ 
+ 	pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
+@@ -1201,15 +1209,18 @@
+ 		s32 m = vfp_get_float(sm);
+ 		u32 except;
+ 
+-		if (op == FOP_EXT)
++		if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
++			pr_debug("VFP: itr%d (d%u) = op[%u] (s%u=%08x)\n",
++				 vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
++		else if (op == FOP_EXT)
+ 			pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n",
+-				 vecitr >> FPSCR_LENGTH_BIT, sd, sn, sm, m);
++				 vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
+ 		else
+ 			pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n",
+-				 vecitr >> FPSCR_LENGTH_BIT, sd, sn,
++				 vecitr >> FPSCR_LENGTH_BIT, dest, sn,
+ 				 FOP_TO_IDX(op), sm, m);
+ 
+-		except = fop(sd, sn, m, fpscr);
++		except = fop(dest, sn, m, fpscr);
+ 		pr_debug("VFP: itr%d: exceptions=%08x\n",
+ 			 vecitr >> FPSCR_LENGTH_BIT, except);
+ 
+@@ -1227,7 +1238,7 @@
+ 		 * we encounter an exception.  We continue.
+ 		 */
+ 
+-		sd = FREG_BANK(sd) + ((FREG_IDX(sd) + vecstride) & 7);
++		dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7);
+ 		sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7);
+ 		if (FREG_BANK(sm) != 0)
+ 			sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/boot-xen/Makefile linux-2.6.18-rc5-xen/arch/i386/boot-xen/Makefile
+--- linux-2.6.18-rc5/arch/i386/boot-xen/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/boot-xen/Makefile	2006-07-20 15:56:36.000000000 +0200
 @@ -0,0 +1,21 @@
 +
 +OBJCOPYFLAGS := -g --strip-unneeded
@@ -23,10 +702,18 @@
 +	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 -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/Kconfig linux-2.6.17-xen/arch/i386/Kconfig
---- linux-2.6.17/arch/i386/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/Kconfig	2006-08-14 15:57:20.000000000 +0200
-@@ -91,6 +91,15 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/Kconfig linux-2.6.18-rc5-xen/arch/i386/Kconfig
+--- linux-2.6.18-rc5/arch/i386/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/Kconfig	2006-09-01 00:09:08.000000000 +0200
+@@ -16,6 +16,7 @@
+ 
+ config GENERIC_TIME
+ 	bool
++	depends on !X86_XEN
+ 	default y
+ 
+ config LOCKDEP_SUPPORT
+@@ -103,6 +104,15 @@
  	help
  	  Choose this option if your computer is a standard PC or compatible.
  
@@ -42,7 +729,7 @@
  config X86_ELAN
  	bool "AMD Elan"
  	help
-@@ -193,6 +202,7 @@
+@@ -213,6 +223,7 @@
  
  config HPET_TIMER
  	bool "HPET Timer Support"
@@ -50,25 +737,7 @@
  	help
  	  This enables the use of the HPET for the kernel's internal timer.
  	  HPET is the next generation timer replacing legacy 8254s.
-@@ -223,7 +233,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
-@@ -233,7 +243,7 @@
- 
- config SCHED_MC
- 	bool "Multi-core scheduler support"
--	depends on SMP
-+	depends on SMP && !X86_XEN
- 	default y
- 	help
- 	  Multi-core scheduler support improves the CPU scheduler's decision
-@@ -244,7 +254,7 @@
+@@ -263,7 +274,7 @@
  
  config X86_UP_APIC
  	bool "Local APIC support on uniprocessors"
@@ -77,7 +746,7 @@
  	help
  	  A local APIC (Advanced Programmable Interrupt Controller) is an
  	  integrated interrupt controller in the CPU. If you have a single-CPU
-@@ -269,12 +279,12 @@
+@@ -288,12 +299,12 @@
  
  config X86_LOCAL_APIC
  	bool
@@ -92,15 +761,8 @@
  	default y
  
  config X86_VISWS_APIC
-@@ -282,9 +292,14 @@
- 	depends on X86_VISWS
- 	default y
+@@ -303,7 +314,7 @@
  
-+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
@@ -108,7 +770,7 @@
  	---help---
  	  Machine Check Exception support allows the processor to notify the
  	  kernel if it detects a problem (e.g. overheating, component failure).
-@@ -374,6 +389,7 @@
+@@ -402,6 +413,7 @@
  
  config MICROCODE
  	tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
@@ -116,7 +778,7 @@
  	---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
-@@ -391,6 +407,7 @@
+@@ -419,6 +431,7 @@
  
  config X86_MSR
  	tristate "/dev/cpu/*/msr - Model-specific register support"
@@ -124,7 +786,7 @@
  	help
  	  This device gives privileged processes access to the x86
  	  Model-Specific Registers (MSRs).  It is a character device with
-@@ -406,6 +423,10 @@
+@@ -434,6 +447,10 @@
  	  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
  	  /dev/cpu/31/cpuid.
  
@@ -135,7 +797,7 @@
  source "drivers/firmware/Kconfig"
  
  choice
-@@ -578,7 +599,7 @@
+@@ -607,7 +624,7 @@
  
  config HIGHPTE
  	bool "Allocate 3rd-level pagetables from highmem"
@@ -144,7 +806,7 @@
  	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
-@@ -587,6 +608,7 @@
+@@ -616,6 +633,7 @@
  
  config MATH_EMULATION
  	bool "Math emulation"
@@ -152,7 +814,7 @@
  	---help---
  	  Linux can emulate a math coprocessor (used for floating point
  	  operations) if you don't have one. 486DX and Pentium processors have
-@@ -612,6 +634,8 @@
+@@ -641,6 +659,8 @@
  
  config MTRR
  	bool "MTRR (Memory Type Range Register) support"
@@ -161,16 +823,16 @@
  	---help---
  	  On Intel P6 family processors (Pentium Pro, Pentium II and later)
  	  the Memory Type Range Registers (MTRRs) may be used to control
-@@ -646,7 +670,7 @@
+@@ -675,7 +695,7 @@
  
  config EFI
- 	bool "Boot from EFI support (EXPERIMENTAL)"
+ 	bool "Boot from EFI support"
 -	depends on ACPI
 +	depends on ACPI && !X86_XEN
  	default n
  	---help---
  	This enables the the kernel to boot on EFI platforms using
-@@ -664,7 +688,7 @@
+@@ -693,7 +713,7 @@
  
  config IRQBALANCE
   	bool "Enable kernel irq balancing"
@@ -179,7 +841,7 @@
  	default y
  	help
   	  The default yes will allow the kernel to do irq load balancing.
-@@ -712,7 +736,7 @@
+@@ -741,7 +761,7 @@
  
  config KEXEC
  	bool "kexec system call (EXPERIMENTAL)"
@@ -188,8 +850,16 @@
  	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
-@@ -767,18 +791,20 @@
- 
+@@ -794,6 +814,7 @@
+ config COMPAT_VDSO
+ 	bool "Compat VDSO support"
+ 	default y
++	depends on !X86_XEN
+ 	help
+ 	  Map the VDSO to the predictable old-style address too.
+ 	---help---
+@@ -810,18 +831,20 @@
+ 	depends on HIGHMEM
  
  menu "Power management options (ACPI, APM)"
 -	depends on !X86_VOYAGER
@@ -212,7 +882,7 @@
  	---help---
  	  APM is a BIOS specification for saving power using several different
  	  techniques. This is mostly useful for battery powered laptops with
-@@ -963,6 +989,7 @@
+@@ -1006,6 +1029,7 @@
  
  config PCI_GOBIOS
  	bool "BIOS"
@@ -220,7 +890,7 @@
  
  config PCI_GOMMCONFIG
  	bool "MMConfig"
-@@ -970,6 +997,13 @@
+@@ -1013,6 +1037,13 @@
  config PCI_GODIRECT
  	bool "Direct"
  
@@ -234,7 +904,7 @@
  config PCI_GOANY
  	bool "Any"
  
-@@ -977,7 +1011,7 @@
+@@ -1020,7 +1051,7 @@
  
  config PCI_BIOS
  	bool
@@ -243,7 +913,7 @@
  	default y
  
  config PCI_DIRECT
-@@ -990,6 +1024,18 @@
+@@ -1033,6 +1064,18 @@
  	depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
  	default y
  
@@ -262,7 +932,7 @@
  source "drivers/pci/pcie/Kconfig"
  
  source "drivers/pci/Kconfig"
-@@ -1000,7 +1046,7 @@
+@@ -1043,7 +1086,7 @@
  
  config ISA
  	bool "ISA support"
@@ -271,7 +941,7 @@
  	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
-@@ -1027,7 +1073,7 @@
+@@ -1070,7 +1113,7 @@
  source "drivers/eisa/Kconfig"
  
  config MCA
@@ -280,7 +950,7 @@
  	default y if X86_VOYAGER
  	help
  	  MicroChannel Architecture is found in some IBM PS/2 machines and
-@@ -1089,6 +1135,8 @@
+@@ -1146,6 +1189,8 @@
  
  source "crypto/Kconfig"
  
@@ -289,7 +959,7 @@
  source "lib/Kconfig"
  
  #
-@@ -1114,7 +1162,7 @@
+@@ -1171,7 +1216,7 @@
  
  config X86_HT
  	bool
@@ -298,7 +968,7 @@
  	default y
  
  config X86_BIOS_REBOOT
-@@ -1127,6 +1175,16 @@
+@@ -1184,6 +1229,16 @@
  	depends on X86_SMP || (X86_VOYAGER && SMP)
  	default y
  
@@ -315,9 +985,9 @@
  config KTIME_SCALAR
  	bool
  	default y
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/Kconfig.cpu linux-2.6.17-xen/arch/i386/Kconfig.cpu
---- linux-2.6.17/arch/i386/Kconfig.cpu	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/Kconfig.cpu	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/Kconfig.cpu linux-2.6.18-rc5-xen/arch/i386/Kconfig.cpu
+--- linux-2.6.18-rc5/arch/i386/Kconfig.cpu	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/Kconfig.cpu	2006-07-20 15:56:36.000000000 +0200
 @@ -251,7 +251,7 @@
  
  config X86_F00F_BUG
@@ -327,10 +997,17 @@
  	default y
  
  config X86_WP_WORKS_OK
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/Kconfig.debug linux-2.6.17-xen/arch/i386/Kconfig.debug
---- linux-2.6.17/arch/i386/Kconfig.debug	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/Kconfig.debug	2006-08-14 15:57:20.000000000 +0200
-@@ -84,6 +84,7 @@
+@@ -311,5 +311,5 @@
+ 
+ config X86_TSC
+ 	bool
+-	depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ
++	depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ && !X86_XEN
+ 	default y
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/Kconfig.debug linux-2.6.18-rc5-xen/arch/i386/Kconfig.debug
+--- linux-2.6.18-rc5/arch/i386/Kconfig.debug	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/Kconfig.debug	2006-09-01 00:09:08.000000000 +0200
+@@ -79,6 +79,7 @@
  config DOUBLEFAULT
  	default y
  	bool "Enable doublefault exception handler" if EMBEDDED
@@ -338,10 +1015,10 @@
  	help
            This option allows trapping of rare doublefault exceptions that
            would otherwise cause a system to silently reboot. Disabling this
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/acpi/boot-xen.c linux-2.6.17-xen/arch/i386/kernel/acpi/boot-xen.c
---- linux-2.6.17/arch/i386/kernel/acpi/boot-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/acpi/boot-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,1167 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/acpi/boot-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/acpi/boot-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/acpi/boot-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/acpi/boot-xen.c	2006-09-01 00:09:08.000000000 +0200
+@@ -0,0 +1,1168 @@
 +/*
 + *  boot.c - Architecture-Specific Low-Level ACPI Boot Support
 + *
@@ -368,7 +1045,6 @@
 + */
 +
 +#include <linux/init.h>
-+#include <linux/config.h>
 +#include <linux/acpi.h>
 +#include <linux/efi.h>
 +#include <linux/module.h>
@@ -404,7 +1080,7 @@
 +
 +#define BAD_MADT_ENTRY(entry, end) (					    \
 +		(!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
-+		((acpi_table_entry_header *)entry)->length != sizeof(*entry))
++		((acpi_table_entry_header *)entry)->length < sizeof(*entry))
 +
 +#define PREFIX			"ACPI: "
 +
@@ -548,6 +1224,8 @@
 +		if (mcfg->config[i].base_reserved) {
 +			printk(KERN_ERR PREFIX
 +			       "MMCONFIG not in low 4GB of memory\n");
++			kfree(pci_mmcfg_config);
++			pci_mmcfg_config_num = 0;
 +			return -ENODEV;
 +		}
 +	}
@@ -561,7 +1239,7 @@
 +{
 +	struct acpi_table_madt *madt = NULL;
 +
-+	if (!phys_addr || !size)
++	if (!phys_addr || !size || !cpu_has_apic)
 +		return -EINVAL;
 +
 +	madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size);
@@ -968,9 +1646,9 @@
 +
 +static int __init acpi_parse_fadt(unsigned long phys, unsigned long size)
 +{
-+	struct fadt_descriptor_rev2 *fadt = NULL;
++	struct fadt_descriptor *fadt = NULL;
 +
-+	fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size);
++	fadt = (struct fadt_descriptor *)__acpi_map_table(phys, size);
 +	if (!fadt) {
 +		printk(KERN_WARNING PREFIX "Unable to map FADT\n");
 +		return 0;
@@ -1101,7 +1779,7 @@
 +		return -ENODEV;
 +	}
 +
-+	if (!cpu_has_apic)
++	if (!cpu_has_apic) 
 +		return -ENODEV;
 +
 +	/*
@@ -1509,9 +2187,9 @@
 +
 +	return 0;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/acpi/Makefile linux-2.6.17-xen/arch/i386/kernel/acpi/Makefile
---- linux-2.6.17/arch/i386/kernel/acpi/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/acpi/Makefile	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/acpi/Makefile linux-2.6.18-rc5-xen/arch/i386/kernel/acpi/Makefile
+--- linux-2.6.18-rc5/arch/i386/kernel/acpi/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/acpi/Makefile	2006-07-20 15:56:36.000000000 +0200
 @@ -6,3 +6,7 @@
  obj-y				+= cstate.o processor.o
  endif
@@ -1520,9 +2198,36 @@
 +include $(srctree)/scripts/Makefile.xen
 +obj-y := $(call cherrypickxen, $(obj-y), $(src))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/apic-xen.c linux-2.6.17-xen/arch/i386/kernel/apic-xen.c
---- linux-2.6.17/arch/i386/kernel/apic-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/apic-xen.c	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/alternative.c linux-2.6.18-rc5-xen/arch/i386/kernel/alternative.c
+--- linux-2.6.18-rc5/arch/i386/kernel/alternative.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/alternative.c	2006-09-01 00:09:08.000000000 +0200
+@@ -4,7 +4,11 @@
+ #include <asm/alternative.h>
+ #include <asm/sections.h>
+ 
++#ifdef CONFIG_X86_64_XEN
++static int no_replacement    = 1;
++#else
+ static int no_replacement    = 0;
++#endif
+ static int smp_alt_once      = 0;
+ static int debug_alternative = 0;
+ 
+@@ -151,7 +155,11 @@
+ #ifdef CONFIG_X86_64
+ 		/* vsyscall code is not mapped yet. resolve it manually. */
+ 		if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) {
++#ifdef CONFIG_XEN
++			instr = __va(instr - (u8*)VSYSCALL_START + (u8*)phys_to_machine(__pa_symbol(&__vsyscall_0)));
++#else
+ 			instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0));
++#endif
+ 			DPRINTK("%s: vsyscall fixup: %p => %p\n",
+ 				__FUNCTION__, a->instr, instr);
+ 		}
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/apic-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/apic-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/apic-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/apic-xen.c	2006-07-20 15:56:36.000000000 +0200
 @@ -0,0 +1,160 @@
 +/*
 + *	Local APIC handling, local APIC timers
@@ -1540,7 +2245,6 @@
 + *	Mikael Pettersson	:	PM converted to driver model.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/init.h>
 +
 +#include <linux/mm.h>
@@ -1562,6 +2266,7 @@
 +#include <asm/arch_hooks.h>
 +#include <asm/hpet.h>
 +#include <asm/i8253.h>
++#include <asm/nmi.h>
 +
 +#include <mach_apic.h>
 +#include <mach_apicdef.h>
@@ -1587,7 +2292,7 @@
 + */
 +int apic_verbosity;
 +
-+int modern_apic(void)
++static int modern_apic(void)
 +{
 +#ifndef CONFIG_XEN
 +	unsigned int lvr, version;
@@ -1684,18 +2389,10 @@
 +
 +	return 0;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/asm-offsets.c linux-2.6.17-xen/arch/i386/kernel/asm-offsets.c
---- linux-2.6.17/arch/i386/kernel/asm-offsets.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/asm-offsets.c	2006-08-14 15:57:20.000000000 +0200
-@@ -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 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/asm-offsets.c linux-2.6.18-rc5-xen/arch/i386/kernel/asm-offsets.c
+--- linux-2.6.18-rc5/arch/i386/kernel/asm-offsets.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/asm-offsets.c	2006-07-31 23:43:28.000000000 +0200
+@@ -66,9 +66,14 @@
  	OFFSET(pbe_orig_address, pbe, orig_address);
  	OFFSET(pbe_next, pbe, next);
  
@@ -1710,13 +2407,11 @@
 +#endif
  
  	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
--	DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
-+	DEFINE(VSYSCALL_BASE, VSYSCALL_BASE);
- }
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/cpu/common-xen.c linux-2.6.17-xen/arch/i386/kernel/cpu/common-xen.c
---- linux-2.6.17/arch/i386/kernel/cpu/common-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/cpu/common-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,732 @@
+ 	DEFINE(VDSO_PRELINK, VDSO_PRELINK);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/cpu/common-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/cpu/common-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/cpu/common-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/cpu/common-xen.c	2006-09-01 00:09:08.000000000 +0200
+@@ -0,0 +1,739 @@
 +#include <linux/init.h>
 +#include <linux/string.h>
 +#include <linux/delay.h>
@@ -1730,6 +2425,8 @@
 +#include <asm/msr.h>
 +#include <asm/io.h>
 +#include <asm/mmu_context.h>
++#include <asm/mtrr.h>
++#include <asm/mce.h>
 +#ifdef CONFIG_X86_LOCAL_APIC
 +#include <asm/mpspec.h>
 +#include <asm/apic.h>
@@ -2014,7 +2711,7 @@
 +			if (c->x86 >= 0x6)
 +				c->x86_model += ((tfms >> 16) & 0xF) << 4;
 +			c->x86_mask = tfms & 15;
-+#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
++#ifdef CONFIG_X86_HT
 +			c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
 +#else
 +			c->apicid = (ebx >> 24) & 0xFF;
@@ -2039,7 +2736,7 @@
 +	early_intel_workaround(c);
 +
 +#ifdef CONFIG_X86_HT
-+	phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
++	c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
 +#endif
 +}
 +
@@ -2197,11 +2894,9 @@
 +{
 +	u32 	eax, ebx, ecx, edx;
 +	int 	index_msb, core_bits;
-+	int 	cpu = smp_processor_id();
 +
 +	cpuid(1, &eax, &ebx, &ecx, &edx);
 +
-+
 +	if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
 +		return;
 +
@@ -2212,16 +2907,17 @@
 +	} 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);
++			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);
++		c->phys_proc_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
 +
 +		printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
-+		       phys_proc_id[cpu]);
++		       c->phys_proc_id);
 +
 +		smp_num_siblings = smp_num_siblings / c->x86_max_cores;
 +
@@ -2229,12 +2925,12 @@
 +
 +		core_bits = get_count_order(c->x86_max_cores);
 +
-+		cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) &
++		c->cpu_core_id = 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]);
++			       c->cpu_core_id);
 +	}
 +}
 +#endif
@@ -2343,7 +3039,7 @@
 +	}
 +	printk(KERN_INFO "Initializing CPU#%d\n", cpu);
 +
-+	if (cpu_has_vme || cpu_has_de)
++	if (cpu_has_vme || cpu_has_tsc || 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");
@@ -2353,6 +3049,12 @@
 +	}
 +
 +#ifndef CONFIG_XEN
++	/* The CPU hotplug case */
++	if (cpu_gdt_descr->address) {
++		gdt = (struct desc_struct *)cpu_gdt_descr->address;
++		memset(gdt, 0, PAGE_SIZE);
++		goto old_gdt;
++	}
 +	/*
 +	 * This is a horrible hack to allocate the GDT.  The problem
 +	 * is that cpu_init() is called really early for the boot CPU
@@ -2371,7 +3073,7 @@
 +				local_irq_enable();
 +		}
 +	}
-+
++old_gdt:
 +	/*
 +	 * Initialize the per-CPU GDT with the boot GDT,
 +	 * and set up the GDT descriptor:
@@ -2449,9 +3151,9 @@
 +	per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;
 +}
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/cpu/Makefile linux-2.6.17-xen/arch/i386/kernel/cpu/Makefile
---- linux-2.6.17/arch/i386/kernel/cpu/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/cpu/Makefile	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/cpu/Makefile linux-2.6.18-rc5-xen/arch/i386/kernel/cpu/Makefile
+--- linux-2.6.18-rc5/arch/i386/kernel/cpu/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/cpu/Makefile	2006-07-20 15:56:36.000000000 +0200
 @@ -17,3 +17,8 @@
  
  obj-$(CONFIG_MTRR)	+= 	mtrr/
@@ -2461,9 +3163,9 @@
 +include $(srctree)/scripts/Makefile.xen
 +obj-y := $(call cherrypickxen, $(obj-y), $(src))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/cpu/mtrr/main-xen.c linux-2.6.17-xen/arch/i386/kernel/cpu/mtrr/main-xen.c
---- linux-2.6.17/arch/i386/kernel/cpu/mtrr/main-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/cpu/mtrr/main-xen.c	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/cpu/mtrr/main-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/cpu/mtrr/main-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/cpu/mtrr/main-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/cpu/mtrr/main-xen.c	2006-09-01 00:09:08.000000000 +0200
 @@ -0,0 +1,197 @@
 +#include <linux/init.h>
 +#include <linux/proc_fs.h>
@@ -2646,7 +3348,7 @@
 +{
 +	struct cpuinfo_x86 *c = &boot_cpu_data;
 +
-+	if (!(xen_start_info->flags & SIF_PRIVILEGED))
++	if (!is_initial_xendomain())
 +		return -ENODEV;
 +
 +	if ((!cpu_has(c, X86_FEATURE_MTRR)) &&
@@ -2662,9 +3364,9 @@
 +}
 +
 +subsys_initcall(mtrr_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/cpu/mtrr/Makefile linux-2.6.17-xen/arch/i386/kernel/cpu/mtrr/Makefile
---- linux-2.6.17/arch/i386/kernel/cpu/mtrr/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/cpu/mtrr/Makefile	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/cpu/mtrr/Makefile linux-2.6.18-rc5-xen/arch/i386/kernel/cpu/mtrr/Makefile
+--- linux-2.6.18-rc5/arch/i386/kernel/cpu/mtrr/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/cpu/mtrr/Makefile	2006-07-20 15:56:36.000000000 +0200
 @@ -3,3 +3,10 @@
  obj-y		+= cyrix.o
  obj-y		+= centaur.o
@@ -2676,43 +3378,25 @@
 +obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
 +obj-y := $(call cherrypickxen, $(obj-y))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/early_printk-xen.c linux-2.6.17-xen/arch/i386/kernel/early_printk-xen.c
---- linux-2.6.17/arch/i386/kernel/early_printk-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/early_printk-xen.c	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/early_printk-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/early_printk-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/early_printk-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/early_printk-xen.c	2006-07-20 15:56:36.000000000 +0200
 @@ -0,0 +1,2 @@
 +
 +#include "../../x86_64/kernel/early_printk-xen.c"
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/entry.S linux-2.6.17-xen/arch/i386/kernel/entry.S
---- linux-2.6.17/arch/i386/kernel/entry.S	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/entry.S	2006-08-14 15:57:20.000000000 +0200
-@@ -177,7 +177,7 @@
- 
- 	# sysenter call handler stub
- ENTRY(sysenter_entry)
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/entry.S linux-2.6.18-rc5-xen/arch/i386/kernel/entry.S
+--- linux-2.6.18-rc5/arch/i386/kernel/entry.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/entry.S	2006-09-01 00:09:08.000000000 +0200
+@@ -265,7 +265,7 @@
+ 	CFI_STARTPROC simple
+ 	CFI_DEF_CFA esp, 0
+ 	CFI_REGISTER esp, ebp
 -	movl TSS_sysenter_esp0(%esp),%esp
 +	movl SYSENTER_stack_esp0(%esp),%esp
  sysenter_past_esp:
- 	sti
- 	pushl $(__USER_DS)
-@@ -410,7 +410,7 @@
- ENTRY(irq_entries_start)
- .rept NR_IRQS
- 	ALIGN
--1:	pushl $vector-256
-+1:	pushl $~(vector)
- 	jmp common_interrupt
- .data
- 	.long 1b
-@@ -427,7 +427,7 @@
- 
- #define BUILD_INTERRUPT(name, nr)	\
- ENTRY(name)				\
--	pushl $nr-256;			\
-+	pushl $~(nr);			\
- 	SAVE_ALL			\
- 	movl %esp,%eax;			\
- 	call smp_/**/name;		\
-@@ -496,7 +496,7 @@
+ 	/*
+ 	 * No need to follow this irqs on/off section: the syscall
+@@ -685,7 +685,7 @@
   * that sets up the real kernel stack. Check here, since we can't
   * allow the wrong stack to be used.
   *
@@ -2721,7 +3405,7 @@
   * already pushed 3 words if it hits on the sysenter instruction:
   * eflags, cs and eip.
   *
-@@ -508,7 +508,7 @@
+@@ -697,7 +697,7 @@
  	cmpw $__KERNEL_CS,4(%esp);		\
  	jne ok;					\
  label:						\
@@ -2730,10 +3414,10 @@
  	pushfl;					\
  	pushl $__KERNEL_CS;			\
  	pushl $sysenter_past_esp
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/entry-xen.S linux-2.6.17-xen/arch/i386/kernel/entry-xen.S
---- linux-2.6.17/arch/i386/kernel/entry-xen.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/entry-xen.S	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,903 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/entry-xen.S linux-2.6.18-rc5-xen/arch/i386/kernel/entry-xen.S
+--- linux-2.6.18-rc5/arch/i386/kernel/entry-xen.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/entry-xen.S	2006-08-06 23:45:52.000000000 +0200
+@@ -0,0 +1,1209 @@
 +/*
 + *  linux/arch/i386/entry.S
 + *
@@ -2776,14 +3460,15 @@
 + * "current" is in register %ebx during any slow entries.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/linkage.h>
 +#include <asm/thread_info.h>
++#include <asm/irqflags.h>
 +#include <asm/errno.h>
 +#include <asm/segment.h>
 +#include <asm/smp.h>
 +#include <asm/page.h>
 +#include <asm/desc.h>
++#include <asm/dwarf2.h>
 +#include "irq_vectors.h"
 +#include <xen/interface/xen.h>
 +
@@ -2842,40 +3527,91 @@
 +#endif
 +
 +#ifdef CONFIG_PREEMPT
-+#define preempt_stop		cli
++#define preempt_stop		cli; TRACE_IRQS_OFF
 +#else
 +#define preempt_stop
 +#define resume_kernel		restore_nocheck
 +#endif
 +
++.macro TRACE_IRQS_IRET
++#ifdef CONFIG_TRACE_IRQFLAGS
++	testl $IF_MASK,EFLAGS(%esp)     # interrupts off?
++	jz 1f
++	TRACE_IRQS_ON
++1:
++#endif
++.endm
++
++#ifdef CONFIG_VM86
++#define resume_userspace_sig	check_userspace
++#else
++#define resume_userspace_sig	resume_userspace
++#endif
++
 +#define SAVE_ALL \
 +	cld; \
 +	pushl %es; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	/*CFI_REL_OFFSET es, 0;*/\
 +	pushl %ds; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	/*CFI_REL_OFFSET ds, 0;*/\
 +	pushl %eax; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	CFI_REL_OFFSET eax, 0;\
 +	pushl %ebp; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	CFI_REL_OFFSET ebp, 0;\
 +	pushl %edi; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	CFI_REL_OFFSET edi, 0;\
 +	pushl %esi; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	CFI_REL_OFFSET esi, 0;\
 +	pushl %edx; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	CFI_REL_OFFSET edx, 0;\
 +	pushl %ecx; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	CFI_REL_OFFSET ecx, 0;\
 +	pushl %ebx; \
++	CFI_ADJUST_CFA_OFFSET 4;\
++	CFI_REL_OFFSET ebx, 0;\
 +	movl $(__USER_DS), %edx; \
 +	movl %edx, %ds; \
 +	movl %edx, %es;
 +
 +#define RESTORE_INT_REGS \
 +	popl %ebx;	\
++	CFI_ADJUST_CFA_OFFSET -4;\
++	CFI_RESTORE ebx;\
 +	popl %ecx;	\
++	CFI_ADJUST_CFA_OFFSET -4;\
++	CFI_RESTORE ecx;\
 +	popl %edx;	\
++	CFI_ADJUST_CFA_OFFSET -4;\
++	CFI_RESTORE edx;\
 +	popl %esi;	\
++	CFI_ADJUST_CFA_OFFSET -4;\
++	CFI_RESTORE esi;\
 +	popl %edi;	\
++	CFI_ADJUST_CFA_OFFSET -4;\
++	CFI_RESTORE edi;\
 +	popl %ebp;	\
-+	popl %eax
++	CFI_ADJUST_CFA_OFFSET -4;\
++	CFI_RESTORE ebp;\
++	popl %eax;	\
++	CFI_ADJUST_CFA_OFFSET -4;\
++	CFI_RESTORE eax
 +
 +#define RESTORE_REGS	\
 +	RESTORE_INT_REGS; \
 +1:	popl %ds;	\
++	CFI_ADJUST_CFA_OFFSET -4;\
++	/*CFI_RESTORE ds;*/\
 +2:	popl %es;	\
++	CFI_ADJUST_CFA_OFFSET -4;\
++	/*CFI_RESTORE es;*/\
 +.section .fixup,"ax";	\
 +3:	movl $0,(%esp);	\
 +	jmp 1b;		\
@@ -2888,13 +3624,43 @@
 +	.long 2b,4b;	\
 +.previous
 +
++#define RING0_INT_FRAME \
++	CFI_STARTPROC simple;\
++	CFI_DEF_CFA esp, 3*4;\
++	/*CFI_OFFSET cs, -2*4;*/\
++	CFI_OFFSET eip, -3*4
++
++#define RING0_EC_FRAME \
++	CFI_STARTPROC simple;\
++	CFI_DEF_CFA esp, 4*4;\
++	/*CFI_OFFSET cs, -2*4;*/\
++	CFI_OFFSET eip, -3*4
++
++#define RING0_PTREGS_FRAME \
++	CFI_STARTPROC simple;\
++	CFI_DEF_CFA esp, OLDESP-EBX;\
++	/*CFI_OFFSET cs, CS-OLDESP;*/\
++	CFI_OFFSET eip, EIP-OLDESP;\
++	/*CFI_OFFSET es, ES-OLDESP;*/\
++	/*CFI_OFFSET ds, DS-OLDESP;*/\
++	CFI_OFFSET eax, EAX-OLDESP;\
++	CFI_OFFSET ebp, EBP-OLDESP;\
++	CFI_OFFSET edi, EDI-OLDESP;\
++	CFI_OFFSET esi, ESI-OLDESP;\
++	CFI_OFFSET edx, EDX-OLDESP;\
++	CFI_OFFSET ecx, ECX-OLDESP;\
++	CFI_OFFSET ebx, EBX-OLDESP
 +
 +ENTRY(ret_from_fork)
++	CFI_STARTPROC
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	call schedule_tail
 +	GET_THREAD_INFO(%ebp)
 +	popl %eax
++	CFI_ADJUST_CFA_OFFSET -4
 +	jmp syscall_exit
++	CFI_ENDPROC
 +
 +/*
 + * Return to user mode is not as complex as all this looks,
@@ -2905,10 +3671,12 @@
 +
 +	# userspace resumption stub bypassing syscall exit tracing
 +	ALIGN
++	RING0_PTREGS_FRAME
 +ret_from_exception:
 +	preempt_stop
 +ret_from_intr:
 +	GET_THREAD_INFO(%ebp)
++check_userspace:
 +	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
 +	movb CS(%esp), %al
 +	testl $(VM_MASK | 2), %eax
@@ -2937,20 +3705,42 @@
 +	call preempt_schedule_irq
 +	jmp need_resched
 +#endif
++	CFI_ENDPROC
 +
 +/* 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)
++	CFI_STARTPROC simple
++	CFI_DEF_CFA esp, 0
++	CFI_REGISTER esp, ebp
 +	movl SYSENTER_stack_esp0(%esp),%esp
 +sysenter_past_esp:
++	/*
++	 * No need to follow this irqs on/off section: the syscall
++	 * disabled irqs and here we enable it straight after entry:
++	 */
 +	sti
 +	pushl $(__USER_DS)
++	CFI_ADJUST_CFA_OFFSET 4
++	/*CFI_REL_OFFSET ss, 0*/
 +	pushl %ebp
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET esp, 0
 +	pushfl
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl $(__USER_CS)
-+	pushl $SYSENTER_RETURN
++	CFI_ADJUST_CFA_OFFSET 4
++	/*CFI_REL_OFFSET cs, 0*/
++	/*
++	 * Push current_thread_info()->sysenter_return to the stack.
++	 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
++	 * pushed above; +8 corresponds to copy_thread's esp0 setting.
++	 */
++	pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET eip, 0
 +
 +/*
 + * Load the potential sixth argument from user stack.
@@ -2965,6 +3755,7 @@
 +.previous
 +
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	GET_THREAD_INFO(%ebp)
 +
@@ -2976,6 +3767,7 @@
 +	call *sys_call_table(,%eax,4)
 +	movl %eax,EAX(%esp)
 +	DISABLE_INTERRUPTS
++	TRACE_IRQS_OFF
 +	movl TI_flags(%ebp), %ecx
 +	testw $_TIF_ALLWORK_MASK, %cx
 +	jne syscall_exit_work
@@ -2983,6 +3775,7 @@
 +	movl EIP(%esp), %edx
 +	movl OLDESP(%esp), %ecx
 +	xorl %ebp,%ebp
++	TRACE_IRQS_ON
 +#ifdef CONFIG_XEN
 +	__ENABLE_INTERRUPTS
 +sysexit_scrit:	/**** START OF SYSEXIT CRITICAL REGION ****/
@@ -2993,18 +3786,23 @@
 +14:	__DISABLE_INTERRUPTS
 +sysexit_ecrit:	/**** END OF SYSEXIT CRITICAL REGION ****/
 +	push %esp
++	CFI_ADJUST_CFA_OFFSET 4
 +	call evtchn_do_upcall
 +	add  $4,%esp
++	CFI_ADJUST_CFA_OFFSET -4
 +	jmp  ret_from_intr
 +#else
 +	sti
 +	sysexit
 +#endif /* !CONFIG_XEN */
++	CFI_ENDPROC
 +
 +
 +	# system call handler stub
 +ENTRY(system_call)
++	RING0_INT_FRAME			# can't unwind into user space anyway
 +	pushl %eax			# save orig_eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	GET_THREAD_INFO(%ebp)
 +	testl $TF_MASK,EFLAGS(%esp)
@@ -3024,6 +3822,7 @@
 +	DISABLE_INTERRUPTS		# make sure we don't miss an interrupt
 +					# setting need_resched or sigpending
 +					# between sampling and the iret
++	TRACE_IRQS_OFF
 +	movl TI_flags(%ebp), %ecx
 +	testw $_TIF_ALLWORK_MASK, %cx	# current->work
 +	jne syscall_exit_work
@@ -3051,12 +3850,17 @@
 +	andb $1,%al			# EAX[0] == IRET_EFLAGS.IF & event_mask
 +	jnz restore_all_enable_events	#        != 0 => enable event delivery
 +#endif
++	TRACE_IRQS_IRET
++	CFI_REMEMBER_STATE
++restore_nocheck_notrace:
 +	RESTORE_REGS
 +	addl $4, %esp
++	CFI_ADJUST_CFA_OFFSET -4
 +1:	iret
 +.section .fixup,"ax"
 +iret_exc:
 +#ifndef CONFIG_XEN
++	TRACE_IRQS_ON
 +	sti
 +#endif
 +	pushl $0			# no error code
@@ -3068,6 +3872,7 @@
 +	.long 1b,iret_exc
 +.previous
 +
++	CFI_RESTORE_STATE
 +#ifndef CONFIG_XEN
 +ldt_ss:
 +	larl OLDSS(%esp), %eax
@@ -3081,11 +3886,15 @@
 +	 * CPUs, which we can try to work around to make
 +	 * dosemu and wine happy. */
 +	subl $8, %esp		# reserve space for switch16 pointer
++	CFI_ADJUST_CFA_OFFSET 8
 +	cli
++	TRACE_IRQS_OFF
 +	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
++	CFI_ADJUST_CFA_OFFSET -8	# frame has moved
++	TRACE_IRQS_IRET
 +	RESTORE_REGS
 +	lss 20+4(%esp), %esp	# switch to 16bit stack
 +1:	iret
@@ -3100,9 +3909,11 @@
 +	addl $4, %esp
 +	jmp  hypercall_page + (__HYPERVISOR_iret * 32)
 +#endif
++	CFI_ENDPROC
 +
 +	# perform work that needs to be done immediately before resumption
 +	ALIGN
++	RING0_PTREGS_FRAME		# can't unwind into user space anyway
 +work_pending:
 +	testb $_TIF_NEED_RESCHED, %cl
 +	jz work_notifysig
@@ -3111,6 +3922,7 @@
 +	DISABLE_INTERRUPTS		# make sure we don't miss an interrupt
 +					# setting need_resched or sigpending
 +					# between sampling and the iret
++	TRACE_IRQS_OFF
 +	movl TI_flags(%ebp), %ecx
 +	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done other
 +					# than syscall tracing?
@@ -3126,18 +3938,20 @@
 +					# vm86-space
 +	xorl %edx, %edx
 +	call do_notify_resume
-+	jmp resume_userspace
++	jmp resume_userspace_sig
 +
 +	ALIGN
 +work_notifysig_v86:
 +#ifdef CONFIG_VM86
 +	pushl %ecx			# save ti_flags for do_notify_resume
++	CFI_ADJUST_CFA_OFFSET 4
 +	call save_v86_state		# %eax contains pt_regs pointer
 +	popl %ecx
++	CFI_ADJUST_CFA_OFFSET -4
 +	movl %eax, %esp
 +	xorl %edx, %edx
 +	call do_notify_resume
-+	jmp resume_userspace
++	jmp resume_userspace_sig
 +#endif
 +
 +	# perform syscall exit tracing
@@ -3160,25 +3974,28 @@
 +syscall_exit_work:
 +	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
 +	jz work_pending
++	TRACE_IRQS_ON
 +	ENABLE_INTERRUPTS		# could let do_syscall_trace() call
 +					# schedule() instead
 +	movl %esp, %eax
 +	movl $1, %edx
 +	call do_syscall_trace
 +	jmp resume_userspace
++	CFI_ENDPROC
 +
-+	ALIGN
++	RING0_INT_FRAME			# can't unwind into user space anyway
 +syscall_fault:
 +	pushl %eax			# save orig_eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	GET_THREAD_INFO(%ebp)
 +	movl $-EFAULT,EAX(%esp)
 +	jmp resume_userspace
 +
-+	ALIGN
 +syscall_badsys:
 +	movl $-ENOSYS,EAX(%esp)
 +	jmp resume_userspace
++	CFI_ENDPROC
 +
 +#ifndef CONFIG_XEN
 +#define FIXUP_ESPFIX_STACK \
@@ -3191,16 +4008,21 @@
 +	movl %eax, %esp;
 +#define UNWIND_ESPFIX_STACK \
 +	pushl %eax; \
++	CFI_ADJUST_CFA_OFFSET 4; \
 +	movl %ss, %eax; \
 +	/* see if on 16bit stack */ \
 +	cmpw $__ESPFIX_SS, %ax; \
-+	jne 28f; \
-+	movl $__KERNEL_DS, %edx; \
-+	movl %edx, %ds; \
-+	movl %edx, %es; \
++	je 28f; \
++27:	popl %eax; \
++	CFI_ADJUST_CFA_OFFSET -4; \
++.section .fixup,"ax"; \
++28:	movl $__KERNEL_DS, %eax; \
++	movl %eax, %ds; \
++	movl %eax, %es; \
 +	/* switch to 32bit stack */ \
-+	FIXUP_ESPFIX_STACK \
-+28:	popl %eax;
++	FIXUP_ESPFIX_STACK; \
++	jmp 27b; \
++.previous
 +
 +/*
 + * Build the entry stubs and pointer table with
@@ -3212,9 +4034,14 @@
 +
 +vector=0
 +ENTRY(irq_entries_start)
++	RING0_INT_FRAME
 +.rept NR_IRQS
 +	ALIGN
++ .if vector
++	CFI_ADJUST_CFA_OFFSET -4
++ .endif
 +1:	pushl $~(vector)
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp common_interrupt
 +.data
 +	.long 1b
@@ -3222,20 +4049,31 @@
 +vector=vector+1
 +.endr
 +
++/*
++ * the CPU automatically disables interrupts when executing an IRQ vector,
++ * so IRQ-flags tracing has to follow that:
++ */
 +	ALIGN
 +common_interrupt:
 +	SAVE_ALL
++	TRACE_IRQS_OFF
 +	movl %esp,%eax
 +	call do_IRQ
 +	jmp ret_from_intr
++	CFI_ENDPROC
 +
 +#define BUILD_INTERRUPT(name, nr)	\
 +ENTRY(name)				\
-+	pushl $~(nr);			\
 +	SAVE_ALL			\
++	RING0_INT_FRAME;		\
++	pushl $~(nr);			\
++	CFI_ADJUST_CFA_OFFSET 4;	\
++	SAVE_ALL;			\
++	TRACE_IRQS_OFF			\
 +	movl %esp,%eax;			\
 +	call smp_/**/name;		\
-+	jmp ret_from_intr;
++	jmp ret_from_intr;		\
++	CFI_ENDPROC
 +
 +/* The include is where all of the SMP etc. interrupts come from */
 +#include "entry_arch.h"
@@ -3244,34 +4082,59 @@
 +#endif
 +
 +ENTRY(divide_error)
++	RING0_INT_FRAME
 +	pushl $0			# no error code
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl $do_divide_error
++	CFI_ADJUST_CFA_OFFSET 4
 +	ALIGN
 +error_code:
 +	pushl %ds
++	CFI_ADJUST_CFA_OFFSET 4
++	/*CFI_REL_OFFSET ds, 0*/
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET eax, 0
 +	xorl %eax, %eax
 +	pushl %ebp
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET ebp, 0
 +	pushl %edi
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET edi, 0
 +	pushl %esi
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET esi, 0
 +	pushl %edx
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET edx, 0
 +	decl %eax			# eax = -1
 +	pushl %ecx
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET ecx, 0
 +	pushl %ebx
++	CFI_ADJUST_CFA_OFFSET 4
++	CFI_REL_OFFSET ebx, 0
 +	cld
 +	pushl %es
++	CFI_ADJUST_CFA_OFFSET 4
++	/*CFI_REL_OFFSET es, 0*/
 +	UNWIND_ESPFIX_STACK
 +	popl %ecx
++	CFI_ADJUST_CFA_OFFSET -4
++	/*CFI_REGISTER es, 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)
++	/*CFI_REL_OFFSET es, ES*/
 +	movl $(__USER_DS), %ecx
 +	movl %ecx, %ds
 +	movl %ecx, %es
 +	movl %esp,%eax			# pt_regs pointer
 +	call *%edi
 +	jmp ret_from_exception
++	CFI_ENDPROC
 +
 +#ifdef CONFIG_XEN
 +# A note on the "critical region" in our callback handler.
@@ -3291,7 +4154,9 @@
 +# critical region we know that the entire frame is present and correct
 +# so we can simply throw away the new one.
 +ENTRY(hypervisor_callback)
++	RING0_INT_FRAME
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	movl EIP(%esp),%eax
 +	cmpl $scrit,%eax
@@ -3302,10 +4167,15 @@
 +	jb   11f
 +	cmpl $sysexit_ecrit,%eax
 +	ja   11f
++	# interrupted in sysexit critical
 +	addl $0x34,%esp			# Remove cs...ebx from stack frame.
++	# this popped off new frame to reuse the old one, therefore no 
++	# CFI_ADJUST_CFA_OFFSET here
 +11:	push %esp
++	CFI_ADJUST_CFA_OFFSET 4
 +	call evtchn_do_upcall
 +	add  $4,%esp
++	CFI_ADJUST_CFA_OFFSET -4
 +	jmp  ret_from_intr
 +
 +        ALIGN
@@ -3316,6 +4186,7 @@
 +	jnz  14f			# process more events if necessary...
 +	RESTORE_REGS
 +	addl $4, %esp
++	CFI_ADJUST_CFA_OFFSET -4
 +1:	iret
 +.section __ex_table,"a"
 +	.align 4
@@ -3351,7 +4222,10 @@
 +	movl %eax,(%edi)
 +	loop 16b
 +17:	movl %edi,%esp			# final %edi is top of merged stack
++	# this popped off new frame to reuse the old one, therefore no 
++	# CFI_DEF_CFA_OFFSET here
 +	jmp  11b
++	CFI_ENDPROC
 +
 +critical_fixup_table:
 +	.byte 0xff,0xff,0xff		# testb $0xff,(%esi) = __TEST_PENDING
@@ -3381,7 +4255,9 @@
 +# 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)
++	RING0_INT_FRAME
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	movl $1,%eax
 +1:	mov 4(%esp),%ds
 +2:	mov 8(%esp),%es
@@ -3389,11 +4265,16 @@
 +4:	mov 16(%esp),%gs
 +	testl %eax,%eax
 +	popl %eax
++	CFI_ADJUST_CFA_OFFSET -4
 +	jz 5f
 +	addl $16,%esp		# EAX != 0 => Category 2 (Bad IRET)
++	CFI_ADJUST_CFA_OFFSET -16
 +	jmp iret_exc
++	CFI_ADJUST_CFA_OFFSET 16
 +5:	addl $16,%esp		# EAX == 0 => Category 1 (Bad segment)
++	CFI_ADJUST_CFA_OFFSET -16
 +	pushl $0
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	jmp ret_from_exception
 +.section .fixup,"ax";		\
@@ -3417,34 +4298,48 @@
 +	.long 3b,8b;		\
 +	.long 4b,9b;		\
 +.previous
++	CFI_ENDPROC
 +#endif
 +
 +ENTRY(coprocessor_error)
++	RING0_INT_FRAME
 +	pushl $0
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl $do_coprocessor_error
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +ENTRY(simd_coprocessor_error)
++	RING0_INT_FRAME
 +	pushl $0
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl $do_simd_coprocessor_error
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +ENTRY(device_not_available)
++	RING0_INT_FRAME
 +	pushl $-1			# mark this as an int
++	CFI_ADJUST_CFA_OFFSET 4
 +	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
++	CFI_ADJUST_CFA_OFFSET 4
 +	call math_emulate
 +	addl $4, %esp
++	CFI_ADJUST_CFA_OFFSET -4
 +	jmp ret_from_exception
 +device_available_emulate:
 +#endif
 +	preempt_stop
 +	call math_state_restore
 +	jmp ret_from_exception
++	CFI_ENDPROC
 +
 +#ifndef CONFIG_XEN
 +/*
@@ -3471,6 +4366,7 @@
 +#endif /* CONFIG_XEN */
 +
 +KPROBE_ENTRY(debug)
++	RING0_INT_FRAME
 +#ifndef CONFIG_XEN
 +	cmpl $sysenter_entry,(%esp)
 +	jne debug_stack_correct
@@ -3478,11 +4374,13 @@
 +debug_stack_correct:
 +#endif /* !CONFIG_XEN */
 +	pushl $-1			# mark this as an int
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	xorl %edx,%edx			# error code 0
 +	movl %esp,%eax			# pt_regs pointer
 +	call do_debug
 +	jmp ret_from_exception
++	CFI_ENDPROC
 +	.previous .text
 +
 +#ifndef CONFIG_XEN
@@ -3495,14 +4393,18 @@
 + * fault happened on the sysenter path.
 + */
 +ENTRY(nmi)
++	RING0_INT_FRAME
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	movl %ss, %eax
 +	cmpw $__ESPFIX_SS, %ax
 +	popl %eax
++	CFI_ADJUST_CFA_OFFSET -4
 +	je nmi_16bit_stack
 +	cmpl $sysenter_entry,(%esp)
 +	je nmi_stack_fixup
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	movl %esp,%eax
 +	/* Do not access memory above the end of our stack page,
 +	 * it might not exist.
@@ -3510,16 +4412,19 @@
 +	andl $(THREAD_SIZE-1),%eax
 +	cmpl $(THREAD_SIZE-20),%eax
 +	popl %eax
++	CFI_ADJUST_CFA_OFFSET -4
 +	jae nmi_stack_correct
 +	cmpl $sysenter_entry,12(%esp)
 +	je nmi_debug_stack_check
 +nmi_stack_correct:
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	xorl %edx,%edx		# zero error code
 +	movl %esp,%eax		# pt_regs pointer
 +	call do_nmi
-+	jmp restore_all
++	jmp restore_nocheck_notrace
++	CFI_ENDPROC
 +
 +nmi_stack_fixup:
 +	FIX_STACK(12,nmi_stack_correct, 1)
@@ -3535,112 +4440,197 @@
 +	jmp nmi_stack_correct
 +
 +nmi_16bit_stack:
++	RING0_INT_FRAME
 +	/* create the pointer to lss back */
 +	pushl %ss
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl %esp
++	CFI_ADJUST_CFA_OFFSET 4
 +	movzwl %sp, %esp
 +	addw $4, (%esp)
 +	/* copy the iret frame of 12 bytes */
 +	.rept 3
 +	pushl 16(%esp)
++	CFI_ADJUST_CFA_OFFSET 4
 +	.endr
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	FIXUP_ESPFIX_STACK		# %eax == %esp
++	CFI_ADJUST_CFA_OFFSET -20	# the frame has now moved
 +	xorl %edx,%edx			# zero error code
 +	call do_nmi
 +	RESTORE_REGS
 +	lss 12+4(%esp), %esp		# back to 16bit stack
 +1:	iret
++	CFI_ENDPROC
 +.section __ex_table,"a"
 +	.align 4
 +	.long 1b,iret_exc
 +.previous
 +#else
 +ENTRY(nmi)
++	RING0_INT_FRAME
 +	pushl %eax
++	CFI_ADJUST_CFA_OFFSET 4
 +	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
++	CFI_ENDPROC
 +#endif
 +
 +KPROBE_ENTRY(int3)
++	RING0_INT_FRAME
 +	pushl $-1			# mark this as an int
++	CFI_ADJUST_CFA_OFFSET 4
 +	SAVE_ALL
 +	xorl %edx,%edx		# zero error code
 +	movl %esp,%eax		# pt_regs pointer
 +	call do_int3
 +	jmp ret_from_exception
++	CFI_ENDPROC
 +	.previous .text
 +
 +ENTRY(overflow)
++	RING0_INT_FRAME
 +	pushl $0
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl $do_overflow
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +ENTRY(bounds)
++	RING0_INT_FRAME
 +	pushl $0
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl $do_bounds
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +ENTRY(invalid_op)
++	RING0_INT_FRAME
 +	pushl $0
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl $do_invalid_op
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +ENTRY(coprocessor_segment_overrun)
++	RING0_INT_FRAME
 +	pushl $0
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl $do_coprocessor_segment_overrun
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +ENTRY(invalid_TSS)
++	RING0_EC_FRAME
 +	pushl $do_invalid_TSS
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +ENTRY(segment_not_present)
++	RING0_EC_FRAME
 +	pushl $do_segment_not_present
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +ENTRY(stack_segment)
++	RING0_EC_FRAME
 +	pushl $do_stack_segment
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +KPROBE_ENTRY(general_protection)
++	RING0_EC_FRAME
 +	pushl $do_general_protection
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +	.previous .text
 +
 +ENTRY(alignment_check)
++	RING0_EC_FRAME
 +	pushl $do_alignment_check
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +
 +KPROBE_ENTRY(page_fault)
++	RING0_EC_FRAME
 +	pushl $do_page_fault
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +	.previous .text
 +
 +#ifdef CONFIG_X86_MCE
 +ENTRY(machine_check)
++	RING0_INT_FRAME
 +	pushl $0
++	CFI_ADJUST_CFA_OFFSET 4
 +	pushl machine_check_vector
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
 +#endif
 +
 +ENTRY(fixup_4gb_segment)
++	RING0_INT_FRAME
 +	pushl $do_fixup_4gb_segment
++	CFI_ADJUST_CFA_OFFSET 4
 +	jmp error_code
++	CFI_ENDPROC
++
++#ifdef CONFIG_STACK_UNWIND
++ENTRY(arch_unwind_init_running)
++	CFI_STARTPROC
++	movl	4(%esp), %edx
++	movl	(%esp), %ecx
++	leal	4(%esp), %eax
++	movl	%ebx, EBX(%edx)
++	xorl	%ebx, %ebx
++	movl	%ebx, ECX(%edx)
++	movl	%ebx, EDX(%edx)
++	movl	%esi, ESI(%edx)
++	movl	%edi, EDI(%edx)
++	movl	%ebp, EBP(%edx)
++	movl	%ebx, EAX(%edx)
++	movl	$__USER_DS, DS(%edx)
++	movl	$__USER_DS, ES(%edx)
++	movl	%ebx, ORIG_EAX(%edx)
++	movl	%ecx, EIP(%edx)
++	movl	12(%esp), %ecx
++	movl	$__KERNEL_CS, CS(%edx)
++	movl	%ebx, EFLAGS(%edx)
++	movl	%eax, OLDESP(%edx)
++	movl	8(%esp), %eax
++	movl	%ecx, 8(%esp)
++	movl	EBX(%edx), %ebx
++	movl	$__KERNEL_DS, OLDSS(%edx)
++	jmpl	*%eax
++	CFI_ENDPROC
++ENDPROC(arch_unwind_init_running)
++#endif
 +
 +.section .rodata,"a"
 +#include "syscall_table.S"
 +
 +syscall_table_size=(.-sys_call_table)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/fixup.c linux-2.6.17-xen/arch/i386/kernel/fixup.c
---- linux-2.6.17/arch/i386/kernel/fixup.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/fixup.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,86 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/fixup.c linux-2.6.18-rc5-xen/arch/i386/kernel/fixup.c
+--- linux-2.6.18-rc5/arch/i386/kernel/fixup.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/fixup.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,92 @@
 +/******************************************************************************
 + * fixup.c
 + * 
@@ -3670,7 +4660,6 @@
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + */
 +
-+#include <linux/config.h>
 +#include <linux/init.h>
 +#include <linux/sched.h>
 +#include <linux/slab.h>
@@ -3682,6 +4671,7 @@
 +
 +fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
 +{
++#if 0
 +	static unsigned long printed = 0;
 +	char info[100];
 +	int i;
@@ -3718,6 +4708,12 @@
 +	}
 +
 +	printk("Continuing...\n\n");
++#else
++	if (printk_ratelimit())
++		printk(KERN_WARNING
++		       "4gb seg fixup, process %s (pid %d), cs:ip %02x:%08lx\n",
++		       current->comm, current->tgid, regs->xcs, regs->eip);
++#endif
 +}
 +
 +static int __init fixup_init(void)
@@ -3727,14 +4723,14 @@
 +	return 0;
 +}
 +__initcall(fixup_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/head-xen.S linux-2.6.17-xen/arch/i386/kernel/head-xen.S
---- linux-2.6.17/arch/i386/kernel/head-xen.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/head-xen.S	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,181 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/head-xen.S linux-2.6.18-rc5-xen/arch/i386/kernel/head-xen.S
+--- linux-2.6.18-rc5/arch/i386/kernel/head-xen.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/head-xen.S	2006-09-01 00:09:08.000000000 +0200
+@@ -0,0 +1,200 @@
 +
 +
 +.text
-+#include <linux/config.h>
++#include <linux/elfnote.h>
 +#include <linux/threads.h>
 +#include <linux/linkage.h>
 +#include <asm/segment.h>
@@ -3742,6 +4738,7 @@
 +#include <asm/thread_info.h>
 +#include <asm/asm-offsets.h>
 +#include <xen/interface/arch-x86_32.h>
++#include <xen/interface/elfnote.h>
 +
 +/*
 + * References to members of the new_cpu_data structure.
@@ -3871,6 +4868,7 @@
 +	.quad 0x0000000000000000	/* 0xf0 - unused */
 +	.quad 0x0000000000000000	/* 0xf8 - GDT entry 31: double-fault TSS */
 +
++#ifdef CONFIG_XEN_COMPAT_030002
 +/*
 + * __xen_guest information
 + */
@@ -3890,12 +4888,8 @@
 +	.ascii	",XEN_VER=xen-3.0"
 +	.ascii	",VIRT_BASE=0x"
 +		utoa __PAGE_OFFSET
-+#ifdef CONFIG_XEN_COMPAT_030002
 +	.ascii	",ELF_PADDR_OFFSET=0x"
 +		utoa __PAGE_OFFSET
-+#else
-+	.ascii	",ELF_PADDR_OFFSET=0x0"
-+#endif /* !CONFIG_XEN_COMPAT_030002 */
 +	.ascii	",VIRT_ENTRY=0x"
 +		utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
 +	.ascii	",HYPERCALL_PAGE=0x"
@@ -3912,9 +4906,30 @@
 +#endif
 +	.ascii	",LOADER=generic"
 +	.byte	0
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/init_task-xen.c linux-2.6.17-xen/arch/i386/kernel/init_task-xen.c
---- linux-2.6.17/arch/i386/kernel/init_task-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/init_task-xen.c	2006-08-14 15:57:20.000000000 +0200
++#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_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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/init_task-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/init_task-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/init_task-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/init_task-xen.c	2006-07-20 15:56:36.000000000 +0200
 @@ -0,0 +1,51 @@
 +#include <linux/mm.h>
 +#include <linux/module.h>
@@ -3967,10 +4982,10 @@
 +DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
 +#endif
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/io_apic-xen.c linux-2.6.17-xen/arch/i386/kernel/io_apic-xen.c
---- linux-2.6.17/arch/i386/kernel/io_apic-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/io_apic-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,2751 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/io_apic-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/io_apic-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/io_apic-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/io_apic-xen.c	2006-09-01 00:09:08.000000000 +0200
+@@ -0,0 +1,2771 @@
 +/*
 + *	Intel IO-APIC support for multi-Pentium hosts.
 + *
@@ -3998,7 +5013,6 @@
 +#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>
@@ -4011,6 +5025,7 @@
 +#include <asm/desc.h>
 +#include <asm/timer.h>
 +#include <asm/i8259.h>
++#include <asm/nmi.h>
 +
 +#include <mach_apic.h>
 +
@@ -4063,6 +5078,7 @@
 +static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 +
 +static DEFINE_SPINLOCK(ioapic_lock);
++static DEFINE_SPINLOCK(vector_lock);
 +
 +int timer_over_8254 __initdata = 1;
 +
@@ -4283,7 +5299,7 @@
 +# include <linux/slab.h>		/* kmalloc() */
 +# include <linux/timer.h>	/* time_after() */
 + 
-+# ifdef CONFIG_BALANCED_IRQ_DEBUG
++#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
@@ -4291,10 +5307,15 @@
 +#  define Dprintk(x...) 
 +# endif
 +
-+
 +#define IRQBALANCE_CHECK_ARCH -999
-+static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH;
-+static int physical_balance = 0;
++#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 int irqbalance_disabled __read_mostly = IRQBALANCE_CHECK_ARCH;
++static int physical_balance __read_mostly;
++static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL;
 +
 +static struct irq_cpu_info {
 +	unsigned long * last_irq;
@@ -4313,12 +5334,14 @@
 +
 +#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 cpumask_t balance_irq_affinity[NR_IRQS] = {
++	[0 ... NR_IRQS-1] = CPU_MASK_ALL
++};
 +
-+static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL;
++void set_balance_irq_affinity(unsigned int irq, cpumask_t mask)
++{
++	balance_irq_affinity[irq] = mask;
++}
 +
 +static unsigned long move(int curr_cpu, cpumask_t allowed_mask,
 +			unsigned long now, int direction)
@@ -4356,7 +5379,7 @@
 +	if (irqbalance_disabled)
 +		return; 
 +
-+	cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]);
++	cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]);
 +	new_cpu = move(cpu, allowed_mask, now, 1);
 +	if (cpu != new_cpu) {
 +		set_pending_irq(irq, cpumask_of_cpu(new_cpu));
@@ -4545,7 +5568,9 @@
 +		}
 +	}
 +
-+	cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]);
++	cpus_and(allowed_mask,
++		 cpu_online_map,
++		 balance_irq_affinity[selected_irq]);
 +	target_cpu_mask = cpumask_of_cpu(min_loaded);
 +	cpus_and(tmp, target_cpu_mask, allowed_mask);
 +
@@ -4586,7 +5611,7 @@
 +	
 +	/* 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);
++		irq_desc[i].pending_mask[i] = cpumask_of_cpu(0);
 +		set_pending_irq(i, cpumask_of_cpu(0));
 +	}
 +
@@ -5173,11 +6198,16 @@
 +int assign_irq_vector(int irq)
 +{
 +	struct physdev_irq irq_op;
++	unsigned long flags;
 +
-+	BUG_ON(irq >= NR_IRQ_VECTORS);
-+	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
-+		return IO_APIC_VECTOR(irq);
++	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
++
++	spin_lock_irqsave(&vector_lock, flags);
 +
++	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
++		spin_unlock_irqrestore(&vector_lock, flags);
++		return IO_APIC_VECTOR(irq);
++	}
 +	irq_op.irq = irq;
 +	if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
 +		return -ENOSPC;
@@ -5186,6 +6216,8 @@
 +	if (irq != AUTO_ASSIGN)
 +		IO_APIC_VECTOR(irq) = irq_op.vector;
 +
++	spin_unlock_irqrestore(&vector_lock, flags);
++
 +	return irq_op.vector;
 +}
 +
@@ -5197,23 +6229,18 @@
 +#define IOAPIC_EDGE	0
 +#define IOAPIC_LEVEL	1
 +
-+static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger)
++static 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]);
-+	}
++	unsigned idx;
++
++	idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq;
++
++	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
++			trigger == IOAPIC_LEVEL)
++		irq_desc[idx].chip = &ioapic_level_type;
++	else
++		irq_desc[idx].chip = &ioapic_edge_type;
++	set_intr_gate(vector, interrupt[idx]);
 +}
 +#else
 +#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0)
@@ -5328,7 +6355,7 @@
 +	 * 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;
++	irq_desc[0].chip = &ioapic_edge_type;
 +
 +	/*
 +	 * Add it to the IO-APIC irq-routing table:
@@ -6079,6 +7106,13 @@
 +#endif
 +#endif
 +
++static int ioapic_retrigger(unsigned int irq)
++{
++	send_IPI_self(IO_APIC_VECTOR(irq));
++
++	return 1;
++}
++
 +/*
 + * Level and edge triggered IO-APIC interrupts need different handling,
 + * so we use two separate IRQ descriptors. Edge triggered IRQs can be
@@ -6098,6 +7132,7 @@
 +#ifdef CONFIG_SMP
 +	.set_affinity 	= set_ioapic_affinity,
 +#endif
++	.retrigger	= ioapic_retrigger,
 +};
 +
 +static struct hw_interrupt_type ioapic_level_type __read_mostly = {
@@ -6111,6 +7146,7 @@
 +#ifdef CONFIG_SMP
 +	.set_affinity 	= set_ioapic_affinity,
 +#endif
++	.retrigger	= ioapic_retrigger,
 +};
 +#endif /* !CONFIG_XEN */
 +
@@ -6147,7 +7183,7 @@
 +#ifndef CONFIG_XEN
 +			else
 +				/* Strange. Oh, well.. */
-+				irq_desc[irq].handler = &no_irq_type;
++				irq_desc[irq].chip = &no_irq_type;
 +#endif
 +		}
 +	}
@@ -6267,9 +7303,9 @@
 +	io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
 +	spin_unlock_irqrestore(&ioapic_lock, flags);
 +}
-+
++#endif /* CONFIG_XEN */
 +int timer_uses_ioapic_pin_0;
-+
++#ifdef CONFI_XEN
 +/*
 + * 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
@@ -6365,7 +7401,7 @@
 +	printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
 +
 +	disable_8259A_irq(0);
-+	irq_desc[0].handler = &lapic_irq_type;
++	irq_desc[0].chip = &lapic_irq_type;
 +	apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector);	/* Fixed mode */
 +	enable_8259A_irq(0);
 +
@@ -6394,7 +7430,6 @@
 +		"report.  Then try booting with the 'noapic' option");
 +}
 +#else
-+int timer_uses_ioapic_pin_0;
 +#define check_timer() ((void)0)
 +#endif
 +
@@ -6456,7 +7491,7 @@
 +{
 +	if(sis_apic_bug == -1)
 +		sis_apic_bug = 0;
-+	if (xen_start_info->flags & SIF_INITDOMAIN) {
++	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;
@@ -6722,9 +7757,9 @@
 +}
 +
 +#endif /* CONFIG_ACPI */
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/ioport-xen.c linux-2.6.17-xen/arch/i386/kernel/ioport-xen.c
---- linux-2.6.17/arch/i386/kernel/ioport-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/ioport-xen.c	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/ioport-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/ioport-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/ioport-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/ioport-xen.c	2006-07-20 15:56:36.000000000 +0200
 @@ -0,0 +1,121 @@
 +/*
 + *	linux/arch/i386/kernel/ioport.c
@@ -6847,24 +7882,10 @@
 +	set_iopl_mask(t->iopl);
 +	return 0;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/irq.c linux-2.6.17-xen/arch/i386/kernel/irq.c
---- linux-2.6.17/arch/i386/kernel/irq.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/irq.c	2006-08-14 15:57:20.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/irq-xen.c linux-2.6.17-xen/arch/i386/kernel/irq-xen.c
---- linux-2.6.17/arch/i386/kernel/irq-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/irq-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,306 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/irq-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/irq-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/irq-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/irq-xen.c	2006-07-20 15:56:36.000000000 +0200
+@@ -0,0 +1,324 @@
 +/*
 + *	linux/arch/i386/kernel/irq.c
 + *
@@ -6909,8 +7930,8 @@
 +	u32                     stack[THREAD_SIZE/sizeof(u32)];
 +};
 +
-+static union irq_ctx *hardirq_ctx[NR_CPUS];
-+static union irq_ctx *softirq_ctx[NR_CPUS];
++static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
++static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
 +#endif
 +
 +/*
@@ -6927,6 +7948,12 @@
 +	u32 *isp;
 +#endif
 +
++	if (unlikely((unsigned)irq >= NR_IRQS)) {
++		printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
++					__FUNCTION__, irq);
++		BUG();
++	}
++
 +	irq_enter();
 +#ifdef CONFIG_DEBUG_STACKOVERFLOW
 +	/* Debugging check for stack overflow: is there less than 1KB free? */
@@ -6962,6 +7989,14 @@
 +		irqctx->tinfo.task = curctx->tinfo.task;
 +		irqctx->tinfo.previous_esp = current_stack_pointer;
 +
++		/*
++		 * Copy the softirq bits in preempt_count so that the
++		 * softirq checks work in the hardirq context.
++		 */
++		irqctx->tinfo.preempt_count =
++			(irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) |
++			 (curctx->tinfo.preempt_count & SOFTIRQ_MASK);
++
 +		asm volatile(
 +			"       xchgl   %%ebx,%%esp      \n"
 +			"       call    __do_IRQ         \n"
@@ -7014,7 +8049,7 @@
 +	irqctx->tinfo.task              = NULL;
 +	irqctx->tinfo.exec_domain       = NULL;
 +	irqctx->tinfo.cpu               = cpu;
-+	irqctx->tinfo.preempt_count     = SOFTIRQ_OFFSET;
++	irqctx->tinfo.preempt_count     = 0;
 +	irqctx->tinfo.addr_limit        = MAKE_MM_SEG(0);
 +
 +	softirq_ctx[cpu] = irqctx;
@@ -7059,6 +8094,10 @@
 +			: "0"(isp)
 +			: "memory", "cc", "edx", "ecx", "eax"
 +		);
++		/*
++		 * Shouldnt happen, we returned above if in_interrupt():
++	 	 */
++		WARN_ON_ONCE(softirq_count());
 +	}
 +
 +	local_irq_restore(flags);
@@ -7086,7 +8125,7 @@
 +	if (i == 0) {
 +		seq_printf(p, "           ");
 +		for_each_online_cpu(j)
-+			seq_printf(p, "CPU%d       ",j);
++			seq_printf(p, "CPU%-8d       ",j);
 +		seq_putc(p, '\n');
 +	}
 +
@@ -7102,7 +8141,7 @@
 +		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, " %14s", irq_desc[i].chip->typename);
 +		seq_printf(p, "  %s", action->name);
 +
 +		for (action=action->next; action; action = action->next)
@@ -7143,13 +8182,13 @@
 +		if (irq == 2)
 +			continue;
 +
-+		cpus_and(mask, irq_affinity[irq], map);
++		cpus_and(mask, irq_desc[irq].affinity, 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);
++		if (irq_desc[irq].chip->set_affinity)
++			irq_desc[irq].chip->set_affinity(irq, mask);
 +		else if (irq_desc[irq].action && !(warned++))
 +			printk("Cannot set affinity for irq %i\n", irq);
 +	}
@@ -7171,10 +8210,10 @@
 +}
 +#endif
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/ldt-xen.c linux-2.6.17-xen/arch/i386/kernel/ldt-xen.c
---- linux-2.6.17/arch/i386/kernel/ldt-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/ldt-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,269 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/ldt-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/ldt-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/ldt-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/ldt-xen.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,270 @@
 +/*
 + * linux/kernel/ldt.c
 + *
@@ -7286,6 +8325,7 @@
 +
 +	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);
@@ -7444,10 +8484,10 @@
 +	}
 +	return ret;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/Makefile linux-2.6.17-xen/arch/i386/kernel/Makefile
---- linux-2.6.17/arch/i386/kernel/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/Makefile	2006-08-14 15:57:20.000000000 +0200
-@@ -42,6 +42,12 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/Makefile linux-2.6.18-rc5-xen/arch/i386/kernel/Makefile
+--- linux-2.6.18-rc5/arch/i386/kernel/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/Makefile	2006-09-01 00:09:08.000000000 +0200
+@@ -45,6 +45,12 @@
  
  obj-$(CONFIG_SCx200)		+= scx200.o
  
@@ -7460,7 +8500,7 @@
  # 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 +68,7 @@
+@@ -66,7 +72,7 @@
  
  $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \
  $(obj)/vsyscall-%.so: $(src)/vsyscall.lds \
@@ -7469,14 +8509,16 @@
  	$(call if_changed,syscall)
  
  # We also create a special relocatable object that should mirror the symbol
-@@ -74,5 +80,17 @@
+@@ -78,8 +84,19 @@
  
  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)
-+
+ 
+ k8-y                      += ../../x86_64/kernel/k8.o
+ 
 +ifdef CONFIG_XEN
 +include $(srctree)/scripts/Makefile.xen
 +
@@ -7488,10 +8530,10 @@
 +obj-y := $(call cherrypickxen, $(obj-y))
 +extra-y := $(call cherrypickxen, $(extra-y))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/microcode-xen.c linux-2.6.17-xen/arch/i386/kernel/microcode-xen.c
---- linux-2.6.17/arch/i386/kernel/microcode-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/microcode-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,148 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/microcode-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/microcode-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/microcode-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/microcode-xen.c	2006-07-20 15:56:36.000000000 +0200
+@@ -0,0 +1,147 @@
 +/*
 + *	Intel CPU Microcode Update Driver for Linux
 + *
@@ -7611,7 +8653,6 @@
 +static struct miscdevice microcode_dev = {
 +	.minor		= MICROCODE_MINOR,
 +	.name		= "microcode",
-+	.devfs_name	= "cpu/microcode",
 +	.fops		= &microcode_fops,
 +};
 +
@@ -7640,10 +8681,10 @@
 +module_init(microcode_init)
 +module_exit(microcode_exit)
 +MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/mpparse-xen.c linux-2.6.17-xen/arch/i386/kernel/mpparse-xen.c
---- linux-2.6.17/arch/i386/kernel/mpparse-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/mpparse-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,1186 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/mpparse-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/mpparse-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/mpparse-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/mpparse-xen.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,1185 @@
 +/*
 + *	Intel Multiprocessor Specification 1.1 and 1.4
 + *	compliant MP-table parsing routines.
@@ -7663,7 +8704,6 @@
 +#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>
@@ -8830,10 +9870,10 @@
 +
 +#endif /* CONFIG_X86_IO_APIC */
 +#endif /* CONFIG_ACPI */
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/pci-dma-xen.c linux-2.6.17-xen/arch/i386/kernel/pci-dma-xen.c
---- linux-2.6.17/arch/i386/kernel/pci-dma-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/pci-dma-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,344 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/pci-dma-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/pci-dma-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/pci-dma-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/pci-dma-xen.c	2006-09-01 00:09:08.000000000 +0200
+@@ -0,0 +1,379 @@
 +/*
 + * Dynamic DMA mapping support.
 + *
@@ -8867,6 +9907,41 @@
 +int iommu_bio_merge __read_mostly = 0;
 +EXPORT_SYMBOL(iommu_bio_merge);
 +
++int iommu_sac_force __read_mostly = 0;
++EXPORT_SYMBOL(iommu_sac_force);
++
++int no_iommu __read_mostly;
++#ifdef CONFIG_IOMMU_DEBUG
++int panic_on_overflow __read_mostly = 1;
++int force_iommu __read_mostly = 1;
++#else
++int panic_on_overflow __read_mostly = 0;
++int force_iommu __read_mostly= 0;
++#endif
++
++/* Set this to 1 if there is a HW IOMMU in the system */
++int iommu_detected __read_mostly = 0;
++
++void __init pci_iommu_alloc(void)
++{
++	/*
++	 * The order of these functions is important for
++	 * fall-back/fail-over reasons
++	 */
++#ifdef CONFIG_IOMMU
++	iommu_hole_init();
++#endif
++
++#ifdef CONFIG_CALGARY_IOMMU
++#include <asm/calgary.h>
++	detect_calgary();
++#endif
++
++#ifdef CONFIG_SWIOTLB
++	pci_swiotlb_init();
++#endif
++}
++
 +__init int iommu_setup(char *p)
 +{
 +    return 1;
@@ -9178,9 +10253,9 @@
 +		swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
 +}
 +EXPORT_SYMBOL(dma_sync_single_for_device);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/process-xen.c linux-2.6.17-xen/arch/i386/kernel/process-xen.c
---- linux-2.6.17/arch/i386/kernel/process-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/process-xen.c	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/process-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/process-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/process-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/process-xen.c	2006-09-01 00:09:08.000000000 +0200
 @@ -0,0 +1,812 @@
 +/*
 + *  linux/arch/i386/kernel/process.c
@@ -9212,7 +10287,6 @@
 +#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>
@@ -9245,9 +10319,6 @@
 +#include <asm/tlbflush.h>
 +#include <asm/cpu.h>
 +
-+#include <asm/tlbflush.h>
-+#include <asm/cpu.h>
-+
 +asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 +
 +static int hlt_counter;
@@ -9292,10 +10363,10 @@
 +	if (need_resched())
 +		local_irq_enable();
 +	else {
-+		clear_thread_flag(TIF_POLLING_NRFLAG);
++		current_thread_info()->status &= ~TS_POLLING;
 +		smp_mb__after_clear_bit();
 +		safe_halt();
-+		set_thread_flag(TIF_POLLING_NRFLAG);
++		current_thread_info()->status |= TS_POLLING;
 +	}
 +}
 +#ifdef CONFIG_APM_MODULE
@@ -9330,7 +10401,8 @@
 +{
 +	int cpu = smp_processor_id();
 +
-+	set_thread_flag(TIF_POLLING_NRFLAG);
++	current_thread_info()->status |= TS_POLLING;
++
 +
 +	/* endless idle loop with no priority at all */
 +	while (1) {
@@ -9412,7 +10484,7 @@
 +	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);
++	show_trace(NULL, regs, &regs->esp);
 +}
 +
 +/*
@@ -9460,15 +10532,16 @@
 + */
 +void exit_thread(void)
 +{
-+	struct task_struct *tsk = current;
-+	struct thread_struct *t = &tsk->thread;
-+
 +	/* The process may have allocated an io port bitmap... nuke it. */
-+	if (unlikely(NULL != t->io_bitmap_ptr)) {
++	if (unlikely(test_thread_flag(TIF_IO_BITMAP))) {
++		struct task_struct *tsk = current;
++		struct thread_struct *t = &tsk->thread;
++
 +		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;
++		clear_thread_flag(TIF_IO_BITMAP);
 +	}
 +}
 +
@@ -9478,6 +10551,7 @@
 +
 +	memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
 +	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));	
++	clear_tsk_thread_flag(tsk, TIF_DEBUG);
 +	/*
 +	 * Forget coprocessor state..
 +	 */
@@ -9522,7 +10596,7 @@
 +	savesegment(gs,p->thread.gs);
 +
 +	tsk = current;
-+	if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) {
++	if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
 +		p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
 +		if (!p->thread.io_bitmap_ptr) {
 +			p->thread.io_bitmap_max = 0;
@@ -9530,6 +10604,7 @@
 +		}
 +		memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr,
 +			IO_BITMAP_BYTES);
++		set_tsk_thread_flag(p, TIF_IO_BITMAP);
 +	}
 +
 +	/*
@@ -9994,14 +11069,13 @@
 +		sp -= get_random_int() % 8192;
 +	return sp & ~0xf;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/quirks-xen.c linux-2.6.17-xen/arch/i386/kernel/quirks-xen.c
---- linux-2.6.17/arch/i386/kernel/quirks-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/quirks-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,48 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/quirks-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/quirks-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/quirks-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/quirks-xen.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,47 @@
 +/*
 + * This file contains work-arounds for x86 and x86_64 platform bugs.
 + */
-+#include <linux/config.h>
 +#include <linux/pci.h>
 +#include <linux/irq.h>
 +
@@ -10046,10 +11120,10 @@
 +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 -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/setup-xen.c linux-2.6.17-xen/arch/i386/kernel/setup-xen.c
---- linux-2.6.17/arch/i386/kernel/setup-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/setup-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,1827 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/setup-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/setup-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/setup-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/setup-xen.c	2006-09-01 00:09:08.000000000 +0200
+@@ -0,0 +1,1845 @@
 +/*
 + *  linux/arch/i386/kernel/setup.c
 + *
@@ -10075,11 +11149,10 @@
 + * 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/screen_info.h>
 +#include <linux/ioport.h>
 +#include <linux/acpi.h>
 +#include <linux/apm_bios.h>
@@ -10096,9 +11169,6 @@
 +#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>
@@ -10119,7 +11189,7 @@
 +#include <xen/interface/physdev.h>
 +#include <xen/interface/memory.h>
 +#include <xen/features.h>
-+#include "setup_arch_pre.h"
++#include "setup_arch.h"
 +#include <bios_ebda.h>
 +
 +/* Forward Declaration. */
@@ -10209,6 +11279,7 @@
 +EXPORT_SYMBOL(ist_info);
 +#endif
 +struct e820map e820;
++static void __init e820_setup_gap(struct e820entry *e820, int nr_map);
 +
 +extern void early_cpu_init(void);
 +extern void generic_apic_probe(char *);
@@ -10238,7 +11309,6 @@
 +	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
 +};
 +
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
 +static struct resource system_rom_resource = {
 +	.name	= "System ROM",
 +	.start	= 0xf0000,
@@ -10294,7 +11364,6 @@
 +	.end	= 0xc7fff,
 +	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
 +};
-+#endif
 +
 +static struct resource video_ram_resource = {
 +	.name	= "Video RAM area",
@@ -10353,7 +11422,6 @@
 +#define STANDARD_IO_RESOURCES \
 +	(sizeof standard_io_resources / sizeof standard_io_resources[0])
 +
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
 +#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
 +
 +static int __init romchecksum(unsigned char *rom, unsigned long length)
@@ -10371,9 +11439,11 @@
 +	unsigned char *rom;
 +	int	      i;
 +
++#ifdef CONFIG_XEN
 +	/* Nothing to do if not running in dom0. */
-+	if (!(xen_start_info->flags & SIF_INITDOMAIN))
++	if (!is_initial_xendomain())
 +		return;
++#endif
 +
 +	/* video rom */
 +	upper = adapter_rom_resources[0].start;
@@ -10390,8 +11460,6 @@
 +		/* 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;
 +	}
 +
@@ -10433,7 +11501,6 @@
 +		start = adapter_rom_resources[i++].end & ~2047UL;
 +	}
 +}
-+#endif
 +
 +/*
 + * Point at the empty zero page to start with. We map the real shared_info
@@ -10450,7 +11517,7 @@
 +start_info_t *xen_start_info;
 +EXPORT_SYMBOL(xen_start_info);
 +
-+static void __init add_memory_region(unsigned long long start,
++void __init add_memory_region(unsigned long long start,
 +                                  unsigned long long size, int type)
 +{
 +	int x;
@@ -10572,7 +11639,7 @@
 +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)
++int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
 +{
 +	struct change_member *change_tmp;
 +	unsigned long current_type, last_type;
@@ -10741,7 +11808,7 @@
 + * thinkpad 560x, for example, does not cooperate with the memory
 + * detection code.)
 + */
-+static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
++int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
 +{
 +#ifndef CONFIG_XEN
 +	/* Only one memory region (or negative)? Ignore it */
@@ -10805,12 +11872,6 @@
 +}
 +#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;
@@ -11199,10 +12260,10 @@
 +free_available_memory(unsigned long start, unsigned long end, void *arg)
 +{
 +	/* check max_low_pfn */
-+	if (start >= ((max_low_pfn + 1) << PAGE_SHIFT))
++	if (start >= (max_low_pfn << PAGE_SHIFT))
 +		return 0;
-+	if (end >= ((max_low_pfn + 1) << PAGE_SHIFT))
-+		end = (max_low_pfn + 1) << PAGE_SHIFT;
++	if (end >= (max_low_pfn << PAGE_SHIFT))
++		end = max_low_pfn << PAGE_SHIFT;
 +	if (start < end)
 +		free_bootmem(start, end - start);
 +
@@ -11439,32 +12500,45 @@
 + * 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)
++legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
 +{
 +	int i;
++	struct e820entry *map = e820.map;
++	int nr_map = e820.nr_map;
++#ifdef CONFIG_XEN_PRIVILEGED_GUEST
++	struct xen_memory_map memmap;
 +
-+#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN)
-+	probe_roms();
++	map = (struct e820entry *)__get_free_page(GFP_ATOMIC);
++	nr_map = E820MAX;
++
++	memmap.nr_entries = E820MAX;
++	set_xen_guest_handle(memmap.buffer, map);
++
++	BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
++	e820_setup_gap(map, memmap.nr_entries);
 +#endif
 +
++	probe_roms();
++
 +	for (i = 0; i < nr_map; i++) {
 +		struct resource *res;
-+		if (e820[i].addr + e820[i].size > 0x100000000ULL)
++		if (map[i].addr + map[i].size > 0x100000000ULL)
 +			continue;
-+		res = alloc_bootmem_low(sizeof(struct resource));
-+		switch (e820[i].type) {
++		res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
++		switch (map[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->start = map[i].addr;
++		res->end = res->start + map[i].size - 1;
 +		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+		request_resource(&iomem_resource, res);
-+		if (e820[i].type == E820_RAM) {
++		if (request_resource(&iomem_resource, res)) {
++			kfree(res);
++			continue;
++		}
++		if (map[i].type == E820_RAM) {
 +			/*
 +			 *  We don't know which RAM region contains kernel data,
 +			 *  so we try it repeatedly and let the resource manager
@@ -11477,9 +12551,43 @@
 +#endif
 +		}
 +	}
++#ifdef CONFIG_XEN
++	free_page((unsigned long)map);
++#endif
 +}
 +
 +/*
++ * Request address space for all standard resources
++ *
++ * This is called just before pcibios_init(), which is also a
++ * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
++ */
++static int __init request_standard_resources(void)
++{
++	int i;
++
++	/* Nothing to do if not running in dom0. */
++	if (!is_initial_xendomain())
++		return 0;
++
++	printk("Setting up standard PCI resources\n");
++	if (efi_enabled)
++		efi_initialize_iomem_resources(&code_resource, &data_resource);
++	else
++		legacy_init_iomem_resources(&code_resource, &data_resource);
++
++	/* 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]);
++	return 0;
++}
++
++subsys_initcall(request_standard_resources);
++
++/*
 + * Locate a unused range of the physical address space below 4G which
 + * can be used for PCI mappings.
 + */
@@ -11532,59 +12640,13 @@
 +		pci_mem_start, gapstart, gapsize);
 +}
 +
-+/*
-+ * Request address space for all standard resources
-+ */
 +static void __init register_memory(void)
 +{
-+#ifdef CONFIG_XEN
-+	struct e820entry *machine_e820;
-+	struct xen_memory_map memmap;
-+#endif
-+	int	      i;
-+
-+	/* Nothing to do if not running in dom0. */
-+	if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
-+		legacy_init_iomem_resources(e820.map, e820.nr_map,
-+					    &code_resource, &data_resource);
-+		return;
-+	}
-+
-+#ifdef CONFIG_XEN
-+	machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
-+
-+	memmap.nr_entries = E820MAX;
-+	set_xen_guest_handle(memmap.buffer, machine_e820);
-+
-+	BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
-+
-+	legacy_init_iomem_resources(machine_e820, memmap.nr_entries,
-+				    &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, memmap.nr_entries);
-+	free_bootmem(__pa(machine_e820), PAGE_SIZE);
-+#else
++#ifndef CONFIG_XEN
 +	e820_setup_gap(e820.map, e820.nr_map);
 +#endif
 +}
 +
-+static char * __init machine_specific_memory_setup(void);
-+
 +#ifdef CONFIG_MCA
 +static void set_mca_bus(int x)
 +{
@@ -11609,7 +12671,7 @@
 +
 +	/* Force a quick death if the kernel panics (not domain 0). */
 +	extern int panic_timeout;
-+	if (!panic_timeout && !(xen_start_info->flags & SIF_INITDOMAIN))
++	if (!panic_timeout && !is_initial_xendomain())
 +		panic_timeout = 1;
 +
 +	/* Register a call for panic conditions. */
@@ -11653,7 +12715,7 @@
 +	}
 +	bootloader_type = LOADER_TYPE;
 +
-+	if (xen_start_info->flags & SIF_INITDOMAIN) {
++	if (is_initial_xendomain()) {
 +		/* This is drawn from a dump from vgacon:startup in
 +		 * standard Linux. */
 +		screen_info.orig_video_mode = 3; 
@@ -11662,6 +12724,35 @@
 +		screen_info.orig_video_cols = 80;
 +		screen_info.orig_video_ega_bx = 3;
 +		screen_info.orig_video_points = 16;
++		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);
++			screen_info.orig_video_mode = info->txt_mode;
++			screen_info.orig_video_isVGA = info->video_type;
++			screen_info.orig_video_lines = info->video_height;
++			screen_info.orig_video_cols = info->video_width;
++			screen_info.orig_video_points = info->txt_points;
++			screen_info.lfb_width = info->video_width;
++			screen_info.lfb_height = info->video_height;
++			screen_info.lfb_depth = info->lfb_depth;
++			screen_info.lfb_base = info->lfb_base;
++			screen_info.lfb_size = info->lfb_size;
++			screen_info.lfb_linelength = info->lfb_linelen;
++			screen_info.red_size = info->red_size;
++			screen_info.red_pos = info->red_pos;
++			screen_info.green_size = info->green_size;
++			screen_info.green_pos = info->green_pos;
++			screen_info.blue_size = info->blue_size;
++			screen_info.blue_pos = info->blue_pos;
++			screen_info.rsvd_size = info->rsvd_size;
++			screen_info.rsvd_pos = info->rsvd_pos;
++		}
++		screen_info.orig_y = screen_info.orig_video_lines - 1;
++		xen_start_info->console.domU.mfn = 0;
++		xen_start_info->console.domU.evtchn = 0;
 +	} else
 +		screen_info.orig_video_isVGA = 0;
 +
@@ -11778,7 +12869,7 @@
 +	 * NOTE: at this point the bootmem allocator is fully available.
 +	 */
 +
-+	if (xen_start_info->flags & SIF_INITDOMAIN)
++	if (is_initial_xendomain())
 +		dmi_scan_machine();
 +
 +#ifdef CONFIG_X86_GENERICARCH
@@ -11790,12 +12881,8 @@
 +	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 (!(xen_start_info->flags & SIF_INITDOMAIN)) {
++	if (!is_initial_xendomain()) {
 +		printk(KERN_INFO "ACPI in unprivileged domain disabled\n");
 +		acpi_disabled = 1;
 +		acpi_ht = 0;
@@ -11805,6 +12892,13 @@
 +	 * Parse the ACPI tables for possible boot-time SMP configuration.
 +	 */
 +	acpi_boot_table_init();
++#endif
++
++#ifdef CONFIG_X86_IO_APIC
++	check_acpi_pci();	/* Checks more than just ACPI actually */
++#endif
++
++#ifdef CONFIG_ACPI
 +	acpi_boot_init();
 +
 +#if defined(CONFIG_SMP) && defined(CONFIG_X86_PC)
@@ -11824,11 +12918,7 @@
 +
 +	register_memory();
 +
-+	if (xen_start_info->flags & SIF_INITDOMAIN) {
-+		if (!(xen_start_info->flags & SIF_PRIVILEGED))
-+			panic("Xen granted us console access "
-+			      "but not privileged status");
-+
++	if (is_initial_xendomain()) {
 +#ifdef CONFIG_VT
 +#if defined(CONFIG_VGA_CONSOLE)
 +		if (!efi_enabled ||
@@ -11842,6 +12932,9 @@
 +		extern int console_use_vt;
 +		console_use_vt = 0;
 +	}
++#ifdef CONFIG_X86_TSC
++	tsc_init();
++#endif
 +}
 +
 +static int
@@ -11869,7 +12962,6 @@
 +}
 +device_initcall(add_pcspkr);
 +
-+#include "setup_arch_post.h"
 +/*
 + * Local Variables:
 + * mode:c
@@ -11877,10 +12969,10 @@
 + * c-basic-offset:8
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/smp-xen.c linux-2.6.17-xen/arch/i386/kernel/smp-xen.c
---- linux-2.6.17/arch/i386/kernel/smp-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/smp-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,614 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/smp-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/smp-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/smp-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/smp-xen.c	2006-07-20 15:56:36.000000000 +0200
+@@ -0,0 +1,624 @@
 +/*
 + *	Intel SMP support routines.
 + *
@@ -12000,7 +13092,17 @@
 +
 +static inline int __prepare_ICR (unsigned int shortcut, int vector)
 +{
-+	return APIC_DM_FIXED | shortcut | vector | APIC_DEST_LOGICAL;
++	unsigned int icr = shortcut | APIC_DEST_LOGICAL;
++
++	switch (vector) {
++	default:
++		icr |= APIC_DM_FIXED | vector;
++		break;
++	case NMI_VECTOR:
++		icr |= APIC_DM_NMI;
++		break;
++	}
++	return icr;
 +}
 +
 +static inline int __prepare_ICR2 (unsigned int mask)
@@ -12495,9 +13597,9 @@
 +	return IRQ_HANDLED;
 +}
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/swiotlb.c linux-2.6.17-xen/arch/i386/kernel/swiotlb.c
---- linux-2.6.17/arch/i386/kernel/swiotlb.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/swiotlb.c	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/swiotlb.c linux-2.6.18-rc5-xen/arch/i386/kernel/swiotlb.c
+--- linux-2.6.18-rc5/arch/i386/kernel/swiotlb.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/swiotlb.c	2006-09-01 00:09:08.000000000 +0200
 @@ -0,0 +1,672 @@
 +/*
 + * Dynamic DMA mapping support.
@@ -12551,7 +13653,7 @@
 +/* Width of DMA addresses in the IO TLB. 31 bits is an aacraid limitation. */
 +#define IO_TLB_DMA_BITS 31
 +
-+static int swiotlb_force;
++int swiotlb_force;
 +static char *iotlb_virt_start;
 +static unsigned long iotlb_nslabs;
 +
@@ -12700,7 +13802,7 @@
 +		swiotlb = 1;
 +	} else if ((swiotlb_force != -1) &&
 +		   is_running_on_xen() &&
-+		   (xen_start_info->flags & SIF_INITDOMAIN)) {
++		   is_initial_xendomain()) {
 +		/* Domain 0 always has a swiotlb. */
 +		ram_end = HYPERVISOR_memory_op(XENMEM_maximum_ram_page, NULL);
 +		if (ram_end <= 0x7ffff)
@@ -13171,17 +14273,10 @@
 +EXPORT_SYMBOL(swiotlb_unmap_page);
 +EXPORT_SYMBOL(swiotlb_dma_mapping_error);
 +EXPORT_SYMBOL(swiotlb_dma_supported);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/sysenter.c linux-2.6.17-xen/arch/i386/kernel/sysenter.c
---- linux-2.6.17/arch/i386/kernel/sysenter.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/sysenter.c	2006-08-14 15:57:20.000000000 +0200
-@@ -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>
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/sysenter.c linux-2.6.18-rc5-xen/arch/i386/kernel/sysenter.c
+--- linux-2.6.18-rc5/arch/i386/kernel/sysenter.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/sysenter.c	2006-07-31 23:43:28.000000000 +0200
+@@ -23,6 +23,10 @@
  #include <asm/pgtable.h>
  #include <asm/unistd.h>
  
@@ -13189,7 +14284,10 @@
 +#include <xen/interface/callback.h>
 +#endif
 +
- extern asmlinkage void sysenter_entry(void);
+ /*
+  * Should the kernel map a VDSO page into processes and pass its
+  * address down to glibc upon exec()?
+@@ -44,6 +48,7 @@
  
  void enable_sep_cpu(void)
  {
@@ -13197,7 +14295,7 @@
  	int cpu = get_cpu();
  	struct tss_struct *tss = &per_cpu(init_tss, cpu);
  
-@@ -37,6 +43,7 @@
+@@ -58,6 +63,7 @@
  	wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
  	wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
  	put_cpu();	
@@ -13205,120 +14303,42 @@
  }
  
  /*
-@@ -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)
+@@ -72,6 +78,18 @@
  {
--	void *page = (void *)get_zeroed_page(GFP_ATOMIC);
-+	syscall_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)) {
 +		struct callback_register 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;
- 	}
+ #ifdef CONFIG_COMPAT_VDSO
+ 	__set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY);
+ 	printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO));
+@@ -79,8 +97,12 @@
+ 	/*
+ 	 * In the non-compat case the ELF coredumping code needs the fixmap:
+ 	 */
++#ifdef CONFIG_XEN
++	__set_fixmap(FIX_VDSO, virt_to_machine(syscall_page), PAGE_KERNEL_RO);
++#else
+ 	__set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO);
+ #endif
++#endif
  
--	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 -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/time-xen.c linux-2.6.17-xen/arch/i386/kernel/time-xen.c
---- linux-2.6.17/arch/i386/kernel/time-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/time-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,1109 @@
+ 	if (!boot_cpu_has(X86_FEATURE_SEP)) {
+ 		memcpy(syscall_page,
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/time-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/time-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/time-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/time-xen.c	2006-09-01 00:09:08.000000000 +0200
+@@ -0,0 +1,1101 @@
 +/*
 + *  linux/arch/i386/kernel/time.c
 + *
@@ -13386,7 +14406,6 @@
 +#include "mach_time.h"
 +
 +#include <linux/timex.h>
-+#include <linux/config.h>
 +
 +#include <asm/hpet.h>
 +
@@ -13410,6 +14429,13 @@
 +struct timezone __sys_tz __section_sys_tz;
 +#endif
 +
++#define USEC_PER_TICK (USEC_PER_SEC / HZ)
++#define NSEC_PER_TICK (NSEC_PER_SEC / HZ)
++#define FSEC_PER_TICK (FSEC_PER_SEC / HZ)
++
++#define NS_SCALE	10 /* 2^10, carefully chosen */
++#define US_SCALE	32 /* 2^32, arbitralrily chosen */
++
 +unsigned int cpu_khz;	/* Detected as we calibrate the TSC */
 +EXPORT_SYMBOL(cpu_khz);
 +
@@ -13418,17 +14444,9 @@
 +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 {
@@ -13487,7 +14505,9 @@
 +}
 +__setup("permitted_clock_jitter=", __permitted_clock_jitter);
 +
++#ifndef CONFIG_X86
 +int tsc_disable __devinitdata = 0;
++#endif
 +
 +static void delay_tsc(unsigned long loops)
 +{
@@ -13531,7 +14551,7 @@
 +		"add  %4,%%eax ; "
 +		"adc  %5,%%edx ; "
 +		: "=A" (product), "=r" (tmp1), "=r" (tmp2)
-+		: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
++		: "a" ((u32)delta), "1" ((u32)(delta >> US_SCALE)), "2" (mul_frac) );
 +#else
 +	__asm__ (
 +		"mul %%rdx ; shrd $32,%%rdx,%%rax"
@@ -13551,7 +14571,7 @@
 +
 +void init_cpu_khz(void)
 +{
-+	u64 __cpu_khz = 1000000ULL << 32;
++	u64 __cpu_khz = 1000000ULL << US_SCALE;
 +	struct vcpu_time_info *info;
 +	info = &HYPERVISOR_shared_info->vcpu_info[0].time;
 +	do_div(__cpu_khz, info->tsc_to_system_mul);
@@ -13791,8 +14811,7 @@
 +	sec = tv->tv_sec;
 +	__normalize_time(&sec, &nsec);
 +
-+	if ((xen_start_info->flags & SIF_INITDOMAIN) &&
-+	    !independent_wallclock) {
++	if (is_initial_xendomain() && !independent_wallclock) {
 +		op.cmd = DOM0_SETTIME;
 +		op.u.settime.secs        = sec;
 +		op.u.settime.nsecs       = nsec;
@@ -13823,8 +14842,7 @@
 +	s64 nsec;
 +	dom0_op_t op;
 +
-+	if (!ntp_synced() || independent_wallclock ||
-+	    !(xen_start_info->flags & SIF_INITDOMAIN))
++	if (!ntp_synced() || independent_wallclock || !is_initial_xendomain())
 +		return;
 +
 +	write_seqlock_irq(&xtime_lock);
@@ -13850,19 +14868,18 @@
 +static int set_rtc_mmss(unsigned long nowtime)
 +{
 +	int retval;
++	unsigned long flags;
 +
-+	WARN_ON(irqs_disabled());
-+
-+	if (independent_wallclock || !(xen_start_info->flags & SIF_INITDOMAIN))
++	if (independent_wallclock || !is_initial_xendomain())
 +		return 0;
 +
 +	/* gets recalled with irq locally disabled */
-+	spin_lock_irq(&rtc_lock);
++	spin_lock_irqsave(&rtc_lock, flags);
 +	if (efi_enabled)
 +		retval = efi_set_rtc_mmss(nowtime);
 +	else
 +		retval = mach_set_rtc_mmss(nowtime);
-+	spin_unlock_irq(&rtc_lock);
++	spin_unlock_irqrestore(&rtc_lock, flags);
 +
 +	return retval;
 +}
@@ -13910,7 +14927,7 @@
 +	   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)) {
++	if (!user_mode_vm(regs) && in_lock_functions(pc)) {
 +		char *v = *(char **)regs->rsp;
 +		if ((v >= _stext && v <= _etext) ||
 +			(v >= _sinittext && v <= _einittext) ||
@@ -13919,7 +14936,7 @@
 +		return ((unsigned long *)regs->rsp)[1];
 +	}
 +#else
-+	if (in_lock_functions(pc))
++	if (!user_mode_vm(regs) && in_lock_functions(pc))
 +		return *(unsigned long *)(regs->ebp + 4);
 +#endif
 +
@@ -14064,15 +15081,16 @@
 +unsigned long get_cmos_time(void)
 +{
 +	unsigned long retval;
++	unsigned long flags;
 +
-+	spin_lock(&rtc_lock);
++	spin_lock_irqsave(&rtc_lock, flags);
 +
 +	if (efi_enabled)
 +		retval = efi_get_time();
 +	else
 +		retval = mach_get_cmos_time();
 +
-+	spin_unlock(&rtc_lock);
++	spin_unlock_irqrestore(&rtc_lock, flags);
 +
 +	return retval;
 +}
@@ -14130,7 +15148,6 @@
 +
 +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)
 +{
 +	/*
@@ -14139,10 +15156,6 @@
 +	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;
 +}
 +
@@ -14164,10 +15177,6 @@
 +	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;
 +}
@@ -14208,10 +15217,6 @@
 +	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
@@ -14259,8 +15264,8 @@
 +
 +#if defined(__x86_64__)
 +	vxtime.mode = VXTIME_TSC;
-+	vxtime.quot = (1000000L << 32) / vxtime_hz;
-+	vxtime.tsc_quot = (1000L << 32) / cpu_khz;
++	vxtime.quot = (1000000L << US_SCALE) / vxtime_hz;
++	vxtime.tsc_quot = (1000L << US_SCALE) / cpu_khz;
 +	sync_core();
 +	rdtscll(vxtime.last_tsc);
 +#endif
@@ -14279,11 +15284,17 @@
 +	do {
 +		seq = read_seqbegin(&xtime_lock);
 +		delta = j - jiffies;
-+		/* NB. The next check can trigger in some wrap-around cases,
-+		 * but that's ok: we'll just end up with a shorter timeout. */
-+		if (delta < 1)
-+			delta = 1;
-+		st = processed_system_time + (delta * (u64)NS_PER_TICK);
++		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;
@@ -14310,14 +15321,15 @@
 +
 +	smp_mb();
 +
-+	/* Leave ourselves in 'tick mode' if rcu or softirq or timer pending. */
++	/* 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;
 +	}
 +
-+	BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
++	if (HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0)
++		BUG();
 +}
 +
 +static void start_hz_timer(void)
@@ -14325,14 +15337,14 @@
 +	cpu_clear(smp_processor_id(), nohz_cpu_mask);
 +}
 +
-+void safe_halt(void)
++void raw_safe_halt(void)
 +{
 +	stop_hz_timer();
 +	/* Blocking includes an implicit local_irq_enable(). */
 +	HYPERVISOR_block();
 +	start_hz_timer();
 +}
-+EXPORT_SYMBOL(safe_halt);
++EXPORT_SYMBOL(raw_safe_halt);
 +
 +void halt(void)
 +{
@@ -14428,10 +15440,10 @@
 +	return 0;
 +}
 +__initcall(xen_sysctl_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/traps.c linux-2.6.17-xen/arch/i386/kernel/traps.c
---- linux-2.6.17/arch/i386/kernel/traps.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/traps.c	2006-08-14 15:57:20.000000000 +0200
-@@ -607,18 +607,11 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/traps.c linux-2.6.18-rc5-xen/arch/i386/kernel/traps.c
+--- linux-2.6.18-rc5/arch/i386/kernel/traps.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/traps.c	2006-09-01 00:09:09.000000000 +0200
+@@ -639,18 +639,11 @@
  
  static void io_check_error(unsigned char reason, struct pt_regs * regs)
  {
@@ -14451,10 +15463,10 @@
  }
  
  static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/traps-xen.c linux-2.6.17-xen/arch/i386/kernel/traps-xen.c
---- linux-2.6.17/arch/i386/kernel/traps-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/traps-xen.c	2006-08-14 15:57:20.000000000 +0200
-@@ -0,0 +1,1136 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/traps-xen.c linux-2.6.18-rc5-xen/arch/i386/kernel/traps-xen.c
+--- linux-2.6.18-rc5/arch/i386/kernel/traps-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/traps-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,1180 @@
 +/*
 + *  linux/arch/i386/traps.c
 + *
@@ -14468,7 +15480,6 @@
 + * '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>
@@ -14485,6 +15496,7 @@
 +#include <linux/utsname.h>
 +#include <linux/kprobes.h>
 +#include <linux/kexec.h>
++#include <linux/unwind.h>
 +
 +#ifdef CONFIG_EISA
 +#include <linux/ioport.h>
@@ -14504,7 +15516,7 @@
 +#include <asm/desc.h>
 +#include <asm/i387.h>
 +#include <asm/nmi.h>
-+
++#include <asm/unwind.h>
 +#include <asm/smp.h>
 +#include <asm/arch_hooks.h>
 +#include <asm/kdebug.h>
@@ -14555,6 +15567,7 @@
 +asmlinkage void machine_check(void);
 +
 +static int kstack_depth_to_print = 24;
++static int call_trace = 1;
 +ATOMIC_NOTIFIER_HEAD(i386die_chain);
 +
 +int register_die_notifier(struct notifier_block *nb)
@@ -14562,13 +15575,13 @@
 +	vmalloc_sync_all();
 +	return atomic_notifier_chain_register(&i386die_chain, nb);
 +}
-+EXPORT_SYMBOL(register_die_notifier);
++EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
 +
 +int unregister_die_notifier(struct notifier_block *nb)
 +{
 +	return atomic_notifier_chain_unregister(&i386die_chain, nb);
 +}
-+EXPORT_SYMBOL(unregister_die_notifier);
++EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
 +
 +static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
 +{
@@ -14577,28 +15590,13 @@
 +}
 +
 +/*
-+ * Print CONFIG_STACK_BACKTRACE_COLS address/symbol entries per line.
++ * Print one address/symbol entries per line.
 + */
-+static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl,
-+					int printed)
++static inline void print_addr_and_symbol(unsigned long addr, char *log_lvl)
 +{
-+	if (!printed)
-+		printk(log_lvl);
-+
-+#if CONFIG_STACK_BACKTRACE_COLS == 1
 +	printk(" [<%08lx>] ", addr);
-+#else
-+	printk(" <%08lx> ", addr);
-+#endif
-+	print_symbol("%s", addr);
-+
-+	printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS;
-+	if (printed)
-+		printk(" ");
-+	else
-+		printk("\n");
 +
-+	return printed;
++	print_symbol("%s\n", addr);
 +}
 +
 +static inline unsigned long print_context_stack(struct thread_info *tinfo,
@@ -14606,28 +15604,44 @@
 +				char *log_lvl)
 +{
 +	unsigned long addr;
-+	int printed = 0; /* nr of entries already printed on current line */
 +
 +#ifdef	CONFIG_FRAME_POINTER
 +	while (valid_stack_ptr(tinfo, (void *)ebp)) {
 +		addr = *(unsigned long *)(ebp + 4);
-+		printed = print_addr_and_symbol(addr, log_lvl, printed);
++		print_addr_and_symbol(addr, log_lvl);
++		/*
++		 * break out of recursive entries (such as
++		 * end_of_stack_stop_unwind_function):
++	 	 */
++		if (ebp == *(unsigned long *)ebp)
++			break;
 +		ebp = *(unsigned long *)ebp;
 +	}
 +#else
 +	while (valid_stack_ptr(tinfo, stack)) {
 +		addr = *stack++;
 +		if (__kernel_text_address(addr))
-+			printed = print_addr_and_symbol(addr, log_lvl, printed);
++			print_addr_and_symbol(addr, log_lvl);
 +	}
 +#endif
-+	if (printed)
-+		printk("\n");
-+
 +	return ebp;
 +}
 +
-+static void show_trace_log_lvl(struct task_struct *task,
++static asmlinkage int
++show_trace_unwind(struct unwind_frame_info *info, void *log_lvl)
++{
++	int n = 0;
++
++	while (unwind(info) == 0 && UNW_PC(info)) {
++		n++;
++		print_addr_and_symbol(UNW_PC(info), log_lvl);
++		if (arch_unw_user_mode(info))
++			break;
++	}
++	return n;
++}
++
++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
 +			       unsigned long *stack, char *log_lvl)
 +{
 +	unsigned long ebp;
@@ -14635,6 +15649,37 @@
 +	if (!task)
 +		task = current;
 +
++	if (call_trace >= 0) {
++		int unw_ret = 0;
++		struct unwind_frame_info info;
++
++		if (regs) {
++			if (unwind_init_frame_info(&info, task, regs) == 0)
++				unw_ret = show_trace_unwind(&info, log_lvl);
++		} else if (task == current)
++			unw_ret = unwind_init_running(&info, show_trace_unwind, log_lvl);
++		else {
++			if (unwind_init_blocked(&info, task) == 0)
++				unw_ret = show_trace_unwind(&info, log_lvl);
++		}
++		if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
++#ifdef CONFIG_STACK_UNWIND
++			print_symbol("DWARF2 unwinder stuck at %s\n",
++				     UNW_PC(&info));
++			if (call_trace == 1) {
++				printk("Leftover inexact backtrace:\n");
++				if (UNW_SP(&info))
++					stack = (void *)UNW_SP(&info);
++			} else if (call_trace > 1)
++				return;
++			else
++				printk("Full inexact backtrace again:\n");
++#else
++			printk("Inexact backtrace:\n");
++#endif
++		}
++	}
++
 +	if (task == current) {
 +		/* Grab ebp right from our regs */
 +		asm ("movl %%ebp, %0" : "=r" (ebp) : );
@@ -14655,13 +15700,13 @@
 +	}
 +}
 +
-+void show_trace(struct task_struct *task, unsigned long * stack)
++void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long * stack)
 +{
-+	show_trace_log_lvl(task, stack, "");
++	show_trace_log_lvl(task, regs, stack, "");
 +}
 +
-+static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp,
-+			       char *log_lvl)
++static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
++			       unsigned long *esp, char *log_lvl)
 +{
 +	unsigned long *stack;
 +	int i;
@@ -14674,7 +15719,6 @@
 +	}
 +
 +	stack = esp;
-+	printk(log_lvl);
 +	for(i = 0; i < kstack_depth_to_print; i++) {
 +		if (kstack_end(stack))
 +			break;
@@ -14683,13 +15727,13 @@
 +		printk("%08lx ", *stack++);
 +	}
 +	printk("\n%sCall Trace:\n", log_lvl);
-+	show_trace_log_lvl(task, esp, log_lvl);
++	show_trace_log_lvl(task, regs, esp, log_lvl);
 +}
 +
 +void show_stack(struct task_struct *task, unsigned long *esp)
 +{
 +	printk("       ");
-+	show_stack_log_lvl(task, esp, "");
++	show_stack_log_lvl(task, NULL, esp, "");
 +}
 +
 +/*
@@ -14699,7 +15743,7 @@
 +{
 +	unsigned long stack;
 +
-+	show_trace(current, &stack);
++	show_trace(current, NULL, &stack);
 +}
 +
 +EXPORT_SYMBOL(dump_stack);
@@ -14732,8 +15776,9 @@
 +		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);
++	printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
++		TASK_COMM_LEN, current->comm, current->pid,
++		current_thread_info(), current, current->thread_info);
 +	/*
 +	 * When in-kernel, we also print out the stack and code at the
 +	 * time of the fault..
@@ -14742,7 +15787,7 @@
 +		u8 __user *eip;
 +
 +		printk("\n" KERN_EMERG "Stack: ");
-+		show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG);
++		show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
 +
 +		printk(KERN_EMERG "Code: ");
 +
@@ -14765,35 +15810,34 @@
 +
 +static void handle_BUG(struct pt_regs *regs)
 +{
++	unsigned long eip = regs->eip;
 +	unsigned short ud2;
-+	unsigned short line;
-+	char *file;
-+	char c;
-+	unsigned long eip;
-+
-+	eip = regs->eip;
 +
 +	if (eip < PAGE_OFFSET)
-+		goto no_bug;
++		return;
 +	if (__get_user(ud2, (unsigned short __user *)eip))
-+		goto no_bug;
++		return;
 +	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>";
++		return;
 +
 +	printk(KERN_EMERG "------------[ cut here ]------------\n");
-+	printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
++#ifdef CONFIG_DEBUG_BUGVERBOSE
++	do {
++		unsigned short line;
++		char *file;
++		char c;
 +
-+no_bug:
-+	return;
++		if (__get_user(line, (unsigned short __user *)(eip + 2)))
++			break;
++		if (__get_user(file, (char * __user *)(eip + 4)) ||
++		    (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
++			file = "<bad filename>";
 +
-+	/* Here we know it was a BUG but file-n-line is unavailable */
-+bug:
-+	printk(KERN_EMERG "Kernel BUG\n");
++		printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
++		return;
++	} while (0);
++#endif
++	printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n");
 +}
 +
 +/* This is gone through when something in the kernel
@@ -14883,11 +15927,9 @@
 +	if (in_interrupt())
 +		panic("Fatal exception in interrupt");
 +
-+	if (panic_on_oops) {
-+		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
-+		ssleep(5);
++	if (panic_on_oops)
 +		panic("Fatal exception");
-+	}
++
 +	oops_exit();
 +	do_exit(SIGSEGV);
 +}
@@ -15591,10 +16633,43 @@
 +	return 1;
 +}
 +__setup("kstack=", kstack_setup);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/vm86.c linux-2.6.17-xen/arch/i386/kernel/vm86.c
---- linux-2.6.17/arch/i386/kernel/vm86.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/kernel/vm86.c	2006-08-14 15:57:20.000000000 +0200
-@@ -98,7 +98,9 @@
++
++static int __init call_trace_setup(char *s)
++{
++	if (strcmp(s, "old") == 0)
++		call_trace = -1;
++	else if (strcmp(s, "both") == 0)
++		call_trace = 0;
++	else if (strcmp(s, "newfallback") == 0)
++		call_trace = 1;
++	else if (strcmp(s, "new") == 2)
++		call_trace = 2;
++	return 1;
++}
++__setup("call_trace=", call_trace_setup);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/tsc.c linux-2.6.18-rc5-xen/arch/i386/kernel/tsc.c
+--- linux-2.6.18-rc5/arch/i386/kernel/tsc.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/tsc.c	2006-07-31 23:43:28.000000000 +0200
+@@ -101,6 +101,7 @@
+ 	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
+ }
+ 
++#ifndef CONFIG_XEN
+ /*
+  * Scheduler clock - returns current time in nanosec units.
+  */
+@@ -124,6 +125,7 @@
+ 	/* return the value in ns */
+ 	return cycles_2_ns(this_offset);
+ }
++#endif
+ 
+ static unsigned long calculate_cpu_khz(void)
+ {
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/vm86.c linux-2.6.18-rc5-xen/arch/i386/kernel/vm86.c
+--- linux-2.6.18-rc5/arch/i386/kernel/vm86.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/vm86.c	2006-07-20 15:56:36.000000000 +0200
+@@ -97,7 +97,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)
  {
@@ -15604,7 +16679,7 @@
  	struct pt_regs *ret;
  	unsigned long tmp;
  
-@@ -123,12 +125,16 @@
+@@ -122,12 +124,16 @@
  		do_exit(SIGSEGV);
  	}
  
@@ -15621,7 +16696,7 @@
  
  	loadsegment(fs, current->thread.saved_fs);
  	loadsegment(gs, current->thread.saved_gs);
-@@ -252,7 +258,9 @@
+@@ -251,7 +257,9 @@
  
  static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk)
  {
@@ -15631,7 +16706,7 @@
  	long eax;
  /*
   * make sure the vm86() system call doesn't try to do anything silly
-@@ -297,12 +305,16 @@
+@@ -296,12 +304,16 @@
  	savesegment(fs, tsk->thread.saved_fs);
  	savesegment(gs, tsk->thread.saved_gs);
  
@@ -15648,9 +16723,50 @@
  
  	tsk->thread.screen_bitmap = info->screen_bitmap;
  	if (info->flags & VM86_SCREEN_BITMAP)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/kernel/vsyscall-note-xen.S linux-2.6.17-xen/arch/i386/kernel/vsyscall-note-xen.S
---- linux-2.6.17/arch/i386/kernel/vsyscall-note-xen.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/kernel/vsyscall-note-xen.S	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/vmlinux.lds.S linux-2.6.18-rc5-xen/arch/i386/kernel/vmlinux.lds.S
+--- linux-2.6.18-rc5/arch/i386/kernel/vmlinux.lds.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/vmlinux.lds.S	2006-09-01 00:09:09.000000000 +0200
+@@ -13,6 +13,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;
+@@ -26,7 +32,7 @@
+ 	KPROBES_TEXT
+ 	*(.fixup)
+ 	*(.gnu.warning)
+-	} = 0x9090
++	} :text = 0x9090
+ 
+   _etext = .;			/* End of text section */
+ 
+@@ -48,7 +54,7 @@
+   .data : AT(ADDR(.data) - LOAD_OFFSET) {	/* Data */
+ 	*(.data)
+ 	CONSTRUCTORS
+-	}
++	} :data
+ 
+   . = ALIGN(4096);
+   __nosave_begin = .;
+@@ -184,4 +190,6 @@
+   STABS_DEBUG
+ 
+   DWARF_DEBUG
++
++  NOTES
+ }
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/kernel/vsyscall-note-xen.S linux-2.6.18-rc5-xen/arch/i386/kernel/vsyscall-note-xen.S
+--- linux-2.6.18-rc5/arch/i386/kernel/vsyscall-note-xen.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/kernel/vsyscall-note-xen.S	2006-07-20 15:56:36.000000000 +0200
 @@ -0,0 +1,32 @@
 +/*
 + * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
@@ -15684,29 +16800,157 @@
 +NOTE_KERNELCAP_BEGIN(1, 1)
 +NOTE_KERNELCAP(1, "nosegneg")  /* Change 1 back to 0 when glibc is fixed! */
 +NOTE_KERNELCAP_END
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mach-xen/Makefile linux-2.6.17-xen/arch/i386/mach-xen/Makefile
---- linux-2.6.17/arch/i386/mach-xen/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/mach-xen/Makefile	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/lib/delay.c linux-2.6.18-rc5-xen/arch/i386/lib/delay.c
+--- linux-2.6.18-rc5/arch/i386/lib/delay.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/lib/delay.c	2006-07-20 15:56:36.000000000 +0200
+@@ -61,6 +61,7 @@
+ 	delay_fn = delay_tsc;
+ }
+ 
++#ifndef CONFIG_X86_XEN
+ int read_current_timer(unsigned long *timer_val)
+ {
+ 	if (delay_fn == delay_tsc) {
+@@ -69,7 +70,7 @@
+ 	}
+ 	return -1;
+ }
+-
++#endif
+ void __delay(unsigned long loops)
+ {
+ 	delay_fn(loops);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mach-xen/irqflags.c linux-2.6.18-rc5-xen/arch/i386/mach-xen/irqflags.c
+--- linux-2.6.18-rc5/arch/i386/mach-xen/irqflags.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mach-xen/irqflags.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,99 @@
++#include <linux/module.h>
++#include <linux/smp.h>
++#include <asm/irqflags.h>
++#include <asm/hypervisor.h>
++
++/* 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.
++ */
++
++unsigned long __raw_local_save_flags(void)
++{
++	struct vcpu_info *_vcpu;
++	unsigned long flags;
++
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	flags = _vcpu->evtchn_upcall_mask;
++	preempt_enable();
++
++	return flags;
++}
++EXPORT_SYMBOL(__raw_local_save_flags);
++
++void raw_local_irq_restore(unsigned long flags)
++{
++	struct vcpu_info *_vcpu;
++
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	if ((_vcpu->evtchn_upcall_mask = flags) == 0) {
++		barrier(); /* unmask then check (avoid races) */
++		if (unlikely(_vcpu->evtchn_upcall_pending))
++			force_evtchn_callback();
++		preempt_enable();
++	} else
++		preempt_enable_no_resched();
++
++}
++EXPORT_SYMBOL(raw_local_irq_restore);
++
++void raw_local_irq_disable(void)
++{
++	struct vcpu_info *_vcpu;
++
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	_vcpu->evtchn_upcall_mask = 1;
++	preempt_enable_no_resched();
++}
++EXPORT_SYMBOL(raw_local_irq_disable);
++
++void raw_local_irq_enable(void)
++{
++	struct vcpu_info *_vcpu;
++
++	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();
++}
++EXPORT_SYMBOL(raw_local_irq_enable);
++
++/* Cannot use preempt_enable() here as we would recurse in preempt_sched(). */
++int raw_irqs_disabled(void)
++{
++	struct vcpu_info *_vcpu;
++	int disabled;
++
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	disabled = (_vcpu->evtchn_upcall_mask != 0);
++	preempt_enable_no_resched();
++	return disabled;
++}
++EXPORT_SYMBOL(raw_irqs_disabled);
++
++unsigned long __raw_local_irq_save(void)
++{
++	struct vcpu_info *_vcpu;
++	unsigned long flags;
++
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	flags = _vcpu->evtchn_upcall_mask;
++	_vcpu->evtchn_upcall_mask = 1;
++	preempt_enable_no_resched();
++
++	return flags;
++}
++EXPORT_SYMBOL(__raw_local_irq_save);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mach-xen/Makefile linux-2.6.18-rc5-xen/arch/i386/mach-xen/Makefile
+--- linux-2.6.18-rc5/arch/i386/mach-xen/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mach-xen/Makefile	2006-09-01 00:09:09.000000000 +0200
 @@ -0,0 +1,5 @@
 +#
 +# Makefile for the linux kernel.
 +#
 +
-+obj-y				:= setup.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mach-xen/setup.c linux-2.6.17-xen/arch/i386/mach-xen/setup.c
---- linux-2.6.17/arch/i386/mach-xen/setup.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/mach-xen/setup.c	2006-08-14 15:57:21.000000000 +0200
-@@ -0,0 +1,49 @@
++obj-y				:= setup.o irqflags.o
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mach-xen/setup.c linux-2.6.18-rc5-xen/arch/i386/mach-xen/setup.c
+--- linux-2.6.18-rc5/arch/i386/mach-xen/setup.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mach-xen/setup.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,153 @@
 +/*
 + *	Machine specific setup for generic
 + */
 +
-+#include <linux/config.h>
 +#include <linux/smp.h>
 +#include <linux/init.h>
 +#include <linux/interrupt.h>
++#include <linux/module.h>
 +#include <asm/acpi.h>
 +#include <asm/arch_hooks.h>
++#include <asm/e820.h>
++#include <asm/setup.h>
++
++#include <xen/interface/callback.h>
++#include <xen/interface/memory.h>
 +
 +#ifdef CONFIG_HOTPLUG_CPU
 +#define DEFAULT_SEND_IPI	(1)
@@ -15736,6 +16980,105 @@
 +late_initcall(print_ipi_mode);
 +
 +/**
++ * 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.
++ **/
++
++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);
++
++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;
++	struct callback_register event = {
++		.type = CALLBACKTYPE_event,
++		.address = { __KERNEL_CS, (unsigned long)hypervisor_callback },
++	};
++	struct callback_register failsafe = {
++		.type = CALLBACKTYPE_failsafe,
++		.address = { __KERNEL_CS, (unsigned long)failsafe_callback },
++	};
++	struct callback_register 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);
++	if (ret == -ENOSYS)
++		ret = HYPERVISOR_set_callbacks(
++			event.address.cs, event.address.eip,
++			failsafe.address.cs, failsafe.address.eip);
++	BUG_ON(ret);
++
++	ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
++	if (ret == -ENOSYS) {
++		struct xennmi_callback cb;
++
++		cb.handler_address = nmi_cb.address.eip;
++		HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
++	}
++
++	if (HYPERVISOR_xen_version(XENVER_platform_parameters,
++				   &pp) == 0)
++		set_fixaddr_top(pp.virt_start - PAGE_SIZE);
++
++	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++;
++}
++
++/**
 + * pre_setup_arch_hook - hook called prior to any setup_arch() execution
 + *
 + * Description:
@@ -15746,9 +17089,9 @@
 +void __init pre_setup_arch_hook(void)
 +{
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/Makefile linux-2.6.17-xen/arch/i386/Makefile
---- linux-2.6.17/arch/i386/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/Makefile	2006-08-14 15:57:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/Makefile linux-2.6.18-rc5-xen/arch/i386/Makefile
+--- linux-2.6.18-rc5/arch/i386/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/Makefile	2006-07-20 15:56:36.000000000 +0200
 @@ -48,6 +48,11 @@
  
  CFLAGS += $(cflags-y)
@@ -15805,10 +17148,10 @@
  	       arch/$(ARCH)/boot/image.iso \
  	       arch/$(ARCH)/boot/mtools.conf
 +CLEAN_FILES += vmlinuz vmlinux-stripped
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/fault-xen.c linux-2.6.17-xen/arch/i386/mm/fault-xen.c
---- linux-2.6.17/arch/i386/mm/fault-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/mm/fault-xen.c	2006-08-14 15:57:21.000000000 +0200
-@@ -0,0 +1,734 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/fault-xen.c linux-2.6.18-rc5-xen/arch/i386/mm/fault-xen.c
+--- linux-2.6.18-rc5/arch/i386/mm/fault-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mm/fault-xen.c	2006-07-20 15:56:37.000000000 +0200
+@@ -0,0 +1,770 @@
 +/*
 + *  linux/arch/i386/mm/fault.c
 + *
@@ -15841,6 +17184,39 @@
 +
 +extern void die(const char *,struct pt_regs *,long);
 +
++#ifdef CONFIG_KPROBES
++ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
++int register_page_fault_notifier(struct notifier_block *nb)
++{
++	vmalloc_sync_all();
++	return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
++}
++
++int unregister_page_fault_notifier(struct notifier_block *nb)
++{
++	return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
++}
++
++static inline int notify_page_fault(enum die_val val, const char *str,
++			struct pt_regs *regs, long err, int trap, int sig)
++{
++	struct die_args args = {
++		.regs = regs,
++		.str = str,
++		.err = err,
++		.trapnr = trap,
++		.signr = sig
++	};
++	return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
++}
++#else
++static inline int notify_page_fault(enum die_val val, const char *str,
++			struct pt_regs *regs, long err, int trap, int sig)
++{
++	return NOTIFY_DONE;
++}
++#endif
++
 +/*
 + * Unlock any spinlocks which will prevent us from getting the
 + * message out 
@@ -15888,13 +17264,16 @@
 +	unsigned seg = regs->xcs & 0xffff;
 +	u32 seg_ar, seg_limit, base, *desc;
 +
++	/* Unlikely, but must come before segment checks. */
++	if (unlikely(regs->eflags & VM_MASK)) {
++		base = seg << 4;
++		*eip_limit = base + 0xffff;
++		return base + (eip & 0xffff);
++	}
++
 +	/* 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;
@@ -16257,7 +17636,7 @@
 +		/* Can take a spurious fault if mapping changes R/O -> R/W. */
 +		if (spurious_fault(regs, address, error_code))
 +			return;
-+		if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
++		if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
 +						SIGSEGV) == NOTIFY_STOP)
 +			return;
 +		/*
@@ -16267,7 +17646,7 @@
 +		goto bad_area_nosemaphore;
 +	}
 +
-+	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
++	if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
 +					SIGSEGV) == NOTIFY_STOP)
 +		return;
 +
@@ -16288,7 +17667,7 @@
 +	/* 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
++	 * erroneous fault occurring 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
@@ -16316,12 +17695,12 @@
 +		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..
++		 * Accessing the stack below %esp is always a bug.
++		 * The large cushion allows instructions like enter
++		 * and pusha to work.  ("enter $65535,$31" pushes
++		 * 32 pointers and then decrements %esp by 65535.)
 +		 */
-+		if (address + 32 < regs->esp)
++		if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
 +			goto bad_area;
 +	}
 +	if (expand_stack(vma, address))
@@ -16543,9 +17922,9 @@
 +	}
 +}
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/highmem-xen.c linux-2.6.17-xen/arch/i386/mm/highmem-xen.c
---- linux-2.6.17/arch/i386/mm/highmem-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/mm/highmem-xen.c	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/highmem-xen.c linux-2.6.18-rc5-xen/arch/i386/mm/highmem-xen.c
+--- linux-2.6.18-rc5/arch/i386/mm/highmem-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mm/highmem-xen.c	2006-07-20 15:56:37.000000000 +0200
 @@ -0,0 +1,133 @@
 +#include <linux/highmem.h>
 +#include <linux/module.h>
@@ -16680,10 +18059,10 @@
 +EXPORT_SYMBOL(kmap_atomic);
 +EXPORT_SYMBOL(kunmap_atomic);
 +EXPORT_SYMBOL(kmap_atomic_to_page);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/hypervisor.c linux-2.6.17-xen/arch/i386/mm/hypervisor.c
---- linux-2.6.17/arch/i386/mm/hypervisor.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/mm/hypervisor.c	2006-08-14 15:57:21.000000000 +0200
-@@ -0,0 +1,453 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/hypervisor.c linux-2.6.18-rc5-xen/arch/i386/mm/hypervisor.c
+--- linux-2.6.18-rc5/arch/i386/mm/hypervisor.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mm/hypervisor.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,457 @@
 +/******************************************************************************
 + * mm/hypervisor.c
 + * 
@@ -16716,7 +18095,6 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/sched.h>
 +#include <linux/mm.h>
 +#include <linux/vmalloc.h>
@@ -16952,6 +18330,7 @@
 +/* 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(
@@ -16996,12 +18375,13 @@
 +	/* 1. Zap current PTEs, remembering MFNs. */
 +	for (i = 0; i < (1UL<<order); i++) {
 +		in_frames[i] = pfn_to_mfn((__pa(vstart) >> PAGE_SHIFT) + i);
-+		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
-+						 __pte_ma(0), 0))
-+			BUG();
++		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;
@@ -17029,15 +18409,16 @@
 +	/* 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];
-+		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
-+						 pfn_pte_ma(frame,
-+							    PAGE_KERNEL),
-+						 0))
-+			BUG();
++		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);
 +	}
 +
-+	flush_tlb_all();
++	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,
@@ -17088,13 +18469,14 @@
 +
 +	/* 2. Zap current PTEs. */
 +	for (i = 0; i < (1UL<<order); i++) {
-+		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
-+						 __pte_ma(0), 0))
-+			BUG();
++		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);
@@ -17115,15 +18497,16 @@
 +	/* 4. Map new pages in place of old pages. */
 +	for (i = 0; i < (1UL<<order); i++) {
 +		frame = success ? out_frames[i] : (in_frame + i);
-+		if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
-+						 pfn_pte_ma(frame,
-+							    PAGE_KERNEL),
-+						 0))
-+			BUG();
++		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);
 +	}
 +
-+	flush_tlb_all();
++	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);
 +}
@@ -17137,10 +18520,10 @@
 +		mach_lp, (u64)entry_a | ((u64)entry_b<<32));
 +}
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/init-xen.c linux-2.6.17-xen/arch/i386/mm/init-xen.c
---- linux-2.6.17/arch/i386/mm/init-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/mm/init-xen.c	2006-08-14 15:57:21.000000000 +0200
-@@ -0,0 +1,850 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/init-xen.c linux-2.6.18-rc5-xen/arch/i386/mm/init-xen.c
+--- linux-2.6.18-rc5/arch/i386/mm/init-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mm/init-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,851 @@
 +/*
 + *  linux/arch/i386/mm/init.c
 + *
@@ -17149,7 +18532,6 @@
 + *  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>
@@ -17166,12 +18548,14 @@
 +#include <linux/init.h>
 +#include <linux/highmem.h>
 +#include <linux/pagemap.h>
++#include <linux/poison.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/cpumask.h>
 +#include <linux/dma-mapping.h>
 +#include <linux/scatterlist.h>
 +
@@ -17558,7 +18942,7 @@
 +	permanent_kmaps_init(pgd_base);
 +}
 +
-+#ifdef CONFIG_SOFTWARE_SUSPEND
++#if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP)
 +/*
 + * Swap suspend & friends need this for resume because things like the intel-agp
 + * driver might have split up a kernel 4MB mapping.
@@ -17709,7 +19093,7 @@
 +
 +	/* Setup mapping of lower 1st MB */
 +	for (i = 0; i < NR_FIX_ISAMAPS; i++)
-+		if (xen_start_info->flags & SIF_PRIVILEGED)
++		if (is_initial_xendomain())
 +			set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
 +		else
 +			__set_fixmap(FIX_ISAMAP_BEGIN - i,
@@ -17866,7 +19250,7 @@
 + */
 +#ifdef CONFIG_MEMORY_HOTPLUG
 +#ifndef CONFIG_NEED_MULTIPLE_NODES
-+int add_memory(u64 start, u64 size)
++int arch_add_memory(u64 start, u64 size)
 +{
 +	struct pglist_data *pgdata = &contig_page_data;
 +	struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
@@ -17942,16 +19326,16 @@
 +
 +#ifdef CONFIG_DEBUG_RODATA
 +
-+extern char __start_rodata, __end_rodata;
 +void mark_rodata_ro(void)
 +{
-+	unsigned long addr = (unsigned long)&__start_rodata;
++	unsigned long addr = (unsigned long)__start_rodata;
 +
-+	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
++	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);
++	printk("Write protecting the kernel read-only data: %uk\n",
++			(__end_rodata - __start_rodata) >> 10);
++
 +
 +	/*
 +	 * change_page_attr() requires a global_flush_tlb() call after it.
@@ -17970,7 +19354,7 @@
 +	for (addr = begin; addr < end; addr += PAGE_SIZE) {
 +		ClearPageReserved(virt_to_page(addr));
 +		init_page_count(virt_to_page(addr));
-+		memset((void *)addr, 0xcc, PAGE_SIZE);
++		memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
 +		free_page(addr);
 +		totalram_pages++;
 +	}
@@ -17991,10 +19375,10 @@
 +}
 +#endif
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/ioremap-xen.c linux-2.6.17-xen/arch/i386/mm/ioremap-xen.c
---- linux-2.6.17/arch/i386/mm/ioremap-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/mm/ioremap-xen.c	2006-08-14 15:57:21.000000000 +0200
-@@ -0,0 +1,476 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/ioremap-xen.c linux-2.6.18-rc5-xen/arch/i386/mm/ioremap-xen.c
+--- linux-2.6.18-rc5/arch/i386/mm/ioremap-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mm/ioremap-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,475 @@
 +/*
 + * arch/i386/mm/ioremap.c
 + *
@@ -18118,11 +19502,13 @@
 +			   domid_t  domid)
 +{
 +	/* Same as remap_pfn_range(). */
-+	vma->vm_flags |= VM_IO | VM_RESERVED;
++	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
 +
 +	if (domid == DOMID_SELF)
 +		return -EINVAL;
 +
++	vma->vm_mm->context.has_foreign_mappings = 1;
++
 +	return __direct_remap_pfn_range(
 +		vma->vm_mm, address, mfn, size, prot, domid);
 +}
@@ -18179,7 +19565,7 @@
 +	int error;
 +       
 +	struct vm_struct *vma;
-+	vma = get_vm_area (vm_size, VM_IOREMAP);
++	vma = get_vm_area (vm_size, VM_IOREMAP | VM_PFNMAP);
 +      
 +	if (vma == NULL) {
 +		printk ("ioremap.c,vm_map_xen_pages(): "
@@ -18240,7 +19626,7 @@
 +	/*
 +	 * Don't remap the low PCI/ISA area, it's always mapped..
 +	 */
-+	if (xen_start_info->flags & SIF_PRIVILEGED &&
++	if (is_initial_xendomain() &&
 +	    phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
 +		return (void __iomem *) isa_bus_to_virt(phys_addr);
 +
@@ -18277,9 +19663,6 @@
 +	area->phys_addr = phys_addr;
 +	addr = (void __iomem *) area->addr;
 +	flags |= _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;
-+#ifdef __x86_64__
-+	flags |= _PAGE_USER;
-+#endif
 +	if (__direct_remap_pfn_range(&init_mm, (unsigned long)addr,
 +				     phys_addr>>PAGE_SHIFT,
 +				     size, __pgprot(flags), domid)) {
@@ -18418,7 +19801,7 @@
 +	/*
 +	 * Don't remap the low PCI/ISA area, it's always mapped..
 +	 */
-+	if (xen_start_info->flags & SIF_PRIVILEGED &&
++	if (is_initial_xendomain() &&
 +	    phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
 +		return isa_bus_to_virt(phys_addr);
 +
@@ -18471,9 +19854,9 @@
 +		--nrpages;
 +	}
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/Makefile linux-2.6.17-xen/arch/i386/mm/Makefile
---- linux-2.6.17/arch/i386/mm/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/mm/Makefile	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/Makefile linux-2.6.18-rc5-xen/arch/i386/mm/Makefile
+--- linux-2.6.18-rc5/arch/i386/mm/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/mm/Makefile	2006-07-20 15:56:37.000000000 +0200
 @@ -8,3 +8,11 @@
  obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
  obj-$(CONFIG_HIGHMEM) += highmem.o
@@ -18486,10 +19869,10 @@
 +
 +obj-y := $(call cherrypickxen, $(obj-y))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/pageattr.c linux-2.6.17-xen/arch/i386/mm/pageattr.c
---- linux-2.6.17/arch/i386/mm/pageattr.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/mm/pageattr.c	2006-08-14 15:57:21.000000000 +0200
-@@ -85,7 +85,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/pageattr.c linux-2.6.18-rc5-xen/arch/i386/mm/pageattr.c
+--- linux-2.6.18-rc5/arch/i386/mm/pageattr.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/mm/pageattr.c	2006-07-20 15:56:37.000000000 +0200
+@@ -84,7 +84,7 @@
  	unsigned long flags;
  
  	set_pte_atomic(kpte, pte); 	/* change init_mm */
@@ -18498,10 +19881,10 @@
  		return;
  
  	spin_lock_irqsave(&pgd_lock, flags);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/pgtable.c linux-2.6.17-xen/arch/i386/mm/pgtable.c
---- linux-2.6.17/arch/i386/mm/pgtable.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/mm/pgtable.c	2006-08-14 15:57:21.000000000 +0200
-@@ -13,6 +13,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/pgtable.c linux-2.6.18-rc5-xen/arch/i386/mm/pgtable.c
+--- linux-2.6.18-rc5/arch/i386/mm/pgtable.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/mm/pgtable.c	2006-07-20 15:56:37.000000000 +0200
+@@ -12,6 +12,7 @@
  #include <linux/slab.h>
  #include <linux/pagemap.h>
  #include <linux/spinlock.h>
@@ -18509,7 +19892,7 @@
  
  #include <asm/system.h>
  #include <asm/pgtable.h>
-@@ -138,6 +139,10 @@
+@@ -137,6 +138,10 @@
  	__flush_tlb_one(vaddr);
  }
  
@@ -18520,7 +19903,7 @@
  void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
  {
  	unsigned long address = __fix_to_virt(idx);
-@@ -147,6 +152,13 @@
+@@ -146,6 +151,13 @@
  		return;
  	}
  	set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
@@ -18534,15 +19917,14 @@
  }
  
  pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/mm/pgtable-xen.c linux-2.6.17-xen/arch/i386/mm/pgtable-xen.c
---- linux-2.6.17/arch/i386/mm/pgtable-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/mm/pgtable-xen.c	2006-08-14 15:57:21.000000000 +0200
-@@ -0,0 +1,694 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/mm/pgtable-xen.c linux-2.6.18-rc5-xen/arch/i386/mm/pgtable-xen.c
+--- linux-2.6.18-rc5/arch/i386/mm/pgtable-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/mm/pgtable-xen.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,699 @@
 +/*
 + *  linux/arch/i386/mm/pgtable.c
 + */
 +
-+#include <linux/config.h>
 +#include <linux/sched.h>
 +#include <linux/kernel.h>
 +#include <linux/errno.h>
@@ -18579,7 +19961,6 @@
 +	struct page *page;
 +	pg_data_t *pgdat;
 +	unsigned long i;
-+	struct page_state ps;
 +	unsigned long flags;
 +
 +	printk(KERN_INFO "Mem-info:\n");
@@ -18607,12 +19988,13 @@
 +	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);
++	printk(KERN_INFO "%lu pages dirty\n", global_page_state(NR_FILE_DIRTY));
++	printk(KERN_INFO "%lu pages writeback\n",
++					global_page_state(NR_WRITEBACK));
++	printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED));
++	printk(KERN_INFO "%lu pages slab\n", global_page_state(NR_SLAB));
++	printk(KERN_INFO "%lu pages pagetables\n",
++					global_page_state(NR_PAGETABLE));
 +}
 +
 +/*
@@ -19192,8 +20574,13 @@
 +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));
@@ -19229,12 +20616,13 @@
 +	task_unlock(tsk);
 +
 +	if (test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags) &&
-+	    (atomic_read(&mm->mm_count) == 1))
++	    (atomic_read(&mm->mm_count) == 1) &&
++	    !mm->context.has_foreign_mappings)
 +		mm_unpin(mm);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/oprofile/Makefile linux-2.6.17-xen/arch/i386/oprofile/Makefile
---- linux-2.6.17/arch/i386/oprofile/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/oprofile/Makefile	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/oprofile/Makefile linux-2.6.18-rc5-xen/arch/i386/oprofile/Makefile
+--- linux-2.6.18-rc5/arch/i386/oprofile/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/oprofile/Makefile	2006-07-20 15:56:37.000000000 +0200
 @@ -6,7 +6,11 @@
  		oprofilefs.o oprofile_stats.o  \
  		timer_int.o )
@@ -19247,10 +20635,10 @@
  					   op_model_ppro.o op_model_p4.o
  oprofile-$(CONFIG_X86_IO_APIC)		+= nmi_timer_int.o
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/oprofile/xenoprof.c linux-2.6.17-xen/arch/i386/oprofile/xenoprof.c
---- linux-2.6.17/arch/i386/oprofile/xenoprof.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/oprofile/xenoprof.c	2006-08-14 15:57:21.000000000 +0200
-@@ -0,0 +1,542 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/oprofile/xenoprof.c linux-2.6.18-rc5-xen/arch/i386/oprofile/xenoprof.c
+--- linux-2.6.18-rc5/arch/i386/oprofile/xenoprof.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/oprofile/xenoprof.c	2006-07-31 23:43:28.000000000 +0200
+@@ -0,0 +1,555 @@
 +/**
 + * @file xenoprof.c
 + *
@@ -19282,6 +20670,7 @@
 +#include <xen/interface/xen.h>
 +#include <xen/interface/xenoprof.h>
 +#include <../../../drivers/oprofile/cpu_buffer.h>
++#include <../../../drivers/oprofile/event_buffer.h>
 +
 +static int xenoprof_start(void);
 +static void xenoprof_stop(void);
@@ -19404,16 +20793,27 @@
 +static void xenoprof_handle_passive(void)
 +{
 +	int i, j;
-+
-+	for (i = 0; i < pdomains; i++)
++	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;
-+                        oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_START, passive_domains[i].domain_id);
++			if (!flag_domain) {
++				if (!oprofile_add_domain_switch(passive_domains[i].
++								domain_id))
++					goto done;
++				flag_domain = 1;
++			}
 +			xenoprof_add_pc(buf, 1);
-+                        oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_STOP, passive_domains[i].domain_id);
-+		}			
++			flag_switch = 1;
++		}
++	}
++done:
++	if (flag_switch)
++		oprofile_add_domain_switch(COORDINATOR_DOMAIN);
 +}
 +
 +static irqreturn_t 
@@ -19430,6 +20830,7 @@
 +
 +	if (is_primary && !test_and_set_bit(0, &flag)) {
 +		xenoprof_handle_passive();
++		smp_mb__before_clear_bit();
 +		clear_bit(0, &flag);
 +	}
 +
@@ -19441,7 +20842,7 @@
 +{
 +	int i;
 +
-+	for_each_cpu(i) {
++	for_each_possible_cpu(i) {
 +		if (ovf_irq[i] >= 0) {
 +			unbind_from_irqhandler(ovf_irq[i], NULL);
 +			ovf_irq[i] = -1;
@@ -19454,7 +20855,7 @@
 +{
 +	int i, result;
 +
-+	for_each_cpu(i) {
++	for_each_possible_cpu(i) {
 +		result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
 +						 i,
 +						 xenoprof_ovf_interrupt,
@@ -19793,17 +21194,16 @@
 +        }
 +
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/pci/irq-xen.c linux-2.6.17-xen/arch/i386/pci/irq-xen.c
---- linux-2.6.17/arch/i386/pci/irq-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/pci/irq-xen.c	2006-08-14 15:57:21.000000000 +0200
-@@ -0,0 +1,1204 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/pci/irq-xen.c linux-2.6.18-rc5-xen/arch/i386/pci/irq-xen.c
+--- linux-2.6.18-rc5/arch/i386/pci/irq-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/pci/irq-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,1206 @@
 +/*
 + *	Low-Level PCI Support for PC -- Routing of Interrupts
 + *
 + *	(c) 1999--2000 Martin Mares <mj at ucw.cz>
 + */
 +
-+#include <linux/config.h>
 +#include <linux/types.h>
 +#include <linux/kernel.h>
 +#include <linux/pci.h>
@@ -19894,7 +21294,10 @@
 +	u8 *addr;
 +	struct irq_routing_table *rt;
 +
-+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
++#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)
@@ -19906,7 +21309,6 @@
 +		if (rt)
 +			return rt;
 +	}
-+#endif
 +	
 +	return NULL;
 +}
@@ -20000,14 +21402,14 @@
 + */
 +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 };
++	static const 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 };
++	static const 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) {
@@ -20058,13 +21460,13 @@
 + */
 +static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 +{
-+	static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
++	static const 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 };
++	static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
 +	write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
 +	return 1;
 +}
@@ -20076,13 +21478,13 @@
 + */
 +static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 +{
-+	static unsigned char pirqmap[4] = { 1, 0, 2, 3 };
++	static const 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 };
++	static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
 +	write_config_nybble(router, 0x43, pirqmap[pirq-1], irq);
 +	return 1;
 +}
@@ -20307,7 +21709,7 @@
 +
 +static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
 +{
-+	static struct pci_device_id pirq_440gx[] = {
++	static struct pci_device_id __initdata 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) },
 +		{ },
@@ -20667,7 +22069,7 @@
 +		for (i = 0; i < 16; i++) {
 +			if (!(mask & (1 << i)))
 +				continue;
-+			if (pirq_penalty[i] < pirq_penalty[newirq] && can_request_irq(i, SA_SHIRQ))
++			if (pirq_penalty[i] < pirq_penalty[newirq] && can_request_irq(i, IRQF_SHARED))
 +				newirq = i;
 +		}
 +	}
@@ -20682,6 +22084,7 @@
 +	((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) {
 +		DBG(" -> got IRQ %d\n", irq);
 +		msg = "Found";
++		eisa_set_level_irq(irq);
 +	} 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)) {
@@ -21001,9 +22404,9 @@
 +
 +	return count;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/pci/Makefile linux-2.6.17-xen/arch/i386/pci/Makefile
---- linux-2.6.17/arch/i386/pci/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/pci/Makefile	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/pci/Makefile linux-2.6.18-rc5-xen/arch/i386/pci/Makefile
+--- linux-2.6.18-rc5/arch/i386/pci/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/pci/Makefile	2006-07-20 15:56:37.000000000 +0200
 @@ -4,6 +4,10 @@
  obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig.o direct.o
  obj-$(CONFIG_PCI_DIRECT)	+= direct.o
@@ -21024,9 +22427,9 @@
 +include $(srctree)/scripts/Makefile.xen
 +obj-y := $(call cherrypickxen, $(obj-y))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/pci/pcifront.c linux-2.6.17-xen/arch/i386/pci/pcifront.c
---- linux-2.6.17/arch/i386/pci/pcifront.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/i386/pci/pcifront.c	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/pci/pcifront.c linux-2.6.18-rc5-xen/arch/i386/pci/pcifront.c
+--- linux-2.6.18-rc5/arch/i386/pci/pcifront.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/i386/pci/pcifront.c	2006-07-20 15:56:37.000000000 +0200
 @@ -0,0 +1,55 @@
 +/*
 + * PCI Frontend Stub - puts some "dummy" functions in to the Linux x86 PCI core
@@ -21083,28 +22486,70 @@
 +}
 +
 +arch_initcall(pcifront_x86_stub_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/i386/power/Makefile linux-2.6.17-xen/arch/i386/power/Makefile
---- linux-2.6.17/arch/i386/power/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/i386/power/Makefile	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/i386/power/Makefile linux-2.6.18-rc5-xen/arch/i386/power/Makefile
+--- linux-2.6.18-rc5/arch/i386/power/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/i386/power/Makefile	2006-07-20 15:56:37.000000000 +0200
 @@ -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 -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/hp/sim/Makefile linux-2.6.17-xen/arch/ia64/hp/sim/Makefile
---- linux-2.6.17/arch/ia64/hp/sim/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/hp/sim/Makefile	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/dig/setup.c linux-2.6.18-rc5-xen/arch/ia64/dig/setup.c
+--- linux-2.6.18-rc5/arch/ia64/dig/setup.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/dig/setup.c	2006-09-01 00:09:09.000000000 +0200
+@@ -67,4 +67,38 @@
+ 	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);
++		screen_info.orig_video_mode = info->txt_mode;
++		screen_info.orig_video_isVGA = info->video_type;
++		screen_info.orig_video_lines = info->video_height;
++		screen_info.orig_video_cols = info->video_width;
++		screen_info.orig_video_points = info->txt_points;
++		screen_info.lfb_width = info->video_width;
++		screen_info.lfb_height = info->video_height;
++		screen_info.lfb_depth = info->lfb_depth;
++		screen_info.lfb_base = info->lfb_base;
++		screen_info.lfb_size = info->lfb_size;
++		screen_info.lfb_linelength = info->lfb_linelen;
++		screen_info.red_size = info->red_size;
++		screen_info.red_pos = info->red_pos;
++		screen_info.green_size = info->green_size;
++		screen_info.green_pos = info->green_pos;
++		screen_info.blue_size = info->blue_size;
++		screen_info.blue_pos = info->blue_pos;
++		screen_info.rsvd_size = info->rsvd_size;
++		screen_info.rsvd_pos = info->rsvd_pos;
++	}
++	screen_info.orig_y = screen_info.orig_video_lines - 1;
++	xen_start_info->console.domU.mfn = 0;
++	xen_start_info->console.domU.evtchn = 0;
++#endif
+ }
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/hp/sim/Makefile linux-2.6.18-rc5-xen/arch/ia64/hp/sim/Makefile
+--- linux-2.6.18-rc5/arch/ia64/hp/sim/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/hp/sim/Makefile	2006-07-20 15:56:37.000000000 +0200
 @@ -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 -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/Kconfig linux-2.6.17-xen/arch/ia64/Kconfig
---- linux-2.6.17/arch/ia64/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/Kconfig	2006-08-14 15:57:21.000000000 +0200
-@@ -58,6 +58,27 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/Kconfig linux-2.6.18-rc5-xen/arch/ia64/Kconfig
+--- linux-2.6.18-rc5/arch/ia64/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/Kconfig	2006-08-14 15:07:20.000000000 +0200
+@@ -58,6 +58,20 @@
  	bool
  	default y
  
@@ -21115,24 +22560,39 @@
 +	  Enable Xen hypervisor support.  Resulting kernel runs
 +	  both as a guest OS on Xen and natively on hardware.
 +
-+config XEN_IA64_DOM0_VP
-+	bool "dom0 vp model"
-+	depends on XEN
-+	default n
-+	help
-+	  dom0 vp model
-+
-+config XEN_IA64_DOM0_NON_VP
++config XEN_IA64_VDSO_PARAVIRT
 +	bool
-+	depends on XEN && !XEN_IA64_DOM0_VP
++	depends on XEN && !ITANIUM
 +	default y
 +	help
-+	  dom0 P=M model
++	  vDSO paravirtualization
 +
  config SCHED_NO_NO_OMIT_FRAME_POINTER
  	bool
  	default y
-@@ -506,3 +527,40 @@
+@@ -461,6 +475,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/pcie/Kconfig"
+ 
+ source "drivers/pci/Kconfig"
+@@ -524,3 +553,40 @@
  source "security/Kconfig"
  
  source "crypto/Kconfig"
@@ -21142,41 +22602,74 @@
 +#
 +if XEN
 +config XEN_UTIL
-+	default n if XEN_IA64_DOM0_VP
++	default n
 +
 +config HAVE_ARCH_ALLOC_SKB
-+	default n if !XEN_IA64_DOM0_VP
++	default y
 +
 +config HAVE_ARCH_DEV_ALLOC_SKB
-+	default n if !XEN_IA64_DOM0_VP
++	default y
 +
 +config XEN_BALLOON
-+	default n if !XEN_IA64_DOM0_VP
++	default y
 +
 +config XEN_SKBUFF
-+	default n if !XEN_IA64_DOM0_VP
++	default y
 +
 +config XEN_NETDEV_BACKEND
-+	default n if !XEN_IA64_DOM0_VP
++	default y
 +
 +config XEN_NETDEV_FRONTEND
-+	default n if !XEN_IA64_DOM0_VP
++	default y
 +
 +config XEN_DEVMEM
 +	default n
 +
 +config XEN_REBOOT
-+	default n
++	default y
 +
 +config XEN_SMPBOOT
 +	default n
 +endif
 +
 +source "drivers/xen/Kconfig"
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/entry.S linux-2.6.17-xen/arch/ia64/kernel/entry.S
---- linux-2.6.17/arch/ia64/kernel/entry.S	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/entry.S	2006-08-14 15:57:21.000000000 +0200
-@@ -181,7 +181,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/asm-offsets.c linux-2.6.18-rc5-xen/arch/ia64/kernel/asm-offsets.c
+--- linux-2.6.18-rc5/arch/ia64/kernel/asm-offsets.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/asm-offsets.c	2006-07-20 15:56:37.000000000 +0200
+@@ -268,4 +268,29 @@
+ 	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_PEND_OFS, pending_interruption);
++	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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/entry.S linux-2.6.18-rc5-xen/arch/ia64/kernel/entry.S
+--- linux-2.6.18-rc5/arch/ia64/kernel/entry.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/entry.S	2006-07-20 15:56:37.000000000 +0200
+@@ -180,7 +180,7 @@
   *	called.  The code starting at .map relies on this.  The rest of the code
   *	doesn't care about the interrupt masking status.
   */
@@ -21185,7 +22678,7 @@
  	.prologue
  	alloc r16=ar.pfs,1,0,0,0
  	DO_SAVE_SWITCH_STACK
-@@ -235,7 +235,7 @@
+@@ -234,7 +234,7 @@
  	;;
  	srlz.d
  	br.cond.sptk .done
@@ -21194,7 +22687,7 @@
  
  /*
   * Note that interrupts are enabled during save_switch_stack and load_switch_stack.  This
-@@ -376,7 +376,7 @@
+@@ -375,7 +375,7 @@
   *	- b7 holds address to return to
   *	- must not touch r8-r11
   */
@@ -21203,7 +22696,7 @@
  	.prologue
  	.altrp b7
  
-@@ -511,7 +511,7 @@
+@@ -510,7 +510,7 @@
  	 * because some system calls (such as ia64_execve) directly
  	 * manipulate ar.pfs.
  	 */
@@ -21212,7 +22705,7 @@
  	PT_REGS_UNWIND_INFO(0)
  	/*
  	 * We need to preserve the scratch registers f6-f11 in case the system
-@@ -583,7 +583,7 @@
+@@ -582,7 +582,7 @@
  (p6)	mov r10=-1
  (p6)	mov r8=r9
  	br.cond.sptk .strace_save_retval
@@ -21221,7 +22714,7 @@
  
  	/*
  	 * When traced and returning from sigreturn, we invoke syscall_trace but then
-@@ -636,8 +636,11 @@
+@@ -635,8 +635,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
@@ -21234,7 +22727,7 @@
  /*
   * 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 @@
+@@ -681,7 +684,7 @@
   *	      ar.csd: cleared
   *	      ar.ssd: cleared
   */
@@ -21243,7 +22736,7 @@
  	PT_REGS_UNWIND_INFO(0)
  	/*
  	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
-@@ -790,7 +793,7 @@
+@@ -789,7 +792,7 @@
  	mov.m ar.ssd=r0			// M2   clear ar.ssd
  	mov f11=f0			// F    clear f11
  	br.cond.sptk.many rbs_switch	// B
@@ -21252,7 +22745,7 @@
  
  #ifdef CONFIG_IA32_SUPPORT
  GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
-@@ -802,10 +805,13 @@
+@@ -801,10 +804,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
@@ -21268,7 +22761,7 @@
  	PT_REGS_UNWIND_INFO(0)
  	/*
  	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
-@@ -1136,7 +1142,7 @@
+@@ -1135,7 +1141,7 @@
  	ld8 r10=[r3]
  	br.cond.sptk.many .work_processed_syscall	// re-check
  
@@ -21277,7 +22770,7 @@
  
  ENTRY(handle_syscall_error)
  	/*
-@@ -1176,7 +1182,7 @@
+@@ -1175,7 +1181,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.
  	 */
@@ -21286,7 +22779,7 @@
  	.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
-@@ -1264,7 +1270,7 @@
+@@ -1263,7 +1269,7 @@
  	adds sp=16,sp
  	;;
  	ld8 r9=[sp]				// load new ar.unat
@@ -21295,490 +22788,214 @@
  	;;
  	mov ar.unat=r9
  	br.many b7
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/gate.lds.S linux-2.6.17-xen/arch/ia64/kernel/gate.lds.S
---- linux-2.6.17/arch/ia64/kernel/gate.lds.S	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/gate.lds.S	1970-01-01 01:00:00.000000000 +0100
-@@ -1,96 +0,0 @@
--/*
-- * Linker script for gate DSO.  The gate pages are an ELF shared object prelinked to its
-- * virtual address, with only one read-only segment and one execute-only segment (both fit
-- * in one page).  This script controls its layout.
-- */
--
--#include <linux/config.h>
--
--#include <asm/system.h>
--
--SECTIONS
--{
--  . = GATE_ADDR + SIZEOF_HEADERS;
--
--  .hash				: { *(.hash) }				:readable
--  .dynsym			: { *(.dynsym) }
--  .dynstr			: { *(.dynstr) }
--  .gnu.version			: { *(.gnu.version) }
--  .gnu.version_d		: { *(.gnu.version_d) }
--  .gnu.version_r		: { *(.gnu.version_r) }
--  .dynamic			: { *(.dynamic) }			:readable :dynamic
--
--  /*
--   * This linker script is used both with -r and with -shared.  For the layouts to match,
--   * we need to skip more than enough space for the dynamic symbol table et al.  If this
--   * amount is insufficient, ld -shared will barf.  Just increase it here.
--   */
--  . = GATE_ADDR + 0x500;
--
--  .data.patch			: {
--				    __start_gate_mckinley_e9_patchlist = .;
--				    *(.data.patch.mckinley_e9)
--				    __end_gate_mckinley_e9_patchlist = .;
--
--				    __start_gate_vtop_patchlist = .;
--				    *(.data.patch.vtop)
--				    __end_gate_vtop_patchlist = .;
--
--				    __start_gate_fsyscall_patchlist = .;
--				    *(.data.patch.fsyscall_table)
--				    __end_gate_fsyscall_patchlist = .;
--
--				    __start_gate_brl_fsys_bubble_down_patchlist = .;
--				    *(.data.patch.brl_fsys_bubble_down)
--				    __end_gate_brl_fsys_bubble_down_patchlist = .;
--  }									:readable
--  .IA_64.unwind_info		: { *(.IA_64.unwind_info*) }
--  .IA_64.unwind			: { *(.IA_64.unwind*) }			:readable :unwind
--#ifdef HAVE_BUGGY_SEGREL
--  .text (GATE_ADDR + PAGE_SIZE)	: { *(.text) *(.text.*) }		:readable
--#else
--  . = ALIGN (PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1));
--  .text				: { *(.text) *(.text.*) }		:epc
--#endif
--
--  /DISCARD/			: {
--  	*(.got.plt) *(.got)
--	*(.data .data.* .gnu.linkonce.d.*)
--	*(.dynbss)
--	*(.bss .bss.* .gnu.linkonce.b.*)
--	*(__ex_table)
--	*(__mca_table)
--  }
--}
--
--/*
-- * We must supply the ELF program headers explicitly to get just one
-- * PT_LOAD segment, and set the flags explicitly to make segments read-only.
-- */
--PHDRS
--{
--  readable  PT_LOAD	FILEHDR	PHDRS	FLAGS(4);	/* PF_R */
--#ifndef HAVE_BUGGY_SEGREL
--  epc	    PT_LOAD	FILEHDR PHDRS	FLAGS(1);	/* PF_X */
--#endif
--  dynamic   PT_DYNAMIC			FLAGS(4);	/* PF_R */
--  unwind    0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */
--}
--
--/*
-- * This controls what symbols we export from the DSO.
-- */
--VERSION
--{
--  LINUX_2.5 {
--    global:
--	__kernel_syscall_via_break;
--	__kernel_syscall_via_epc;
--	__kernel_sigtramp;
--
--    local: *;
--  };
--}
--
--/* The ELF entry point can be used to set the AT_SYSINFO value.  */
--ENTRY(__kernel_syscall_via_epc)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/gate.S linux-2.6.17-xen/arch/ia64/kernel/gate.S
---- linux-2.6.17/arch/ia64/kernel/gate.S	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/gate.S	1970-01-01 01:00:00.000000000 +0100
-@@ -1,376 +0,0 @@
--/*
-- * This file contains the code that gets mapped at the upper end of each task's text
-- * region.  For now, it contains the signal trampoline code only.
-- *
-- * Copyright (C) 1999-2003 Hewlett-Packard Co
-- * 	David Mosberger-Tang <davidm at hpl.hp.com>
-- */
--
--#include <linux/config.h>
--
--#include <asm/asmmacro.h>
--#include <asm/errno.h>
--#include <asm/asm-offsets.h>
--#include <asm/sigcontext.h>
--#include <asm/system.h>
--#include <asm/unistd.h>
--
--/*
-- * We can't easily refer to symbols inside the kernel.  To avoid full runtime relocation,
-- * complications with the linker (which likes to create PLT stubs for branches
-- * to targets outside the shared object) and to avoid multi-phase kernel builds, we
-- * simply create minimalistic "patch lists" in special ELF sections.
-- */
--	.section ".data.patch.fsyscall_table", "a"
--	.previous
--#define LOAD_FSYSCALL_TABLE(reg)			\
--[1:]	movl reg=0;					\
--	.xdata4 ".data.patch.fsyscall_table", 1b-.
--
--	.section ".data.patch.brl_fsys_bubble_down", "a"
--	.previous
--#define BRL_COND_FSYS_BUBBLE_DOWN(pr)			\
--[1:](pr)brl.cond.sptk 0;				\
--	.xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
--
--GLOBAL_ENTRY(__kernel_syscall_via_break)
--	.prologue
--	.altrp b6
--	.body
--	/*
--	 * Note: for (fast) syscall restart to work, the break instruction must be
--	 *	 the first one in the bundle addressed by syscall_via_break.
--	 */
--{ .mib
--	break 0x100000
--	nop.i 0
--	br.ret.sptk.many b6
--}
--END(__kernel_syscall_via_break)
--
--/*
-- * On entry:
-- *	r11 = saved ar.pfs
-- *	r15 = system call #
-- *	b0  = saved return address
-- *	b6  = return address
-- * On exit:
-- *	r11 = saved ar.pfs
-- *	r15 = system call #
-- *	b0  = saved return address
-- *	all other "scratch" registers:	undefined
-- *	all "preserved" registers:	same as on entry
-- */
--
--GLOBAL_ENTRY(__kernel_syscall_via_epc)
--	.prologue
--	.altrp b6
--	.body
--{
--	/*
--	 * Note: the kernel cannot assume that the first two instructions in this
--	 * bundle get executed.  The remaining code must be safe even if
--	 * they do not get executed.
--	 */
--	adds r17=-1024,r15			// A
--	mov r10=0				// A    default to successful syscall execution
--	epc					// B	causes split-issue
--}
--	;;
--	rsm psr.be | psr.i			// M2 (5 cyc to srlz.d)
--	LOAD_FSYSCALL_TABLE(r14)		// X
--	;;
--	mov r16=IA64_KR(CURRENT)		// M2 (12 cyc)
--	shladd r18=r17,3,r14			// A
--	mov r19=NR_syscalls-1			// A
--	;;
--	lfetch [r18]				// M0|1
--	mov r29=psr				// M2 (12 cyc)
--	// If r17 is a NaT, p6 will be zero
--	cmp.geu p6,p7=r19,r17			// A    (sysnr > 0 && sysnr < 1024+NR_syscalls)?
--	;;
--	mov r21=ar.fpsr				// M2 (12 cyc)
--	tnat.nz p10,p9=r15			// I0
--	mov.i r26=ar.pfs			// I0 (would stall anyhow due to srlz.d...)
--	;;
--	srlz.d					// M0 (forces split-issue) ensure PSR.BE==0
--(p6)	ld8 r18=[r18]				// M0|1
--	nop.i 0
--	;;
--	nop.m 0
--(p6)	tbit.z.unc p8,p0=r18,0			// I0 (dual-issues with "mov b7=r18"!)
--	nop.i 0
--	;;
--(p8)	ssm psr.i
--(p6)	mov b7=r18				// I0
--(p8)	br.dptk.many b7				// B
--
--	mov r27=ar.rsc				// M2 (12 cyc)
--/*
-- * brl.cond doesn't work as intended because the linker would convert this branch
-- * into a branch to a PLT.  Perhaps there will be a way to avoid this with some
-- * future version of the linker.  In the meantime, we just use an indirect branch
-- * instead.
-- */
--#ifdef CONFIG_ITANIUM
--(p6)	add r14=-8,r14				// r14 <- addr of fsys_bubble_down entry
--	;;
--(p6)	ld8 r14=[r14]				// r14 <- fsys_bubble_down
--	;;
--(p6)	mov b7=r14
--(p6)	br.sptk.many b7
--#else
--	BRL_COND_FSYS_BUBBLE_DOWN(p6)
--#endif
--	ssm psr.i
--	mov r10=-1
--(p10)	mov r8=EINVAL
--(p9)	mov r8=ENOSYS
--	FSYS_RETURN
--END(__kernel_syscall_via_epc)
--
--#	define ARG0_OFF		(16 + IA64_SIGFRAME_ARG0_OFFSET)
--#	define ARG1_OFF		(16 + IA64_SIGFRAME_ARG1_OFFSET)
--#	define ARG2_OFF		(16 + IA64_SIGFRAME_ARG2_OFFSET)
--#	define SIGHANDLER_OFF	(16 + IA64_SIGFRAME_HANDLER_OFFSET)
--#	define SIGCONTEXT_OFF	(16 + IA64_SIGFRAME_SIGCONTEXT_OFFSET)
--
--#	define FLAGS_OFF	IA64_SIGCONTEXT_FLAGS_OFFSET
--#	define CFM_OFF		IA64_SIGCONTEXT_CFM_OFFSET
--#	define FR6_OFF		IA64_SIGCONTEXT_FR6_OFFSET
--#	define BSP_OFF		IA64_SIGCONTEXT_AR_BSP_OFFSET
--#	define RNAT_OFF		IA64_SIGCONTEXT_AR_RNAT_OFFSET
--#	define UNAT_OFF		IA64_SIGCONTEXT_AR_UNAT_OFFSET
--#	define FPSR_OFF		IA64_SIGCONTEXT_AR_FPSR_OFFSET
--#	define PR_OFF		IA64_SIGCONTEXT_PR_OFFSET
--#	define RP_OFF		IA64_SIGCONTEXT_IP_OFFSET
--#	define SP_OFF		IA64_SIGCONTEXT_R12_OFFSET
--#	define RBS_BASE_OFF	IA64_SIGCONTEXT_RBS_BASE_OFFSET
--#	define LOADRS_OFF	IA64_SIGCONTEXT_LOADRS_OFFSET
--#	define base0		r2
--#	define base1		r3
--	/*
--	 * When we get here, the memory stack looks like this:
--	 *
--	 *   +===============================+
--       	 *   |				     |
--       	 *   //	    struct sigframe          //
--       	 *   |				     |
--	 *   +-------------------------------+ <-- sp+16
--	 *   |      16 byte of scratch       |
--	 *   |            space              |
--	 *   +-------------------------------+ <-- sp
--	 *
--	 * The register stack looks _exactly_ the way it looked at the time the signal
--	 * occurred.  In other words, we're treading on a potential mine-field: each
--	 * incoming general register may be a NaT value (including sp, in which case the
--	 * process ends up dying with a SIGSEGV).
--	 *
--	 * The first thing need to do is a cover to get the registers onto the backing
--	 * store.  Once that is done, we invoke the signal handler which may modify some
--	 * of the machine state.  After returning from the signal handler, we return
--	 * control to the previous context by executing a sigreturn system call.  A signal
--	 * handler may call the rt_sigreturn() function to directly return to a given
--	 * sigcontext.  However, the user-level sigreturn() needs to do much more than
--	 * calling the rt_sigreturn() system call as it needs to unwind the stack to
--	 * restore preserved registers that may have been saved on the signal handler's
--	 * call stack.
--	 */
--
--#define SIGTRAMP_SAVES										\
--	.unwabi 3, 's';		/* mark this as a sigtramp handler (saves scratch regs) */	\
--	.unwabi @svr4, 's'; /* backwards compatibility with old unwinders (remove in v2.7) */	\
--	.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF;						\
--	.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF;						\
--	.savesp pr, PR_OFF+SIGCONTEXT_OFF;     							\
--	.savesp rp, RP_OFF+SIGCONTEXT_OFF;							\
--	.savesp ar.pfs, CFM_OFF+SIGCONTEXT_OFF;							\
--	.vframesp SP_OFF+SIGCONTEXT_OFF
--
--GLOBAL_ENTRY(__kernel_sigtramp)
--	// describe the state that is active when we get here:
--	.prologue
--	SIGTRAMP_SAVES
--	.body
--
--	.label_state 1
--
--	adds base0=SIGHANDLER_OFF,sp
--	adds base1=RBS_BASE_OFF+SIGCONTEXT_OFF,sp
--	br.call.sptk.many rp=1f
--1:
--	ld8 r17=[base0],(ARG0_OFF-SIGHANDLER_OFF)	// get pointer to signal handler's plabel
--	ld8 r15=[base1]					// get address of new RBS base (or NULL)
--	cover				// push args in interrupted frame onto backing store
--	;;
--	cmp.ne p1,p0=r15,r0		// do we need to switch rbs? (note: pr is saved by kernel)
--	mov.m r9=ar.bsp			// fetch ar.bsp
--	.spillsp.p p1, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
--(p1)	br.cond.spnt setup_rbs		// yup -> (clobbers p8, r14-r16, and r18-r20)
--back_from_setup_rbs:
--	alloc r8=ar.pfs,0,0,3,0
--	ld8 out0=[base0],16		// load arg0 (signum)
--	adds base1=(ARG1_OFF-(RBS_BASE_OFF+SIGCONTEXT_OFF)),base1
--	;;
--	ld8 out1=[base1]		// load arg1 (siginfop)
--	ld8 r10=[r17],8			// get signal handler entry point
--	;;
--	ld8 out2=[base0]		// load arg2 (sigcontextp)
--	ld8 gp=[r17]			// get signal handler's global pointer
--	adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
--	;;
--	.spillsp ar.bsp, BSP_OFF+SIGCONTEXT_OFF
--	st8 [base0]=r9			// save sc_ar_bsp
--	adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
--	adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
--	;;
--	stf.spill [base0]=f6,32
--	stf.spill [base1]=f7,32
--	;;
--	stf.spill [base0]=f8,32
--	stf.spill [base1]=f9,32
--	mov b6=r10
--	;;
--	stf.spill [base0]=f10,32
--	stf.spill [base1]=f11,32
--	;;
--	stf.spill [base0]=f12,32
--	stf.spill [base1]=f13,32
--	;;
--	stf.spill [base0]=f14,32
--	stf.spill [base1]=f15,32
--	br.call.sptk.many rp=b6			// call the signal handler
--.ret0:	adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
--	;;
--	ld8 r15=[base0]				// fetch sc_ar_bsp
--	mov r14=ar.bsp
--	;;
--	cmp.ne p1,p0=r14,r15			// do we need to restore the rbs?
--(p1)	br.cond.spnt restore_rbs		// yup -> (clobbers r14-r18, f6 & f7)
--	;;
--back_from_restore_rbs:
--	adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
--	adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
--	;;
--	ldf.fill f6=[base0],32
--	ldf.fill f7=[base1],32
--	;;
--	ldf.fill f8=[base0],32
--	ldf.fill f9=[base1],32
--	;;
--	ldf.fill f10=[base0],32
--	ldf.fill f11=[base1],32
--	;;
--	ldf.fill f12=[base0],32
--	ldf.fill f13=[base1],32
--	;;
--	ldf.fill f14=[base0],32
--	ldf.fill f15=[base1],32
--	mov r15=__NR_rt_sigreturn
--	.restore sp				// pop .prologue
--	break __BREAK_SYSCALL
--
--	.prologue
--	SIGTRAMP_SAVES
--setup_rbs:
--	mov ar.rsc=0				// put RSE into enforced lazy mode
--	;;
--	.save ar.rnat, r19
--	mov r19=ar.rnat				// save RNaT before switching backing store area
--	adds r14=(RNAT_OFF+SIGCONTEXT_OFF),sp
--
--	mov r18=ar.bspstore
--	mov ar.bspstore=r15			// switch over to new register backing store area
--	;;
--
--	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
--	st8 [r14]=r19				// save sc_ar_rnat
--	.body
--	mov.m r16=ar.bsp			// sc_loadrs <- (new bsp - new bspstore) << 16
--	adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp
--	;;
--	invala
--	sub r15=r16,r15
--	extr.u r20=r18,3,6
--	;;
--	mov ar.rsc=0xf				// set RSE into eager mode, pl 3
--	cmp.eq p8,p0=63,r20
--	shl r15=r15,16
--	;;
--	st8 [r14]=r15				// save sc_loadrs
--(p8)	st8 [r18]=r19		// if bspstore points at RNaT slot, store RNaT there now
--	.restore sp				// pop .prologue
--	br.cond.sptk back_from_setup_rbs
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/gate.lds.S linux-2.6.18-rc5-xen/arch/ia64/kernel/gate.lds.S
+--- linux-2.6.18-rc5/arch/ia64/kernel/gate.lds.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/gate.lds.S	2006-09-01 00:09:09.000000000 +0200
+@@ -43,6 +43,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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/gate.S linux-2.6.18-rc5-xen/arch/ia64/kernel/gate.S
+--- linux-2.6.18-rc5/arch/ia64/kernel/gate.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/gate.S	2006-08-14 15:07:20.000000000 +0200
+@@ -6,13 +6,15 @@
+  * 	David Mosberger-Tang <davidm at hpl.hp.com>
+  */
+ 
 -
--	.prologue
--	SIGTRAMP_SAVES
--	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
--	.body
--restore_rbs:
--	// On input:
--	//	r14 = bsp1 (bsp at the time of return from signal handler)
--	//	r15 = bsp0 (bsp at the time the signal occurred)
--	//
--	// Here, we need to calculate bspstore0, the value that ar.bspstore needs
--	// to be set to, based on bsp0 and the size of the dirty partition on
--	// the alternate stack (sc_loadrs >> 16).  This can be done with the
--	// following algorithm:
--	//
--	//  bspstore0 = rse_skip_regs(bsp0, -rse_num_regs(bsp1 - (loadrs >> 19), bsp1));
--	//
--	// This is what the code below does.
--	//
--	alloc r2=ar.pfs,0,0,0,0			// alloc null frame
--	adds r16=(LOADRS_OFF+SIGCONTEXT_OFF),sp
--	adds r18=(RNAT_OFF+SIGCONTEXT_OFF),sp
--	;;
--	ld8 r17=[r16]
--	ld8 r16=[r18]			// get new rnat
--	extr.u r18=r15,3,6	// r18 <- rse_slot_num(bsp0)
--	;;
--	mov ar.rsc=r17			// put RSE into enforced lazy mode
--	shr.u r17=r17,16
--	;;
--	sub r14=r14,r17		// r14 (bspstore1) <- bsp1 - (sc_loadrs >> 16)
--	shr.u r17=r17,3		// r17 <- (sc_loadrs >> 19)
--	;;
--	loadrs			// restore dirty partition
--	extr.u r14=r14,3,6	// r14 <- rse_slot_num(bspstore1)
--	;;
--	add r14=r14,r17		// r14 <- rse_slot_num(bspstore1) + (sc_loadrs >> 19)
--	;;
--	shr.u r14=r14,6		// r14 <- (rse_slot_num(bspstore1) + (sc_loadrs >> 19))/0x40
--	;;
--	sub r14=r14,r17		// r14 <- -rse_num_regs(bspstore1, bsp1)
--	movl r17=0x8208208208208209
--	;;
--	add r18=r18,r14		// r18 (delta) <- rse_slot_num(bsp0) - rse_num_regs(bspstore1,bsp1)
--	setf.sig f7=r17
--	cmp.lt p7,p0=r14,r0	// p7 <- (r14 < 0)?
--	;;
--(p7)	adds r18=-62,r18	// delta -= 62
--	;;
--	setf.sig f6=r18
--	;;
--	xmpy.h f6=f6,f7
--	;;
--	getf.sig r17=f6
--	;;
--	add r17=r17,r18
--	shr r18=r18,63
--	;;
--	shr r17=r17,5
--	;;
--	sub r17=r17,r18		// r17 = delta/63
--	;;
--	add r17=r14,r17		// r17 <- delta/63 - rse_num_regs(bspstore1, bsp1)
--	;;
--	shladd r15=r17,3,r15	// r15 <- bsp0 + 8*(delta/63 - rse_num_regs(bspstore1, bsp1))
--	;;
--	mov ar.bspstore=r15			// switch back to old register backing store area
--	;;
--	mov ar.rnat=r16				// restore RNaT
--	mov ar.rsc=0xf				// (will be restored later on from sc_ar_rsc)
--	// invala not necessary as that will happen when returning to user-mode
--	br.cond.sptk back_from_restore_rbs
--END(__kernel_sigtramp)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/head.S linux-2.6.17-xen/arch/ia64/kernel/head.S
---- linux-2.6.17/arch/ia64/kernel/head.S	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/head.S	2006-08-14 15:57:21.000000000 +0200
-@@ -363,6 +363,12 @@
+ #include <asm/asmmacro.h>
+ #include <asm/errno.h>
+ #include <asm/asm-offsets.h>
+ #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,
+@@ -32,6 +34,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
+@@ -76,7 +124,39 @@
+ 	epc					// B	causes split-issue
+ }
+ 	;;
++#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
++	// r20 = 1
++	// r22 = &vcpu->evtchn_mask
++	// r23 = &vpsr.ic
++	// r24 = &vcpu->pending_interruption
++	// 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
++	movl r23=XSI_PSR_IC
++	movl r24=XSI_PSR_I_ADDR+(XSI_PEND_OFS-XSI_PSR_I_ADDR_OFS)
++	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)
+@@ -84,7 +164,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)?
+ 	;;
+@@ -98,9 +185,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
+ 
+@@ -121,9 +220,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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/head.S linux-2.6.18-rc5-xen/arch/ia64/kernel/head.S
+--- linux-2.6.18-rc5/arch/ia64/kernel/head.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/head.S	2006-09-01 00:09:09.000000000 +0200
+@@ -362,6 +362,12 @@
  	;;
  (isBP)	st8 [r2]=r28		// save the address of the boot param area passed by the bootloader
  
@@ -21791,10 +23008,10 @@
  #ifdef CONFIG_SMP
  (isAP)	br.call.sptk.many rp=start_secondary
  .ret0:
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/iosapic.c linux-2.6.17-xen/arch/ia64/kernel/iosapic.c
---- linux-2.6.17/arch/ia64/kernel/iosapic.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/iosapic.c	2006-08-14 15:57:21.000000000 +0200
-@@ -160,6 +160,65 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/iosapic.c linux-2.6.18-rc5-xen/arch/ia64/kernel/iosapic.c
+--- linux-2.6.18-rc5/arch/ia64/kernel/iosapic.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/iosapic.c	2006-07-20 15:56:37.000000000 +0200
+@@ -159,6 +159,65 @@
  static int iosapic_kmalloc_ok;
  static LIST_HEAD(free_rte_list);
  
@@ -21860,7 +23077,7 @@
  /*
   * Find an IOSAPIC associated with a GSI
   */
-@@ -654,6 +713,9 @@
+@@ -653,6 +712,9 @@
  	iosapic_intr_info[vector].dmode    = delivery;
  	iosapic_intr_info[vector].trigger  = trigger;
  
@@ -21870,7 +23087,7 @@
  	if (trigger == IOSAPIC_EDGE)
  		irq_type = &irq_type_iosapic_edge;
  	else
-@@ -1016,6 +1078,9 @@
+@@ -1015,6 +1077,9 @@
  	}
  
  	pcat_compat = system_pcat_compat;
@@ -21880,10 +23097,20 @@
  	if (pcat_compat) {
  		/*
  		 * Disable the compatibility mode interrupts (8259 style),
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/irq_ia64.c linux-2.6.17-xen/arch/ia64/kernel/irq_ia64.c
---- linux-2.6.17/arch/ia64/kernel/irq_ia64.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/irq_ia64.c	2006-08-14 15:57:21.000000000 +0200
-@@ -66,6 +66,13 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/irq_ia64.c linux-2.6.18-rc5-xen/arch/ia64/kernel/irq_ia64.c
+--- linux-2.6.18-rc5/arch/ia64/kernel/irq_ia64.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/irq_ia64.c	2006-08-14 15:07:20.000000000 +0200
+@@ -30,6 +30,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>
+@@ -69,6 +72,13 @@
  assign_irq_vector (int irq)
  {
  	int pos, vector;
@@ -21897,7 +23124,7 @@
   again:
  	pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
  	vector = IA64_FIRST_DEVICE_VECTOR + pos;
-@@ -224,6 +231,157 @@
+@@ -240,14 +250,215 @@
  };
  #endif
  
@@ -21905,6 +23132,9 @@
 +#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 char timer_name[NR_CPUS][15];
 +static char ipi_name[NR_CPUS][15];
 +static char resched_name[NR_CPUS][15];
@@ -21922,6 +23152,7 @@
 +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.
@@ -21938,6 +23169,7 @@
 +	.flags =	SA_INTERRUPT,
 +	.name =		"RESCHED"
 +};
++#endif
 +
 +/*
 + * This is xen version percpu irq registration, which needs bind
@@ -21964,6 +23196,7 @@
 +			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:
@@ -21971,6 +23204,7 @@
 +			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:
@@ -21978,6 +23212,7 @@
 +			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:
@@ -22013,7 +23248,7 @@
 +	 */
 +	for (i = 0; i < late_irq_cnt; i++)
 +		xen_register_percpu_irq(saved_percpu_irqs[i].irq,
-+			saved_percpu_irqs[i].action, 0);
++		                        saved_percpu_irqs[i].action, 0);
 +}
 +
 +/* FIXME: There's no obvious point to check whether slab is ready. So
@@ -22023,6 +23258,38 @@
 +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(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)
 +{
@@ -22033,21 +23300,22 @@
 +		.type = CALLBACKTYPE_event,
 +		.address = (unsigned long)&xen_event_callback,
 +	};
-+	static cpumask_t registered_cpumask;
 +
-+	if (!cpu)
++	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));
 +
-+	if (!cpu_isset(cpu, registered_cpumask)) {
-+		cpu_set(cpu, registered_cpumask);
-+		for (i = 0; i < saved_irq_cnt; i++)
-+			xen_register_percpu_irq(saved_percpu_irqs[i].irq,
-+						saved_percpu_irqs[i].action,
-+						0);
-+	}
++	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 */
@@ -22055,18 +23323,24 @@
  void
  register_percpu_irq (ia64_vector vec, struct irqaction *action)
  {
-@@ -232,6 +390,10 @@
+ 	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) {
 +#ifdef CONFIG_XEN
 +			if (is_running_on_xen())
 +				return xen_register_percpu_irq(vec, action, 1);
 +#endif
- 			desc = irq_descp(irq);
+ 			desc = irq_desc + irq;
  			desc->status |= IRQ_PER_CPU;
- 			desc->handler = &irq_type_ia64_lsapic;
-@@ -243,6 +405,21 @@
+ 			desc->chip = &irq_type_ia64_lsapic;
+@@ -259,6 +470,21 @@
  void __init
  init_IRQ (void)
  {
@@ -22088,7 +23362,7 @@
  	register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
  #ifdef CONFIG_SMP
  	register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
-@@ -260,6 +437,37 @@
+@@ -276,6 +502,39 @@
  	unsigned long ipi_data;
  	unsigned long phys_cpu_id;
  
@@ -22096,6 +23370,7 @@
 +        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);
@@ -22103,6 +23378,7 @@
 +			//vcpu_prepare_and_up(cpu);
 +			return;
 +		}
++#endif
 +
 +		switch(vector) {
 +		case IA64_IPI_VECTOR:
@@ -22126,9 +23402,9 @@
  #ifdef CONFIG_SMP
  	phys_cpu_id = cpu_physical_id(cpu);
  #else
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/pal.S linux-2.6.17-xen/arch/ia64/kernel/pal.S
---- linux-2.6.17/arch/ia64/kernel/pal.S	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/pal.S	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/pal.S linux-2.6.18-rc5-xen/arch/ia64/kernel/pal.S
+--- linux-2.6.18-rc5/arch/ia64/kernel/pal.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/pal.S	2006-09-01 00:09:09.000000000 +0200
 @@ -16,6 +16,7 @@
  #include <asm/processor.h>
  
@@ -22155,211 +23431,98 @@
  
  /*
   * Make a PAL call using the stacked registers calling convention.
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/patch.c linux-2.6.17-xen/arch/ia64/kernel/patch.c
---- linux-2.6.17/arch/ia64/kernel/patch.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/patch.c	1970-01-01 01:00:00.000000000 +0100
-@@ -1,197 +0,0 @@
--/*
-- * Instruction-patching support.
-- *
-- * Copyright (C) 2003 Hewlett-Packard Co
-- *	David Mosberger-Tang <davidm at hpl.hp.com>
-- */
--#include <linux/init.h>
--#include <linux/string.h>
--
--#include <asm/patch.h>
--#include <asm/processor.h>
--#include <asm/sections.h>
--#include <asm/system.h>
--#include <asm/unistd.h>
--
--/*
-- * This was adapted from code written by Tony Luck:
-- *
-- * The 64-bit value in a "movl reg=value" is scattered between the two words of the bundle
-- * like this:
-- *
-- * 6  6         5         4         3         2         1
-- * 3210987654321098765432109876543210987654321098765432109876543210
-- * ABBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCDEEEEEFFFFFFFFFGGGGGGG
-- *
-- * CCCCCCCCCCCCCCCCCCxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-- * xxxxAFFFFFFFFFEEEEEDxGGGGGGGxxxxxxxxxxxxxBBBBBBBBBBBBBBBBBBBBBBB
-- */
--static u64
--get_imm64 (u64 insn_addr)
--{
--	u64 *p = (u64 *) (insn_addr & -16);	/* mask out slot number */
--
--	return ( (p[1] & 0x0800000000000000UL) << 4)  | /*A*/
--		((p[1] & 0x00000000007fffffUL) << 40) | /*B*/
--		((p[0] & 0xffffc00000000000UL) >> 24) | /*C*/
--		((p[1] & 0x0000100000000000UL) >> 23) | /*D*/
--		((p[1] & 0x0003e00000000000UL) >> 29) | /*E*/
--		((p[1] & 0x07fc000000000000UL) >> 43) | /*F*/
--		((p[1] & 0x000007f000000000UL) >> 36);  /*G*/
--}
--
--/* Patch instruction with "val" where "mask" has 1 bits. */
--void
--ia64_patch (u64 insn_addr, u64 mask, u64 val)
--{
--	u64 m0, m1, v0, v1, b0, b1, *b = (u64 *) (insn_addr & -16);
--#	define insn_mask ((1UL << 41) - 1)
--	unsigned long shift;
--
--	b0 = b[0]; b1 = b[1];
--	shift = 5 + 41 * (insn_addr % 16); /* 5 bits of template, then 3 x 41-bit instructions */
--	if (shift >= 64) {
--		m1 = mask << (shift - 64);
--		v1 = val << (shift - 64);
--	} else {
--		m0 = mask << shift; m1 = mask >> (64 - shift);
--		v0 = val  << shift; v1 = val >> (64 - shift);
--		b[0] = (b0 & ~m0) | (v0 & m0);
--	}
--	b[1] = (b1 & ~m1) | (v1 & m1);
--}
--
--void
--ia64_patch_imm64 (u64 insn_addr, u64 val)
--{
--	/* The assembler may generate offset pointing to either slot 1
--	   or slot 2 for a long (2-slot) instruction, occupying slots 1
--	   and 2.  */
--  	insn_addr &= -16UL;
--	ia64_patch(insn_addr + 2,
--		   0x01fffefe000UL, (  ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
--				     | ((val & 0x0000000000200000UL) <<  0) /* bit 21 -> 21 */
--				     | ((val & 0x00000000001f0000UL) <<  6) /* bit 16 -> 22 */
--				     | ((val & 0x000000000000ff80UL) << 20) /* bit  7 -> 27 */
--				     | ((val & 0x000000000000007fUL) << 13) /* bit  0 -> 13 */));
--	ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
--}
--
--void
--ia64_patch_imm60 (u64 insn_addr, u64 val)
--{
--	/* The assembler may generate offset pointing to either slot 1
--	   or slot 2 for a long (2-slot) instruction, occupying slots 1
--	   and 2.  */
--  	insn_addr &= -16UL;
--	ia64_patch(insn_addr + 2,
--		   0x011ffffe000UL, (  ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
--				     | ((val & 0x00000000000fffffUL) << 13) /* bit  0 -> 13 */));
--	ia64_patch(insn_addr + 1, 0x1fffffffffcUL, val >> 18);
--}
--
--/*
-- * We need sometimes to load the physical address of a kernel
-- * object.  Often we can convert the virtual address to physical
-- * at execution time, but sometimes (either for performance reasons
-- * or during error recovery) we cannot to this.  Patch the marked
-- * bundles to load the physical address.
-- */
--void __init
--ia64_patch_vtop (unsigned long start, unsigned long end)
--{
--	s32 *offp = (s32 *) start;
--	u64 ip;
--
--	while (offp < (s32 *) end) {
--		ip = (u64) offp + *offp;
--
--		/* replace virtual address with corresponding physical address: */
--		ia64_patch_imm64(ip, ia64_tpa(get_imm64(ip)));
--		ia64_fc((void *) ip);
--		++offp;
--	}
--	ia64_sync_i();
--	ia64_srlz_i();
--}
--
--void __init
--ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
--{
--	static int first_time = 1;
--	int need_workaround;
--	s32 *offp = (s32 *) start;
--	u64 *wp;
--
--	need_workaround = (local_cpu_data->family == 0x1f && local_cpu_data->model == 0);
--
--	if (first_time) {
--		first_time = 0;
--		if (need_workaround)
--			printk(KERN_INFO "Leaving McKinley Errata 9 workaround enabled\n");
--		else
--			printk(KERN_INFO "McKinley Errata 9 workaround not needed; "
--			       "disabling it\n");
--	}
--	if (need_workaround)
--		return;
--
--	while (offp < (s32 *) end) {
--		wp = (u64 *) ia64_imva((char *) offp + *offp);
--		wp[0] = 0x0000000100000000UL; /* nop.m 0; nop.i 0; nop.i 0 */
--		wp[1] = 0x0004000000000200UL;
--		wp[2] = 0x0000000100000011UL; /* nop.m 0; nop.i 0; br.ret.sptk.many b6 */
--		wp[3] = 0x0084006880000200UL;
--		ia64_fc(wp); ia64_fc(wp + 2);
--		++offp;
--	}
--	ia64_sync_i();
--	ia64_srlz_i();
--}
--
--static void __init
--patch_fsyscall_table (unsigned long start, unsigned long end)
--{
--	extern unsigned long fsyscall_table[NR_syscalls];
--	s32 *offp = (s32 *) start;
--	u64 ip;
--
--	while (offp < (s32 *) end) {
--		ip = (u64) ia64_imva((char *) offp + *offp);
--		ia64_patch_imm64(ip, (u64) fsyscall_table);
--		ia64_fc((void *) ip);
--		++offp;
--	}
--	ia64_sync_i();
--	ia64_srlz_i();
--}
--
--static void __init
--patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
--{
--	extern char fsys_bubble_down[];
--	s32 *offp = (s32 *) start;
--	u64 ip;
--
--	while (offp < (s32 *) end) {
--		ip = (u64) offp + *offp;
--		ia64_patch_imm60((u64) ia64_imva((void *) ip),
--				 (u64) (fsys_bubble_down - (ip & -16)) / 16);
--		ia64_fc((void *) ip);
--		++offp;
--	}
--	ia64_sync_i();
--	ia64_srlz_i();
--}
--
--void __init
--ia64_patch_gate (void)
--{
--#	define START(name)	((unsigned long) __start_gate_##name##_patchlist)
--#	define END(name)	((unsigned long)__end_gate_##name##_patchlist)
--
--	patch_fsyscall_table(START(fsyscall), END(fsyscall));
--	patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
--	ia64_patch_vtop(START(vtop), END(vtop));
--	ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
--}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/kernel/setup.c linux-2.6.17-xen/arch/ia64/kernel/setup.c
---- linux-2.6.17/arch/ia64/kernel/setup.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/kernel/setup.c	2006-08-14 15:57:21.000000000 +0200
-@@ -61,6 +61,10 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/patch.c linux-2.6.18-rc5-xen/arch/ia64/kernel/patch.c
+--- linux-2.6.18-rc5/arch/ia64/kernel/patch.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/patch.c	2006-08-06 23:45:52.000000000 +0200
+@@ -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 __init
++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 __init
++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 __init
++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 __init
+ 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/kernel/setup.c linux-2.6.18-rc5-xen/arch/ia64/kernel/setup.c
+--- linux-2.6.18-rc5/arch/ia64/kernel/setup.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/kernel/setup.c	2006-09-01 00:09:09.000000000 +0200
+@@ -60,6 +60,10 @@
  #include <asm/system.h>
  #include <asm/unistd.h>
  #include <asm/system.h>
@@ -22370,7 +23533,102 @@
  
  #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
  # error "struct cpuinfo_ia64 too big!"
-@@ -243,6 +247,14 @@
+@@ -70,6 +74,22 @@
+ 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 = {
++	.notifier_call	= xen_panic_event,
++	.next		= NULL,
++	.priority	= 0	/* try to go last */
++};
++#endif
++
+ extern void ia64_setup_printk_clock(void);
+ 
+ DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
+@@ -176,15 +196,33 @@
+ 	return 0;
+ }
+ 
++static int __init
++rsvd_region_cmp(struct rsvd_region *lhs, struct rsvd_region *rhs)
++{
++	if (lhs->start > rhs->start)
++		return 1;
++	if (lhs->start < rhs->start)
++		return -1;
++
++	if (lhs->end > rhs->end)
++		return 1;
++	if (lhs->end < rhs->end)
++		return -1;
++
++	return 0;
++}
++
+ static void __init
+ sort_regions (struct rsvd_region *rsvd_region, int max)
+ {
++	int num = max;
+ 	int j;
+ 
+ 	/* simple bubble sorting */
+ 	while (max--) {
+ 		for (j = 0; j < max; ++j) {
+-			if (rsvd_region[j].start > rsvd_region[j+1].start) {
++			if (rsvd_region_cmp(&rsvd_region[j],
++					    &rsvd_region[j + 1]) > 0) {
+ 				struct rsvd_region tmp;
+ 				tmp = rsvd_region[j];
+ 				rsvd_region[j] = rsvd_region[j + 1];
+@@ -192,6 +230,36 @@
+ 			}
+ 		}
+ 	}
++
++	for (j = 0; j < num - 1; j++) {
++		int k;
++		unsigned long start = rsvd_region[j].start;
++		unsigned long end = rsvd_region[j].end;
++		int collapsed;
++		
++		for (k = j + 1; k < num; k++) {
++			BUG_ON(start > rsvd_region[k].start);
++			if (end < rsvd_region[k].start) {
++				k--;
++				break;
++			}
++			end = max(end, rsvd_region[k].end);
++		}
++		if (k == num)
++			k--;
++		rsvd_region[j].end = end;
++		collapsed = k - j;
++		num -= collapsed;
++		for (k = j + 1; k < num; k++) {
++			rsvd_region[k] = rsvd_region[k + collapsed];
++		}
++	}
++
++	num_rsvd_regions = num;
++	for (j = 0; j < num; j++) {
++		printk("rsvd_region[%d]: [0x%016lx, 0x%06lx)\n",
++		       j, rsvd_region[j].start, rsvd_region[j].end);
++	}
+ }
+ 
+ /*
+@@ -242,6 +310,14 @@
  	rsvd_region[n].end   = (unsigned long) ia64_imva(_end);
  	n++;
  
@@ -22385,15 +23643,7 @@
  #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 +272,7 @@
- 	n++;
- 
- 	num_rsvd_regions = n;
-+	BUG_ON(IA64_MAX_RSVD_REGIONS + 1 < n);
- 
- 	sort_regions(rsvd_region, num_rsvd_regions);
- }
-@@ -333,6 +346,16 @@
+@@ -333,6 +409,16 @@
  {
  	int earlycons = 0;
  
@@ -22410,19 +23660,22 @@
  #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
  	{
  		extern int sn_serial_console_early_setup(void);
-@@ -402,6 +425,11 @@
+@@ -402,6 +488,14 @@
  {
  	unw_init();
  
 +#ifdef CONFIG_XEN
-+	if (is_running_on_xen())
++	if (is_running_on_xen()) {
 +		setup_xen_features();
++		/* Register a call for panic conditions. */
++		atomic_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);
-@@ -478,6 +506,29 @@
+@@ -478,6 +572,23 @@
  			conswitchp = &vga_con;
  # endif
  	}
@@ -22431,18 +23684,12 @@
 +		shared_info_t *s = HYPERVISOR_shared_info;
 +
 +		xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT);
-+		xen_start_info->flags = s->arch.flags;
 +
 +		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);
 +
-+		/* xen_start_info isn't setup yet, get the flags manually */
-+		if (s->arch.flags & SIF_INITDOMAIN) {
-+			if (!(s->arch.flags & SIF_PRIVILEGED))
-+				panic("Xen granted us console access "
-+				      "but not privileged status");
-+		} else {
++		if (!is_initial_xendomain()) {
 +			extern int console_use_vt;
 +			conswitchp = NULL;
 +			console_use_vt = 0;
@@ -22452,7 +23699,7 @@
  #endif
  
  	/* enable IA-64 Machine Check Abort Handling unless disabled */
-@@ -486,6 +537,7 @@
+@@ -486,6 +597,7 @@
  
  	platform_setup(cmdline_p);
  	paging_init();
@@ -22460,7 +23707,7 @@
  }
  
  /*
-@@ -870,6 +922,15 @@
+@@ -870,6 +982,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();
@@ -22476,9 +23723,9 @@
  	pm_idle = default_idle;
  }
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/Makefile linux-2.6.17-xen/arch/ia64/Makefile
---- linux-2.6.17/arch/ia64/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/Makefile	2006-08-14 15:57:21.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/Makefile linux-2.6.18-rc5-xen/arch/ia64/Makefile
+--- linux-2.6.18-rc5/arch/ia64/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/Makefile	2006-07-20 15:56:37.000000000 +0200
 @@ -45,6 +45,12 @@
  endif
  
@@ -22508,16 +23755,7 @@
  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/
-@@ -71,6 +83,8 @@
- 
- compressed: vmlinux.gz
- 
-+vmlinuz: vmlinux.gz
-+
- vmlinux.gz: vmlinux
- 	$(Q)$(MAKE) $(build)=$(boot) $@
- 
-@@ -85,8 +99,8 @@
+@@ -87,8 +99,8 @@
  boot:	lib/lib.a vmlinux
  	$(Q)$(MAKE) $(build)=$(boot) $@
  
@@ -22528,10 +23766,10 @@
  
  define archhelp
    echo '* compressed	- Build compressed kernel image'
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/mm/ioremap.c linux-2.6.17-xen/arch/ia64/mm/ioremap.c
---- linux-2.6.17/arch/ia64/mm/ioremap.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/ia64/mm/ioremap.c	2006-08-14 15:57:22.000000000 +0200
-@@ -15,6 +15,9 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/mm/ioremap.c linux-2.6.18-rc5-xen/arch/ia64/mm/ioremap.c
+--- linux-2.6.18-rc5/arch/ia64/mm/ioremap.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/ia64/mm/ioremap.c	2006-09-01 00:09:09.000000000 +0200
+@@ -16,6 +16,9 @@
  static inline void __iomem *
  __ioremap (unsigned long offset, unsigned long size)
  {
@@ -22541,23 +23779,22 @@
  	return (void __iomem *) (__IA64_UNCACHED_OFFSET | offset);
  }
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/drivers/README linux-2.6.17-xen/arch/ia64/xen/drivers/README
---- linux-2.6.17/arch/ia64/xen/drivers/README	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/drivers/README	2006-08-14 15:57:22.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/drivers/README linux-2.6.18-rc5-xen/arch/ia64/xen/drivers/README
+--- linux-2.6.18-rc5/arch/ia64/xen/drivers/README	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/drivers/README	2006-07-20 15:56:37.000000000 +0200
 @@ -0,0 +1,2 @@
 +This is a temporary location for source/Makefiles that need to be
 +patched/reworked in drivers/xen to work with xenlinux/ia64.
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/hypercall.S linux-2.6.17-xen/arch/ia64/xen/hypercall.S
---- linux-2.6.17/arch/ia64/xen/hypercall.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/hypercall.S	2006-08-14 15:57:22.000000000 +0200
-@@ -0,0 +1,353 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/hypercall.S linux-2.6.18-rc5-xen/arch/ia64/xen/hypercall.S
+--- linux-2.6.18-rc5/arch/ia64/xen/hypercall.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/hypercall.S	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,413 @@
 +/*
 + * Support routines for Xen hypercalls
 + *
 + * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer at hp.com>
 + */
 +
-+#include <linux/config.h>
 +#include <asm/processor.h>
 +#include <asm/asmmacro.h>
 +
@@ -22904,10 +24141,71 @@
 +        br.ret.sptk.many rp
 +        ;;
 +END(xen_send_ipi)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/hypervisor.c linux-2.6.17-xen/arch/ia64/xen/hypervisor.c
---- linux-2.6.17/arch/ia64/xen/hypervisor.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/hypervisor.c	2006-08-14 15:57:22.000000000 +0200
-@@ -0,0 +1,784 @@
++
++#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)
++	ld8 r22=[r22]
++	;; 
++	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->evtchn_mask
++	// r23 = &vpsr.ic
++	// r24 = &vcpu->pending_interruption
++	// r25 = tmp
++	// r31 = tmp
++	// p11 = tmp
++	// p14 = tmp
++#define XEN_SET_PSR_I			\
++	ld4 r31=[r22];			\
++	ld4 r25=[r24];			\
++	;;				\
++	st4 [r22]=r0;			\
++	cmp.ne.unc p14,p0=r0,r31;	\
++	;;				\
++(p14)	cmp.ne.unc p11,p0=r0,r25;	\
++	;;				\
++(p11)	st4 [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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/hypervisor.c linux-2.6.18-rc5-xen/arch/ia64/xen/hypervisor.c
+--- linux-2.6.18-rc5/arch/ia64/xen/hypervisor.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/hypervisor.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,810 @@
 +/******************************************************************************
 + * include/asm-ia64/shadow.h
 + *
@@ -22945,6 +24243,7 @@
 +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);
@@ -22991,7 +24290,7 @@
 +			//    of a non-privileged domain, 
 +			if ((op == XENMEM_increase_reservation ||
 +			     op == XENMEM_populate_physmap) &&
-+			    !(xen_start_info->flags & SIF_PRIVILEGED) &&
++			    !is_initial_xendomain() &&
 +			    reservation.extent_order > 0)
 +				return ret;
 +		}
@@ -23001,6 +24300,7 @@
 +	}
 +	return ret;
 +}
++EXPORT_SYMBOL(ia64_xenmem_reservation_op);
 +
 +//XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
 +// move those to lib/contiguous_bitmap?
@@ -23071,43 +24371,13 @@
 +	}
 +}
 +
-+static unsigned long
-+HYPERVISOR_populate_physmap(unsigned long gpfn, unsigned int extent_order,
-+			    unsigned int address_bits)
-+{
-+	unsigned long ret;
-+        struct xen_memory_reservation reservation = {
-+		.nr_extents   = 1,
-+                .address_bits = address_bits,
-+                .extent_order = extent_order,
-+                .domid        = DOMID_SELF
-+        };
-+	set_xen_guest_handle(reservation.extent_start, &gpfn);
-+	ret = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
-+	// it may fail on non-privileged domain with extent_order > 0.
-+	BUG_ON(ret != 1 &&
-+	       !(ret == 0 && !(xen_start_info->flags & SIF_PRIVILEGED) &&
-+		 extent_order > 0));
-+	if (ret != 1)
-+		return -EINVAL;//XXX
-+	return 0;
-+}
++// __xen_create_contiguous_region(), __xen_destroy_contiguous_region()
++// are based on i386 xen_create_contiguous_region(),
++// xen_destroy_contiguous_region()
 +
-+static unsigned long
-+HYPERVISOR_remove_physmap(unsigned long gpfn, unsigned int extent_order)
-+{
-+	unsigned long ret;
-+	struct xen_memory_reservation reservation = {
-+		.nr_extents   = 1,
-+		.address_bits = 0,
-+		.extent_order = extent_order,
-+		.domid        = DOMID_SELF
-+	};
-+	set_xen_guest_handle(reservation.extent_start, &gpfn);
-+	ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
-+	BUG_ON(ret != 1);
-+	return 0;
-+}
++/* 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
@@ -23121,57 +24391,92 @@
 +	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);
 +
-+	error = HYPERVISOR_remove_physmap(start_gpfn, order);
-+	if (error) {
-+		goto fail;
++	/* Get a new contiguous memory extent. */
++	for (i = 0; i < num_gpfn; i++) {
++		in_frames[i] = start_gpfn + i;
 +	}
-+
-+	error = HYPERVISOR_populate_physmap(start_gpfn, order, address_bits);
-+	if (error) {
-+		goto fail;
++	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;
 +	}
-+	contiguous_bitmap_set(start_gpfn, num_gpfn);
++	if (success)
++		contiguous_bitmap_set(start_gpfn, num_gpfn);
 +#if 0
-+	{
-+	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);
++	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;
 +			}
-+			xprintk("\n");
-+			goto out;
++			mfn_prev = mfn;
 +		}
-+		mfn_prev = mfn;
-+	}
 +	}
 +#endif
-+out:
 +	balloon_unlock(flags);
-+	return error;
-+
-+fail:
-+	for (i = 0; i < num_gpfn; i++) {
-+		error = HYPERVISOR_populate_physmap(start_gpfn + i, 0, 0);
-+		if (error) {
-+			BUG();//XXX
-+		}
-+	}
-+	goto out;
++	return success? 0: -ENOMEM;
 +}
 +
 +void
@@ -23181,55 +24486,61 @@
 +	unsigned long error = 0;
 +	unsigned long start_gpfn = __pa(vstart) >> PAGE_SHIFT;
 +	unsigned long num_gpfn = 1UL << order;
-+	unsigned long* gpfns;
-+	struct xen_memory_reservation reservation;
 +	unsigned long i;
 +
-+	gpfns = kmalloc(sizeof(gpfns[0]) * num_gpfn,
-+			GFP_KERNEL | __GFP_NOFAIL);
-+	for (i = 0; i < num_gpfn; i++) {
-+		gpfns[i] = start_gpfn + 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);
-+	error = HYPERVISOR_remove_physmap(start_gpfn, order);
-+	if (error) {
-+		goto fail;
-+	}
-+
-+	set_xen_guest_handle(reservation.extent_start, gpfns);
-+	reservation.nr_extents   = num_gpfn;
-+	reservation.address_bits = 0;
-+	reservation.extent_order = 0;
-+	reservation.domid        = DOMID_SELF;
-+	error = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation);
-+	if (error != num_gpfn) {
-+		error = -EFAULT;//XXX
-+		goto fail;
-+	}
-+	error = 0;
-+out:
-+	balloon_unlock(flags);
-+	kfree(gpfns);
-+	if (error) {
-+		// error can't be returned.
-+		BUG();//XXX
-+	}
-+	return;
 +
-+fail:
++        /* Do the exchange for non-contiguous MFNs. */
++	in_frame = start_gpfn;
 +	for (i = 0; i < num_gpfn; i++) {
-+		int tmp_error;// don't overwrite error.
-+		tmp_error = HYPERVISOR_populate_physmap(start_gpfn + i, 0, 0);
-+		if (tmp_error) {
-+			BUG();//XXX
-+		}
++		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);
 +	}
-+	goto out;
++	balloon_unlock(flags);
 +}
 +
 +
@@ -23278,12 +24589,13 @@
 +
 +	return ____HYPERVISOR_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
@@ -23446,8 +24758,10 @@
 +	unsigned long gpfn;
 +	unsigned long flags;
 +
-+	BUG_ON((addr & ~PAGE_MASK) != 0);
-+	BUG_ON(mfn == INVALID_MFN);
++	if ((addr & ~PAGE_MASK) != 0 || mfn == INVALID_MFN) {
++		error = -EINVAL;
++		goto out;
++	}
 +
 +	if (entry->gpfn != INVALID_GPFN) {
 +		error = -EBUSY;
@@ -23692,22 +25006,32 @@
 +	return error;
 +}
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/Makefile linux-2.6.17-xen/arch/ia64/xen/Makefile
---- linux-2.6.17/arch/ia64/xen/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/Makefile	2006-08-14 15:57:22.000000000 +0200
++
++/* 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();
++}
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/Makefile linux-2.6.18-rc5-xen/arch/ia64/xen/Makefile
+--- linux-2.6.18-rc5/arch/ia64/xen/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/Makefile	2006-08-14 15:07:20.000000000 +0200
 @@ -0,0 +1,8 @@
 +#
 +# Makefile for Xen components
 +#
 +
-+obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o
++obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o \
++	 hypervisor.o pci-dma-xen.o util.o
 +
-+obj-$(CONFIG_XEN_IA64_DOM0_VP) += hypervisor.o pci-dma-xen.o util.o
-+pci-dma-xen-$(CONFIG_XEN_IA64_DOM0_VP) := ../../i386/kernel/pci-dma-xen.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/util.c linux-2.6.17-xen/arch/ia64/xen/util.c
---- linux-2.6.17/arch/ia64/xen/util.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/util.c	2006-08-14 15:57:22.000000000 +0200
-@@ -0,0 +1,130 @@
++pci-dma-xen-y := ../../i386/kernel/pci-dma-xen.o
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/util.c linux-2.6.18-rc5-xen/arch/ia64/xen/util.c
+--- linux-2.6.18-rc5/arch/ia64/xen/util.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/util.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,115 @@
 +/******************************************************************************
 + * arch/ia64/xen/util.c
 + * This file is the ia64 counterpart of drivers/xen/util.c
@@ -23731,7 +25055,6 @@
 + *
 + */
 +
-+#include <linux/config.h>
 +#include <linux/mm.h>
 +#include <linux/module.h>
 +#include <linux/slab.h>
@@ -23764,7 +25087,7 @@
 +        area->size = size;
 +        area->pages = NULL; //XXX
 +        area->nr_pages = nr_pages;
-+        area->phys_addr = __pa(virt);
++        area->phys_addr = 0; 	/* xenbus_map_ring_valloc uses this field!  */
 +
 +	return area;
 +
@@ -23780,12 +25103,13 @@
 +{
 +	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 = (area->phys_addr >> PAGE_SHIFT) + i;
++		unsigned long gpfn = (phys_addr >> PAGE_SHIFT) + i;
 +		struct xen_memory_reservation reservation = {
 +			.nr_extents   = 1,
 +			.address_bits = 0,
@@ -23814,21 +25138,6 @@
 +}
 +EXPORT_SYMBOL_GPL(unlock_vm_area);
 +
-+#ifndef CONFIG_XEN_IA64_DOM0_VP
-+/* We just need a range of legal va here, though finally identity
-+ * mapped one is instead used for gnttab mapping.
-+ */
-+unsigned long alloc_empty_foreign_map_page_range(unsigned long pages)
-+{
-+	struct vm_struct *vma;
-+
-+	if ( (vma = get_vm_area(PAGE_SIZE * pages, VM_ALLOC)) == NULL )
-+		return NULL;
-+
-+	return (unsigned long)vma->addr;
-+}
-+#endif
-+
 +/*
 + * Local variables:
 + *  c-file-style: "linux"
@@ -23838,10 +25147,10 @@
 + *  tab-width: 8
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/xenentry.S linux-2.6.17-xen/arch/ia64/xen/xenentry.S
---- linux-2.6.17/arch/ia64/xen/xenentry.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/xenentry.S	2006-08-14 15:57:22.000000000 +0200
-@@ -0,0 +1,883 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/xenentry.S linux-2.6.18-rc5-xen/arch/ia64/xen/xenentry.S
+--- linux-2.6.18-rc5/arch/ia64/xen/xenentry.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/xenentry.S	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,867 @@
 +/*
 + * ia64/xen/entry.S
 + *
@@ -23852,8 +25161,6 @@
 + *	Dan Magenheimer <dan.magenheimer at .hp.com>
 + */
 +
-+#include <linux/config.h>
-+
 +#include <asm/asmmacro.h>
 +#include <asm/cache.h>
 +#include <asm/errno.h>
@@ -24609,7 +25916,7 @@
 +#ifdef CONFIG_XEN
 +	movl r25=XSI_IPSR
 +	;;
-+	st8[r25]=r29,XSI_IFS-XSI_IPSR
++	st8[r25]=r29,XSI_IFS_OFS-XSI_IPSR_OFS
 +	;;
 +#else
 +	mov cr.ipsr=r29		// M2
@@ -24620,7 +25927,7 @@
 +#ifdef CONFIG_XEN
 +(p9)	st8 [r25]=r30
 +	;;
-+	adds r25=XSI_IIP-XSI_IFS,r25
++	adds r25=XSI_IIP_OFS-XSI_IFS_OFS,r25
 +	;;
 +#else
 +(p9)	mov cr.ifs=r30		// M2
@@ -24663,9 +25970,6 @@
 +	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
@@ -24701,17 +26005,6 @@
 +(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
@@ -24725,9 +26018,9 @@
 +#else
 +END(ia64_leave_kernel)
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/xenhpski.c linux-2.6.17-xen/arch/ia64/xen/xenhpski.c
---- linux-2.6.17/arch/ia64/xen/xenhpski.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/xenhpski.c	2006-08-14 15:57:22.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/xenhpski.c linux-2.6.18-rc5-xen/arch/ia64/xen/xenhpski.c
+--- linux-2.6.18-rc5/arch/ia64/xen/xenhpski.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/xenhpski.c	2006-07-20 15:56:37.000000000 +0200
 @@ -0,0 +1,19 @@
 +
 +extern unsigned long xen_get_cpuid(int);
@@ -24748,10 +26041,10 @@
 +	return 1;
 +}
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/xenivt.S linux-2.6.17-xen/arch/ia64/xen/xenivt.S
---- linux-2.6.17/arch/ia64/xen/xenivt.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/xenivt.S	2006-08-14 15:57:22.000000000 +0200
-@@ -0,0 +1,2171 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/xenivt.S linux-2.6.18-rc5-xen/arch/ia64/xen/xenivt.S
+--- linux-2.6.18-rc5/arch/ia64/xen/xenivt.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/xenivt.S	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,2169 @@
 +/*
 + * arch/ia64/xen/ivt.S
 + *
@@ -24783,8 +26076,6 @@
 + * Table is based upon EAS2.6 (Oct 1999)
 + */
 +
-+#include <linux/config.h>
-+
 +#include <asm/asmmacro.h>
 +#include <asm/break.h>
 +#include <asm/ia32.h>
@@ -25200,7 +26491,7 @@
 +#ifdef CONFIG_XEN
 +	movl r31=XSI_IPSR
 +	;;
-+	ld8 r21=[r31],XSI_IFA-XSI_IPSR	// get ipsr, point to ifa
++	ld8 r21=[r31],XSI_IFA_OFS-XSI_IPSR_OFS	// get ipsr, point to ifa
 +	movl r17=PAGE_KERNEL
 +	;;
 +	ld8 r16=[r31]		// get ifa
@@ -25262,10 +26553,10 @@
 +#ifdef CONFIG_XEN
 +	movl r31=XSI_IPSR
 +	;;
-+	ld8 r21=[r31],XSI_ISR-XSI_IPSR	// get ipsr, point to isr
++	ld8 r21=[r31],XSI_ISR_OFS-XSI_IPSR_OFS	// get ipsr, point to isr
 +	movl r17=PAGE_KERNEL
 +	;;
-+	ld8 r20=[r31],XSI_IFA-XSI_ISR	// get isr, point to ifa
++	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
@@ -25442,12 +26733,12 @@
 +#ifdef CONFIG_XEN
 +	movl r3=XSI_ISR
 +	;;
-+	ld8 out1=[r3],XSI_IFA-XSI_ISR		// get vcr.isr, point to ifa
++	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-XSI_IFA, r3		// point to vpsr.ic
++	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
@@ -25491,7 +26782,7 @@
 +	;;
 +(p15)	ld8 r3=[r3]
 +	;;
-+(p15)	st1 [r3]=r0,XSI_PEND-XSI_PSR_I_ADDR	// if (p15) vpsr.i = 1
++(p15)	st1 [r3]=r0,XSI_PEND_OFS-XSI_PSR_I_ADDR_OFS	// if (p15) vpsr.i = 1
 +	mov r14=r0
 +	;;
 +(p15)	ld4 r14=[r3]				// if (pending_interrupts)
@@ -25801,7 +27092,7 @@
 +#ifdef CONFIG_XEN
 +	movl r22=XSI_IPSR
 +	;;
-+	ld8 r29=[r22],XSI_IIM-XSI_IPSR		// get ipsr, point to iip
++	ld8 r29=[r22],XSI_IIM_OFS-XSI_IPSR_OFS	// get ipsr, point to iip
 +#else
 +	mov r29=cr.ipsr				// M2 (12 cyc)
 +#endif
@@ -25809,7 +27100,7 @@
 +
 +#ifdef CONFIG_XEN
 +	;;
-+	ld8 r17=[r22],XSI_IIP-XSI_IIM
++	ld8 r17=[r22],XSI_IIP_OFS-XSI_IIM_OFS
 +#else
 +	mov r17=cr.iim				// M2 (2 cyc)
 +#endif
@@ -25910,7 +27201,7 @@
 +	movl r16=XSI_PSR_IC
 +	mov r3=1
 +	;;
-+	st4 [r16]=r3,XSI_PSR_I_ADDR-XSI_PSR_IC	// vpsr.ic = 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
@@ -25924,7 +27215,7 @@
 +#ifdef CONFIG_XEN
 +(p15)	ld8 r16=[r16]				// vpsr.i
 +	;;
-+(p15)	st1 [r16]=r0,XSI_PEND-XSI_PSR_I_ADDR	// if (p15) vpsr.i = 1
++(p15)	st1 [r16]=r0,XSI_PEND_OFS-XSI_PSR_I_ADDR_OFS	// if (p15) vpsr.i = 1
 +	mov r2=r0
 +	;;
 +(p15)	ld4 r2=[r16]				// if (pending_interrupts)
@@ -26923,11 +28214,10 @@
 +	br.call.sptk.many b6=evtchn_do_upcall
 +END(xen_event_callback)
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/xenminstate.h linux-2.6.17-xen/arch/ia64/xen/xenminstate.h
---- linux-2.6.17/arch/ia64/xen/xenminstate.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/xenminstate.h	2006-08-14 15:57:22.000000000 +0200
-@@ -0,0 +1,369 @@
-+#include <linux/config.h>
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/xenminstate.h linux-2.6.18-rc5-xen/arch/ia64/xen/xenminstate.h
+--- linux-2.6.18-rc5/arch/ia64/xen/xenminstate.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/xenminstate.h	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,368 @@
 +
 +#include <asm/cache.h>
 +
@@ -27296,9 +28586,9 @@
 +#else
 +#define SAVE_MIN		DO_SAVE_MIN(     , mov r30=r0, )
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/xenpal.S linux-2.6.17-xen/arch/ia64/xen/xenpal.S
---- linux-2.6.17/arch/ia64/xen/xenpal.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/xenpal.S	2006-08-14 15:57:22.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/xenpal.S linux-2.6.18-rc5-xen/arch/ia64/xen/xenpal.S
+--- linux-2.6.18-rc5/arch/ia64/xen/xenpal.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/xenpal.S	2006-07-20 15:56:37.000000000 +0200
 @@ -0,0 +1,76 @@
 +/*
 + * ia64/xen/xenpal.S
@@ -27347,7 +28637,7 @@
 +	;;
 +(p6)	st4 [r31]=r0
 +	;;
-+(p7)	adds r31=XSI_PSR_I_ADDR-XSI_PSR_IC,r31
++(p7)	adds r31=XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS,r31
 +(p7)	mov r22=1
 +	;;
 +(p7)	ld8 r31=[r31]
@@ -27376,17 +28666,16 @@
 +	srlz.d				// seralize restoration of psr.l
 +	br.ret.sptk.many b0
 +END(xen_pal_call_static)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/ia64/xen/xensetup.S linux-2.6.17-xen/arch/ia64/xen/xensetup.S
---- linux-2.6.17/arch/ia64/xen/xensetup.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/ia64/xen/xensetup.S	2006-08-14 15:57:22.000000000 +0200
-@@ -0,0 +1,24 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/ia64/xen/xensetup.S linux-2.6.18-rc5-xen/arch/ia64/xen/xensetup.S
+--- linux-2.6.18-rc5/arch/ia64/xen/xensetup.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/ia64/xen/xensetup.S	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,54 @@
 +/*
 + * Support routines for Xen
 + *
 + * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer at hp.com>
 + */
 +
-+#include <linux/config.h>
 +#include <asm/processor.h>
 +#include <asm/asmmacro.h>
 +
@@ -27397,16 +28686,47 @@
 +	mov r8=ar.rsc		// Initialized in head.S
 +(isBP)	movl r9=running_on_xen;;
 +	extr.u r8=r8,2,2;;	// Extract pl fields
-+	cmp.ne p7,p0=r8,r0;;	// p7: running on xen 
-+(p7)	mov r8=1		// booleanize.
-+(p7)	movl r10=xen_ivt;;
++	cmp.eq p7,p0=r8,r0	// p7: !running on xen
++	mov r8=1		// booleanize.
++(p7)	br.ret.sptk.many rp;;
 +(isBP)	st4 [r9]=r8
-+(p7)	mov cr.iva=r10
-+	br.ret.sptk.many rp;;
++	movl r10=xen_ivt;;
++	
++	mov cr.iva=r10
++
++#if XSI_BASE != 0xf100000000000000UL
++	/* Backward compatibility.  */
++(isBP)	mov r2=0x600
++(isBP)	movl r28=XSI_BASE;;
++(isBP)	break 0x1000;;
++#endif
++
++	br.ret.sptk.many rp
++	;;
 +END(early_xen_setup)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/um/kernel/physmem.c linux-2.6.17-xen/arch/um/kernel/physmem.c
---- linux-2.6.17/arch/um/kernel/physmem.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/um/kernel/physmem.c	2006-08-14 15:57:35.000000000 +0200
++
++#include <xen/interface/xen.h>
++
++/* Stub for suspend.
++   Just force the stacked registers to be written in memory.  */	
++GLOBAL_ENTRY(HYPERVISOR_suspend)
++	alloc r20=ar.pfs,0,0,0,0
++	mov r14=2
++	mov r15=r12
++	;;
++	/* We don't want to deal with RSE.  */
++	flushrs
++	mov r2=__HYPERVISOR_sched_op
++	st4 [r12]=r14
++	;;
++	break 0x1000
++	;; 
++	mov ar.pfs=r20
++	br.ret.sptk.many b0
++END(HYPERVISOR_suspend)
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/um/kernel/physmem.c linux-2.6.18-rc5-xen/arch/um/kernel/physmem.c
+--- linux-2.6.18-rc5/arch/um/kernel/physmem.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/um/kernel/physmem.c	2006-07-20 15:56:47.000000000 +0200
 @@ -226,7 +226,7 @@
  EXPORT_SYMBOL(physmem_remove_mapping);
  EXPORT_SYMBOL(physmem_subst_mapping);
@@ -27425,10 +28745,10 @@
  }
  
  int is_remapped(void *virt)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/ia32/ia32entry-xen.S linux-2.6.17-xen/arch/x86_64/ia32/ia32entry-xen.S
---- linux-2.6.17/arch/x86_64/ia32/ia32entry-xen.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/ia32/ia32entry-xen.S	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,726 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/ia32/ia32entry-xen.S linux-2.6.18-rc5-xen/arch/x86_64/ia32/ia32entry-xen.S
+--- linux-2.6.18-rc5/arch/x86_64/ia32/ia32entry-xen.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/ia32/ia32entry-xen.S	2006-08-06 23:45:52.000000000 +0200
+@@ -0,0 +1,743 @@
 +/*
 + * Compatibility mode system call entry point for x86-64. 
 + * 		
@@ -27444,6 +28764,7 @@
 +#include <asm/thread_info.h>	
 +#include <asm/segment.h>
 +#include <asm/vsyscall32.h>
++#include <asm/irqflags.h>
 +#include <linux/linkage.h>
 +
 +#define __XEN_X86_64 1
@@ -27523,6 +28844,10 @@
 +	__swapgs 
 +	movq	%gs:pda_kernelstack, %rsp
 +	addq	$(PDA_STACKOFFSET),%rsp
++	/*
++	 * No need to follow this irqs on/off section: the syscall
++	 * disabled irqs, here we enable it straight after entry:
++	 */
 +	XEN_UNBLOCK_EVENTS(%r11)	
 +	__sti
 + 	movl	%ebp,%ebp		/* zero extension */
@@ -27547,7 +28872,7 @@
 +	pushq	%rax
 +	CFI_ADJUST_CFA_OFFSET 8
 +	cld
-+	SAVE_ARGS 0,0,1
++	SAVE_ARGS 0,0,0
 + 	/* no need to do an access_ok check here because rbp has been
 + 	   32bit zero extended */ 
 +1:	movl	(%rbp),%r9d
@@ -27568,6 +28893,7 @@
 +	GET_THREAD_INFO(%r10)
 +	XEN_BLOCK_EVENTS(%r11)	
 +	__cli
++	TRACE_IRQS_OFF
 +	testl	$_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
 +	jnz	int_ret_from_sys_call
 +	andl    $~TS_COMPAT,threadinfo_status(%r10)
@@ -27582,6 +28908,7 @@
 +	CFI_REGISTER rsp,rcx
 +	movl	$VSYSCALL32_SYSEXIT,%edx	/* User %eip */
 +	CFI_REGISTER rip,rdx
++	TRACE_IRQS_ON
 +	__swapgs
 +	XEN_UNBLOCK_EVENTS(%r11)		
 +	__sti		/* sti only takes effect after the next instruction */
@@ -27606,6 +28933,7 @@
 +	.previous
 +	jmp	sysenter_do_call
 +	CFI_ENDPROC
++ENDPROC(ia32_sysenter_target)
 +
 +/*
 + * 32bit SYSCALL instruction entry.
@@ -27629,13 +28957,17 @@
 + */ 	
 +ENTRY(ia32_cstar_target)
 +	CFI_STARTPROC32	simple
-+	CFI_DEF_CFA	rsp,0
++	CFI_DEF_CFA	rsp,PDA_STACKOFFSET
 +	CFI_REGISTER	rip,rcx
 +	/*CFI_REGISTER	rflags,r11*/
 +	__swapgs
 +	movl	%esp,%r8d
 +	CFI_REGISTER	rsp,r8
 +	movq	%gs:pda_kernelstack,%rsp
++	/*
++	 * No need to follow this irqs on/off section: the syscall
++	 * disabled irqs and here we enable it straight after entry:
++	 */
 +	XEN_UNBLOCK_EVENTS(%r11)	
 +	__sti
 +	SAVE_ARGS 8,1,1
@@ -27672,6 +29004,7 @@
 +	GET_THREAD_INFO(%r10)
 +	XEN_BLOCK_EVENTS(%r11)		
 +	__cli
++	TRACE_IRQS_OFF
 +	testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
 +	jnz  int_ret_from_sys_call
 +	andl $~TS_COMPAT,threadinfo_status(%r10)
@@ -27680,6 +29013,7 @@
 +	CFI_REGISTER rip,rcx
 +	movl EFLAGS-ARGOFFSET(%rsp),%r11d	
 +	/*CFI_REGISTER rflags,r11*/
++	TRACE_IRQS_ON
 +	movl RSP-ARGOFFSET(%rsp),%esp
 +	CFI_RESTORE rsp
 +	__swapgs
@@ -27702,6 +29036,7 @@
 +	.quad 1b,ia32_badarg
 +	.previous
 +	jmp cstar_do_call
++END(ia32_cstar_target)
 +				
 +ia32_badarg:
 +	movq $-EFAULT,%rax
@@ -27738,6 +29073,10 @@
 +	/*CFI_REL_OFFSET	cs,CS-RIP*/
 +	CFI_REL_OFFSET	rip,RIP-RIP
 +	__swapgs
++	/*
++	 * No need to follow this irqs on/off section: the syscall
++	 * disabled irqs and here we enable it straight after entry:
++	 */
 +	XEN_UNBLOCK_EVENTS(%r11)
 +	__sti
 +	movq (%rsp),%rcx
@@ -27772,16 +29111,13 @@
 +	LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
 +	RESTORE_REST
 +	jmp ia32_do_syscall
++END(ia32_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
@@ -27828,10 +29164,10 @@
 +	RESTORE_REST
 +	jmp  ia32_sysret	/* misbalances the return cache */
 +	CFI_ENDPROC
++END(ia32_ptregs_common)
 +
 +	.section .rodata,"a"
 +	.align 8
-+	.globl ia32_sys_call_table
 +ia32_sys_call_table:
 +	.quad sys_restart_syscall
 +	.quad sys_exit
@@ -28154,11 +29490,12 @@
 +	.quad sys_sync_file_range
 +	.quad sys_tee
 +	.quad compat_sys_vmsplice
++	.quad compat_sys_move_pages
 +ia32_syscall_end:		
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/ia32/Makefile linux-2.6.17-xen/arch/x86_64/ia32/Makefile
---- linux-2.6.17/arch/x86_64/ia32/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/ia32/Makefile	2006-08-14 15:57:36.000000000 +0200
-@@ -23,9 +23,25 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/ia32/Makefile linux-2.6.18-rc5-xen/arch/x86_64/ia32/Makefile
+--- linux-2.6.18-rc5/arch/x86_64/ia32/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/ia32/Makefile	2006-09-01 00:09:09.000000000 +0200
+@@ -27,9 +27,25 @@
  			   -Wl,-soname=linux-gate.so.1 -o $@ \
  			   -Wl,-T,$(filter-out FORCE,$^)
  
@@ -28186,9 +29523,9 @@
 +
 +obj-y := $(call cherrypickxen, $(obj-y))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/ia32/syscall32_syscall-xen.S linux-2.6.17-xen/arch/x86_64/ia32/syscall32_syscall-xen.S
---- linux-2.6.17/arch/x86_64/ia32/syscall32_syscall-xen.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/ia32/syscall32_syscall-xen.S	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/ia32/syscall32_syscall-xen.S linux-2.6.18-rc5-xen/arch/x86_64/ia32/syscall32_syscall-xen.S
+--- linux-2.6.18-rc5/arch/x86_64/ia32/syscall32_syscall-xen.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/ia32/syscall32_syscall-xen.S	2006-07-20 15:56:48.000000000 +0200
 @@ -0,0 +1,28 @@
 +/* 32bit VDSOs mapped into user space. */
 +
@@ -28218,9 +29555,9 @@
 +syscall32_sysenter:
 +	.incbin "arch/x86_64/ia32/vsyscall-sysenter.so"
 +syscall32_sysenter_end:
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/ia32/syscall32-xen.c linux-2.6.17-xen/arch/x86_64/ia32/syscall32-xen.c
---- linux-2.6.17/arch/x86_64/ia32/syscall32-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/ia32/syscall32-xen.c	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/ia32/syscall32-xen.c linux-2.6.18-rc5-xen/arch/x86_64/ia32/syscall32-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/ia32/syscall32-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/ia32/syscall32-xen.c	2006-07-20 15:56:48.000000000 +0200
 @@ -0,0 +1,128 @@
 +/* Copyright 2002,2003 Andi Kleen, SuSE Labs */
 +
@@ -28350,9 +29687,9 @@
 +	wrmsrl(MSR_CSTAR, ia32_cstar_target);
 +#endif
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/ia32/vsyscall-int80.S linux-2.6.17-xen/arch/x86_64/ia32/vsyscall-int80.S
---- linux-2.6.17/arch/x86_64/ia32/vsyscall-int80.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/ia32/vsyscall-int80.S	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/ia32/vsyscall-int80.S linux-2.6.18-rc5-xen/arch/x86_64/ia32/vsyscall-int80.S
+--- linux-2.6.18-rc5/arch/x86_64/ia32/vsyscall-int80.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/ia32/vsyscall-int80.S	2006-07-20 15:56:48.000000000 +0200
 @@ -0,0 +1,58 @@
 +/*
 + * Code for the vsyscall page.  This version uses the old int $0x80 method.
@@ -28412,9 +29749,9 @@
 + */
 +#define SYSCALL_ENTER_KERNEL    int $0x80
 +#include "vsyscall-sigreturn.S"
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/ia32/vsyscall-sigreturn.S linux-2.6.17-xen/arch/x86_64/ia32/vsyscall-sigreturn.S
---- linux-2.6.17/arch/x86_64/ia32/vsyscall-sigreturn.S	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/ia32/vsyscall-sigreturn.S	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/ia32/vsyscall-sigreturn.S linux-2.6.18-rc5-xen/arch/x86_64/ia32/vsyscall-sigreturn.S
+--- linux-2.6.18-rc5/arch/x86_64/ia32/vsyscall-sigreturn.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/ia32/vsyscall-sigreturn.S	2006-07-20 15:56:48.000000000 +0200
 @@ -139,5 +139,5 @@
  	.align 4
  .LENDFDE3:
@@ -28422,10 +29759,18 @@
 -#include "../../i386/kernel/vsyscall-note.S"
 +#include <vsyscall-note.S>
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/Kconfig linux-2.6.17-xen/arch/x86_64/Kconfig
---- linux-2.6.17/arch/x86_64/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/Kconfig	2006-08-14 15:57:36.000000000 +0200
-@@ -123,6 +123,22 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/Kconfig linux-2.6.18-rc5-xen/arch/x86_64/Kconfig
+--- linux-2.6.18-rc5/arch/x86_64/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/Kconfig	2006-09-01 00:09:09.000000000 +0200
+@@ -30,6 +30,7 @@
+ 
+ config STACKTRACE_SUPPORT
+ 	bool
++	depends on !X86_64_XEN
+ 	default y
+ 
+ config SEMAPHORE_SLEEPERS
+@@ -131,6 +132,22 @@
  
  endchoice
  
@@ -28448,7 +29793,7 @@
  #
  # Define implied options from the CPU selection here
  #
-@@ -143,6 +159,7 @@
+@@ -151,6 +168,7 @@
  
  config X86_TSC
  	bool
@@ -28456,7 +29801,7 @@
  	default y
  
  config X86_GOOD_APIC
-@@ -185,7 +202,7 @@
+@@ -193,7 +211,7 @@
  
  config X86_HT
  	bool
@@ -28465,7 +29810,7 @@
  	default y
  
  config MATH_EMULATION
-@@ -199,14 +216,22 @@
+@@ -207,14 +225,22 @@
  
  config X86_IO_APIC
  	bool
@@ -28488,7 +29833,7 @@
  	---help---
  	  On Intel P6 family processors (Pentium Pro, Pentium II and later)
  	  the Memory Type Range Registers (MTRRs) may be used to control
-@@ -247,7 +272,7 @@
+@@ -255,7 +281,7 @@
  
  config SCHED_SMT
  	bool "SMT (Hyperthreading) scheduler support"
@@ -28497,7 +29842,7 @@
  	default n
  	help
  	  SMT scheduler support improves the CPU scheduler's decision making
-@@ -257,7 +282,7 @@
+@@ -265,7 +291,7 @@
  
  config SCHED_MC
  	bool "Multi-core scheduler support"
@@ -28506,7 +29851,7 @@
  	default y
  	help
  	  Multi-core scheduler support improves the CPU scheduler's decision
-@@ -268,7 +293,7 @@
+@@ -276,7 +302,7 @@
  
  config NUMA
         bool "Non Uniform Memory Access (NUMA) Support"
@@ -28515,7 +29860,16 @@
         help
  	 Enable NUMA (Non Uniform Memory Access) support. The kernel 
  	 will try to allocate memory used by a CPU on the local memory 
-@@ -352,6 +377,7 @@
+@@ -337,7 +363,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
+@@ -361,6 +387,7 @@
  	int "Maximum number of CPUs (2-256)"
  	range 2 255
  	depends on SMP
@@ -28523,7 +29877,7 @@
  	default "8"
  	help
  	  This allows you to specify the maximum number of CPUs which this
-@@ -372,6 +398,7 @@
+@@ -383,6 +410,7 @@
  
  config HPET_TIMER
  	bool
@@ -28531,16 +29885,16 @@
  	default y
  	help
  	  Use the IA-PC HPET (High Precision Event Timer) to manage
-@@ -389,7 +416,7 @@
- 	bool "K8 GART IOMMU support"
+@@ -403,7 +431,7 @@
  	default y
  	select SWIOTLB
+ 	select AGP
 -	depends on PCI
 +	depends on PCI && !X86_64_XEN
  	help
- 	  Support for hardware IOMMU in AMD's Opteron/Athlon64 Processors
- 	  and for the bounce buffering software IOMMU.
-@@ -409,6 +436,7 @@
+ 	  Support for full DMA access of devices with 32bit memory access only
+ 	  on systems with more than 3GB. This is usually needed for USB,
+@@ -440,6 +468,7 @@
  
  config X86_MCE
  	bool "Machine check support" if EMBEDDED
@@ -28548,7 +29902,7 @@
  	default y
  	help
  	   Include a machine check error handler to report hardware errors.
-@@ -434,7 +462,7 @@
+@@ -465,7 +494,7 @@
  
  config KEXEC
  	bool "kexec system call (EXPERIMENTAL)"
@@ -28557,7 +29911,7 @@
  	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
-@@ -525,8 +553,11 @@
+@@ -560,8 +589,11 @@
  	default y
  
  menu "Power management options"
@@ -28569,7 +29923,7 @@
  
  source "drivers/acpi/Kconfig"
  
-@@ -549,6 +580,21 @@
+@@ -584,6 +616,21 @@
  	bool "Support mmconfig PCI config space access"
  	depends on PCI && ACPI
  
@@ -28591,25 +29945,25 @@
  source "drivers/pci/pcie/Kconfig"
  
  source "drivers/pci/Kconfig"
-@@ -619,4 +665,6 @@
+@@ -654,4 +701,6 @@
  
  source "crypto/Kconfig"
  
 +source "drivers/xen/Kconfig"
 +
  source "lib/Kconfig"
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/acpi/Makefile linux-2.6.17-xen/arch/x86_64/kernel/acpi/Makefile
---- linux-2.6.17/arch/x86_64/kernel/acpi/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/kernel/acpi/Makefile	2006-08-14 15:57:36.000000000 +0200
-@@ -6,3 +6,4 @@
- obj-y			+= processor.o
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/acpi/Makefile linux-2.6.18-rc5-xen/arch/x86_64/kernel/acpi/Makefile
+--- linux-2.6.18-rc5/arch/x86_64/kernel/acpi/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/acpi/Makefile	2006-07-20 15:56:48.000000000 +0200
+@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/apic-xen.c linux-2.6.17-xen/arch/x86_64/kernel/apic-xen.c
---- linux-2.6.17/arch/x86_64/kernel/apic-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/apic-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,198 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/apic-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/apic-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/apic-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/apic-xen.c	2006-07-20 15:56:48.000000000 +0200
+@@ -0,0 +1,197 @@
 +/*
 + *	Local APIC handling, local APIC timers
 + *
@@ -28626,7 +29980,6 @@
 + *	Mikael Pettersson	:	PM converted to driver model.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/init.h>
 +
 +#include <linux/mm.h>
@@ -28808,10 +30161,10 @@
 +
 +	return 1;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/asm-offsets.c linux-2.6.17-xen/arch/x86_64/kernel/asm-offsets.c
---- linux-2.6.17/arch/x86_64/kernel/asm-offsets.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/kernel/asm-offsets.c	2006-08-14 15:57:36.000000000 +0200
-@@ -66,7 +66,9 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/asm-offsets.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/asm-offsets.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/asm-offsets.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/asm-offsets.c	2006-07-20 15:56:48.000000000 +0200
+@@ -67,8 +67,10 @@
  	DEFINE(pbe_address, offsetof(struct pbe, address));
  	DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
  	DEFINE(pbe_next, offsetof(struct pbe, next));
@@ -28819,16 +30172,16 @@
  	BLANK();
  	DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
 +#endif
+ 	BLANK();
+ 	DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
  	return 0;
- }
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/e820-xen.c linux-2.6.17-xen/arch/x86_64/kernel/e820-xen.c
---- linux-2.6.17/arch/x86_64/kernel/e820-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/e820-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,753 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/e820-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/e820-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/e820-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/e820-xen.c	2006-07-20 15:56:48.000000000 +0200
+@@ -0,0 +1,752 @@
 +/* 
 + * 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).
@@ -28836,7 +30189,6 @@
 + *  Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
 + *
 + */
-+#include <linux/config.h>
 +#include <linux/kernel.h>
 +#include <linux/types.h>
 +#include <linux/init.h>
@@ -28846,6 +30198,7 @@
 +#include <linux/kexec.h>
 +#include <linux/module.h>
 +
++#include <asm/pgtable.h>
 +#include <asm/page.h>
 +#include <asm/e820.h>
 +#include <asm/proto.h>
@@ -28875,6 +30228,7 @@
 +
 +/* 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; 
 +
@@ -28921,7 +30275,6 @@
 +	return 0;
 +} 
 +
-+#ifndef CONFIG_XEN
 +/*
 + * This function checks if any part of the range <start,end> is mapped
 + * with type.
@@ -28940,7 +30293,6 @@
 +	} 
 +	return 0;
 +}
-+#endif
 +
 +/*
 + * This function checks if the entire range <start,end> is mapped with type.
@@ -28986,7 +30338,7 @@
 +			addr = start;
 +		if (addr > ei->addr + ei->size) 
 +			continue; 
-+		while (bad_addr(&addr, size) && addr+size < ei->addr + ei->size)
++		while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
 +			;
 +		last = addr + size;
 +		if (last > ei->addr + ei->size)
@@ -29520,6 +30872,7 @@
 +}
 +
 +unsigned long pci_mem_start = 0xaeedbabe;
++EXPORT_SYMBOL(pci_mem_start);
 +
 +/*
 + * Search for the biggest gap in the low 32 bits of the e820
@@ -29578,16 +30931,16 @@
 +	printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
 +		pci_mem_start, gapstart, gapsize);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/early_printk-xen.c linux-2.6.17-xen/arch/x86_64/kernel/early_printk-xen.c
---- linux-2.6.17/arch/x86_64/kernel/early_printk-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/early_printk-xen.c	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/early_printk-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/early_printk-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/early_printk-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/early_printk-xen.c	2006-08-14 15:07:20.000000000 +0200
 @@ -0,0 +1,304 @@
-+#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 <linux/screen_info.h>
 +#include <asm/io.h>
 +#include <asm/processor.h>
 +#include <asm/fcntl.h>
@@ -29886,22 +31239,10 @@
 +}
 +
 +__setup("earlyprintk=", setup_early_printk);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/entry.S linux-2.6.17-xen/arch/x86_64/kernel/entry.S
---- linux-2.6.17/arch/x86_64/kernel/entry.S	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/kernel/entry.S	2006-08-14 15:57:36.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/entry-xen.S linux-2.6.17-xen/arch/x86_64/kernel/entry-xen.S
---- linux-2.6.17/arch/x86_64/kernel/entry-xen.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/entry-xen.S	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,1141 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/entry-xen.S linux-2.6.18-rc5-xen/arch/x86_64/kernel/entry-xen.S
+--- linux-2.6.18-rc5/arch/x86_64/kernel/entry-xen.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/entry-xen.S	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,1210 @@
 +/*
 + *  linux/arch/x86_64/entry.S
 + *
@@ -29936,7 +31277,6 @@
 + */
 +
 +#define ASSEMBLY 1
-+#include <linux/config.h>
 +#ifdef CONFIG_DEBUG_INFO
 +#undef CONFIG_DEBUG_INFO
 +#endif
@@ -29953,6 +31293,7 @@
 +#include <asm/thread_info.h>
 +#include <asm/hw_irq.h>
 +#include <asm/page.h>
++#include <asm/irqflags.h>
 +#include <asm/errno.h>
 +#include <xen/interface/arch-x86_64.h>
 +#include <xen/interface/features.h>
@@ -29967,6 +31308,16 @@
 +#define retint_kernel retint_restore_args
 +#endif	
 +
++
++.macro TRACE_IRQS_IRETQ offset=ARGOFFSET
++#ifdef CONFIG_TRACE_IRQFLAGS
++	bt   $9,EFLAGS-\offset(%rsp)	/* interrupts off? */
++	jnc  1f
++	TRACE_IRQS_ON
++1:
++#endif
++.endm
++
 +NMI_MASK = 0x80000000
 +	
 +/*
@@ -30099,6 +31450,7 @@
 +	GET_THREAD_INFO(%rcx)	
 +	jmp rff_action
 +	CFI_ENDPROC
++END(ret_from_fork)
 +
 +/*
 + * System call entry. Upto 6 arguments in registers are supported.
@@ -30133,11 +31485,15 @@
 +
 +ENTRY(system_call)
 +	CFI_STARTPROC	simple
-+	CFI_DEF_CFA	rsp,0
++	CFI_DEF_CFA	rsp,PDA_STACKOFFSET
 +	CFI_REGISTER	rip,rcx
 +	/*CFI_REGISTER	rflags,r11*/
 +	SAVE_ARGS -8,0
 +	movq  %rax,ORIG_RAX-ARGOFFSET(%rsp) 
++	/*
++	 * No need to follow this irqs off/on section - it's straight
++	 * and short:
++	 */
 +        XEN_UNBLOCK_EVENTS(%r11)        
 +	GET_THREAD_INFO(%rcx)
 +	testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
@@ -30159,10 +31515,15 @@
 +sysret_check:		
 +	GET_THREAD_INFO(%rcx)
 +        XEN_BLOCK_EVENTS(%rsi)        
++	TRACE_IRQS_OFF
 +	movl threadinfo_flags(%rcx),%edx
 +	andl %edi,%edx
 +	CFI_REMEMBER_STATE
 +	jnz  sysret_careful 
++	/*
++	 * sysretq will re-enable interrupts:
++	 */
++	TRACE_IRQS_ON
 +        XEN_UNBLOCK_EVENTS(%rsi)                
 +	CFI_REGISTER	rip,rcx
 +	RESTORE_ARGS 0,8,0
@@ -30175,7 +31536,8 @@
 +	CFI_RESTORE_STATE
 +	bt $TIF_NEED_RESCHED,%edx
 +	jnc sysret_signal
-+        XEN_BLOCK_EVENTS(%rsi)        
++	TRACE_IRQS_ON
++        XEN_UNBLOCK_EVENTS(%rsi)        
 +	pushq %rdi
 +	CFI_ADJUST_CFA_OFFSET 8
 +	call schedule
@@ -30185,6 +31547,7 @@
 +
 +	/* Handle a signal */ 
 +sysret_signal:
++	TRACE_IRQS_ON
 +/*	sti */
 +        XEN_UNBLOCK_EVENTS(%rsi)        
 +	testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
@@ -30200,6 +31563,7 @@
 +	/* Use IRET because user could have changed frame. This
 +	   works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
 +	cli
++	TRACE_IRQS_OFF
 +	jmp int_with_check
 +	
 +badsys:
@@ -30220,15 +31584,11 @@
 +	ja  1f
 +	movq %r10,%rcx	/* fixup for C */
 +	call *sys_call_table(,%rax,8)
-+	movq %rax,RAX-ARGOFFSET(%rsp)
-+1:	SAVE_REST
-+	movq %rsp,%rdi
-+	call syscall_trace_leave
-+	RESTORE_TOP_OF_STACK %rbx
-+	RESTORE_REST
++1:	movq %rax,RAX-ARGOFFSET(%rsp)
 +	/* Use IRET because user could have changed frame */
 +	jmp int_ret_from_sys_call
 +	CFI_ENDPROC
++END(system_call)
 +		
 +/* 
 + * Syscall return path ending with IRET.
@@ -30252,6 +31612,7 @@
 +	CFI_REL_OFFSET	r10,R10-ARGOFFSET
 +	CFI_REL_OFFSET	r11,R11-ARGOFFSET
 +        XEN_BLOCK_EVENTS(%rsi)
++	TRACE_IRQS_OFF
 +	testb $3,CS-ARGOFFSET(%rsp)
 +        jnz 1f
 +        /* Need to set the proper %ss (not NULL) for ring 3 iretq */
@@ -30274,6 +31635,7 @@
 +int_careful:
 +	bt $TIF_NEED_RESCHED,%edx
 +	jnc  int_very_careful
++	TRACE_IRQS_ON
 +/*	sti */
 +        XEN_UNBLOCK_EVENTS(%rsi)
 +	pushq %rdi
@@ -30281,11 +31643,13 @@
 +	call schedule
 +	popq %rdi
 +	CFI_ADJUST_CFA_OFFSET -8
-+	cli
++	XEN_BLOCK_EVENTS(%rsi)
++	TRACE_IRQS_OFF
 +	jmp int_with_check
 +
 +	/* handle signals and tracing -- both require a full stack frame */
 +int_very_careful:
++	TRACE_IRQS_ON
 +/*	sti */
 +        XEN_UNBLOCK_EVENTS(%rsi)
 +	SAVE_REST
@@ -30299,7 +31663,8 @@
 +	popq %rdi
 +	CFI_ADJUST_CFA_OFFSET -8
 +	andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
-+	cli
++	XEN_BLOCK_EVENTS(%rsi)
++	TRACE_IRQS_OFF
 +	jmp int_restore_rest
 +	
 +int_signal:
@@ -30311,9 +31676,11 @@
 +1:	movl $_TIF_NEED_RESCHED,%edi	
 +int_restore_rest:
 +	RESTORE_REST
-+	cli
++	XEN_BLOCK_EVENTS(%rsi)
++	TRACE_IRQS_OFF
 +	jmp int_with_check
 +	CFI_ENDPROC
++END(int_ret_from_sys_call)
 +		
 +/* 
 + * Certain special system calls that need to save a complete full stack frame.
@@ -30325,6 +31692,7 @@
 +	leaq	\func(%rip),%rax
 +	leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
 +	jmp	ptregscall_common
++END(\label)
 +	.endm
 +
 +	CFI_STARTPROC
@@ -30354,6 +31722,7 @@
 +	CFI_REL_OFFSET rip, 0
 +	ret
 +	CFI_ENDPROC
++END(ptregscall_common)
 +	
 +ENTRY(stub_execve)
 +	CFI_STARTPROC
@@ -30368,6 +31737,7 @@
 +	RESTORE_REST
 +	jmp int_ret_from_sys_call
 +	CFI_ENDPROC
++END(stub_execve)
 +	
 +/*
 + * sigreturn is special because it needs to restore all registers on return.
@@ -30385,6 +31755,7 @@
 +	RESTORE_REST
 +	jmp int_ret_from_sys_call
 +	CFI_ENDPROC
++END(stub_rt_sigreturn)
 +
 +/*
 + * initial frame state for interrupts and exceptions
@@ -30423,7 +31794,7 @@
 +	andb $1,%al			# EAX[0] == IRET_EFLAGS.IF & event_mask
 +	jnz restore_all_enable_events	#        != 0 => enable event delivery
 +	XEN_PUT_VCPU_INFO(%rsi)
-+		
++	TRACE_IRQS_IRETQ
 +	RESTORE_ARGS 0,8,0
 +	HYPERVISOR_IRET 0
 +	
@@ -30432,6 +31803,7 @@
 +	CFI_RESTORE_STATE
 +	bt    $TIF_NEED_RESCHED,%edx
 +	jnc   retint_signal
++	TRACE_IRQS_ON
 +	XEN_UNBLOCK_EVENTS(%rsi)
 +/*	sti */        
 +	pushq %rdi
@@ -30439,14 +31811,16 @@
 +	call  schedule
 +	popq %rdi		
 +	CFI_ADJUST_CFA_OFFSET	-8
-+	XEN_BLOCK_EVENTS(%rsi)		
 +	GET_THREAD_INFO(%rcx)
++	XEN_BLOCK_EVENTS(%rsi)		
++	TRACE_IRQS_OFF
 +/*	cli */
 +	jmp retint_check
 +	
 +retint_signal:
 +	testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
 +	jz    retint_restore_args
++	TRACE_IRQS_ON
 +        XEN_UNBLOCK_EVENTS(%rsi)
 +	SAVE_REST
 +	movq $-1,ORIG_RAX(%rsp) 			
@@ -30455,6 +31829,7 @@
 +	call do_notify_resume
 +	RESTORE_REST
 +        XEN_BLOCK_EVENTS(%rsi)		
++	TRACE_IRQS_OFF
 +	movl $_TIF_NEED_RESCHED,%edi
 +	GET_THREAD_INFO(%rcx)
 +	jmp retint_check
@@ -30473,7 +31848,9 @@
 +	call preempt_schedule_irq
 +	jmp retint_kernel       /* check again */
 +#endif	
++
 +	CFI_ENDPROC
++END(common_interrupt)
 +	
 +/*
 + * APIC interrupts.
@@ -30490,17 +31867,21 @@
 +#ifndef CONFIG_XEN
 +ENTRY(thermal_interrupt)
 +	apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
++END(thermal_interrupt)
 +
 +ENTRY(threshold_interrupt)
 +	apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt
++END(threshold_interrupt)
 +
 +#ifdef CONFIG_SMP	
 +ENTRY(reschedule_interrupt)
 +	apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
++END(reschedule_interrupt)
 +
 +	.macro INVALIDATE_ENTRY num
 +ENTRY(invalidate_interrupt\num)
 +	apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt	
++END(invalidate_interrupt\num)
 +	.endm
 +
 +	INVALIDATE_ENTRY 0
@@ -30514,17 +31895,21 @@
 +
 +ENTRY(call_function_interrupt)
 +	apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
++END(call_function_interrupt)
 +#endif
 +
 +#ifdef CONFIG_X86_LOCAL_APIC	
 +ENTRY(apic_timer_interrupt)
 +	apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
++END(apic_timer_interrupt)
 +
 +ENTRY(error_interrupt)
 +	apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
++END(error_interrupt)
 +
 +ENTRY(spurious_interrupt)
 +	apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
++END(spurious_interrupt)
 +#endif
 +#endif /* !CONFIG_XEN */
 +				
@@ -30590,6 +31975,7 @@
 +	addq	$EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
 +	.endif
 +/*	cli */
++	TRACE_IRQS_OFF
 +	XEN_BLOCK_EVENTS(%rsi)		
 +	.endm
 +#endif
@@ -30647,11 +32033,12 @@
 +	RESTORE_REST
 +/*	cli */
 +	XEN_BLOCK_EVENTS(%rsi)		
++	TRACE_IRQS_OFF
 +	GET_THREAD_INFO(%rcx)	
 +	testb $3,CS-ARGOFFSET(%rsp)
 +	jz retint_kernel
 +	movl  threadinfo_flags(%rcx),%edx
-+	movl  $_TIF_WORK_MASK,%edi	
++	movl  $_TIF_WORK_MASK,%edi
 +	andl  %edi,%edx
 +	jnz   retint_careful
 +	jmp   retint_restore_args
@@ -30681,7 +32068,8 @@
 +        je   error_swapgs
 +	jmp  error_sti
 +#endif        
-+	
++END(error_entry)
++		
 +ENTRY(hypervisor_callback)
 +	zeroentry do_hypervisor_callback
 +        
@@ -30840,7 +32228,7 @@
 +	UNFAKE_STACK_FRAME
 +	ret
 +	CFI_ENDPROC
-+
++ENDPROC(kernel_thread)
 +	
 +child_rip:
 +	/*
@@ -30853,6 +32241,7 @@
 +	# exit
 +	xorl %edi, %edi
 +	call do_exit
++ENDPROC(child_rip)
 +
 +/*
 + * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
@@ -30883,19 +32272,24 @@
 +	UNFAKE_STACK_FRAME
 +	ret
 +	CFI_ENDPROC
++ENDPROC(execve)
 +
 +KPROBE_ENTRY(page_fault)
 +	errorentry do_page_fault
++END(page_fault)
 +	.previous .text
 +
 +ENTRY(coprocessor_error)
 +	zeroentry do_coprocessor_error
++END(coprocessor_error)
 +
 +ENTRY(simd_coprocessor_error)
 +	zeroentry do_simd_coprocessor_error	
++END(simd_coprocessor_error)
 +
 +ENTRY(device_not_available)
 +	zeroentry math_state_restore
++END(device_not_available)
 +
 +	/* runs on exception stack */
 +KPROBE_ENTRY(debug)
@@ -30905,6 +32299,7 @@
 +	zeroentry do_debug
 +/*	jmp paranoid_exit */
 +	CFI_ENDPROC
++END(debug)
 +	.previous .text
 +
 +#if 0
@@ -30913,49 +32308,14 @@
 +	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
++	paranoidentry do_nmi, 0, 0
++#ifdef CONFIG_TRACE_IRQFLAGS
++	paranoidexit 0
++#else
++	jmp paranoid_exit1
++ 	CFI_ENDPROC
++#endif
++END(nmi)
 +	.previous .text
 +#endif        
 +
@@ -30966,56 +32326,69 @@
 + 	zeroentry do_int3
 +/* 	jmp paranoid_exit */
 + 	CFI_ENDPROC
++END(int3)
 +	.previous .text
 +
 +ENTRY(overflow)
 +	zeroentry do_overflow
++END(overflow)
 +
 +ENTRY(bounds)
 +	zeroentry do_bounds
++END(bounds)
 +
 +ENTRY(invalid_op)
 +	zeroentry do_invalid_op	
++END(invalid_op)
 +
 +ENTRY(coprocessor_segment_overrun)
 +	zeroentry do_coprocessor_segment_overrun
++END(coprocessor_segment_overrun)
 +
 +ENTRY(reserved)
 +	zeroentry do_reserved
++END(reserved)
 +
 +#if 0
 +	/* runs on exception stack */
 +ENTRY(double_fault)
 +	XCPT_FRAME
 +	paranoidentry do_double_fault
-+	jmp paranoid_exit
++	jmp paranoid_exit1
 +	CFI_ENDPROC
++END(double_fault)
 +#endif
 +
 +ENTRY(invalid_TSS)
 +	errorentry do_invalid_TSS
++END(invalid_TSS)
 +
 +ENTRY(segment_not_present)
 +	errorentry do_segment_not_present
-+
++END(segment_not_present)
 +	/* runs on exception stack */
 +ENTRY(stack_segment)
 +	XCPT_FRAME
 +	errorentry do_stack_segment
 +	CFI_ENDPROC
++END(stack_segment)
 +
 +KPROBE_ENTRY(general_protection)
 +	errorentry do_general_protection
++END(general_protection)
 +	.previous .text
 +
 +ENTRY(alignment_check)
 +	errorentry do_alignment_check
++END(alignment_check)
 +
 +ENTRY(divide_error)
 +	zeroentry do_divide_error
++END(divide_error)
 +
 +ENTRY(spurious_interrupt_bug)
 +	zeroentry do_spurious_interrupt_bug
++END(spurious_interrupt_bug)
 +
 +#ifdef CONFIG_X86_MCE
 +	/* runs on exception stack */
@@ -31024,29 +32397,66 @@
 +	pushq $0
 +	CFI_ADJUST_CFA_OFFSET 8	
 +	paranoidentry do_machine_check
-+	jmp paranoid_exit
++	jmp paranoid_exit1
 +	CFI_ENDPROC
++END(machine_check)
 +#endif
 +
 +ENTRY(call_softirq)
 +	CFI_STARTPROC
-+	movq %gs:pda_irqstackptr,%rax
-+	movq %rsp,%rdx
-+	CFI_DEF_CFA_REGISTER	rdx
++	push %rbp
++	CFI_ADJUST_CFA_OFFSET	8
++	CFI_REL_OFFSET rbp,0
++	mov  %rsp,%rbp
++	CFI_DEF_CFA_REGISTER rbp
 +	incl %gs:pda_irqcount
-+	cmove %rax,%rsp
-+	pushq %rdx
-+	/*todo CFI_DEF_CFA_EXPRESSION ...*/
++	cmove %gs:pda_irqstackptr,%rsp
++	push  %rbp			# backlink for old unwinder
 +	call __do_softirq
-+	popq %rsp
++	leaveq
 +	CFI_DEF_CFA_REGISTER	rsp
++	CFI_ADJUST_CFA_OFFSET   -8
 +	decl %gs:pda_irqcount
 +	ret
 +	CFI_ENDPROC
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/genapic_xen.c linux-2.6.17-xen/arch/x86_64/kernel/genapic_xen.c
---- linux-2.6.17/arch/x86_64/kernel/genapic_xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/genapic_xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,162 @@
++ENDPROC(call_softirq)
++
++#ifdef CONFIG_STACK_UNWIND
++ENTRY(arch_unwind_init_running)
++	CFI_STARTPROC
++	movq	%r15, R15(%rdi)
++	movq	%r14, R14(%rdi)
++	xchgq	%rsi, %rdx
++	movq	%r13, R13(%rdi)
++	movq	%r12, R12(%rdi)
++	xorl	%eax, %eax
++	movq	%rbp, RBP(%rdi)
++	movq	%rbx, RBX(%rdi)
++	movq	(%rsp), %rcx
++	movq	%rax, R11(%rdi)
++	movq	%rax, R10(%rdi)
++	movq	%rax, R9(%rdi)
++	movq	%rax, R8(%rdi)
++	movq	%rax, RAX(%rdi)
++	movq	%rax, RCX(%rdi)
++	movq	%rax, RDX(%rdi)
++	movq	%rax, RSI(%rdi)
++	movq	%rax, RDI(%rdi)
++	movq	%rax, ORIG_RAX(%rdi)
++	movq	%rcx, RIP(%rdi)
++	leaq	8(%rsp), %rcx
++	movq	$__KERNEL_CS, CS(%rdi)
++	movq	%rax, EFLAGS(%rdi)
++	movq	%rcx, RSP(%rdi)
++	movq	$__KERNEL_DS, SS(%rdi)
++	jmpq	*%rdx
++	CFI_ENDPROC
++ENDPROC(arch_unwind_init_running)
++#endif
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/genapic_xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/genapic_xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/genapic_xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/genapic_xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,176 @@
 +/*
 + * Copyright 2004 James Cleverdon, IBM.
 + * Subject to the GNU Public License, v.2
@@ -31059,7 +32469,6 @@
 + *
 + * Hacked to pieces for Xen by Chris Wright.
 + */
-+#include <linux/config.h>
 +#include <linux/threads.h>
 +#include <linux/cpumask.h>
 +#include <linux/string.h>
@@ -31131,24 +32540,6 @@
 +	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];
@@ -31167,6 +32558,40 @@
 +	local_irq_restore(flags);
 +}
 +
++static void xen_send_IPI_allbutself(int vector)
++{
++#ifdef	CONFIG_HOTPLUG_CPU
++	int hotplug = 1;
++#else
++	int hotplug = 0;
++#endif
++	/*
++	 * 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 (hotplug || vector == NMI_VECTOR) {
++		cpumask_t allbutme = cpu_online_map;
++
++		cpu_clear(smp_processor_id(), allbutme);
++
++		if (!cpus_empty(allbutme))
++			xen_send_IPI_mask(allbutme, vector);
++	} else 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__);
++	if (vector == NMI_VECTOR)
++		xen_send_IPI_mask(cpu_online_map, vector);
++	else
++		xen_send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL);
++}
++
 +#ifdef CONFIG_XEN_PRIVILEGED_GUEST
 +static int xen_apic_id_registered(void)
 +{
@@ -31184,8 +32609,7 @@
 +
 +static unsigned int phys_pkg_id(int index_msb)
 +{
-+	u32 ebx;
-+
++	int ebx;
 +	Dprintk("%s\n", __FUNCTION__);
 +	ebx = cpuid_ebx(1);
 +	return ((ebx >> 24) & 0xFF) >> index_msb;
@@ -31209,10 +32633,10 @@
 +	.cpu_mask_to_apicid = xen_cpu_mask_to_apicid,
 +	.phys_pkg_id = phys_pkg_id,
 +};
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/genapic-xen.c linux-2.6.17-xen/arch/x86_64/kernel/genapic-xen.c
---- linux-2.6.17/arch/x86_64/kernel/genapic-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/genapic-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,144 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/genapic-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/genapic-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/genapic-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/genapic-xen.c	2006-07-20 15:56:48.000000000 +0200
+@@ -0,0 +1,143 @@
 +/*
 + * Copyright 2004 James Cleverdon, IBM.
 + * Subject to the GNU Public License, v.2
@@ -31223,7 +32647,6 @@
 + * 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>
@@ -31357,17 +32780,15 @@
 +	xen_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
 +#endif
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/head64-xen.c linux-2.6.17-xen/arch/x86_64/kernel/head64-xen.c
---- linux-2.6.17/arch/x86_64/kernel/head64-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/head64-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,159 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/head64-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/head64-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/head64-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/head64-xen.c	2006-07-20 15:56:48.000000000 +0200
+@@ -0,0 +1,161 @@
 +/*
 + *  linux/arch/x86_64/kernel/head64.c -- prepare to run common code
 + *
 + *  Copyright (C) 2000 Andrea Arcangeli <andrea at suse.de> SuSE
 + *
-+ *  $Id: head64.c,v 1.22 2001/07/06 14:28:20 ak Exp $
-+ *
 + *  Jun Nakajima <jun.nakajima at intel.com>
 + *	Modified for Xen.
 + */
@@ -31477,7 +32898,6 @@
 +			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) {
@@ -31493,6 +32913,11 @@
 +	asm volatile("lidt %0" :: "m" (idt_descr));
 +#endif
 +
++	/*
++	 * This must be called really, really early:
++	 */
++	lockdep_init();
++
 + 	for (i = 0; i < NR_CPUS; i++)
 + 		cpu_pda(i) = &boot_cpu_pda[i];
 +
@@ -31520,10 +32945,10 @@
 +	setup_boot_cpu_data();
 +	start_kernel();
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/head-xen.S linux-2.6.17-xen/arch/x86_64/kernel/head-xen.S
---- linux-2.6.17/arch/x86_64/kernel/head-xen.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/head-xen.S	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,176 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/head-xen.S linux-2.6.18-rc5-xen/arch/x86_64/kernel/head-xen.S
+--- linux-2.6.18-rc5/arch/x86_64/kernel/head-xen.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/head-xen.S	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,191 @@
 +/*
 + *  linux/arch/x86_64/kernel/head.S -- start in 32bit and switch to 64bit
 + *
@@ -31542,12 +32967,15 @@
 +#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
 +	.section .bootstrap.text
 +	.code64
@@ -31665,6 +33093,7 @@
 +ENTRY(empty_zero_page)
 +	.skip PAGE_SIZE
 +
++#ifdef CONFIG_XEN_COMPAT_030002
 +/*
 + * __xen_guest information
 + */
@@ -31684,12 +33113,8 @@
 +	.ascii	",XEN_VER=xen-3.0"
 +	.ascii	",VIRT_BASE=0x"
 +		utoh __START_KERNEL_map
-+#ifdef CONFIG_XEN_COMPAT_030002
 +	.ascii	",ELF_PADDR_OFFSET=0x"
 +		utoh __START_KERNEL_map
-+#else
-+	.ascii	",ELF_PADDR_OFFSET=0x0"
-+#endif /* !CONFIG_XEN_COMPAT_030002 */
 +	.ascii	",VIRT_ENTRY=0x"
 +		utoh (__START_KERNEL_map + __PHYSICAL_START + VIRT_ENTRY_OFFSET)
 +	.ascii	",HYPERCALL_PAGE=0x"
@@ -31700,9 +33125,24 @@
 +	.ascii	         "|supervisor_mode_kernel"
 +	.ascii	",LOADER=generic"
 +	.byte	0
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/init_task.c linux-2.6.17-xen/arch/x86_64/kernel/init_task.c
---- linux-2.6.17/arch/x86_64/kernel/init_task.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/kernel/init_task.c	2006-08-14 15:57:36.000000000 +0200
++#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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/init_task.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/init_task.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/init_task.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/init_task.c	2006-07-20 15:56:48.000000000 +0200
 @@ -37,6 +37,8 @@
  struct task_struct init_task = INIT_TASK(init_task);
  
@@ -31719,10 +33159,10 @@
 +#endif
  
  #define ALIGN_TO_4K __attribute__((section(".data.init_task")))
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/io_apic-xen.c linux-2.6.17-xen/arch/x86_64/kernel/io_apic-xen.c
---- linux-2.6.17/arch/x86_64/kernel/io_apic-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/io_apic-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,2232 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/io_apic-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/io_apic-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/io_apic-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/io_apic-xen.c	2006-07-20 15:56:48.000000000 +0200
+@@ -0,0 +1,2263 @@
 +/*
 + *	Intel IO-APIC support for multi-Pentium hosts.
 + *
@@ -31750,7 +33190,6 @@
 +#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>
@@ -31766,6 +33205,7 @@
 +#include <asm/mach_apic.h>
 +#include <asm/acpi.h>
 +#include <asm/dma.h>
++#include <asm/nmi.h>
 +
 +#define __apicdebuginit  __init
 +
@@ -31783,6 +33223,7 @@
 +#endif
 +
 +static DEFINE_SPINLOCK(ioapic_lock);
++static DEFINE_SPINLOCK(vector_lock);
 +
 +/*
 + * # of IRQ routing registers
@@ -32046,6 +33487,18 @@
 +#include <linux/pci_ids.h>
 +#include <linux/pci.h>
 +
++
++#ifdef CONFIG_ACPI
++
++static int nvidia_hpet_detected __initdata;
++
++static int __init nvidia_hpet_check(unsigned long phys, unsigned long size)
++{
++	nvidia_hpet_detected = 1;
++	return 0;
++}
++#endif
++
 +/* 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. 
@@ -32080,7 +33533,7 @@
 +				vendor &= 0xffff;
 +				switch (vendor) { 
 +				case PCI_VENDOR_ID_VIA:
-+#ifdef CONFIG_GART_IOMMU
++#ifdef CONFIG_IOMMU
 +					if ((end_pfn > MAX_DMA32_PFN ||
 +					     force_iommu) &&
 +					    !iommu_aperture_allowed) {
@@ -32092,11 +33545,19 @@
 +					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");
++					/*
++					 * All timer overrides on Nvidia are
++					 * wrong unless HPET is enabled.
++					 */
++					nvidia_hpet_detected = 0;
++					acpi_table_parse(ACPI_HPET,
++							nvidia_hpet_check);
++					if (nvidia_hpet_detected == 0) {
++						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;
@@ -32593,11 +34054,16 @@
 +int assign_irq_vector(int irq)
 +{
 +	struct physdev_irq irq_op;
-+  
++	unsigned long flags;
++
 +  	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
-+  	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
-+  		return IO_APIC_VECTOR(irq);
 +
++	spin_lock_irqsave(&vector_lock, flags);
++
++	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
++		spin_unlock_irqrestore(&vector_lock, flags);
++  		return IO_APIC_VECTOR(irq);
++	}
 +	irq_op.irq = irq;
 +	if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
 +		return -ENOSPC;
@@ -32606,6 +34072,7 @@
 +	if (irq != AUTO_ASSIGN)
 +		IO_APIC_VECTOR(irq) = irq_op.vector;
 +
++	spin_unlock_irqrestore(&vector_lock, flags);
 +	return irq_op.vector;
 +}
 +
@@ -32618,23 +34085,18 @@
 +#define IOAPIC_EDGE	0
 +#define IOAPIC_LEVEL	1
 +
-+static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger)
++static 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]);
-+	}
++	unsigned idx;
++
++	idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq;
++
++	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
++			trigger == IOAPIC_LEVEL)
++		irq_desc[idx].chip = &ioapic_level_type;
++	else
++		irq_desc[idx].chip = &ioapic_edge_type;
++	set_intr_gate(vector, interrupt[idx]);
 +}
 +#else
 +#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0)
@@ -32739,7 +34201,7 @@
 +	 * 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;
++	irq_desc[0].chip = &ioapic_edge_type;
 +
 +	/*
 +	 * Add it to the IO-APIC irq-routing table:
@@ -33384,6 +34846,13 @@
 +#endif // CONFIG_SMP
 +#endif // CONFIG_PCI_MSI
 +
++static int ioapic_retrigger(unsigned int irq)
++{
++	send_IPI_self(IO_APIC_VECTOR(irq));
++
++	return 1;
++}
++
 +/*
 + * Level and edge triggered IO-APIC interrupts need different handling,
 + * so we use two separate IRQ descriptors. Edge triggered IRQs can be
@@ -33404,6 +34873,7 @@
 +#ifdef CONFIG_SMP
 +	.set_affinity = set_ioapic_affinity,
 +#endif
++	.retrigger	= ioapic_retrigger,
 +};
 +
 +static struct hw_interrupt_type ioapic_level_type __read_mostly = {
@@ -33417,6 +34887,7 @@
 +#ifdef CONFIG_SMP
 +	.set_affinity = set_ioapic_affinity,
 +#endif
++	.retrigger	= ioapic_retrigger,
 +};
 +#endif /* !CONFIG_XEN */
 +
@@ -33453,7 +34924,7 @@
 +#ifndef CONFIG_XEN
 +			else
 +				/* Strange. Oh, well.. */
-+				irq_desc[irq].handler = &no_irq_type;
++				irq_desc[irq].chip = &no_irq_type;
 +#endif
 +		}
 +	}
@@ -33672,7 +35143,7 @@
 +	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;
++	irq_desc[0].chip = &lapic_irq_type;
 +	apic_write(APIC_LVT0, APIC_DM_FIXED | vector);	/* Fixed mode */
 +	enable_8259A_irq(0);
 +
@@ -33955,9 +35426,9 @@
 +}
 +#endif
 +#endif /* !CONFIG_XEN */
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/ioport-xen.c linux-2.6.17-xen/arch/x86_64/kernel/ioport-xen.c
---- linux-2.6.17/arch/x86_64/kernel/ioport-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/ioport-xen.c	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/ioport-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/ioport-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/ioport-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/ioport-xen.c	2006-07-20 15:56:48.000000000 +0200
 @@ -0,0 +1,99 @@
 +/*
 + *	linux/arch/x86_64/kernel/ioport.c
@@ -34058,82 +35529,196 @@
 +
 +	return 0;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/irq.c linux-2.6.17-xen/arch/x86_64/kernel/irq.c
---- linux-2.6.17/arch/x86_64/kernel/irq.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/kernel/irq.c	2006-08-14 15:57:36.000000000 +0200
-@@ -91,8 +91,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 -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/irq-xen.c linux-2.6.17-xen/arch/x86_64/kernel/irq-xen.c
---- linux-2.6.17/arch/x86_64/kernel/irq-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/irq-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,163 @@
-+/*
-+ *	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>
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/irqflags-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/irqflags-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/irqflags-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/irqflags-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,100 @@
 +#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
++#include <linux/smp.h>
++#include <asm/irqflags.h>
++#include <asm/hypervisor.h>
 +
-+/*
-+ * Generic, controller-independent functions:
++/* 
++ * 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.
 + */
 +
-+int show_interrupts(struct seq_file *p, void *v)
++unsigned long __raw_local_save_flags(void)
 +{
-+	int i = *(loff_t *) v, j;
-+	struct irqaction * action;
++	struct vcpu_info *_vcpu;
 +	unsigned long flags;
 +
-+	if (i == 0) {
-+		seq_printf(p, "           ");
-+		for_each_online_cpu(j)
-+			seq_printf(p, "CPU%d       ",j);
-+		seq_putc(p, '\n');
-+	}
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	flags = _vcpu->evtchn_upcall_mask;
++	preempt_enable();
 +
-+	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
++	return flags;
++}
++EXPORT_SYMBOL(__raw_local_save_flags);
++
++void raw_local_irq_restore(unsigned long flags)
++{
++	struct vcpu_info *_vcpu;
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	if ((_vcpu->evtchn_upcall_mask = flags) == 0) {
++		barrier(); /* unmask then check (avoid races) */
++		if ( unlikely(_vcpu->evtchn_upcall_pending) )
++			force_evtchn_callback();
++		preempt_enable();
++	} else
++		preempt_enable_no_resched();
++}
++EXPORT_SYMBOL(raw_local_irq_restore);
++
++void raw_local_irq_disable(void)
++{
++	struct vcpu_info *_vcpu;
++
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	_vcpu->evtchn_upcall_mask = 1;
++	preempt_enable_no_resched();
++}
++EXPORT_SYMBOL(raw_local_irq_disable);
++
++void raw_local_irq_enable(void)
++{
++	struct vcpu_info *_vcpu;
++
++	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();
++}
++EXPORT_SYMBOL(raw_local_irq_enable);
++
++/*
++ * For spinlocks, etc.:
++ */
++
++unsigned long __raw_local_irq_save(void)
++{
++	struct vcpu_info *_vcpu;
++	unsigned long flags;
++
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	flags = _vcpu->evtchn_upcall_mask;
++	_vcpu->evtchn_upcall_mask = 1;
++	preempt_enable_no_resched();
++
++	return flags;
++}
++EXPORT_SYMBOL(__raw_local_irq_save);
++
++/* Cannot use preempt_enable() here as we would recurse in preempt_sched(). */
++int raw_irqs_disabled(void)
++{
++	struct vcpu_info *_vcpu;
++	int disabled;
++
++	preempt_disable();
++	_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id];
++	disabled = (_vcpu->evtchn_upcall_mask != 0);
++	preempt_enable_no_resched();
++
++	return disabled;
++}
++EXPORT_SYMBOL(raw_irqs_disabled);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/irq-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/irq-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/irq-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/irq-xen.c	2006-07-20 15:56:48.000000000 +0200
+@@ -0,0 +1,198 @@
++/*
++ *	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
++
++#ifdef CONFIG_DEBUG_STACKOVERFLOW
++/*
++ * Probabilistic stack overflow check:
++ *
++ * Only check the stack in process context, because everything else
++ * runs on the big interrupt stacks. Checking reliably is too expensive,
++ * so we just check from interrupts.
++ */
++static inline void stack_overflow_check(struct pt_regs *regs)
++{
++	u64 curbase = (u64) current->thread_info;
++	static unsigned long warned = -60*HZ;
++
++	if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE &&
++	    regs->rsp <  curbase + sizeof(struct thread_info) + 128 &&
++	    time_after(jiffies, warned + 60*HZ)) {
++		printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n",
++		       current->comm, curbase, regs->rsp);
++		show_stack(NULL,NULL);
++		warned = jiffies;
++	}
++}
++#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_each_online_cpu(j)
++			seq_printf(p, "CPU%-8d       ",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, " %14s", irq_desc[i].chip->typename);
 +
 +		seq_printf(p, "  %s", action->name);
 +		for (action=action->next; action; action = action->next)
@@ -34172,9 +35757,18 @@
 +	/* high bit used in ret_from_ code  */
 +	unsigned irq = ~regs->orig_rax;
 +
++	if (unlikely(irq >= NR_IRQS)) {
++		printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
++					__FUNCTION__, irq);
++		BUG();
++	}
++
 +	exit_idle();
 +	irq_enter();
 +
++#ifdef CONFIG_DEBUG_STACKOVERFLOW
++	stack_overflow_check(regs);
++#endif
 +	__do_IRQ(irq, regs);
 +	irq_exit();
 +
@@ -34192,13 +35786,13 @@
 +		if (irq == 2)
 +			continue;
 +
-+		cpus_and(mask, irq_affinity[irq], map);
++		cpus_and(mask, irq_desc[irq].affinity, 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);
++		if (irq_desc[irq].chip->set_affinity)
++			irq_desc[irq].chip->set_affinity(irq, mask);
 +		else if (irq_desc[irq].action && !(warned++))
 +			printk("Cannot set affinity for irq %i\n", irq);
 +	}
@@ -34223,8 +35817,10 @@
 + 	local_irq_save(flags);
 + 	pending = local_softirq_pending();
 + 	/* Switch to interrupt stack */
-+ 	if (pending)
++ 	if (pending) {
 +		call_softirq();
++		WARN_ON_ONCE(softirq_count());
++	}
 + 	local_irq_restore(flags);
 +}
 +EXPORT_SYMBOL(do_softirq);
@@ -34239,9 +35835,9 @@
 +        printk("unexpected IRQ trap at vector %02x\n", irq);
 +}
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/ldt-xen.c linux-2.6.17-xen/arch/x86_64/kernel/ldt-xen.c
---- linux-2.6.17/arch/x86_64/kernel/ldt-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/ldt-xen.c	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/ldt-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/ldt-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/ldt-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/ldt-xen.c	2006-07-20 15:56:48.000000000 +0200
 @@ -0,0 +1,282 @@
 +/*
 + * linux/arch/x86_64/kernel/ldt.c
@@ -34525,10 +36121,10 @@
 +	}
 +	return ret;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/Makefile linux-2.6.17-xen/arch/x86_64/kernel/Makefile
---- linux-2.6.17/arch/x86_64/kernel/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/kernel/Makefile	2006-08-14 15:57:36.000000000 +0200
-@@ -20,11 +20,13 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/Makefile linux-2.6.18-rc5-xen/arch/x86_64/kernel/Makefile
+--- linux-2.6.18-rc5/arch/x86_64/kernel/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/Makefile	2006-09-01 00:09:09.000000000 +0200
+@@ -21,11 +21,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
@@ -34543,12 +36139,12 @@
  obj-$(CONFIG_SOFTWARE_SUSPEND)	+= suspend_asm.o
  obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
  obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
-@@ -49,3 +51,18 @@
- quirks-y			+= ../../i386/kernel/quirks.o
- i8237-y				+= ../../i386/kernel/i8237.o
+@@ -55,3 +57,18 @@
  msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
-+
+ alternative-y			+= ../../i386/kernel/alternative.o
+ 
 +ifdef CONFIG_XEN
++obj-y				+= irqflags.o
 +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
@@ -34562,10 +36158,10 @@
 +obj-y := $(call cherrypickxen, $(obj-y))
 +extra-y := $(call cherrypickxen, $(extra-y))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/mpparse-xen.c linux-2.6.17-xen/arch/x86_64/kernel/mpparse-xen.c
---- linux-2.6.17/arch/x86_64/kernel/mpparse-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/mpparse-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,1012 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/mpparse-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/mpparse-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/mpparse-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/mpparse-xen.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,1011 @@
 +/*
 + *	Intel Multiprocessor Specification 1.1 and 1.4
 + *	compliant MP-table parsing routines.
@@ -34584,7 +36180,6 @@
 +#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>
@@ -35578,9 +37173,9 @@
 +
 +#endif /*CONFIG_X86_IO_APIC*/
 +#endif /*CONFIG_ACPI*/
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/pci-swiotlb-xen.c linux-2.6.17-xen/arch/x86_64/kernel/pci-swiotlb-xen.c
---- linux-2.6.17/arch/x86_64/kernel/pci-swiotlb-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/pci-swiotlb-xen.c	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/pci-swiotlb-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/pci-swiotlb-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/pci-swiotlb-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/pci-swiotlb-xen.c	2006-07-20 15:56:48.000000000 +0200
 @@ -0,0 +1,54 @@
 +/* Glue code to lib/swiotlb.c */
 +
@@ -35636,10 +37231,10 @@
 +	}
 +#endif
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/process-xen.c linux-2.6.17-xen/arch/x86_64/kernel/process-xen.c
---- linux-2.6.17/arch/x86_64/kernel/process-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/process-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,791 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/process-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/process-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/process-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/process-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,794 @@
 +/*
 + *  linux/arch/x86-64/kernel/process.c
 + *
@@ -35652,7 +37247,6 @@
 + *	Andi Kleen.
 + *
 + *	CPU hotplug support - ashok.raj at intel.com
-+ *  $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $
 + * 
 + *  Jun Nakajima <jun.nakajima at intel.com> 
 + *     Modified for Xen
@@ -35762,10 +37356,10 @@
 +	if (need_resched())
 +		local_irq_enable();
 +	else {
-+		clear_thread_flag(TIF_POLLING_NRFLAG);
++		current_thread_info()->status &= ~TS_POLLING;
 +		smp_mb__after_clear_bit();
 +		safe_halt();
-+		set_thread_flag(TIF_POLLING_NRFLAG);
++		current_thread_info()->status |= TS_POLLING;
 +	}
 +}
 +
@@ -35794,8 +37388,7 @@
 + */
 +void cpu_idle (void)
 +{
-+	set_thread_flag(TIF_POLLING_NRFLAG);
-+
++	current_thread_info()->status |= TS_POLLING;
 +	/* endless idle loop with no priority at all */
 +	while (1) {
 +		while (!need_resched()) {
@@ -35865,7 +37458,7 @@
 +		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,
++	printk("RSP: %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);
@@ -35898,7 +37491,7 @@
 +{
 +	printk("CPU %d:", smp_processor_id());
 +	__show_regs(regs);
-+	show_trace(&regs->rsp);
++	show_trace(NULL, regs, &regs->rsp);
 +}
 +
 +/*
@@ -35943,8 +37536,12 @@
 +	struct task_struct *tsk = current;
 +	struct thread_info *t = current_thread_info();
 +
-+	if (t->flags & _TIF_ABI_PENDING)
++	if (t->flags & _TIF_ABI_PENDING) {
 +		t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);
++		if (t->flags & _TIF_IA32)
++			current_thread_info()->status |= TS_COMPAT;
++	}
++
 +
 +	tsk->thread.debugreg0 = 0;
 +	tsk->thread.debugreg1 = 0;
@@ -36102,18 +37699,6 @@
 +	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.
-+	 */
-+	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;
@@ -36181,11 +37766,24 @@
 +		HYPERVISOR_set_segment_base(SEGBASE_GS_USER, next->gs); 
 +
 +	/* 
-+	 * Switch the PDA.
++	 * Switch the PDA and FPU context.
 +	 */
 +	prev->userrsp = read_pda(oldrsp); 
 +	write_pda(oldrsp, next->userrsp); 
 +	write_pda(pcurrent, next_p); 
++
++	/* This must be here to ensure both math_state_restore() and
++	   kernel_fpu_begin() work consistently. 
++	   And the AMD workaround requires it to be after DS reload. */
++	/*
++	 * 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() */
++		HYPERVISOR_fpu_taskswitch(1);
++	}
 +	write_pda(kernelstack,
 +		  task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
 +
@@ -36431,22 +38029,20 @@
 +{
 +}
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/setup64-xen.c linux-2.6.17-xen/arch/x86_64/kernel/setup64-xen.c
---- linux-2.6.17/arch/x86_64/kernel/setup64-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/setup64-xen.c	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/setup64-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/setup64-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/setup64-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/setup64-xen.c	2006-07-20 15:56:48.000000000 +0200
 @@ -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 at intel.com> 
 + *   Modified for Xen
 + *
 + */ 
-+#include <linux/config.h>
 +#include <linux/init.h>
 +#include <linux/kernel.h>
 +#include <linux/sched.h>
@@ -36475,6 +38071,7 @@
 +cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
 +
 +struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly;
++EXPORT_SYMBOL(_cpu_pda);
 +struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
 +
 +#ifndef CONFIG_X86_NO_IDT
@@ -36484,6 +38081,7 @@
 +char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
 +
 +unsigned long __supported_pte_mask __read_mostly = ~0UL;
++EXPORT_SYMBOL(__supported_pte_mask);
 +static int do_not_nx __cpuinitdata = 0;
 +
 +/* noexec=on|off
@@ -36795,10 +38393,10 @@
 +
 +	fpu_init(); 
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/setup-xen.c linux-2.6.17-xen/arch/x86_64/kernel/setup-xen.c
---- linux-2.6.17/arch/x86_64/kernel/setup-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/setup-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,1710 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/setup-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/setup-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/setup-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/setup-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,1656 @@
 +/*
 + *  linux/arch/x86-64/kernel/setup.c
 + *
@@ -36806,8 +38404,6 @@
 + *
 + *  Nov 2001 Dave Jones <davej at suse.de>
 + *  Forked from i386 setup code.
-+ *
-+ *  $Id$
 + */
 +
 +/*
@@ -36824,10 +38420,9 @@
 +#include <linux/slab.h>
 +#include <linux/user.h>
 +#include <linux/a.out.h>
-+#include <linux/tty.h>
++#include <linux/screen_info.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>
@@ -36866,9 +38461,7 @@
 +#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>
 +#include <asm/dmi.h>
 +#ifdef CONFIG_XEN
 +#include <linux/percpu.h>
@@ -36884,6 +38477,7 @@
 +
 +extern unsigned long start_pfn;
 +extern struct edid_info edid_info;
++EXPORT_SYMBOL_GPL(edid_info);
 +
 +shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
 +EXPORT_SYMBOL(HYPERVISOR_shared_info);
@@ -36917,6 +38511,7 @@
 + */
 +
 +struct cpuinfo_x86 boot_cpu_data __read_mostly;
++EXPORT_SYMBOL(boot_cpu_data);
 +
 +unsigned long mmu_cr4_features;
 +
@@ -36945,6 +38540,7 @@
 + * Setup options
 + */
 +struct screen_info screen_info;
++EXPORT_SYMBOL(screen_info);
 +struct sys_desc_table_struct {
 +	unsigned short length;
 +	unsigned char table[0];
@@ -36998,7 +38594,6 @@
 +
 +#define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM)
 +
-+#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN)
 +static struct resource system_rom_resource = {
 +	.name = "System ROM",
 +	.start = 0xf0000,
@@ -37027,19 +38622,16 @@
 +	{ .name = "Adapter ROM", .start = 0, .end = 0,
 +		.flags = IORESOURCE_ROM }
 +};
-+#endif
 +
 +#define ADAPTER_ROM_RESOURCES \
 +	(sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
 +
-+#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN)
 +static struct resource video_rom_resource = {
 +	.name = "Video ROM",
 +	.start = 0xc0000,
 +	.end = 0xc7fff,
 +	.flags = IORESOURCE_ROM,
 +};
-+#endif
 +
 +static struct resource video_ram_resource = {
 +	.name = "Video RAM area",
@@ -37048,7 +38640,6 @@
 +	.flags = IORESOURCE_RAM,
 +};
 +
-+#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN)
 +#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
 +
 +static int __init romchecksum(unsigned char *rom, unsigned long length)
@@ -37066,6 +38657,12 @@
 +	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) {
@@ -37124,7 +38721,6 @@
 +		start = adapter_rom_resources[i++].end & ~2047UL;
 +	}
 +}
-+#endif
 +
 +/* Check for full argument with no trailing characters */
 +static int fullarg(char *p, char *arg)
@@ -37327,80 +38923,6 @@
 +} 
 +#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 1;
-+} 
-+
-+__setup("noreplacement", noreplacement_setup); 
-+
 +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 +struct edd edd;
 +#ifdef CONFIG_EDD_MODULE
@@ -37454,11 +38976,8 @@
 +void __init setup_arch(char **cmdline_p)
 +{
 +	unsigned long kernel_end;
-+
-+#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
 +	struct e820entry *machine_e820;
 +	struct xen_memory_map memmap;
-+#endif
 +
 +#ifdef CONFIG_XEN
 +	/* Register a call for panic conditions. */
@@ -37468,7 +38987,7 @@
 +	kernel_end = 0;		/* dummy */
 + 	screen_info = SCREEN_INFO;
 +
-+	if (xen_start_info->flags & SIF_INITDOMAIN) {
++	if (is_initial_xendomain()) {
 +		/* This is drawn from a dump from vgacon:startup in
 +		 * standard Linux. */
 +		screen_info.orig_video_mode = 3;
@@ -37477,6 +38996,35 @@
 +		screen_info.orig_video_cols = 80;
 +		screen_info.orig_video_ega_bx = 3;
 +		screen_info.orig_video_points = 16;
++		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);
++			screen_info.orig_video_mode = info->txt_mode;
++			screen_info.orig_video_isVGA = info->video_type;
++			screen_info.orig_video_lines = info->video_height;
++			screen_info.orig_video_cols = info->video_width;
++			screen_info.orig_video_points = info->txt_points;
++			screen_info.lfb_width = info->video_width;
++			screen_info.lfb_height = info->video_height;
++			screen_info.lfb_depth = info->lfb_depth;
++			screen_info.lfb_base = info->lfb_base;
++			screen_info.lfb_size = info->lfb_size;
++			screen_info.lfb_linelength = info->lfb_linelen;
++			screen_info.red_size = info->red_size;
++			screen_info.red_pos = info->red_pos;
++			screen_info.green_size = info->green_size;
++			screen_info.green_pos = info->green_pos;
++			screen_info.blue_size = info->blue_size;
++			screen_info.blue_pos = info->blue_pos;
++			screen_info.rsvd_size = info->rsvd_size;
++			screen_info.rsvd_pos = info->rsvd_pos;
++		}
++		screen_info.orig_y = screen_info.orig_video_lines - 1;
++		xen_start_info->console.domU.mfn = 0;
++		xen_start_info->console.domU.evtchn = 0;
 +	} else
 +		screen_info.orig_video_isVGA = 0;
 +
@@ -37637,7 +39185,7 @@
 +#endif	/* !CONFIG_XEN */
 +#ifdef CONFIG_KEXEC
 +	if (crashk_res.start != crashk_res.end) {
-+		reserve_bootmem(crashk_res.start,
++		reserve_bootmem_generic(crashk_res.start,
 +			crashk_res.end - crashk_res.start + 1);
 +	}
 +#endif
@@ -37695,11 +39243,10 @@
 +
 +	}
 +
-+	if (xen_start_info->flags & SIF_INITDOMAIN)
++	if (is_initial_xendomain())
 +		dmi_scan_machine();
 +
-+	if ( ! (xen_start_info->flags & SIF_INITDOMAIN))
-+	{
++	if (!is_initial_xendomain()) {
 +		acpi_disabled = 1;
 +#ifdef  CONFIG_ACPI
 +		acpi_ht = 0;
@@ -37752,9 +39299,9 @@
 +	 * Request address space for all standard RAM and ROM resources
 +	 * and also for regions reported as reserved by the e820.
 +	 */
-+#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
 +	probe_roms();
-+	if (xen_start_info->flags & SIF_INITDOMAIN) {
++#ifdef CONFIG_XEN
++	if (is_initial_xendomain()) {
 +		machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
 +
 +		memmap.nr_entries = E820MAX;
@@ -37763,14 +39310,9 @@
 +		BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
 +
 +		e820_reserve_resources(machine_e820, memmap.nr_entries);
-+	} else if (!(xen_start_info->flags & SIF_INITDOMAIN))
-+		e820_reserve_resources(e820.map, e820.nr_map);
-+#elif defined(CONFIG_XEN)
-+	e820_reserve_resources(e820.map, e820.nr_map);
-+#else
-+	probe_roms();
-+	e820_reserve_resources(e820.map, e820.nr_map);
++	} else
 +#endif
++	e820_reserve_resources(e820.map, e820.nr_map);
 +
 +	request_resource(&iomem_resource, &video_ram_resource);
 +
@@ -37781,19 +39323,15 @@
 +		request_resource(&ioport_resource, &standard_io_resources[i]);
 +	}
 +
-+#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
-+	if (xen_start_info->flags & SIF_INITDOMAIN) {
++#ifdef CONFIG_XEN
++	if (is_initial_xendomain()) {
 +		e820_setup_gap(machine_e820, memmap.nr_entries);
 +		free_bootmem(__pa(machine_e820), PAGE_SIZE);
 +	}
-+#elif !defined(CONFIG_XEN)
++#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;
@@ -37801,11 +39339,7 @@
 +		set_iopl.iopl = 1;
 +		HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
 +
-+		if (xen_start_info->flags & SIF_INITDOMAIN) {
-+			if (!(xen_start_info->flags & SIF_PRIVILEGED))
-+				panic("Xen granted us console access "
-+				      "but not privileged status");
-+		       
++		if (is_initial_xendomain()) {
 +#ifdef CONFIG_VT
 +#if defined(CONFIG_VGA_CONSOLE)
 +			conswitchp = &vga_con;
@@ -37917,24 +39451,32 @@
 +static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
 +{
 +#ifdef CONFIG_SMP
-+	int cpu = smp_processor_id();
 +	unsigned bits;
 +#ifdef CONFIG_NUMA
++	int cpu = smp_processor_id();
 +	int node = 0;
 +	unsigned apicid = hard_smp_processor_id();
 +#endif
++	unsigned ecx = cpuid_ecx(0x80000008);
 +
-+	bits = 0;
-+	while ((1 << bits) < c->x86_max_cores)
-+		bits++;
++	c->x86_max_cores = (ecx & 0xff) + 1;
++
++	/* CPU telling us the core id bits shift? */
++	bits = (ecx >> 12) & 0xF;
++
++	/* Otherwise recompute */
++	if (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);
++	c->cpu_core_id = c->phys_proc_id & ((1 << bits)-1);
 +	/* Convert the APIC ID into the socket ID */
-+	phys_proc_id[cpu] = phys_pkg_id(bits);
++	c->phys_proc_id = phys_pkg_id(bits);
 +
 +#ifdef CONFIG_NUMA
-+  	node = phys_proc_id[cpu];
++  	node = c->phys_proc_id;
 + 	if (apicid_to_node[apicid] != NUMA_NO_NODE)
 + 		node = apicid_to_node[apicid];
 + 	if (!node_online(node)) {
@@ -37947,7 +39489,7 @@
 + 		   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);
++ 		int ht_nodeid = apicid - (cpu_data[0].phys_proc_id << bits);
 + 		if (ht_nodeid >= 0 &&
 + 		    apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
 + 			node = apicid_to_node[ht_nodeid];
@@ -37957,15 +39499,13 @@
 + 	}
 +	numa_set_node(cpu, node);
 +
-+  	printk(KERN_INFO "CPU %d/%x(%d) -> Node %d -> Core %d\n",
-+  			cpu, apicid, c->x86_max_cores, node, cpu_core_id[cpu]);
++	printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
 +#endif
 +#endif
 +}
 +
-+static int __init init_amd(struct cpuinfo_x86 *c)
++static void __init init_amd(struct cpuinfo_x86 *c)
 +{
-+	int r;
 +	unsigned level;
 +
 +#ifdef CONFIG_SMP
@@ -37998,8 +39538,8 @@
 +	if (c->x86 >= 6)
 +		set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
 +
-+	r = get_model_name(c);
-+	if (!r) { 
++	level = get_model_name(c);
++	if (!level) { 
 +		switch (c->x86) { 
 +		case 15:
 +			/* Should distinguish Models here, but this is only
@@ -38014,13 +39554,12 @@
 +	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;
-+
++	/* Multi core CPU? */
++	if (c->extended_cpuid_level >= 0x80000008)
 +		amd_detect_cmp(c);
-+	}
 +
-+	return r;
++	/* Fix cpuid4 emulation for more */
++	num_cache_leaves = 3;
 +}
 +
 +static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
@@ -38033,8 +39572,10 @@
 +	cpuid(1, &eax, &ebx, &ecx, &edx);
 +
 +
-+	if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
++	if (!cpu_has(c, X86_FEATURE_HT))
 +		return;
++ 	if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
++		goto out;
 +
 +	smp_num_siblings = (ebx & 0xff0000) >> 16;
 +
@@ -38049,10 +39590,7 @@
 +		}
 +
 +		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]);
++		c->phys_proc_id = phys_pkg_id(index_msb);
 +
 +		smp_num_siblings = smp_num_siblings / c->x86_max_cores;
 +
@@ -38060,12 +39598,13 @@
 +
 +		core_bits = get_count_order(c->x86_max_cores);
 +
-+		cpu_core_id[cpu] = phys_pkg_id(index_msb) &
++		c->cpu_core_id = 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]);
++	}
++out:
++	if ((c->x86_max_cores * smp_num_siblings) > 1) {
++		printk(KERN_INFO  "CPU: Physical Processor ID: %d\n", c->phys_proc_id);
++		printk(KERN_INFO  "CPU: Processor Core ID: %d\n", c->cpu_core_id);
 +	}
 +#endif
 +}
@@ -38075,15 +39614,12 @@
 + */
 +static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
 +{
-+	unsigned int eax;
++	unsigned int eax, t;
 +
 +	if (c->cpuid_level < 4)
 +		return 1;
 +
-+	__asm__("cpuid"
-+		: "=a" (eax)
-+		: "0" (4), "c" (0)
-+		: "bx", "dx");
++	cpuid_count(4, 0, &eax, &t, &t, &t);
 +
 +	if (eax & 0x1f)
 +		return ((eax >> 26) + 1);
@@ -38096,16 +39632,17 @@
 +#ifdef CONFIG_NUMA
 +	unsigned node;
 +	int cpu = smp_processor_id();
++	int apicid = hard_smp_processor_id();
 +
 +	/* Don't do the funky fallback heuristics the AMD version employs
 +	   for now. */
-+	node = apicid_to_node[hard_smp_processor_id()];
++	node = apicid_to_node[apicid];
 +	if (node == NUMA_NO_NODE)
-+		node = 0;
++		node = first_node(node_online_map);
 +	numa_set_node(cpu, node);
 +
 +	if (acpi_numa > 0)
-+		printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node);
++		printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
 +#endif
 +}
 +
@@ -38115,6 +39652,13 @@
 +	unsigned n;
 +
 +	init_intel_cacheinfo(c);
++	if (c->cpuid_level > 9 ) {
++		unsigned eax = cpuid_eax(10);
++		/* Check for version and the number of counters */
++		if ((eax & 0xff) && (((eax>>8) & 0xff) > 1))
++			set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability);
++	}
++
 +	n = c->extended_cpuid_level;
 +	if (n >= 0x80000008) {
 +		unsigned eax = cpuid_eax(0x80000008);
@@ -38206,7 +39750,7 @@
 +	}
 +
 +#ifdef CONFIG_SMP
-+	phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
++	c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
 +#endif
 +}
 +
@@ -38333,7 +39877,7 @@
 +		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",
++		NULL, "fxsr_opt", NULL, "rdtscp", NULL, "lm", "3dnowext", "3dnow",
 +
 +		/* Transmeta-defined */
 +		"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
@@ -38345,7 +39889,7 @@
 +		"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,
++		"up", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 +		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 +
 +		/* Intel-defined (#2) */
@@ -38414,9 +39958,9 @@
 +#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, "physical id\t: %d\n", c->phys_proc_id);
 +		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, "core id\t\t: %d\n", c->cpu_core_id);
 +		seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
 +	}
 +#endif	
@@ -38490,7 +40034,7 @@
 +	.show =	show_cpuinfo,
 +};
 +
-+#ifdef CONFIG_INPUT_PCSPKR
++#if defined(CONFIG_INPUT_PCSPKR) || defined(CONFIG_INPUT_PCSPKR_MODULE)
 +#include <linux/platform_device.h>
 +static __init int add_pcspkr(void)
 +{
@@ -38509,26 +40053,10 @@
 +}
 +device_initcall(add_pcspkr);
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/smp.c linux-2.6.17-xen/arch/x86_64/kernel/smp.c
---- linux-2.6.17/arch/x86_64/kernel/smp.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/kernel/smp.c	2006-08-14 15:57:36.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/smp-xen.c linux-2.6.17-xen/arch/x86_64/kernel/smp-xen.c
---- linux-2.6.17/arch/x86_64/kernel/smp-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/smp-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,596 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/smp-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/smp-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/smp-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/smp-xen.c	2006-08-14 15:07:20.000000000 +0200
+@@ -0,0 +1,600 @@
 +/*
 + *	Intel SMP support routines.
 + *
@@ -38740,7 +40268,7 @@
 +{
 +	int i;
 +	for_each_cpu_mask(i, cpu_possible_map) {
-+		spin_lock_init(&per_cpu(flush_state.tlbstate_lock, i));
++		spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock);
 +	}
 +	return 0;
 +}
@@ -38761,6 +40289,7 @@
 +		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
 +	preempt_enable();
 +}
++EXPORT_SYMBOL(flush_tlb_current_task);
 +
 +void flush_tlb_mm (struct mm_struct * mm)
 +{
@@ -38781,6 +40310,7 @@
 +
 +	preempt_enable();
 +}
++EXPORT_SYMBOL(flush_tlb_mm);
 +
 +void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
 +{
@@ -38803,6 +40333,7 @@
 +
 +	preempt_enable();
 +}
++EXPORT_SYMBOL(flush_tlb_page);
 +
 +static void do_flush_tlb_all(void* info)
 +{
@@ -39000,6 +40531,7 @@
 +	spin_unlock(&call_lock);
 +	return 0;
 +}
++EXPORT_SYMBOL(smp_call_function);
 +
 +void smp_stop_cpu(void)
 +{
@@ -39031,7 +40563,7 @@
 +#endif
 +	/* Don't deadlock on the call lock in panic */
 +	if (!spin_trylock(&call_lock)) {
-+		/* ignore locking because we have paniced anyways */
++		/* ignore locking because we have panicked anyways */
 +		nolock = 1;
 +	}
 +	__smp_call_function(smp_really_stop_cpu, NULL, 0, 0);
@@ -39103,13 +40635,13 @@
 +#ifdef CONFIG_XEN
 +	return smp_processor_id();
 +#else
-+	int apicid, i;
++	unsigned apicid, i;
 +
 +	if (disable_apic)
 +		return 0;
 +
 +	apicid = hard_smp_processor_id();
-+	if (x86_cpu_to_apicid[apicid] == apicid)
++	if (apicid < NR_CPUS && x86_cpu_to_apicid[apicid] == apicid)
 +		return apicid;
 +
 +	for (i = 0; i < NR_CPUS; ++i) {
@@ -39125,10 +40657,10 @@
 +	return 0; /* Should not happen */
 +#endif
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/traps-xen.c linux-2.6.17-xen/arch/x86_64/kernel/traps-xen.c
---- linux-2.6.17/arch/x86_64/kernel/traps-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/traps-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,1035 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/traps-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/traps-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/traps-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/traps-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,1166 @@
 +/*
 + *  linux/arch/x86-64/traps.c
 + *
@@ -39137,15 +40669,12 @@
 + *
 + *  Pentium III FXSR, SSE support
 + *	Gareth Hughes <gareth at 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>
@@ -39162,6 +40691,7 @@
 +#include <linux/nmi.h>
 +#include <linux/kprobes.h>
 +#include <linux/kexec.h>
++#include <linux/unwind.h>
 +
 +#include <asm/system.h>
 +#include <asm/uaccess.h>
@@ -39172,7 +40702,7 @@
 +#include <asm/i387.h>
 +#include <asm/kdebug.h>
 +#include <asm/processor.h>
-+
++#include <asm/unwind.h>
 +#include <asm/smp.h>
 +#include <asm/pgalloc.h>
 +#include <asm/pda.h>
@@ -39208,13 +40738,13 @@
 +	vmalloc_sync_all();
 +	return atomic_notifier_chain_register(&die_chain, nb);
 +}
-+EXPORT_SYMBOL(register_die_notifier);
++EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
 +
 +int unregister_die_notifier(struct notifier_block *nb)
 +{
 +	return atomic_notifier_chain_unregister(&die_chain, nb);
 +}
-+EXPORT_SYMBOL(unregister_die_notifier);
++EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
 +
 +static inline void conditional_sti(struct pt_regs *regs)
 +{
@@ -39233,34 +40763,40 @@
 +{
 +	if (regs->eflags & X86_EFLAGS_IF)
 +		local_irq_disable();
++	/* Make sure to not schedule here because we could be running
++	   on an exception stack. */
 +	preempt_enable_no_resched();
 +}
 +
 +static int kstack_depth_to_print = 10;
++static int call_trace = 1;
 +
 +#ifdef CONFIG_KALLSYMS
-+#include <linux/kallsyms.h> 
-+int printk_address(unsigned long address)
-+{ 
++# include <linux/kallsyms.h>
++void printk_address(unsigned long address)
++{
 +	unsigned long offset = 0, symsize;
 +	const char *symname;
 +	char *modname;
-+	char *delim = ":"; 
++	char *delim = ":";
 +	char namebuf[128];
 +
-+	symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); 
-+	if (!symname) 
-+		return printk("[<%016lx>]", address);
-+	if (!modname) 
++	symname = kallsyms_lookup(address, &symsize, &offset,
++					&modname, namebuf);
++	if (!symname) {
++		printk(" [<%016lx>]\n", address);
++		return;
++	}
++	if (!modname)
 +		modname = delim = ""; 		
-+        return printk("<%016lx>{%s%s%s%s%+ld}",
-+		      address, delim, modname, delim, symname, offset); 
-+} 
++	printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n",
++		address, delim, modname, delim, symname, offset, symsize);
++}
 +#else
-+int printk_address(unsigned long address)
-+{ 
-+	return printk("[<%016lx>]", address);
-+} 
++void printk_address(unsigned long address)
++{
++	printk(" [<%016lx>]\n", address);
++}
 +#endif
 +
 +static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
@@ -39279,10 +40815,22 @@
 +	};
 +	unsigned k;
 +
++	/*
++	 * Iterate over all exception stacks, and figure out whether
++	 * 'stack' is in one of them:
++	 */
 +	for (k = 0; k < N_EXCEPTION_STACKS; k++) {
 +		unsigned long end;
 +
++		/*
++		 * set 'end' to the end of the exception stack.
++		 */
 +		switch (k + 1) {
++		/*
++		 * TODO: this block is not needed i think, because
++		 * setup64.c:cpu_init() sets up t->ist[DEBUG_STACK]
++		 * properly too.
++		 */
 +#if DEBUG_STKSZ > EXCEPTION_STKSZ
 +		case DEBUG_STACK:
 +			end = cpu_pda(cpu)->debugstack + DEBUG_STKSZ;
@@ -39292,19 +40840,43 @@
 +			end = per_cpu(init_tss, cpu).ist[k];
 +			break;
 +		}
++		/*
++		 * Is 'stack' above this exception frame's end?
++		 * If yes then skip to the next frame.
++		 */
 +		if (stack >= end)
 +			continue;
++		/*
++		 * Is 'stack' above this exception frame's start address?
++		 * If yes then we found the right frame.
++		 */
 +		if (stack >= end - EXCEPTION_STKSZ) {
++			/*
++			 * Make sure we only iterate through an exception
++			 * stack once. If it comes up for the second time
++			 * then there's something wrong going on - just
++			 * break out and return NULL:
++			 */
 +			if (*usedp & (1U << k))
 +				break;
 +			*usedp |= 1U << k;
 +			*idp = ids[k];
 +			return (unsigned long *)end;
 +		}
++		/*
++		 * If this is a debug stack, and if it has a larger size than
++		 * the usual exception stacks, then 'stack' might still
++		 * be within the lower portion of the debug stack:
++		 */
 +#if DEBUG_STKSZ > EXCEPTION_STKSZ
 +		if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) {
 +			unsigned j = N_EXCEPTION_STACKS - 1;
 +
++			/*
++			 * Black magic. A large debug stack is composed of
++			 * multiple exception stack entries, which we
++			 * iterate through now. Dont look:
++			 */
 +			do {
 +				++j;
 +				end -= EXCEPTION_STKSZ;
@@ -39322,6 +40894,19 @@
 +	return NULL;
 +}
 +
++static int show_trace_unwind(struct unwind_frame_info *info, void *context)
++{
++	int n = 0;
++
++	while (unwind(info) == 0 && UNW_PC(info)) {
++		if (arch_unw_user_mode(info))
++			break;
++		n++;
++		printk_address(UNW_PC(info));
++	}
++	return n;
++}
++
 +/*
 + * x86-64 can have upto three kernel stacks: 
 + * process stack
@@ -39329,25 +40914,55 @@
 + * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
 + */
 +
-+void show_trace(unsigned long *stack)
++void show_trace(struct task_struct *tsk, struct pt_regs *regs, 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:");
++	printk("\nCall Trace:\n");
++
++	if (!tsk)
++		tsk = current;
 +
++	if (call_trace >= 0) {
++		int unw_ret = 0;
++		struct unwind_frame_info info;
++
++		if (regs) {
++			if (unwind_init_frame_info(&info, tsk, regs) == 0)
++				unw_ret = show_trace_unwind(&info, NULL);
++		} else if (tsk == current)
++			unw_ret = unwind_init_running(&info, show_trace_unwind, NULL);
++		else {
++			if (unwind_init_blocked(&info, tsk) == 0)
++				unw_ret = show_trace_unwind(&info, NULL);
++		}
++		if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
++#ifdef CONFIG_STACK_UNWIND
++			unsigned long rip = info.regs.rip;
++			print_symbol("DWARF2 unwinder stuck at %s\n", rip);
++			if (call_trace == 1) {
++				printk("Leftover inexact backtrace:\n");
++				stack = (unsigned long *)info.regs.rsp;
++			} else if (call_trace > 1)
++				return;
++			else
++				printk("Full inexact backtrace again:\n");
++#else
++			printk("Inexact backtrace:\n");
++#endif
++		}
++	}
++ 	/*
++ 	 * Print function call entries within a stack. 'cond' is the
++ 	 * "end of stackframe" condition, that the 'stack++'
++ 	 * iteration will eventually trigger.
++ 	 */
 +#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 \
@@ -39356,20 +40971,30 @@
 +			 * down the cause of the crash will be able to figure \
 +			 * out the call path that was taken. \
 +			 */ \
-+			i += printk_address(addr); \
++			printk_address(addr); \
 +		} \
 +	} while (0)
 +
-+	for(i = 11; ; ) {
++	/*
++	 * Print function call entries in all stacks, starting at the
++	 * current stack address. If the stacks consist of nested
++	 * exceptions
++	 */
++	for ( ; ; ) {
 +		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);
++			printk(" <%s>", id);
 +			HANDLE_STACK (stack < estack_end);
-+			i += printk(" <EOE>");
++			printk(" <EOE>");
++			/*
++			 * We link to the next stack via the
++			 * second-to-last pointer (index -2 to end) in the
++			 * exception stack:
++			 */
 +			stack = (unsigned long *) estack_end[-2];
 +			continue;
 +		}
@@ -39379,23 +41004,32 @@
 +				(IRQSTACKSIZE - 64) / sizeof(*irqstack);
 +
 +			if (stack >= irqstack && stack < irqstack_end) {
-+				i += printk(" <IRQ>");
++				printk(" <IRQ>");
 +				HANDLE_STACK (stack < irqstack_end);
++				/*
++				 * We link to the next stack (which would be
++				 * the process stack normally) the last
++				 * pointer (index -1 to end) in the IRQ stack:
++				 */
 +				stack = (unsigned long *) (irqstack_end[-1]);
 +				irqstack_end = NULL;
-+				i += printk(" <EOI>");
++				printk(" <EOI>");
 +				continue;
 +			}
 +		}
 +		break;
 +	}
 +
++	/*
++	 * This prints the process stack:
++	 */
 +	HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0);
 +#undef HANDLE_STACK
++
 +	printk("\n");
 +}
 +
-+void show_stack(struct task_struct *tsk, unsigned long * rsp)
++static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long * rsp)
 +{
 +	unsigned long *stack;
 +	int i;
@@ -39425,11 +41059,16 @@
 +			break;
 +		}
 +		if (i && ((i % 4) == 0))
-+			printk("\n       ");
-+		printk("%016lx ", *stack++);
++			printk("\n");
++		printk(" %016lx ", *stack++);
 +		touch_nmi_watchdog();
 +	}
-+	show_trace((unsigned long *)rsp);
++	show_trace(tsk, regs, rsp);
++}
++
++void show_stack(struct task_struct *tsk, unsigned long * rsp)
++{
++	_show_stack(tsk, NULL, rsp);
 +}
 +
 +/*
@@ -39438,7 +41077,7 @@
 +void dump_stack(void)
 +{
 +	unsigned long dummy;
-+	show_trace(&dummy);
++	show_trace(NULL, NULL, &dummy);
 +}
 +
 +EXPORT_SYMBOL(dump_stack);
@@ -39465,7 +41104,7 @@
 +	if (in_kernel) {
 +
 +		printk("Stack: ");
-+		show_stack(NULL, (unsigned long*)rsp);
++		_show_stack(NULL, regs, (unsigned long*)rsp);
 +
 +		printk("\nCode: ");
 +		if (regs->rip < PAGE_OFFSET)
@@ -39552,7 +41191,7 @@
 +		/* Nest count reaches zero, release the lock. */
 +		spin_unlock_irqrestore(&die_lock, flags);
 +	if (panic_on_oops)
-+		panic("Oops");
++		panic("Fatal exception");
 +}
 +
 +void __kprobes __die(const char * str, struct pt_regs * regs, long err)
@@ -39618,8 +41257,6 @@
 +{
 +	struct task_struct *tsk = current;
 +
-+	conditional_sti(regs);
-+
 +	tsk->thread.error_code = error_code;
 +	tsk->thread.trap_no = trapnr;
 +
@@ -39656,6 +41293,7 @@
 +	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
 +							== NOTIFY_STOP) \
 +		return; \
++	conditional_sti(regs);						\
 +	do_trap(trapnr, signr, str, regs, error_code, NULL); \
 +}
 +
@@ -39670,6 +41308,7 @@
 +	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
 +							== NOTIFY_STOP) \
 +		return; \
++	conditional_sti(regs);						\
 +	do_trap(trapnr, signr, str, regs, error_code, &info); \
 +}
 +
@@ -39683,7 +41322,17 @@
 +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)
++
++/* Runs on IST stack */
++asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
++{
++	if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
++			12, SIGBUS) == NOTIFY_STOP)
++		return;
++	preempt_conditional_sti(regs);
++	do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL);
++	preempt_conditional_cli(regs);
++}
 +
 +asmlinkage void do_double_fault(struct pt_regs * regs, long error_code)
 +{
@@ -39821,8 +41470,9 @@
 +	if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
 +		return;
 +	}
++	preempt_conditional_sti(regs);
 +	do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
-+	return;
++	preempt_conditional_cli(regs);
 +}
 +
 +/* Help handler running on IST stack to switch back to user stack
@@ -40164,9 +41814,81 @@
 +}
 +__setup("kstack=", kstack_setup);
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/vsyscall-xen.c linux-2.6.17-xen/arch/x86_64/kernel/vsyscall-xen.c
---- linux-2.6.17/arch/x86_64/kernel/vsyscall-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/vsyscall-xen.c	2006-08-14 15:57:36.000000000 +0200
++static int __init call_trace_setup(char *s)
++{
++	if (strcmp(s, "old") == 0)
++		call_trace = -1;
++	else if (strcmp(s, "both") == 0)
++		call_trace = 0;
++	else if (strcmp(s, "newfallback") == 0)
++		call_trace = 1;
++ 	else if (strcmp(s, "new") == 0)
++		call_trace = 2;
++	return 1;
++}
++__setup("call_trace=", call_trace_setup);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/vmlinux.lds.S linux-2.6.18-rc5-xen/arch/x86_64/kernel/vmlinux.lds.S
+--- linux-2.6.18-rc5/arch/x86_64/kernel/vmlinux.lds.S	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/vmlinux.lds.S	2006-09-01 00:09:09.000000000 +0200
+@@ -13,6 +13,12 @@
+ 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;
+@@ -31,7 +37,7 @@
+ 	KPROBES_TEXT
+ 	*(.fixup)
+ 	*(.gnu.warning)
+-	} = 0x9090
++	} :text = 0x9090
+   				/* out-of-line lock text */
+   .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
+ 
+@@ -57,7 +63,7 @@
+   .data : AT(ADDR(.data) - LOAD_OFFSET) {
+ 	*(.data)
+ 	CONSTRUCTORS
+-	}
++	} :data
+ 
+   _edata = .;			/* End of data section */
+ 
+@@ -89,7 +95,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);
+@@ -132,7 +138,7 @@
+   . = 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) {
+@@ -235,4 +241,6 @@
+   STABS_DEBUG
+ 
+   DWARF_DEBUG
++
++  NOTES
+ }
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/vsyscall-xen.c linux-2.6.18-rc5-xen/arch/x86_64/kernel/vsyscall-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/kernel/vsyscall-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/vsyscall-xen.c	2006-07-20 15:56:48.000000000 +0200
 @@ -0,0 +1,239 @@
 +/*
 + *  linux/arch/x86_64/kernel/vsyscall.c
@@ -40277,7 +41999,7 @@
 +
 +int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
 +{
-+	if (unlikely(!__sysctl_vsyscall))
++	if (!__sysctl_vsyscall)
 +		return gettimeofday(tv,tz);
 +	if (tv)
 +		do_vgettimeofday(tv);
@@ -40290,7 +42012,7 @@
 + * unlikely */
 +time_t __vsyscall(1) vtime(time_t *t)
 +{
-+	if (unlikely(!__sysctl_vsyscall))
++	if (!__sysctl_vsyscall)
 +		return time_syscall(t);
 +	else if (t)
 +		*t = __xtime.tv_sec;		
@@ -40407,168 +42129,9 @@
 +}
 +
 +__initcall(vsyscall_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/x8664_ksyms-xen.c linux-2.6.17-xen/arch/x86_64/kernel/x8664_ksyms-xen.c
---- linux-2.6.17/arch/x86_64/kernel/x8664_ksyms-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/x8664_ksyms-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,155 @@
-+#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
-+
-+#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
-+
-+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(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);
-+
-+#ifdef CONFIG_SMP
-+EXPORT_SYMBOL(cpu_sibling_map);
-+EXPORT_SYMBOL(smp_num_siblings);
-+#endif
-+
-+#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 -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/kernel/xen_entry.S linux-2.6.17-xen/arch/x86_64/kernel/xen_entry.S
---- linux-2.6.17/arch/x86_64/kernel/xen_entry.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/kernel/xen_entry.S	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/kernel/xen_entry.S linux-2.6.18-rc5-xen/arch/x86_64/kernel/xen_entry.S
+--- linux-2.6.18-rc5/arch/x86_64/kernel/xen_entry.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/kernel/xen_entry.S	2006-07-20 15:56:48.000000000 +0200
 @@ -0,0 +1,40 @@
 +/*
 + * Copied from arch/xen/i386/kernel/entry.S
@@ -40610,10 +42173,10 @@
 +VGCF_IN_SYSCALL = (1<<8)
 +        
 +	
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/Makefile linux-2.6.17-xen/arch/x86_64/Makefile
---- linux-2.6.17/arch/x86_64/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/Makefile	2006-08-14 15:57:36.000000000 +0200
-@@ -31,6 +31,10 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/Makefile linux-2.6.18-rc5-xen/arch/x86_64/Makefile
+--- linux-2.6.18-rc5/arch/x86_64/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/Makefile	2006-07-20 15:56:48.000000000 +0200
+@@ -32,6 +32,10 @@
  cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
  cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
  
@@ -40624,7 +42187,7 @@
  cflags-y += -m64
  cflags-y += -mno-red-zone
  cflags-y += -mcmodel=kernel
-@@ -72,6 +76,21 @@
+@@ -74,6 +78,21 @@
  PHONY += bzImage bzlilo install archmrproper \
  	 fdimage fdimage144 fdimage288 isoimage archclean
  
@@ -40646,7 +42209,7 @@
  #Default target when executing "make"
  all: bzImage
  
-@@ -92,6 +111,7 @@
+@@ -94,6 +113,7 @@
  
  install:
  	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ 
@@ -40654,10 +42217,10 @@
  
  archclean:
  	$(Q)$(MAKE) $(clean)=$(boot)
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/mm/fault-xen.c linux-2.6.17-xen/arch/x86_64/mm/fault-xen.c
---- linux-2.6.17/arch/x86_64/mm/fault-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/mm/fault-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,690 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/mm/fault-xen.c linux-2.6.18-rc5-xen/arch/x86_64/mm/fault-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/mm/fault-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/mm/fault-xen.c	2006-07-20 15:56:48.000000000 +0200
+@@ -0,0 +1,723 @@
 +/*
 + *  linux/arch/x86-64/mm/fault.c
 + *
@@ -40665,7 +42228,6 @@
 + *  Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/signal.h>
 +#include <linux/sched.h>
 +#include <linux/kernel.h>
@@ -40701,6 +42263,41 @@
 +#define PF_RSVD	(1<<3)
 +#define PF_INSTR	(1<<4)
 +
++#ifdef CONFIG_KPROBES
++ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
++
++/* Hook to register for page fault notifications */
++int register_page_fault_notifier(struct notifier_block *nb)
++{
++	vmalloc_sync_all();
++	return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
++}
++
++int unregister_page_fault_notifier(struct notifier_block *nb)
++{
++	return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
++}
++
++static inline int notify_page_fault(enum die_val val, const char *str,
++			struct pt_regs *regs, long err, int trap, int sig)
++{
++	struct die_args args = {
++		.regs = regs,
++		.str = str,
++		.err = err,
++		.trapnr = trap,
++		.signr = sig
++	};
++	return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
++}
++#else
++static inline int notify_page_fault(enum die_val val, const char *str,
++			struct pt_regs *regs, long err, int trap, int sig)
++{
++	return NOTIFY_DONE;
++}
++#endif
++
 +void bust_spinlocks(int yes)
 +{
 +	int loglevel_save = console_loglevel;
@@ -40818,7 +42415,7 @@
 +	printk("PGD %lx ", pgd_val(*pgd));
 +	if (!pgd_present(*pgd)) goto ret; 
 +
-+	pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address);
++	pud = pud_offset(pgd, address);
 +	if (bad_address(pud)) goto bad;
 +	printk("PUD %lx ", pud_val(*pud));
 +	if (!pud_present(*pud))	goto ret;
@@ -41063,11 +42660,11 @@
 +		 * kernel text. Only vmalloc may need PML4 syncups.
 +		 */
 +		if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
-+		    address >= PAGE_OFFSET) {
++		      ((address >= VMALLOC_START && address < VMALLOC_END))) {
 +			if (vmalloc_fault(address) >= 0)
 +				return;
 +		}
-+		if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
++		if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
 +						SIGSEGV) == NOTIFY_STOP)
 +			return;
 +		/* Can take a spurious fault if mapping changes R/O -> R/W. */
@@ -41080,7 +42677,7 @@
 +		goto bad_area_nosemaphore;
 +	}
 +
-+	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
++	if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
 +					SIGSEGV) == NOTIFY_STOP)
 +		return;
 +
@@ -41105,7 +42702,7 @@
 +	/* 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
++	 * erroneous fault occurring 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
@@ -41256,7 +42853,6 @@
 +		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;
@@ -41348,10 +42944,10 @@
 +	return 1;
 +}
 +__setup("pagefaulttrace", enable_pagefaulttrace);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/mm/init-xen.c linux-2.6.17-xen/arch/x86_64/mm/init-xen.c
---- linux-2.6.17/arch/x86_64/mm/init-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/mm/init-xen.c	2006-08-14 15:57:36.000000000 +0200
-@@ -0,0 +1,1202 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/mm/init-xen.c linux-2.6.18-rc5-xen/arch/x86_64/mm/init-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/mm/init-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/mm/init-xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,1200 @@
 +/*
 + *  linux/arch/x86_64/mm/init.c
 + *
@@ -41363,7 +42959,6 @@
 + *	Modified for Xen.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/signal.h>
 +#include <linux/sched.h>
 +#include <linux/kernel.h>
@@ -41380,6 +42975,7 @@
 +#include <linux/bootmem.h>
 +#include <linux/proc_fs.h>
 +#include <linux/pci.h>
++#include <linux/poison.h>
 +#include <linux/dma-mapping.h>
 +#include <linux/module.h>
 +#include <linux/memory_hotplug.h>
@@ -41398,8 +42994,6 @@
 +#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>
 +
@@ -41552,8 +43146,6 @@
 +	printk(KERN_INFO "%lu pages swap cached\n",cached);
 +}
 +
-+/* References to section boundaries */
-+
 +int after_bootmem;
 +
 +static __init void *spp_getpage(void)
@@ -41839,8 +43431,9 @@
 +		pte_t *pte, *pte_save;
 +
 +		if (address >= end) {
-+			for (; i < PTRS_PER_PMD; i++, pmd++)
-+				set_pmd(pmd, __pmd(0));
++			if (!after_bootmem)
++				for (; i < PTRS_PER_PMD; i++, pmd++)
++					set_pmd(pmd, __pmd(0));
 +			break;
 +		}
 +		pte = alloc_static_page(&pte_phys);
@@ -41927,7 +43520,7 @@
 +		mk_kernel_pgd(__pa_symbol(level3_kernel_pgt));
 +	level3_kernel_pgt[pud_index(__START_KERNEL_map)] = 
 +		__pud(__pa_symbol(level2_kernel_pgt) |
-+		      _KERNPG_TABLE | _PAGE_USER);
++		      _KERNPG_TABLE);
 +	memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
 +
 +	early_make_page_readonly(init_level4_pgt,
@@ -41976,7 +43569,7 @@
 +			pte_page = alloc_static_page(&phys);
 +			early_make_page_readonly(
 +				pte_page, XENFEAT_writable_page_tables);
-+			set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER));
++			set_pmd(pmd, __pmd(phys | _KERNPG_TABLE));
 +		} else {
 +			addr = page[pmd_index(va)];
 +			addr_to_page(addr, pte_page);
@@ -41985,7 +43578,7 @@
 +		if (pte_none(*pte)) {
 +			new_pte = pfn_pte(
 +				(va - __START_KERNEL_map) >> PAGE_SHIFT, 
-+				__pgprot(_KERNPG_TABLE | _PAGE_USER));
++				__pgprot(_KERNPG_TABLE));
 +			xen_l1_entry_update(pte, new_pte);
 +		}
 +		va += PAGE_SIZE;
@@ -42019,7 +43612,8 @@
 +	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);
++		end, table_start << PAGE_SHIFT,
++		     (table_end << PAGE_SHIFT) + tables);
 +}
 +
 +/* Setup the direct mapping of the physical memory at PAGE_OFFSET.
@@ -42049,7 +43643,7 @@
 +		pud_t *pud;
 +
 +		if (after_bootmem) {
-+			pud = pud_offset_k(pgd, start & PGDIR_MASK);
++			pud = pud_offset(pgd, start & PGDIR_MASK);
 +			make_page_readonly(pud, XENFEAT_writable_page_tables);
 +			pud_phys = __pa(pud);
 +		} else {
@@ -42187,7 +43781,7 @@
 +
 +	/* Setup mapping of lower 1st MB */
 +	for (i = 0; i < NR_FIX_ISAMAPS; i++)
-+		if (xen_start_info->flags & SIF_PRIVILEGED)
++		if (is_initial_xendomain())
 +			set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
 +		else
 +			__set_fixmap(FIX_ISAMAP_BEGIN - i,
@@ -42233,7 +43827,6 @@
 +/*
 + * Memory hotplug specific functions
 + */
-+#if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)
 +
 +void online_page(struct page *page)
 +{
@@ -42244,31 +43837,17 @@
 +	num_physpages++;
 +}
 +
-+#ifndef CONFIG_MEMORY_HOTPLUG
++#ifdef CONFIG_MEMORY_HOTPLUG
 +/*
-+ * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
-+ * just online the pages.
++ * XXX: memory_add_physaddr_to_nid() is to find node id from physical address
++ *	via probe interface of sysfs. If acpi notifies hot-add event, then it
++ *	can tell node id by searching dsdt. But, probe interface doesn't have
++ *	node id. So, return 0 as node id at this time.
 + */
-+int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
++#ifdef CONFIG_NUMA
++int memory_add_physaddr_to_nid(u64 start)
 +{
-+	int err = -EIO;
-+	unsigned long pfn;
-+	unsigned long total = 0, mem = 0;
-+	for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
-+		if (pfn_valid(pfn)) {
-+			online_page(pfn_to_page(pfn));
-+			err = 0;
-+			mem++;
-+		}
-+		total++;
-+	}
-+	if (!err) {
-+		z->spanned_pages += total;
-+		z->present_pages += mem;
-+		z->zone_pgdat->node_spanned_pages += total;
-+		z->zone_pgdat->node_present_pages += mem;
-+	}
-+	return err;
++	return 0;
 +}
 +#endif
 +
@@ -42276,9 +43855,9 @@
 + * Memory is added always to NORMAL zone. This means you will never get
 + * additional DMA/DMA32 memory.
 + */
-+int add_memory(u64 start, u64 size)
++int arch_add_memory(int nid, u64 start, u64 size)
 +{
-+	struct pglist_data *pgdat = NODE_DATA(0);
++	struct pglist_data *pgdat = NODE_DATA(nid);
 +	struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2;
 +	unsigned long start_pfn = start >> PAGE_SHIFT;
 +	unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -42295,7 +43874,7 @@
 +	printk("%s: Problem encountered in __add_pages!\n", __func__);
 +	return ret;
 +}
-+EXPORT_SYMBOL_GPL(add_memory);
++EXPORT_SYMBOL_GPL(arch_add_memory);
 +
 +int remove_memory(u64 start, u64 size)
 +{
@@ -42303,7 +43882,33 @@
 +}
 +EXPORT_SYMBOL_GPL(remove_memory);
 +
-+#endif
++#else /* CONFIG_MEMORY_HOTPLUG */
++/*
++ * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
++ * just online the pages.
++ */
++int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
++{
++	int err = -EIO;
++	unsigned long pfn;
++	unsigned long total = 0, mem = 0;
++	for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
++		if (pfn_valid(pfn)) {
++			online_page(pfn_to_page(pfn));
++			err = 0;
++			mem++;
++		}
++		total++;
++	}
++	if (!err) {
++		z->spanned_pages += total;
++		z->present_pages += mem;
++		z->zone_pgdat->node_spanned_pages += total;
++		z->zone_pgdat->node_present_pages += mem;
++	}
++	return err;
++}
++#endif /* CONFIG_MEMORY_HOTPLUG */
 +
 +static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
 +			 kcore_vsyscall;
@@ -42318,10 +43923,7 @@
 +	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();
++	pci_iommu_alloc();
 +
 +	/* How many end-of-memory variables you have, grandma! */
 +	max_low_pfn = end_pfn;
@@ -42383,48 +43985,48 @@
 +#endif
 +}
 +
-+void free_initmem(void)
++void free_init_pages(char *what, unsigned long begin, unsigned long end)
 +{
 +#ifdef __DO_LATER__
-+	/*
-+	 * Some pages can be pinned, but some are not. Unpinning such pages 
-+	 * triggers BUG(). 
-+	 */
 +	unsigned long addr;
 +
-+	addr = (unsigned long)(&__init_begin);
-+	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
++	if (begin >= end)
++		return;
++
++	printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
++	for (addr = begin; addr < end; addr += PAGE_SIZE) {
 +		ClearPageReserved(virt_to_page(addr));
 +		init_page_count(virt_to_page(addr));
-+		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);
++		memset((void *)(addr & ~(PAGE_SIZE-1)),
++			POISON_FREE_INITMEM, PAGE_SIZE);
 +		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
++}
++
++void free_initmem(void)
++{
++#ifdef __DO_LATER__
++	memset(__initdata_begin, POISON_FREE_INITDATA,
++	       __initdata_end - __initdata_begin);
++	free_init_pages("unused kernel memory",
++			(unsigned long)(&__init_begin),
++			(unsigned long)(&__init_end));
 +#endif
 +}
 +
 +#ifdef CONFIG_DEBUG_RODATA
 +
-+extern char __start_rodata, __end_rodata;
 +void mark_rodata_ro(void)
 +{
-+	unsigned long addr = (unsigned long)&__start_rodata;
++	unsigned long addr = (unsigned long)__start_rodata;
 +
-+	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
++	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);
-+
++			(__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
@@ -42438,15 +44040,7 @@
 +#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));
-+		init_page_count(virt_to_page(start));
-+		free_page(start);
-+		totalram_pages++;
-+	}
++	free_init_pages("initrd memory", start, end);
 +}
 +#endif
 +
@@ -42554,9 +44148,9 @@
 +{
 +	return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/mm/Makefile linux-2.6.17-xen/arch/x86_64/mm/Makefile
---- linux-2.6.17/arch/x86_64/mm/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/mm/Makefile	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/mm/Makefile linux-2.6.18-rc5-xen/arch/x86_64/mm/Makefile
+--- linux-2.6.18-rc5/arch/x86_64/mm/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/mm/Makefile	2006-07-20 15:56:48.000000000 +0200
 @@ -9,3 +9,13 @@
  obj-$(CONFIG_ACPI_NUMA) += srat.o
  
@@ -42571,16 +44165,15 @@
 +
 +obj-y := $(call cherrypickxen, $(obj-y))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/mm/pageattr-xen.c linux-2.6.17-xen/arch/x86_64/mm/pageattr-xen.c
---- linux-2.6.17/arch/x86_64/mm/pageattr-xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/arch/x86_64/mm/pageattr-xen.c	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/mm/pageattr-xen.c linux-2.6.18-rc5-xen/arch/x86_64/mm/pageattr-xen.c
+--- linux-2.6.18-rc5/arch/x86_64/mm/pageattr-xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/arch/x86_64/mm/pageattr-xen.c	2006-08-14 15:07:20.000000000 +0200
 @@ -0,0 +1,396 @@
 +/* 
 + * 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>
@@ -42736,7 +44329,8 @@
 +
 +    task_unlock(tsk);
 +
-+    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) )
++    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) &&
++         !mm->context.has_foreign_mappings )
 +        mm_unpin(mm);
 +}
 +
@@ -42971,9 +44565,9 @@
 +
 +EXPORT_SYMBOL(change_page_attr);
 +EXPORT_SYMBOL(global_flush_tlb);
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/oprofile/Makefile linux-2.6.17-xen/arch/x86_64/oprofile/Makefile
---- linux-2.6.17/arch/x86_64/oprofile/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/oprofile/Makefile	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/oprofile/Makefile linux-2.6.18-rc5-xen/arch/x86_64/oprofile/Makefile
+--- linux-2.6.18-rc5/arch/x86_64/oprofile/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/oprofile/Makefile	2006-07-20 15:56:49.000000000 +0200
 @@ -11,9 +11,12 @@
  	oprofilefs.o oprofile_stats.o \
  	timer_int.o )
@@ -42988,9 +44582,9 @@
 -
 +endif
  oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
-diff -urN -x .hg -x .hgtags linux-2.6.17/arch/x86_64/pci/Makefile linux-2.6.17-xen/arch/x86_64/pci/Makefile
---- linux-2.6.17/arch/x86_64/pci/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/arch/x86_64/pci/Makefile	2006-08-14 15:57:36.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/arch/x86_64/pci/Makefile linux-2.6.18-rc5-xen/arch/x86_64/pci/Makefile
+--- linux-2.6.18-rc5/arch/x86_64/pci/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/arch/x86_64/pci/Makefile	2006-07-20 15:56:49.000000000 +0200
 @@ -15,11 +15,23 @@
  
  obj-$(CONFIG_NUMA)	+= k8-bus.o
@@ -43015,40 +44609,10 @@
 +
 +obj-y := $(call cherrypickxen, $(obj-y))
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/Documentation/networking/netdevices.txt linux-2.6.17-xen/Documentation/networking/netdevices.txt
---- linux-2.6.17/Documentation/networking/netdevices.txt	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/Documentation/networking/netdevices.txt	2006-08-14 15:57:10.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/acpi/Kconfig linux-2.6.17-xen/drivers/acpi/Kconfig
---- linux-2.6.17/drivers/acpi/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/acpi/Kconfig	2006-08-14 15:57:38.000000000 +0200
-@@ -46,7 +46,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/acpi/Kconfig linux-2.6.18-rc5-xen/drivers/acpi/Kconfig
+--- linux-2.6.18-rc5/drivers/acpi/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/acpi/Kconfig	2006-07-20 15:56:50.000000000 +0200
+@@ -45,7 +45,7 @@
  
  config ACPI_SLEEP
  	bool "Sleep States"
@@ -43057,7 +44621,7 @@
  	depends on PM
  	default y
  	---help---
-@@ -300,6 +300,7 @@
+@@ -305,6 +305,7 @@
  config X86_PM_TIMER
  	bool "Power Management Timer Support" if EMBEDDED
  	depends on X86
@@ -43065,10 +44629,22 @@
  	default y
  	help
  	  The Power Management Timer is available on all ACPI-capable,
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/mem.c linux-2.6.17-xen/drivers/char/mem.c
---- linux-2.6.17/drivers/char/mem.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/char/mem.c	2006-08-14 15:57:42.000000000 +0200
-@@ -103,6 +103,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/hangcheck-timer.c linux-2.6.18-rc5-xen/drivers/char/hangcheck-timer.c
+--- linux-2.6.18-rc5/drivers/char/hangcheck-timer.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/char/hangcheck-timer.c	2006-07-20 15:56:52.000000000 +0200
+@@ -117,7 +117,7 @@
+ __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
+ #endif /* not MODULE */
+ 
+-#if defined(CONFIG_X86_64) || defined(CONFIG_S390)
++#if defined(CONFIG_X86_64) || defined(CONFIG_S390) || defined(CONFIG_X86_XEN)
+ # define HAVE_MONOTONIC
+ # define TIMER_FREQ 1000000000ULL
+ #elif defined(CONFIG_IA64)
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/mem.c linux-2.6.18-rc5-xen/drivers/char/mem.c
+--- linux-2.6.18-rc5/drivers/char/mem.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/char/mem.c	2006-07-20 15:56:52.000000000 +0200
+@@ -101,6 +101,7 @@
  }
  #endif
  
@@ -43076,7 +44652,7 @@
  /*
   * This funcion reads the *physical* memory. The f_pos points directly to the 
   * memory location. 
-@@ -225,6 +226,7 @@
+@@ -223,6 +224,7 @@
  	*ppos += written;
  	return written;
  }
@@ -43084,15 +44660,15 @@
  
  #ifndef __HAVE_PHYS_MEM_ACCESS_PROT
  static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
-@@ -778,6 +780,7 @@
+@@ -776,6 +778,7 @@
  #define open_kmem	open_mem
  #define open_oldmem	open_mem
  
 +#ifndef ARCH_HAS_DEV_MEM
- static struct file_operations mem_fops = {
+ static const struct file_operations mem_fops = {
  	.llseek		= memory_lseek,
  	.read		= read_mem,
-@@ -785,6 +788,9 @@
+@@ -783,6 +786,9 @@
  	.mmap		= mmap_mem,
  	.open		= open_mem,
  };
@@ -43100,11 +44676,11 @@
 +extern struct file_operations mem_fops;
 +#endif
  
- static struct file_operations kmem_fops = {
+ static const struct file_operations kmem_fops = {
  	.llseek		= memory_lseek,
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/tpm/Kconfig linux-2.6.17-xen/drivers/char/tpm/Kconfig
---- linux-2.6.17/drivers/char/tpm/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/char/tpm/Kconfig	2006-08-14 15:57:43.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/tpm/Kconfig linux-2.6.18-rc5-xen/drivers/char/tpm/Kconfig
+--- linux-2.6.18-rc5/drivers/char/tpm/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/char/tpm/Kconfig	2006-07-20 15:56:52.000000000 +0200
 @@ -31,7 +31,7 @@
  
  config TCG_NSC
@@ -43129,18 +44705,18 @@
 +	  will be called tpm_xenu.
  
 +endmenu
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/tpm/Makefile linux-2.6.17-xen/drivers/char/tpm/Makefile
---- linux-2.6.17/drivers/char/tpm/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/char/tpm/Makefile	2006-08-14 15:57:43.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/tpm/Makefile linux-2.6.18-rc5-xen/drivers/char/tpm/Makefile
+--- linux-2.6.18-rc5/drivers/char/tpm/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/char/tpm/Makefile	2006-07-20 15:56:52.000000000 +0200
 @@ -9,3 +9,5 @@
  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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/tpm/tpm.c linux-2.6.17-xen/drivers/char/tpm/tpm.c
---- linux-2.6.17/drivers/char/tpm/tpm.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/char/tpm/tpm.c	2006-08-14 15:57:43.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/tpm/tpm.c linux-2.6.18-rc5-xen/drivers/char/tpm/tpm.c
+--- linux-2.6.18-rc5/drivers/char/tpm/tpm.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/char/tpm/tpm.c	2006-09-01 00:09:09.000000000 +0200
 @@ -30,7 +30,9 @@
  
  enum tpm_const {
@@ -43261,9 +44837,9 @@
  	return ret_size;
  }
  EXPORT_SYMBOL_GPL(tpm_read);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/tpm/tpm.h linux-2.6.17-xen/drivers/char/tpm/tpm.h
---- linux-2.6.17/drivers/char/tpm/tpm.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/char/tpm/tpm.h	2006-08-14 15:57:43.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/tpm/tpm.h linux-2.6.18-rc5-xen/drivers/char/tpm/tpm.h
+--- linux-2.6.18-rc5/drivers/char/tpm/tpm.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/char/tpm/tpm.h	2006-07-20 15:56:52.000000000 +0200
 @@ -61,6 +61,7 @@
  	const u8 req_complete_mask;
  	const u8 req_complete_val;
@@ -43292,9 +44868,9 @@
  extern void tpm_get_timeouts(struct tpm_chip *);
  extern void tpm_gen_interrupt(struct tpm_chip *);
  extern void tpm_continue_selftest(struct tpm_chip *);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/tpm/tpm_vtpm.c linux-2.6.17-xen/drivers/char/tpm/tpm_vtpm.c
---- linux-2.6.17/drivers/char/tpm/tpm_vtpm.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/char/tpm/tpm_vtpm.c	2006-08-14 15:57:43.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/tpm/tpm_vtpm.c linux-2.6.18-rc5-xen/drivers/char/tpm/tpm_vtpm.c
+--- linux-2.6.18-rc5/drivers/char/tpm/tpm_vtpm.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/char/tpm/tpm_vtpm.c	2006-07-20 15:56:52.000000000 +0200
 @@ -0,0 +1,547 @@
 +/*
 + * Copyright (C) 2006 IBM Corporation
@@ -43843,9 +45419,9 @@
 +	tpm_remove_hardware(dev);
 +	kfree(vtpms);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/tpm/tpm_vtpm.h linux-2.6.17-xen/drivers/char/tpm/tpm_vtpm.h
---- linux-2.6.17/drivers/char/tpm/tpm_vtpm.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/char/tpm/tpm_vtpm.h	2006-08-14 15:57:43.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/tpm/tpm_vtpm.h linux-2.6.18-rc5-xen/drivers/char/tpm/tpm_vtpm.h
+--- linux-2.6.18-rc5/drivers/char/tpm/tpm_vtpm.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/char/tpm/tpm_vtpm.h	2006-07-20 15:56:52.000000000 +0200
 @@ -0,0 +1,68 @@
 +#ifndef TPM_VTPM_H
 +#define TPM_VTPM_H
@@ -43915,10 +45491,10 @@
 +}
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/tpm/tpm_xen.c linux-2.6.17-xen/drivers/char/tpm/tpm_xen.c
---- linux-2.6.17/drivers/char/tpm/tpm_xen.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/char/tpm/tpm_xen.c	2006-08-14 15:57:43.000000000 +0200
-@@ -0,0 +1,758 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/tpm/tpm_xen.c linux-2.6.18-rc5-xen/drivers/char/tpm/tpm_xen.c
+--- linux-2.6.18-rc5/drivers/char/tpm/tpm_xen.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/char/tpm/tpm_xen.c	2006-09-01 00:09:09.000000000 +0200
+@@ -0,0 +1,756 @@
 +/*
 + * Copyright (c) 2005, IBM Corporation
 + *
@@ -44264,7 +45840,6 @@
 +	case XenbusStateInitialising:
 +	case XenbusStateInitWait:
 +	case XenbusStateInitialised:
-+	case XenbusStateUnknown:
 +		break;
 +
 +	case XenbusStateConnected:
@@ -44275,10 +45850,10 @@
 +		tpmif_set_connected_state(tp, 0);
 +		break;
 +
++	case XenbusStateUnknown:
 +	case XenbusStateClosed:
-+		if (tp->is_suspended == 0) {
++		if (tp->is_suspended == 0)
 +			device_unregister(&dev->dev);
-+		}
 +		xenbus_switch_state(dev, XenbusStateClosed);
 +		break;
 +	}
@@ -44639,9 +46214,8 @@
 +	long rc = 0;
 +	struct tpm_private *tp;
 +
-+	if ((xen_start_info->flags & SIF_INITDOMAIN)) {
++	if (is_initial_xendomain())
 +		return -EPERM;
-+	}
 +
 +	tp = tpm_private_get();
 +	if (!tp) {
@@ -44677,10 +46251,10 @@
 +module_init(tpmif_init);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/char/tty_io.c linux-2.6.17-xen/drivers/char/tty_io.c
---- linux-2.6.17/drivers/char/tty_io.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/char/tty_io.c	2006-08-14 15:57:43.000000000 +0200
-@@ -132,6 +132,8 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/char/tty_io.c linux-2.6.18-rc5-xen/drivers/char/tty_io.c
+--- linux-2.6.18-rc5/drivers/char/tty_io.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/char/tty_io.c	2006-09-01 00:09:09.000000000 +0200
+@@ -130,6 +130,8 @@
     vt.c for deeply disgusting hack reasons */
  DEFINE_MUTEX(tty_mutex);
  
@@ -44689,7 +46263,7 @@
  #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 */
-@@ -2060,7 +2062,7 @@
+@@ -2483,7 +2485,7 @@
  		goto got_driver;
  	}
  #ifdef CONFIG_VT
@@ -44698,7 +46272,7 @@
  		extern struct tty_driver *console_driver;
  		driver = console_driver;
  		index = fg_console;
-@@ -3258,6 +3260,8 @@
+@@ -3909,6 +3911,8 @@
  #endif
  
  #ifdef CONFIG_VT
@@ -44707,7 +46281,7 @@
  	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)
-@@ -3266,6 +3270,7 @@
+@@ -3916,6 +3920,7 @@
  	class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
  
  	vty_init();
@@ -44715,22 +46289,22 @@
  #endif
  	return 0;
  }
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/firmware/Kconfig linux-2.6.17-xen/drivers/firmware/Kconfig
---- linux-2.6.17/drivers/firmware/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/firmware/Kconfig	2006-08-14 15:57:44.000000000 +0200
-@@ -8,7 +8,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/firmware/Kconfig linux-2.6.18-rc5-xen/drivers/firmware/Kconfig
+--- linux-2.6.18-rc5/drivers/firmware/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/firmware/Kconfig	2006-07-20 15:56:53.000000000 +0200
+@@ -7,7 +7,7 @@
+ 
  config EDD
- 	tristate "BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)"
- 	depends on EXPERIMENTAL
+ 	tristate "BIOS Enhanced Disk Drive calls determine boot disk"
 -	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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/ide/ide-lib.c linux-2.6.17-xen/drivers/ide/ide-lib.c
---- linux-2.6.17/drivers/ide/ide-lib.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/ide/ide-lib.c	2006-08-14 15:57:46.000000000 +0200
-@@ -410,10 +410,10 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/ide/ide-lib.c linux-2.6.18-rc5-xen/drivers/ide/ide-lib.c
+--- linux-2.6.18-rc5/drivers/ide/ide-lib.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/ide/ide-lib.c	2006-07-20 15:56:53.000000000 +0200
+@@ -408,10 +408,10 @@
  {
  	u64 addr = BLK_BOUNCE_HIGH;	/* dma64_addr_t */
  
@@ -44745,32 +46319,9 @@
  			addr = HWIF(drive)->pci_dev->dma_mask;
  	}
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/infiniband/ulp/ipoib/ipoib_multicast.c linux-2.6.17-xen/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
---- linux-2.6.17/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2006-08-14 15:57:46.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/Makefile linux-2.6.17-xen/drivers/Makefile
---- linux-2.6.17/drivers/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/Makefile	2006-08-14 15:57:38.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/Makefile linux-2.6.18-rc5-xen/drivers/Makefile
+--- linux-2.6.18-rc5/drivers/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/Makefile	2006-07-20 15:56:50.000000000 +0200
 @@ -31,6 +31,7 @@
  obj-$(CONFIG_NUBUS)		+= nubus/
  obj-$(CONFIG_ATM)		+= atm/
@@ -44779,660 +46330,9 @@
  obj-$(CONFIG_IDE)		+= ide/
  obj-$(CONFIG_FC4)		+= fc4/
  obj-$(CONFIG_SCSI)		+= scsi/
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/media/dvb/dvb-core/dvb_net.c linux-2.6.17-xen/drivers/media/dvb/dvb-core/dvb_net.c
---- linux-2.6.17/drivers/media/dvb/dvb-core/dvb_net.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/media/dvb/dvb-core/dvb_net.c	2006-08-14 15:57:48.000000000 +0200
-@@ -1052,7 +1052,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);
-@@ -1077,7 +1077,7 @@
- 		}
- 	}
- 
--	spin_unlock_bh(&dev->xmit_lock);
-+	netif_tx_unlock_bh(dev);
- 	dvb_net_feed_start(dev);
- }
- 
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/8139cp.c linux-2.6.17-xen/drivers/net/8139cp.c
---- linux-2.6.17/drivers/net/8139cp.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/8139cp.c	2006-08-14 15:57:51.000000000 +0200
-@@ -792,7 +792,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/bnx2.c linux-2.6.17-xen/drivers/net/bnx2.c
---- linux-2.6.17/drivers/net/bnx2.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/bnx2.c	2006-08-14 15:57:52.000000000 +0200
-@@ -1638,7 +1638,7 @@
- 		skb = tx_buf->skb;
- #ifdef BCM_TSO 
- 		/* partial BD completions possible with TSO packets */
--		if (skb_shinfo(skb)->tso_size) {
-+		if (skb_shinfo(skb)->gso_size) {
- 			u16 last_idx, last_ring_idx;
- 
- 			last_idx = sw_cons +
-@@ -2009,7 +2009,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
-@@ -4252,7 +4252,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
-@@ -4290,7 +4290,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/bonding/bond_main.c linux-2.6.17-xen/drivers/net/bonding/bond_main.c
---- linux-2.6.17/drivers/net/bonding/bond_main.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/bonding/bond_main.c	2006-08-14 15:57:52.000000000 +0200
-@@ -1199,8 +1199,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
-@@ -1218,9 +1217,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;
- 
- 	/* 
-@@ -4191,7 +4188,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/chelsio/sge.c linux-2.6.17-xen/drivers/net/chelsio/sge.c
---- linux-2.6.17/drivers/net/chelsio/sge.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/chelsio/sge.c	2006-08-14 15:57:52.000000000 +0200
-@@ -1418,7 +1418,7 @@
- 	struct cpl_tx_pkt *cpl;
- 
- #ifdef NETIF_F_TSO
--	if (skb_shinfo(skb)->tso_size) {
-+	if (skb_shinfo(skb)->gso_size) {
- 		int eth_type;
- 		struct cpl_tx_pkt_lso *hdr;
- 
-@@ -1433,7 +1433,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/e1000/e1000_main.c linux-2.6.17-xen/drivers/net/e1000/e1000_main.c
---- linux-2.6.17/drivers/net/e1000/e1000_main.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/e1000/e1000_main.c	2006-08-14 15:57:52.000000000 +0200
-@@ -2413,7 +2413,7 @@
- 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
- 	int err;
- 
--	if (skb_shinfo(skb)->tso_size) {
-+	if (skb_shinfo(skb)->gso_size) {
- 		if (skb_header_cloned(skb)) {
- 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
- 			if (err)
-@@ -2421,7 +2421,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;
-@@ -2538,7 +2538,7 @@
- 		 * tso gets written back prematurely before the data is fully
- 		 * DMA'd to the controller */
- 		if (!skb->data_len && tx_ring->last_tx_tso &&
--		    !skb_shinfo(skb)->tso_size) {
-+				!skb_shinfo(skb)->gso_size) {
- 			tx_ring->last_tx_tso = 0;
- 			size -= 4;
- 		}
-@@ -2776,7 +2776,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:
-@@ -2826,7 +2826,7 @@
- #ifdef NETIF_F_TSO
- 	/* Controller Erratum workaround */
- 	if (!skb->data_len && tx_ring->last_tx_tso &&
--	    !skb_shinfo(skb)->tso_size)
-+	    !skb_shinfo(skb)->gso_size)
- 		count++;
- #endif
- 
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/forcedeth.c linux-2.6.17-xen/drivers/net/forcedeth.c
---- linux-2.6.17/drivers/net/forcedeth.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/forcedeth.c	2006-08-14 15:57:52.000000000 +0200
-@@ -533,9 +533,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 */
-@@ -1213,7 +1213,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)
- {
-@@ -1303,8 +1303,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_shinfo(skb)->gso_size)
-+		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);
-@@ -1407,7 +1407,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)
- {
-@@ -1736,8 +1736,8 @@
- 		 * guessed, there is probably a simpler approach.
- 		 * Changing the MTU is a rare event, it shouldn't matter.
- 		 */
--		nv_disable_irq(dev);
--		spin_lock_bh(&dev->xmit_lock);
-+		disable_irq(dev->irq);
-+		netif_tx_lock_bh(dev);
- 		spin_lock(&np->lock);
- 		/* stop engines */
- 		nv_stop_rx(dev);
-@@ -1768,8 +1768,8 @@
- 		nv_start_rx(dev);
- 		nv_start_tx(dev);
- 		spin_unlock(&np->lock);
--		spin_unlock_bh(&dev->xmit_lock);
--		nv_enable_irq(dev);
-+		netif_tx_unlock_bh(dev);
-+		enable_irq(dev->irq);
- 	}
- 	return 0;
- }
-@@ -1803,7 +1803,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 */
-@@ -1815,7 +1815,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);
- 	}
-@@ -1824,7 +1824,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/hamradio/6pack.c linux-2.6.17-xen/drivers/net/hamradio/6pack.c
---- linux-2.6.17/drivers/net/hamradio/6pack.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/hamradio/6pack.c	2006-08-14 15:57:52.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/hamradio/mkiss.c linux-2.6.17-xen/drivers/net/hamradio/mkiss.c
---- linux-2.6.17/drivers/net/hamradio/mkiss.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/hamradio/mkiss.c	2006-08-14 15:57:52.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/ifb.c linux-2.6.17-xen/drivers/net/ifb.c
---- linux-2.6.17/drivers/net/ifb.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/ifb.c	2006-08-14 15:57:52.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/irda/vlsi_ir.c linux-2.6.17-xen/drivers/net/irda/vlsi_ir.c
---- linux-2.6.17/drivers/net/irda/vlsi_ir.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/irda/vlsi_ir.c	2006-08-14 15:57:52.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/ixgb/ixgb_main.c linux-2.6.17-xen/drivers/net/ixgb/ixgb_main.c
---- linux-2.6.17/drivers/net/ixgb/ixgb_main.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/ixgb/ixgb_main.c	2006-08-14 15:57:52.000000000 +0200
-@@ -1168,7 +1168,7 @@
- 	uint16_t ipcse, tucse, mss;
- 	int err;
- 
--	if(likely(skb_shinfo(skb)->tso_size)) {
-+	if(likely(skb_shinfo(skb)->gso_size)) {
- 		if (skb_header_cloned(skb)) {
- 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
- 			if (err)
-@@ -1176,7 +1176,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/loopback.c linux-2.6.17-xen/drivers/net/loopback.c
---- linux-2.6.17/drivers/net/loopback.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/loopback.c	2006-08-14 15:57:52.000000000 +0200
-@@ -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_shinfo(skb)->gso_size) {
- 		BUG_ON(skb->protocol != htons(ETH_P_IP));
- 		BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
- 
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/mv643xx_eth.c linux-2.6.17-xen/drivers/net/mv643xx_eth.c
---- linux-2.6.17/drivers/net/mv643xx_eth.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/mv643xx_eth.c	2006-08-14 15:57:52.000000000 +0200
-@@ -1200,7 +1200,7 @@
- 	}
- 
- 	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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/natsemi.c linux-2.6.17-xen/drivers/net/natsemi.c
---- linux-2.6.17/drivers/net/natsemi.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/natsemi.c	2006-08-14 15:57:52.000000000 +0200
-@@ -318,12 +318,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/r8169.c linux-2.6.17-xen/drivers/net/r8169.c
---- linux-2.6.17/drivers/net/r8169.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/r8169.c	2006-08-14 15:57:53.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/s2io.c linux-2.6.17-xen/drivers/net/s2io.c
---- linux-2.6.17/drivers/net/s2io.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/s2io.c	2006-08-14 15:57:53.000000000 +0200
-@@ -3564,8 +3564,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);
- 	}
-@@ -3585,10 +3585,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);
-@@ -3614,7 +3614,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;
-@@ -3629,12 +3629,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];
-@@ -3648,7 +3648,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/sky2.c linux-2.6.17-xen/drivers/net/sky2.c
---- linux-2.6.17/drivers/net/sky2.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/sky2.c	2006-08-14 15:57:53.000000000 +0200
-@@ -1160,7 +1160,7 @@
- 	count = sizeof(dma_addr_t) / sizeof(u32);
- 	count += skb_shinfo(skb)->nr_frags * count;
- 
--	if (skb_shinfo(skb)->tso_size)
-+	if (skb_shinfo(skb)->gso_size)
- 		++count;
- 
- 	if (skb->ip_summed == CHECKSUM_HW)
-@@ -1232,7 +1232,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/tg3.c linux-2.6.17-xen/drivers/net/tg3.c
---- linux-2.6.17/drivers/net/tg3.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/tg3.c	2006-08-14 15:57:53.000000000 +0200
-@@ -3743,7 +3743,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) &&
-@@ -3871,7 +3871,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/tulip/winbond-840.c linux-2.6.17-xen/drivers/net/tulip/winbond-840.c
---- linux-2.6.17/drivers/net/tulip/winbond-840.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/tulip/winbond-840.c	2006-08-14 15:57:53.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/typhoon.c linux-2.6.17-xen/drivers/net/typhoon.c
---- linux-2.6.17/drivers/net/typhoon.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/typhoon.c	2006-08-14 15:57:53.000000000 +0200
-@@ -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
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/via-velocity.c linux-2.6.17-xen/drivers/net/via-velocity.c
---- linux-2.6.17/drivers/net/via-velocity.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/via-velocity.c	2006-08-14 15:57:53.000000000 +0200
-@@ -1899,6 +1899,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];
-@@ -1914,8 +1921,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);
-@@ -1933,7 +1938,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/net/wireless/orinoco.c linux-2.6.17-xen/drivers/net/wireless/orinoco.c
---- linux-2.6.17/drivers/net/wireless/orinoco.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/net/wireless/orinoco.c	2006-08-14 15:57:56.000000000 +0200
-@@ -1833,7 +1833,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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/oprofile/buffer_sync.c linux-2.6.17-xen/drivers/oprofile/buffer_sync.c
---- linux-2.6.17/drivers/oprofile/buffer_sync.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/oprofile/buffer_sync.c	2006-08-14 15:57:56.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/oprofile/buffer_sync.c linux-2.6.18-rc5-xen/drivers/oprofile/buffer_sync.c
+--- linux-2.6.18-rc5/drivers/oprofile/buffer_sync.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/oprofile/buffer_sync.c	2006-07-20 15:57:08.000000000 +0200
 @@ -6,6 +6,10 @@
   *
   * @author John Levon <levon at movementarian.org>
@@ -45444,7 +46344,7 @@
   * This is the core of the buffer management. Each
   * CPU buffer is processed and entered into the
   * global event buffer. Such processing is necessary
-@@ -275,15 +279,30 @@
+@@ -275,15 +279,31 @@
  	last_cookie = INVALID_COOKIE;
  }
  
@@ -45466,22 +46366,23 @@
 +	case CPU_MODE_XEN:
 +		add_event_entry(XEN_ENTER_SWITCH_CODE);
 +	  	break;
-+        case CPU_MODE_PASSIVE_START:
-+                add_event_entry(PASSIVE_START_CODE);
-+                break;
-+        case CPU_MODE_PASSIVE_STOP:
-+                add_event_entry(PASSIVE_STOP_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 +367,9 @@
+@@ -348,9 +368,9 @@
   * for later lookup from userspace.
   */
  static int
@@ -45493,7 +46394,7 @@
  		add_sample_entry(s->eip, s->event);
  		return 1;
  	} else if (mm) {
-@@ -496,10 +515,11 @@
+@@ -496,10 +516,11 @@
  	struct mm_struct *mm = NULL;
  	struct task_struct * new;
  	unsigned long cookie = 0;
@@ -45502,34 +46403,35 @@
  	unsigned int i;
  	sync_buffer_state state = sb_buffer_start;
  	unsigned long available;
-+	int domain_switch = NO_DOMAIN_SWITCH;
++	int domain_switch = 0;
  
- 	down(&buffer_sem);
+ 	mutex_lock(&buffer_mutex);
   
-@@ -513,12 +533,19 @@
+@@ -512,16 +533,18 @@
+ 	for (i = 0; i < available; ++i) {
  		struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
   
- 		if (is_code(s->eip)) {
+-		if (is_code(s->eip)) {
 -			if (s->event <= CPU_IS_KERNEL) {
-+			if (s->event < CPU_TRACE_BEGIN) {
- 				/* kernel/userspace switch */
+-				/* 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);
-+
-+				if (s->event == CPU_MODE_PASSIVE_START)
-+					domain_switch = DOMAIN_SWITCH_START_EVENT1;
-+				else if (s->event == CPU_MODE_PASSIVE_STOP)
-+					domain_switch = DOMAIN_SWITCH_STOP_EVENT1;
-+
-+				if (domain_switch != DOMAIN_SWITCH_START_EVENT2)
-+					add_cpu_mode_switch(s->event);
++				add_cpu_mode_switch(s->event);
  			} else if (s->event == CPU_TRACE_BEGIN) {
  				state = sb_bt_start;
  				add_trace_begin();
-@@ -535,11 +562,20 @@
++			} else if (s->event == CPU_DOMAIN_SWITCH) {
++					domain_switch = 1;				
+ 			} else {
+ 				struct mm_struct * oldmm = mm;
+ 
+@@ -535,11 +558,16 @@
  				add_user_ctx_switch(new, cookie);
  			}
  		} else {
@@ -45538,13 +46440,9 @@
 -				if (state == sb_bt_start) {
 -					state = sb_bt_ignore;
 -					atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-+			if (domain_switch == DOMAIN_SWITCH_START_EVENT1) {
-+			        add_event_entry(s->event);
-+				domain_switch = DOMAIN_SWITCH_START_EVENT2;
-+			} else if (domain_switch == DOMAIN_SWITCH_START_EVENT1) {
-+				add_sample_entry(s->eip, s->event);
-+			} else if (domain_switch == DOMAIN_SWITCH_STOP_EVENT1) {
-+				domain_switch = NO_DOMAIN_SWITCH;
++			if (domain_switch) {
++				add_domain_switch(s->eip);
++				domain_switch = 0;
 +			} else {
 +				if (state >= sb_bt_start &&
 +				    !add_sample(mm, s, cpu_mode)) {
@@ -45555,24 +46453,9 @@
  				}
  			}
  		}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/oprofile/buffer_sync.h linux-2.6.17-xen/drivers/oprofile/buffer_sync.h
---- linux-2.6.17/drivers/oprofile/buffer_sync.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/oprofile/buffer_sync.h	2006-08-14 15:57:56.000000000 +0200
-@@ -9,6 +9,11 @@
- 
- #ifndef OPROFILE_BUFFER_SYNC_H
- #define OPROFILE_BUFFER_SYNC_H
-+
-+#define NO_DOMAIN_SWITCH		-1
-+#define DOMAIN_SWITCH_START_EVENT1	0
-+#define DOMAIN_SWITCH_START_EVENT2	1
-+#define DOMAIN_SWITCH_STOP_EVENT1	2
-  
- /* add the necessary profiling hooks */
- int sync_start(void);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/oprofile/cpu_buffer.c linux-2.6.17-xen/drivers/oprofile/cpu_buffer.c
---- linux-2.6.17/drivers/oprofile/cpu_buffer.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/oprofile/cpu_buffer.c	2006-08-14 15:57:56.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/oprofile/cpu_buffer.c linux-2.6.18-rc5-xen/drivers/oprofile/cpu_buffer.c
+--- linux-2.6.18-rc5/drivers/oprofile/cpu_buffer.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/oprofile/cpu_buffer.c	2006-07-20 15:57:08.000000000 +0200
 @@ -6,6 +6,10 @@
   *
   * @author John Levon <levon at movementarian.org>
@@ -45584,7 +46467,16 @@
   * 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
-@@ -57,7 +61,7 @@
+@@ -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;
+@@ -57,7 +63,7 @@
  			goto fail;
   
  		b->last_task = NULL;
@@ -45593,7 +46485,7 @@
  		b->tracing = 0;
  		b->buffer_size = buffer_size;
  		b->tail_pos = 0;
-@@ -113,7 +117,7 @@
+@@ -113,7 +119,7 @@
  	 * collected will populate the buffer with proper
  	 * values to initialize the buffer
  	 */
@@ -45602,7 +46494,7 @@
  	cpu_buf->last_task = NULL;
  }
  
-@@ -163,13 +167,13 @@
+@@ -163,13 +169,13 @@
   * because of the head/tail separation of the writer and reader
   * of the CPU buffer.
   *
@@ -45620,7 +46512,7 @@
  {
  	struct task_struct * task;
  
-@@ -180,16 +184,16 @@
+@@ -180,18 +186,20 @@
  		return 0;
  	}
  
@@ -45640,11 +46532,42 @@
 -
 +	
  	/* notice a task switch */
- 	if (cpu_buf->last_task != task) {
+-	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;
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/oprofile/cpu_buffer.h linux-2.6.17-xen/drivers/oprofile/cpu_buffer.h
---- linux-2.6.17/drivers/oprofile/cpu_buffer.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/oprofile/cpu_buffer.h	2006-08-14 15:57:56.000000000 +0200
+ 		add_code(cpu_buf, (unsigned long)task);
+ 	}
+@@ -275,6 +283,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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/oprofile/cpu_buffer.h linux-2.6.18-rc5-xen/drivers/oprofile/cpu_buffer.h
+--- linux-2.6.18-rc5/drivers/oprofile/cpu_buffer.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/oprofile/cpu_buffer.h	2006-07-20 15:57:08.000000000 +0200
 @@ -36,7 +36,7 @@
  	volatile unsigned long tail_pos;
  	unsigned long buffer_size;
@@ -45654,7 +46577,7 @@
  	int tracing;
  	struct op_sample * buffer;
  	unsigned long sample_received;
-@@ -51,7 +51,13 @@
+@@ -51,7 +51,10 @@
  void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
  
  /* transient events for the CPU buffer -> event buffer */
@@ -45663,17 +46586,14 @@
 +#define CPU_MODE_USER           0
 +#define CPU_MODE_KERNEL         1
 +#define CPU_MODE_XEN            2
-+#define CPU_MODE_PASSIVE_START  3
-+#define CPU_MODE_PASSIVE_STOP   4
-+#define CPU_TRACE_BEGIN         5
-+
-+#define IGNORED_PC              0
++#define CPU_TRACE_BEGIN         3
++#define CPU_DOMAIN_SWITCH       4
  
  #endif /* OPROFILE_CPU_BUFFER_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/oprofile/event_buffer.h linux-2.6.17-xen/drivers/oprofile/event_buffer.h
---- linux-2.6.17/drivers/oprofile/event_buffer.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/oprofile/event_buffer.h	2006-08-14 15:57:56.000000000 +0200
-@@ -29,11 +29,14 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/oprofile/event_buffer.h linux-2.6.18-rc5-xen/drivers/oprofile/event_buffer.h
+--- linux-2.6.18-rc5/drivers/oprofile/event_buffer.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/oprofile/event_buffer.h	2006-07-20 15:57:08.000000000 +0200
+@@ -29,15 +29,20 @@
  #define CPU_SWITCH_CODE 		2
  #define COOKIE_SWITCH_CODE 		3
  #define KERNEL_ENTER_SWITCH_CODE	4
@@ -45684,14 +46604,20 @@
  #define TRACE_BEGIN_CODE		8
  #define TRACE_END_CODE			9
 +#define XEN_ENTER_SWITCH_CODE		10
-+#define PASSIVE_START_CODE		11
-+#define PASSIVE_STOP_CODE		12
++#define DOMAIN_SWITCH_CODE		11
   
  #define INVALID_COOKIE ~0UL
  #define NO_COOKIE 0UL
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/oprofile/oprof.c linux-2.6.17-xen/drivers/oprofile/oprof.c
---- linux-2.6.17/drivers/oprofile/oprof.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/oprofile/oprof.c	2006-08-14 15:57:56.000000000 +0200
+ 
++/* 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/oprofile/oprof.c linux-2.6.18-rc5-xen/drivers/oprofile/oprof.c
+--- linux-2.6.18-rc5/drivers/oprofile/oprof.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/oprofile/oprof.c	2006-08-14 15:07:20.000000000 +0200
 @@ -5,6 +5,10 @@
   * @remark Read the file COPYING
   *
@@ -45723,9 +46649,9 @@
 +	if (!oprofile_ops.set_active)
 +		return -EINVAL;
 +
-+	down(&start_sem);
++	mutex_lock(&start_mutex);
 +	err = oprofile_ops.set_active(active_domains, adomains);
-+	up(&start_sem);
++	mutex_unlock(&start_mutex);
 +	return err;
 +}
 +
@@ -45736,18 +46662,18 @@
 +	if (!oprofile_ops.set_passive)
 +		return -EINVAL;
 +
-+	down(&start_sem);
++	mutex_lock(&start_mutex);
 +	err = oprofile_ops.set_passive(passive_domains, pdomains);
-+	up(&start_sem);
++	mutex_unlock(&start_mutex);
 +	return err;
 +}
 +
  int oprofile_setup(void)
  {
  	int err;
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/oprofile/oprof.h linux-2.6.17-xen/drivers/oprofile/oprof.h
---- linux-2.6.17/drivers/oprofile/oprof.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/oprofile/oprof.h	2006-08-14 15:57:56.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/oprofile/oprof.h linux-2.6.18-rc5-xen/drivers/oprofile/oprof.h
+--- linux-2.6.18-rc5/drivers/oprofile/oprof.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/oprofile/oprof.h	2006-07-20 15:57:08.000000000 +0200
 @@ -35,5 +35,8 @@
  void oprofile_timer_init(struct oprofile_operations * ops);
  
@@ -45757,9 +46683,9 @@
 +int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
   
  #endif /* OPROF_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/oprofile/oprofile_files.c linux-2.6.17-xen/drivers/oprofile/oprofile_files.c
---- linux-2.6.17/drivers/oprofile/oprofile_files.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/oprofile/oprofile_files.c	2006-08-14 15:57:56.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/oprofile/oprofile_files.c linux-2.6.18-rc5-xen/drivers/oprofile/oprofile_files.c
+--- linux-2.6.18-rc5/drivers/oprofile/oprofile_files.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/oprofile/oprofile_files.c	2006-07-20 15:57:08.000000000 +0200
 @@ -5,15 +5,21 @@
   * @remark Read the file COPYING
   *
@@ -45783,12 +46709,14 @@
  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 @@
+@@ -117,11 +123,208 @@
  static struct file_operations dump_fops = {
  	.write		= dump_write,
  };
 - 
 +
++#ifdef CONFIG_XEN
++
 +#define TMPBUFSIZE 512
 +
 +static unsigned int adomains = 0;
@@ -45978,18 +46906,22 @@
 +	.write		= pdomain_write,
 +};
 +
++#endif /* CONFIG_XEN */
++
  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);
++#ifdef CONFIG_XEN
 +	oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
 +	oprofilefs_create_file(sb, root, "passive_domains", &passive_domain_ops);
++#endif
  	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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/pci/Kconfig linux-2.6.17-xen/drivers/pci/Kconfig
---- linux-2.6.17/drivers/pci/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/pci/Kconfig	2006-08-14 15:57:56.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/pci/Kconfig linux-2.6.18-rc5-xen/drivers/pci/Kconfig
+--- linux-2.6.18-rc5/drivers/pci/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/pci/Kconfig	2006-07-20 15:57:09.000000000 +0200
 @@ -5,6 +5,7 @@
  	bool "Message Signaled Interrupts (MSI and MSI-X)"
  	depends on PCI
@@ -45998,88 +46930,47 @@
  	help
  	   This allows device drivers to enable MSI (Message Signaled
  	   Interrupts).  Message Signaled Interrupts enable a device to
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/s390/net/qeth_eddp.c linux-2.6.17-xen/drivers/s390/net/qeth_eddp.c
---- linux-2.6.17/drivers/s390/net/qeth_eddp.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/s390/net/qeth_eddp.c	2006-08-14 15:57:57.000000000 +0200
-@@ -420,7 +420,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){
-@@ -515,20 +515,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);
- }
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/serial/8250_pci.c linux-2.6.18-rc5-xen/drivers/serial/8250_pci.c
+--- linux-2.6.18-rc5/drivers/serial/8250_pci.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/serial/8250_pci.c	2006-09-01 00:09:11.000000000 +0200
+@@ -936,6 +936,7 @@
+ 	pbn_b1_8_1382400,
+ 
+ 	pbn_b2_1_115200,
++	pbn_b2_2_115200,
+ 	pbn_b2_8_115200,
+ 
+ 	pbn_b2_1_460800,
+@@ -1243,6 +1244,12 @@
+ 		.base_baud	= 115200,
+ 		.uart_offset	= 8,
+ 	},
++	[pbn_b2_2_115200] = {
++		.flags		= FL_BASE2,
++		.num_ports	= 2,
++		.base_baud	= 115200,
++		.uart_offset	= 8,
++	},
+ 	[pbn_b2_8_115200] = {
+ 		.flags		= FL_BASE2,
+ 		.num_ports	= 8,
+@@ -2340,6 +2347,13 @@
+ 		pbn_b0_1_115200 },
  
- static inline struct qeth_eddp_context *
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/s390/net/qeth_main.c linux-2.6.17-xen/drivers/s390/net/qeth_main.c
---- linux-2.6.17/drivers/s390/net/qeth_main.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/s390/net/qeth_main.c	2006-08-14 15:57:57.000000000 +0200
-@@ -4417,7 +4417,6 @@
- 	struct qeth_eddp_context *ctx = NULL;
- 	int tx_bytes = skb->len;
- 	unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
--	unsigned short tso_size = skb_shinfo(skb)->tso_size;
- 	int rc;
- 
- 	QETH_DBF_TEXT(trace, 6, "sendpkt");
-@@ -4453,7 +4452,7 @@
- 	queue = card->qdio.out_qs
- 		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
- 
--	if (skb_shinfo(skb)->tso_size)
-+	if (skb_shinfo(skb)->gso_size)
- 		large_send = card->options.large_send;
- 
- 	/*are we able to do TSO ? If so ,prepare and send it from here */
-@@ -4500,7 +4499,7 @@
- 		card->stats.tx_packets++;
- 		card->stats.tx_bytes += tx_bytes;
- #ifdef CONFIG_QETH_PERF_STATS
--		if (tso_size &&
-+		if (skb_shinfo(skb)->gso_size &&
- 		   !(large_send == QETH_LARGE_SEND_NO)) {
- 			card->perf_stats.large_send_bytes += tx_bytes;
- 			card->perf_stats.large_send_cnt++;
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/s390/net/qeth_tso.h linux-2.6.17-xen/drivers/s390/net/qeth_tso.h
---- linux-2.6.17/drivers/s390/net/qeth_tso.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/s390/net/qeth_tso.h	2006-08-14 15:57:57.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/serial/Kconfig linux-2.6.17-xen/drivers/serial/Kconfig
---- linux-2.6.17/drivers/serial/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/serial/Kconfig	2006-08-14 15:58:01.000000000 +0200
+ 	/*
++	 * IntaShield IS-200
++	 */
++	{	PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS200,
++		PCI_ANY_ID, PCI_ANY_ID, 0, 0,	/* 135a.0811 */
++		pbn_b2_2_115200 },
++
++	/*
+ 	 * These entries match devices with class COMMUNICATION_SERIAL,
+ 	 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
+ 	 */
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/serial/Kconfig linux-2.6.18-rc5-xen/drivers/serial/Kconfig
+--- linux-2.6.18-rc5/drivers/serial/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/drivers/serial/Kconfig	2006-07-20 15:57:13.000000000 +0200
 @@ -11,6 +11,7 @@
  config SERIAL_8250
  	tristate "8250/16550 and compatible serial support"
@@ -46088,22 +46979,10 @@
  	select SERIAL_CORE
  	---help---
  	  This selects whether you want to include the driver for the standard
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/video/Kconfig linux-2.6.17-xen/drivers/video/Kconfig
---- linux-2.6.17/drivers/video/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/drivers/video/Kconfig	2006-08-14 15:58:03.000000000 +0200
-@@ -513,7 +513,7 @@
- 
- config VIDEO_SELECT
- 	bool
--	depends on (FB = y) && X86
-+	depends on (FB = y) && X86 && !XEN
- 	default y
- 
- config FB_SGIVW
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/balloon/balloon.c linux-2.6.17-xen/drivers/xen/balloon/balloon.c
---- linux-2.6.17/drivers/xen/balloon/balloon.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/balloon/balloon.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,608 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/balloon/balloon.c linux-2.6.18-rc5-xen/drivers/xen/balloon/balloon.c
+--- linux-2.6.18-rc5/drivers/xen/balloon/balloon.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/balloon/balloon.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,625 @@
 +/******************************************************************************
 + * balloon.c
 + *
@@ -46138,7 +47017,6 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/sched.h>
@@ -46182,7 +47060,7 @@
 +static unsigned long target_pages;
 +
 +/* We increase/decrease in batches which fit in a page */
-+static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; 
++static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)];
 +
 +/* VM /proc information for memory */
 +extern unsigned long totalram_pages;
@@ -46546,20 +47424,16 @@
 +		"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(current_pages), PAGES2KB(target_pages), 
-+		PAGES2KB(balloon_low), PAGES2KB(balloon_high));
++		PAGES2KB(balloon_low), PAGES2KB(balloon_high),
++		PAGES2KB(driver_pages));
 +
-+	if (hard_limit != ~0UL) {
-+		len += sprintf(
-+			page + len, 
-+			"%8lu kB (inc. %8lu kB driver headroom)\n",
-+			PAGES2KB(hard_limit), PAGES2KB(driver_pages));
-+	} else {
-+		len += sprintf(
-+			page + len,
-+			"     ??? kB\n");
-+	}
++	if (hard_limit != ~0UL)
++		len += sprintf(page + len, "%8lu kB\n", PAGES2KB(hard_limit));
++	else
++		len += sprintf(page + len, "     ??? kB\n");
 +
 +	*eof = 1;
 +	return len;
@@ -46669,10 +47543,14 @@
 +		set_xen_guest_handle(reservation.extent_start, &gmfn);
 +		ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
 +					   &reservation);
++		if (ret == -ENOSYS)
++			goto err;
 +		BUG_ON(ret != 1);
 +	} else {
 +		ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
 +					  dealloc_pte_fn, NULL);
++		if (ret == -ENOSYS)
++			goto err;
 +		BUG_ON(ret);
 +	}
 +	current_pages -= 1UL << order;
@@ -46689,6 +47567,11 @@
 +		init_page_count(page + i);
 +
 +	return page;
++
++ err:
++	free_pages(vstart, order);
++	balloon_unlock(flags);
++	return NULL;
 +}
 +
 +void balloon_dealloc_empty_page_range(
@@ -46707,21 +47590,34 @@
 +	schedule_work(&balloon_worker);
 +}
 +
++void balloon_release_driver_page(struct page *page)
++{
++	unsigned long flags;
++
++	balloon_lock(flags);
++	balloon_append(page);
++	driver_pages--;
++	balloon_unlock(flags);
++
++	schedule_work(&balloon_worker);
++}
++
 +EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
 +EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range);
 +EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);
++EXPORT_SYMBOL_GPL(balloon_release_driver_page);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/balloon/Makefile linux-2.6.17-xen/drivers/xen/balloon/Makefile
---- linux-2.6.17/drivers/xen/balloon/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/balloon/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/balloon/Makefile linux-2.6.18-rc5-xen/drivers/xen/balloon/Makefile
+--- linux-2.6.18-rc5/drivers/xen/balloon/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/balloon/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,2 @@
 +
 +obj-y += balloon.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkback/blkback.c linux-2.6.17-xen/drivers/xen/blkback/blkback.c
---- linux-2.6.17/drivers/xen/blkback/blkback.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkback/blkback.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,568 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkback/blkback.c linux-2.6.18-rc5-xen/drivers/xen/blkback/blkback.c
+--- linux-2.6.18-rc5/drivers/xen/blkback/blkback.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkback/blkback.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,567 @@
 +/******************************************************************************
 + * arch/xen/drivers/blkif/backend/main.c
 + * 
@@ -46764,6 +47660,7 @@
 +#include <linux/list.h>
 +#include <xen/balloon.h>
 +#include <asm/hypervisor.h>
++#include <asm/hypercall.h>
 +#include "common.h"
 +
 +/*
@@ -47065,7 +47962,7 @@
 +				 blkif_request_t *req,
 +				 pending_req_t *pending_req)
 +{
-+	extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); 
++	extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
 +	int operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
 +	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 +	struct phys_req preq;
@@ -47122,14 +48019,9 @@
 +		}
 +
 +		pending_handle(pending_req, i) = map[i].handle;
-+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
-+		pending_vaddrs[vaddr_pagenr(pending_req, i)] =
-+			(unsigned long)gnttab_map_vaddr(map[i]);
-+#else
 +		set_phys_to_machine(__pa(vaddr(
 +			pending_req, i)) >> PAGE_SHIFT,
 +			FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
-+#endif
 +		seg[i].buf  = map[i].dev_bus_addr | 
 +			(req->seg[i].first_sect << 9);
 +	}
@@ -47138,7 +48030,7 @@
 +		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); 
++			preq.sector_number + preq.nr_sects, preq.dev);
 +		goto fail_flush;
 +	}
 +
@@ -47242,6 +48134,19 @@
 +		return -ENODEV;
 +
 +	mmap_pages            = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
++
++#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
++	extern unsigned long alloc_empty_foreign_map_page_range(
++		unsigned long pages);
++	mmap_vstart = (unsigned long)
++		alloc_empty_foreign_map_page_range(mmap_pages);
++#else /* ! ia64 */
++	page = balloon_alloc_empty_page_range(mmap_pages);
++	if (page == NULL)
++		return -ENOMEM;
++	mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
++#endif
++
 +	pending_reqs          = kmalloc(sizeof(pending_reqs[0]) *
 +					blkif_reqs, GFP_KERNEL);
 +	pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
@@ -47258,16 +48163,6 @@
 +
 +	blkif_interface_init();
 +	
-+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
-+	extern unsigned long alloc_empty_foreign_map_page_range(
-+		unsigned long pages);
-+	mmap_vstart = (unsigned long)
-+		alloc_empty_foreign_map_page_range(mmap_pages);
-+#else /* ! ia64 */
-+	page = balloon_alloc_empty_page_range(mmap_pages);
-+	BUG_ON(page == NULL);
-+	mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
-+#endif
 +	printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
 +	       __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
 +	BUG_ON(mmap_vstart == 0);
@@ -47290,10 +48185,10 @@
 +module_init(blkif_init);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkback/common.h linux-2.6.17-xen/drivers/xen/blkback/common.h
---- linux-2.6.17/drivers/xen/blkback/common.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkback/common.h	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,134 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkback/common.h linux-2.6.18-rc5-xen/drivers/xen/blkback/common.h
+--- linux-2.6.18-rc5/drivers/xen/blkback/common.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkback/common.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,133 @@
 +/* 
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License version 2
@@ -47323,7 +48218,6 @@
 +#ifndef __BLKIF__BACKEND__COMMON_H__
 +#define __BLKIF__BACKEND__COMMON_H__
 +
-+#include <linux/config.h>
 +#include <linux/version.h>
 +#include <linux/module.h>
 +#include <linux/interrupt.h>
@@ -47351,9 +48245,9 @@
 +	unsigned char  type;        /* VDISK_xxx */
 +	u32            pdevice;     /* phys device that this vbd maps to */
 +	struct block_device *bdev;
-+}; 
++};
 +
-+struct backend_info; 
++struct backend_info;
 +
 +typedef struct blkif_st {
 +	/* Unique identifier for this interface. */
@@ -47368,7 +48262,7 @@
 +	/* The VBD attached to this interface. */
 +	struct vbd        vbd;
 +	/* Back pointer to the backend_info. */
-+	struct backend_info *be; 
++	struct backend_info *be;
 +	/* Private fields. */
 +	spinlock_t       blk_ring_lock;
 +	atomic_t         refcnt;
@@ -47418,7 +48312,7 @@
 +	blkif_sector_t       sector_number;
 +};
 +
-+int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); 
++int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation);
 +
 +void blkif_interface_init(void);
 +
@@ -47428,10 +48322,10 @@
 +int blkif_schedule(void *arg);
 +
 +#endif /* __BLKIF__BACKEND__COMMON_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkback/interface.c linux-2.6.17-xen/drivers/xen/blkback/interface.c
---- linux-2.6.17/drivers/xen/blkback/interface.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkback/interface.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,177 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkback/interface.c linux-2.6.18-rc5-xen/drivers/xen/blkback/interface.c
+--- linux-2.6.18-rc5/drivers/xen/blkback/interface.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkback/interface.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,171 @@
 +/******************************************************************************
 + * arch/xen/drivers/blkif/backend/interface.c
 + * 
@@ -47510,12 +48404,6 @@
 +	blkif->shmem_ref = shared_page;
 +	blkif->shmem_handle = op.handle;
 +
-+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
-+	/* on some arch's, map_grant_ref behaves like mmap, in that the
-+	 * passed address is a hint and a different address may be returned */
-+	blkif->blk_ring_area->addr = gnttab_map_vaddr(op);
-+#endif
-+
 +	return 0;
 +}
 +
@@ -47609,16 +48497,16 @@
 +	blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 
 +					 0, 0, NULL, NULL);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkback/Makefile linux-2.6.17-xen/drivers/xen/blkback/Makefile
---- linux-2.6.17/drivers/xen/blkback/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkback/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkback/Makefile linux-2.6.18-rc5-xen/drivers/xen/blkback/Makefile
+--- linux-2.6.18-rc5/drivers/xen/blkback/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkback/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,3 @@
 +obj-$(CONFIG_XEN_BLKDEV_BACKEND) := blkbk.o
 +
 +blkbk-y	:= blkback.o xenbus.o interface.o vbd.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkback/vbd.c linux-2.6.17-xen/drivers/xen/blkback/vbd.c
---- linux-2.6.17/drivers/xen/blkback/vbd.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkback/vbd.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkback/vbd.c linux-2.6.18-rc5-xen/drivers/xen/blkback/vbd.c
+--- linux-2.6.18-rc5/drivers/xen/blkback/vbd.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkback/vbd.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,119 @@
 +/******************************************************************************
 + * blkback/vbd.c
@@ -47739,10 +48627,10 @@
 + out:
 +	return rc;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkback/xenbus.c linux-2.6.17-xen/drivers/xen/blkback/xenbus.c
---- linux-2.6.17/drivers/xen/blkback/xenbus.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkback/xenbus.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,460 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkback/xenbus.c linux-2.6.18-rc5-xen/drivers/xen/blkback/xenbus.c
+--- linux-2.6.18-rc5/drivers/xen/blkback/xenbus.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkback/xenbus.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,464 @@
 +/*  Xenbus code for blkif backend
 +    Copyright (C) 2005 Rusty Russell <rusty at rustcorp.com.au>
 +    Copyright (C) 2005 XenSource Ltd
@@ -47939,7 +48827,7 @@
 +	}
 +
 +	/* setup back pointer */
-+	be->blkif->be = be; 
++	be->blkif->be = be;
 +
 +	err = xenbus_watch_path2(dev, dev->nodename, "physical-device",
 +				 &be->backend_watch, backend_changed);
@@ -48032,7 +48920,7 @@
 +		}
 +
 +		/* We're potentially connected now */
-+		update_blkif_status(be->blkif); 
++		update_blkif_status(be->blkif);
 +	}
 +}
 +
@@ -48050,6 +48938,11 @@
 +
 +	switch (frontend_state) {
 +	case XenbusStateInitialising:
++		if (dev->state == XenbusStateClosing) {
++			printk("%s: %s: prepare for reconnect\n",
++			       __FUNCTION__, dev->nodename);
++			xenbus_switch_state(dev, XenbusStateInitWait);
++		}
 +		break;
 +
 +	case XenbusStateInitialised:
@@ -48071,12 +48964,11 @@
 +		xenbus_switch_state(dev, XenbusStateClosing);
 +		break;
 +
++	case XenbusStateUnknown:
 +	case XenbusStateClosed:
 +		device_unregister(&dev->dev);
 +		break;
 +
-+	case XenbusStateUnknown:
-+	case XenbusStateInitWait:
 +	default:
 +		xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
 +				 frontend_state);
@@ -48203,10 +49095,10 @@
 +{
 +	xenbus_register_backend(&blkback);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkfront/blkfront.c linux-2.6.17-xen/drivers/xen/blkfront/blkfront.c
---- linux-2.6.17/drivers/xen/blkfront/blkfront.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkfront/blkfront.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,841 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkfront/blkfront.c linux-2.6.18-rc5-xen/drivers/xen/blkfront/blkfront.c
+--- linux-2.6.18-rc5/drivers/xen/blkfront/blkfront.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkfront/blkfront.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,842 @@
 +/******************************************************************************
 + * blkfront.c
 + * 
@@ -48255,6 +49147,7 @@
 +#include <xen/interface/grant_table.h>
 +#include <xen/gnttab.h>
 +#include <asm/hypervisor.h>
++#include <asm/maddr.h>
 +
 +#define BLKIF_STATE_DISCONNECTED 0
 +#define BLKIF_STATE_CONNECTED    1
@@ -48464,10 +49357,10 @@
 +	DPRINTK("blkfront:backend_changed.\n");
 +
 +	switch (backend_state) {
-+	case XenbusStateUnknown:
 +	case XenbusStateInitialising:
 +	case XenbusStateInitWait:
 +	case XenbusStateInitialised:
++	case XenbusStateUnknown:
 +	case XenbusStateClosed:
 +		break;
 +
@@ -49048,10 +49941,10 @@
 +module_exit(xlblk_exit);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkfront/block.h linux-2.6.17-xen/drivers/xen/blkfront/block.h
---- linux-2.6.17/drivers/xen/blkfront/block.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkfront/block.h	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,156 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkfront/block.h linux-2.6.18-rc5-xen/drivers/xen/blkfront/block.h
+--- linux-2.6.18-rc5/drivers/xen/blkfront/block.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkfront/block.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,154 @@
 +/******************************************************************************
 + * block.h
 + * 
@@ -49089,7 +49982,6 @@
 +#ifndef __XEN_DRIVERS_BLOCK_H__
 +#define __XEN_DRIVERS_BLOCK_H__
 +
-+#include <linux/config.h>
 +#include <linux/version.h>
 +#include <linux/module.h>
 +#include <linux/kernel.h>
@@ -49101,7 +49993,6 @@
 +#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>
@@ -49208,9 +50099,9 @@
 +void xlvbd_del(struct blkfront_info *info);
 +
 +#endif /* __XEN_DRIVERS_BLOCK_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkfront/Kconfig linux-2.6.17-xen/drivers/xen/blkfront/Kconfig
---- linux-2.6.17/drivers/xen/blkfront/Kconfig	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkfront/Kconfig	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkfront/Kconfig linux-2.6.18-rc5-xen/drivers/xen/blkfront/Kconfig
+--- linux-2.6.18-rc5/drivers/xen/blkfront/Kconfig	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkfront/Kconfig	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,6 @@
 +
 +config XENBLOCK
@@ -49218,18 +50109,18 @@
 +	depends on ARCH_XEN
 +	help
 +	  Block device driver for Xen
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkfront/Makefile linux-2.6.17-xen/drivers/xen/blkfront/Makefile
---- linux-2.6.17/drivers/xen/blkfront/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkfront/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkfront/Makefile linux-2.6.18-rc5-xen/drivers/xen/blkfront/Makefile
+--- linux-2.6.18-rc5/drivers/xen/blkfront/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkfront/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,5 @@
 +
 +obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	:= xenblk.o
 +
 +xenblk-objs := blkfront.o vbd.o
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/blkfront/vbd.c linux-2.6.17-xen/drivers/xen/blkfront/vbd.c
---- linux-2.6.17/drivers/xen/blkfront/vbd.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/blkfront/vbd.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blkfront/vbd.c linux-2.6.18-rc5-xen/drivers/xen/blkfront/vbd.c
+--- linux-2.6.18-rc5/drivers/xen/blkfront/vbd.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blkfront/vbd.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,318 @@
 +/******************************************************************************
 + * vbd.c
@@ -49363,7 +50254,7 @@
 +		return NULL;
 +	}
 +
-+	devfs_mk_dir(ptr->type->devname);
++/*	devfs_mk_dir(ptr->type->devname);*/
 +	major_info[index] = ptr;
 +	return ptr;
 +}
@@ -49549,209 +50440,22 @@
 +	blk_cleanup_queue(info->rq);
 +	info->rq = NULL;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/char/Makefile linux-2.6.17-xen/drivers/xen/char/Makefile
---- linux-2.6.17/drivers/xen/char/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/char/Makefile	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,2 @@
-+
-+obj-y	:= mem.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/char/mem.c linux-2.6.17-xen/drivers/xen/char/mem.c
---- linux-2.6.17/drivers/xen/char/mem.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/char/mem.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,182 @@
-+/*
-+ *  Originally from linux/drivers/char/mem.c
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ *
-+ *  Added devfs support. 
-+ *    Jan-11-1998, C. Scott Ananian <cananian at alumni.princeton.edu>
-+ *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj at 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>
-+
-+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;
-+}
-+
-+/*
-+ * 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;
-+
-+	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);
-+
-+		if ((v = ioremap(p, sz)) == 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);
-+		iounmap(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;
-+
-+	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);
-+
-+		if ((v = ioremap(p, sz)) == NULL)
-+			break;
-+
-+		ignored = copy_from_user(v, buf, sz);
-+		iounmap(v);
-+		if (ignored) {
-+			written += sz - ignored;
-+			if (written)
-+				break;
-+			return -EFAULT;
-+		}
-+		buf += sz;
-+		p += sz;
-+		count -= sz;
-+		written += sz;
-+	}
-+
-+	*ppos += written;
-+	return written;
-+}
-+
-+static int 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);
-+}
-+
-+/*
-+ * 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		= mmap_mem,
-+	.open		= open_mem,
-+};
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/console/console.c linux-2.6.17-xen/drivers/xen/console/console.c
---- linux-2.6.17/drivers/xen/console/console.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/console/console.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,640 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blktap/blktap.c linux-2.6.18-rc5-xen/drivers/xen/blktap/blktap.c
+--- linux-2.6.18-rc5/drivers/xen/blktap/blktap.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blktap/blktap.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,1444 @@
 +/******************************************************************************
-+ * console.c
-+ * 
-+ * Virtual console driver.
++ * drivers/xen/blktap/blktap.c
 + * 
-+ * Copyright (c) 2002-2004, K A Fraser.
++ * 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
++ *
 + * 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
@@ -49777,113 +50481,2396 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
++#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/miscdevice.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 <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/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]+'.
-+ *                 [XC_DEFAULT]: DOM0 -> XC_SERIAL ; all others -> XC_TTY.
-+ * 
-+ * NB. In mode XC_TTY, we create dummy consoles for tty2-63. This suppresses
-+ * warnings from standard distro startup scripts.
-+ */
-+static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT;
-+static int xc_num = -1;
++#include <linux/gfp.h>
++#include <linux/poll.h>
++#include <asm/tlbflush.h>
 +
-+#ifdef CONFIG_MAGIC_SYSRQ
-+static unsigned long sysrq_requested;
-+extern int sysrq_enabled;
-+#endif
++#define MAX_TAP_DEV 100     /*the maximum number of tapdisk ring devices    */
++#define MAX_DEV_NAME 100    /*the max tapdisk ring device name e.g. blktap0 */
 +
-+static int __init xencons_setup(char *str)
-+{
-+	char *q;
-+	int n;
++/*
++ * 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 MAX_DYNAMIC_MEM 64
++#define MAX_PENDING_REQS 64   
++#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 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          */
++} tap_blkif_t;
 +
-+	if (!strncmp(str, "ttyS", 4))
-+		xc_mode = XC_SERIAL;
-+	else if (!strncmp(str, "tty", 3))
-+		xc_mode = XC_TTY;
-+	else if (!strncmp(str, "off", 3))
-+		xc_mode = XC_OFF;
++/*Private data struct associated with the inode*/
++typedef struct private_info {
++	int idx;
++} private_info_t;
 +
-+	switch (xc_mode) {
-+	case XC_SERIAL:
-+		n = simple_strtol(str+4, &q, 10);
-+		if (q > (str + 4))
-+			xc_num = n;
-+		break;
-+	case XC_TTY:
-+		n = simple_strtol(str+3, &q, 10);
-+		if (q > (str + 3))
-+			xc_num = n;
-+		break;
-+	default:
-+		break;
-+	}
++/*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 ;
 +
-+	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 */
++domid_translate_t  translate_domid[MAX_TAP_DEV];
++tap_blkif_t *tapfds[MAX_TAP_DEV];
 +
-+static int __init xencons_bufsz_setup(char *str)
++static int __init set_blkif_reqs(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;
-+	}
++	get_option(&str, &blkif_reqs);
 +	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);
++__setup("blkif_reqs=", set_blkif_reqs);
 +
-+static struct tty_driver *xencons_driver;
-+
-+/******************** Kernel console driver ********************************/
++/* 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);
 +
-+static void kcons_write(struct console *c, const char *s, unsigned int count)
++/*
++ * 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)
++
++typedef struct mmap_page {
++	unsigned long start;
++	struct page *mpage;
++} mmap_page_t;
++
++static mmap_page_t mmap_start[MAX_DYNAMIC_MEM];
++static unsigned short mmap_alloc = 0;
++static unsigned short mmap_lock = 0;
++static unsigned short mmap_inuse = 0;
++static unsigned long *pending_addrs[MAX_DYNAMIC_MEM];
++
++/******************************************************************
++ * 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;
++};
++
++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(int idx); /*local prototypes*/
++
++#define BLKTAP_MINOR 0  /*/dev/xen/blktap resides at device number
++			  major=254, minor numbers begin at 0            */ 
++#define BLKTAP_DEV_MAJOR 254         /* TODO: Make major number dynamic  *
++                                      * and create devices in the kernel *
++				      */
++#define BLKTAP_DEV_DIR  "/dev/xen"
++
++/* 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) == 0xFFFF) && ((_g->user) == 0xFFFF))
++
++#define BLKTAP_INVALIDATE_HANDLE(_g) do {       \
++    (_g)->kernel = 0xFFFF; (_g)->user = 0xFFFF; \
++    } 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 int 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);
++
++struct miscdevice *set_misc(int minor, char *name, int dev);
++
++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 int get_next_free_dev(void)
++{
++	tap_blkif_t *info;
++	int i = 0, ret = -1;
++	unsigned long flags;
++
++	spin_lock_irqsave(&pending_free_lock, flags);
++	
++	while (i < MAX_TAP_DEV) {
++		info = tapfds[i];
++		if ( (tapfds[i] != NULL) && (info->dev_inuse == 0)
++			&& (info->dev_pending == 0) ) {
++			info->dev_pending = 1;
++			ret = i;
++			goto done;
++		}
++		i++;
++	}
++	
++done:
++	spin_unlock_irqrestore(&pending_free_lock, flags);
++	return ret;
++}
++
++int dom_to_devid(domid_t domid, int xenbus_id, blkif_t *blkif) 
++{
++	int i;
++		
++	for (i = 0; i < MAX_TAP_DEV; i++)
++		if ( (translate_domid[i].domid == domid)
++		    && (translate_domid[i].busid == xenbus_id) ) {
++			tapfds[i]->blkif = blkif;
++			tapfds[i]->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->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;
++	private_info_t *prv;
++	int i;
++	
++	if (tapfds[idx] == NULL) {
++		WPRINTK("Unable to open device /dev/xen/blktap%d\n",
++		       idx);
++		return -ENOMEM;
++	}
++	DPRINTK("Opening device /dev/xen/blktap%d\n",idx);
++	
++	info = tapfds[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);
++	
++	prv = kzalloc(sizeof(private_info_t),GFP_KERNEL);
++	prv->idx = idx;
++	filp->private_data = prv;
++	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)
++{
++	int idx = iminor(inode) - BLKTAP_MINOR;
++	tap_blkif_t *info;
++	
++	if (tapfds[idx] == NULL) {
++		WPRINTK("Trying to free device that doesn't exist "
++		       "[/dev/xen/blktap%d]\n",idx);
++		return -1;
++	}
++	info = tapfds[idx];
++	info->dev_inuse = 0;
++	DPRINTK("Freeing device [/dev/xen/blktap%d]\n",idx);
++
++	/* 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 (filp->private_data) kfree(filp->private_data);
++
++	if ( (info->status != CLEANSHUTDOWN) && (info->blkif != 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;
++	private_info_t *prv;
++	tap_blkif_t *info;
++
++	/*Retrieve the dev info*/
++	prv = (private_info_t *)filp->private_data;
++	if (prv == NULL) {
++		WPRINTK("blktap: mmap, retrieving idx failed\n");
++		return -ENOMEM;
++	}
++	info = tapfds[prv->idx];
++	
++	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. */
++	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++
++	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)
++{
++	int idx = iminor(inode) - BLKTAP_MINOR;
++	switch(cmd) {
++	case BLKTAP_IOCTL_KICK_FE: 
++	{
++		/* There are fe messages to process. */
++		return blktap_read_ufe_ring(idx);
++	}
++	case BLKTAP_IOCTL_SETMODE:
++	{
++		tap_blkif_t *info = tapfds[idx];
++		
++		if ( (idx > 0) && (idx < MAX_TAP_DEV) 
++		     && (tapfds[idx] != NULL) ) 
++		{
++			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:
++        {
++		tap_blkif_t *info = tapfds[idx];
++		
++		if ( (idx > 0) && (idx < MAX_TAP_DEV) 
++		     && (tapfds[idx] != NULL) ) 
++		{
++			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:
++	{
++		tap_blkif_t *info = tapfds[idx];
++		
++		if ( (idx > 0) && (idx < MAX_TAP_DEV) 
++		     && (tapfds[idx] != NULL) ) 
++		{
++			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;
++		int newdev;
++
++		DPRINTK("NEWINTF Req for domid %d and bus id %d\n", 
++		       tr->domid, tr->busid);
++		newdev = get_next_free_dev();
++		if (newdev < 1) {
++			WPRINTK("Error initialising /dev/xen/blktap - "
++				"No more devices\n");
++			return -1;
++		}
++		translate_domid[newdev].domid = tr->domid;
++		translate_domid[newdev].busid = tr->busid;
++		return newdev;
++	}
++	case BLKTAP_IOCTL_FREEINTF:
++	{
++		unsigned long dev = arg;
++		tap_blkif_t *info = NULL;
++
++		if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev];
++
++		if ( (info != NULL) && (info->dev_pending) )
++			info->dev_pending = 0;
++		return 0;
++	}
++	case BLKTAP_IOCTL_MINOR:
++	{
++		unsigned long dev = arg;
++		tap_blkif_t *info = NULL;
++		
++		if ( (dev > 0) && (dev < MAX_TAP_DEV) ) info = tapfds[dev];
++		
++		if (info != NULL) return info->minor;
++		else return -1;
++	}
++	case BLKTAP_IOCTL_MAJOR:
++		return BLKTAP_DEV_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 *file, poll_table *wait)
++{
++	private_info_t *prv;
++	tap_blkif_t *info;
++	
++	/*Retrieve the dev info*/
++	prv = (private_info_t *)file->private_data;
++	if (prv == NULL) {
++		WPRINTK(" poll, retrieving idx failed\n");
++		return 0;
++	}
++	
++	if (prv->idx == 0) return 0;
++	
++	info = tapfds[prv->idx];
++	
++	poll_wait(file, &info->wait, wait);
++	if (info->ufe_ring.req_prod_pvt != info->ufe_ring.sring->req_prod) {
++		flush_tlb_all();
++		RING_PUSH_REQUESTS(&info->ufe_ring);
++		return POLLIN | POLLRDNORM;
++	}
++	return 0;
++}
++
++void blktap_kick_user(int idx)
++{
++	tap_blkif_t *info;
++
++	if (idx == 0) return;
++	
++	info = tapfds[idx];
++	
++	if (info != NULL) 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;
++	struct page *page;
++	unsigned long flags;
++	int ret;
++
++	spin_lock_irqsave(&pending_free_lock, flags);
++
++	ret = -EINVAL;
++	if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) 
++		goto done;
++
++#ifdef __ia64__
++	extern unsigned long alloc_empty_foreign_map_page_range(
++		unsigned long pages);
++	mmap_start[mmap_alloc].start = (unsigned long)
++		alloc_empty_foreign_map_page_range(mmap_pages);
++#else /* ! ia64 */
++	page = balloon_alloc_empty_page_range(mmap_pages);
++	ret = -ENOMEM;
++	if (page == NULL) {
++		printk("%s balloon_alloc_empty_page_range gave NULL\n", __FUNCTION__);
++		goto done;
++	}
++
++	/* Pin all of the pages. */
++	for (i=0; i<mmap_pages; i++)
++		get_page(&page[i]);
++
++	mmap_start[mmap_alloc].start = 
++		(unsigned long)pfn_to_kaddr(page_to_pfn(page));
++	mmap_start[mmap_alloc].mpage = page;
++
++#endif
++
++	pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t) *
++					blkif_reqs, GFP_KERNEL);
++	pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
++					mmap_pages, GFP_KERNEL);
++
++	ret = -ENOMEM;
++	if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
++		kfree(pending_reqs[mmap_alloc]);
++		kfree(pending_addrs[mmap_alloc]);
++		WPRINTK("%s: out of memory\n", __FUNCTION__);
++		ret = -ENOMEM;
++		goto done;
++	}
++
++	ret = 0;
++
++	DPRINTK("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
++	        __FUNCTION__, blkif_reqs, mmap_pages, 
++	       mmap_start[mmap_alloc].start);
++
++	BUG_ON(mmap_start[mmap_alloc].start == 0);
++
++	for (i = 0; i < mmap_pages; i++) 
++		pending_addrs[mmap_alloc][i] = 
++			mmap_start[mmap_alloc].start + (i << PAGE_SHIFT);
++
++	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);
++ done:
++	spin_unlock_irqrestore(&pending_free_lock, flags);
++	return ret;
++}
++
++static void mmap_req_del(int mmap)
++{
++	int i;
++	struct page *page;
++
++	/*Spinlock already acquired*/
++	kfree(pending_reqs[mmap]);
++	kfree(pending_addrs[mmap]);
++
++#ifdef __ia64__
++	/*Not sure what goes here yet!*/
++#else
++
++	/* Unpin all of the pages. */
++	page = mmap_start[mmap].mpage;
++	for (i=0; i<mmap_pages; i++)
++		put_page(&page[i]);
++
++	balloon_dealloc_empty_page_range(mmap_start[mmap].mpage, mmap_pages);
++#endif
++
++	mmap_lock = 0;
++	DPRINTK("# MMAPs decreased to %d\n",mmap_alloc);
++	mmap_alloc--;
++}
++
++/*N.B. Currently unused - will be accessed via sysfs*/
++static void req_decrease(void)
++{
++	pending_req_t *req;
++	int i;
++	unsigned long flags;
++
++	spin_lock_irqsave(&pending_free_lock, flags);
++
++	DPRINTK("Req decrease called.\n");
++	if (mmap_lock || mmap_alloc == 1) 
++		goto done;
++
++	mmap_lock = 1;
++	mmap_inuse = MAX_PENDING_REQS;
++	
++        /*Go through reqs and remove any that aren't in use*/
++	for (i = 0; i < MAX_PENDING_REQS ; i++) {
++		req = &pending_reqs[mmap_alloc-1][i];
++		if (req->inuse == 0) {
++			list_del(&req->free_list);
++			mmap_inuse--;
++		}
++	}
++	if (mmap_inuse == 0) mmap_req_del(mmap_alloc-1);
++ done:
++	spin_unlock_irqrestore(&pending_free_lock, flags);
++	return;
++}
++
++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 = tapfds[tapidx];
++	
++	if (info == NULL) {
++		WPRINTK("fast_flush: Couldn't get info!\n");
++		return;
++	}
++	mmap_idx = req->mem_idx;
++
++	for (i = 0; i < req->nr_pages; i++) {
++		kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i);
++		uvaddr = MMAP_VADDR(info->user_vstart, u_idx, i);
++
++		khandle = &pending_handle(mmap_idx, k_idx, i);
++		if (BLKTAP_INVALID_HANDLE(khandle)) {
++			WPRINTK("BLKTAP_INVALID_HANDLE\n");
++			continue;
++		}
++		gnttab_set_unmap_op(&unmap[invcount], 
++			MMAP_VADDR(mmap_start[mmap_idx].start, k_idx, i), 
++				    GNTMAP_host_map, khandle->kernel);
++		invcount++;
++
++		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,
++			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)
++		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(int idx)
++{
++	/* 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;
++	tap_blkif_t *info;
++	
++	info = tapfds[idx];
++	if (info == NULL) {
++		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++) {
++		resp = RING_GET_RESPONSE(&info->ufe_ring, i);
++		++info->ufe_ring.rsp_cons;
++
++		/*retrieve [usr_idx] to [mmap_idx,pending_idx] mapping*/
++		usr_idx = (int)resp->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 = MMAP_VADDR(mmap_start[mmap_idx].start, 
++					    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, idx);
++		make_response(blkif, pending_req->id, resp->operation,
++			      resp->status);
++		info->idx_map[usr_idx] = INVALID_REQ;
++		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 == -1) {
++		/*oops*/
++		if (print_dbug) {
++			WPRINTK("Corresponding UE " 
++			       "ring does not exist!\n");
++			print_dbug = 0; /*We only print this message once*/
++		}
++		return 1;
++	}
++
++	info = tapfds[blkif->dev_num];
++	if (info == NULL || !info->dev_inuse) {
++		if (print_dbug) {
++			WPRINTK("Can't get UE info!\n");
++			print_dbug = 0;
++		}
++		return 1;
++	}
++
++	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;
++		}
++
++		req = RING_GET_REQUEST(blk_ring, rc);
++		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 = tapfds[blkif->dev_num];
++	uint64_t sector;
++	
++	blkif_request_t *target;
++	int pending_idx = RTN_PEND_IDX(pending_req,pending_req->mem_idx);
++	int usr_idx = GET_NEXT_REQ(info->idx_map);
++	uint16_t mmap_idx = pending_req->mem_idx;
++
++	/*Check we have space on user ring - should never fail*/
++	if(usr_idx == INVALID_REQ) goto fail_flush;
++	
++	/* 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;
++		struct page *page;
++		uint32_t flags;
++
++		uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
++		kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
++				    pending_idx, i);
++		page = virt_to_page(kvaddr);
++
++		sector = req->sector_number + (8*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,
++				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++;
++
++		/* 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");
++			fast_flush_area(pending_req, pending_idx, usr_idx, 
++					blkif->dev_num);
++			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);
++
++	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 = MMAP_VADDR(mmap_start[mmap_idx].start, 
++				    pending_idx, i/2);
++
++		if (unlikely(map[i].status != 0)) {
++			WPRINTK("invalid kernel buffer -- "
++				"could not remap it\n");
++			goto fail_flush;
++		}
++
++		if (unlikely(map[i+1].status != 0)) {
++			WPRINTK("invalid user buffer -- "
++				"could not remap it\n");
++			goto fail_flush;
++		}
++
++		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;
++		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;
++	}
++	/* Mark mapped pages as reserved: */
++	for (i = 0; i < req->nr_segments; i++) {
++		unsigned long kvaddr;
++		struct page *pg;
++
++		kvaddr = MMAP_VADDR(mmap_start[mmap_idx].start, 
++				    pending_idx, i);
++		pg = pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
++		SetPageReserved(pg);
++	}
++	
++	/*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;
++	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;
++	tap_blkif_t *info;
++
++	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();
++
++	/*Create the blktap devices, but do not map memory or waitqueue*/
++	for(i = 0; i < MAX_TAP_DEV; i++) translate_domid[i].domid = 0xFFFF;
++
++	ret = register_chrdev(BLKTAP_DEV_MAJOR,"blktap",&blktap_fops);
++
++	if ( (ret < 0) ) {
++		WPRINTK("Couldn't register /dev/xen/blktap\n");
++		return -ENOMEM;
++	}	
++	
++	for(i = 0; i < MAX_TAP_DEV; i++ ) {
++		info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL);
++		if(tapfds[i] == NULL) return -ENOMEM;
++		info->minor = i;
++		info->pid = 0;
++		info->blkif = NULL;
++
++		info->dev_pending = info->dev_inuse = 0;
++
++		DPRINTK("Created misc_dev [/dev/xen/blktap%d]\n",i);
++	}
++	
++	DPRINTK("Blktap device successfully created\n");
++
++	return 0;
++}
++
++module_init(blkif_init);
++
++MODULE_LICENSE("Dual BSD/GPL");
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blktap/common.h linux-2.6.18-rc5-xen/drivers/xen/blktap/common.h
+--- linux-2.6.18-rc5/drivers/xen/blktap/common.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blktap/common.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,119 @@
++/* 
++ * 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/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);
++
++#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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blktap/interface.c linux-2.6.18-rc5-xen/drivers/xen/blktap/interface.c
+--- linux-2.6.18-rc5/drivers/xen/blktap/interface.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blktap/interface.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,159 @@
++/******************************************************************************
++ * 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_free(blkif_t *blkif)
++{
++	atomic_dec(&blkif->refcnt);
++	wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
++
++	/* Already disconnected? */
++	if (blkif->irq)
++		unbind_from_irqhandler(blkif->irq, blkif);
++
++	if (blkif->blk_ring.sring) {
++		unmap_frontend_page(blkif);
++		free_vm_area(blkif->blk_ring_area);
++	}
++
++	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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blktap/Makefile linux-2.6.18-rc5-xen/drivers/xen/blktap/Makefile
+--- linux-2.6.18-rc5/drivers/xen/blktap/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blktap/Makefile	2006-07-20 15:57:17.000000000 +0200
+@@ -0,0 +1,3 @@
++LINUXINCLUDE += -I../xen/include/public/io
++obj-y	:= xenbus.o interface.o blktap.o 
++
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/blktap/xenbus.c linux-2.6.18-rc5-xen/drivers/xen/blktap/xenbus.c
+--- linux-2.6.18-rc5/drivers/xen/blktap/xenbus.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/blktap/xenbus.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,353 @@
++/* 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 at 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");
++	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("");
++
++	switch (frontend_state) {
++	case XenbusStateInitialising:
++		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:
++		xenbus_switch_state(dev, XenbusStateClosing);
++		break;
++
++	case XenbusStateUnknown:
++	case XenbusStateClosed:
++		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", 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/char/Makefile linux-2.6.18-rc5-xen/drivers/xen/char/Makefile
+--- linux-2.6.18-rc5/drivers/xen/char/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/char/Makefile	2006-07-20 15:57:17.000000000 +0200
+@@ -0,0 +1,2 @@
++
++obj-y	:= mem.o
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/char/mem.c linux-2.6.18-rc5-xen/drivers/xen/char/mem.c
+--- linux-2.6.18-rc5/drivers/xen/char/mem.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/char/mem.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,180 @@
++/*
++ *  Originally from linux/drivers/char/mem.c
++ *
++ *  Copyright (C) 1991, 1992  Linus Torvalds
++ *
++ *  Added devfs support. 
++ *    Jan-11-1998, C. Scott Ananian <cananian at alumni.princeton.edu>
++ *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj at sgi.com>
++ */
++
++#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/ptrace.h>
++#include <linux/device.h>
++#include <asm/pgalloc.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <asm/hypervisor.h>
++
++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;
++}
++
++/*
++ * 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;
++
++	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);
++
++		if ((v = ioremap(p, sz)) == 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);
++		iounmap(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;
++
++	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);
++
++		if ((v = ioremap(p, sz)) == NULL)
++			break;
++
++		ignored = copy_from_user(v, buf, sz);
++		iounmap(v);
++		if (ignored) {
++			written += sz - ignored;
++			if (written)
++				break;
++			return -EFAULT;
++		}
++		buf += sz;
++		p += sz;
++		count -= sz;
++		written += sz;
++	}
++
++	*ppos += written;
++	return written;
++}
++
++static int 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);
++}
++
++/*
++ * 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		= mmap_mem,
++	.open		= open_mem,
++};
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/console/console.c linux-2.6.18-rc5-xen/drivers/xen/console/console.c
+--- linux-2.6.18-rc5/drivers/xen/console/console.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/console/console.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,644 @@
++/******************************************************************************
++ * 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/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/vt.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 <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/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]+'.
++ *                 [XC_DEFAULT]: DOM0 -> XC_SERIAL ; all others -> XC_TTY.
++ * 
++ * NB. In mode XC_TTY, we create dummy consoles for tty2-63. This suppresses
++ * warnings from standard distro startup scripts.
++ */
++static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT;
++static int xc_num = -1;
++
++#ifdef CONFIG_MAGIC_SYSRQ
++static unsigned long sysrq_requested;
++extern int sysrq_enabled;
++#endif
++
++static int __init xencons_setup(char *str)
++{
++	char *q;
++	int n;
++
++	if (!strncmp(str, "ttyS", 4))
++		xc_mode = XC_SERIAL;
++	else if (!strncmp(str, "tty", 3))
++		xc_mode = XC_TTY;
++	else if (!strncmp(str, "off", 3))
++		xc_mode = XC_OFF;
++
++	switch (xc_mode) {
++	case XC_SERIAL:
++		n = simple_strtol(str+4, &q, 10);
++		if (q > (str + 4))
++			xc_num = n;
++		break;
++	case XC_TTY:
++		n = simple_strtol(str+3, &q, 10);
++		if (q > (str + 3))
++			xc_num = n;
++		break;
++	default:
++		break;
++	}
++
++	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;
@@ -49925,7 +52912,7 @@
 +
 +static struct console kcons_info = {
 +	.device	= kcons_device,
-+	.flags	= CON_PRINTBUFFER,
++	.flags	= CON_PRINTBUFFER | CON_ENABLED,
 +	.index	= -1,
 +};
 +
@@ -49935,12 +52922,10 @@
 +	if (!is_running_on_xen())
 +		return __RETCODE;
 +
-+	if (xen_start_info->flags & SIF_INITDOMAIN) {
++	if (is_initial_xendomain()) {
 +		if (xc_mode == XC_DEFAULT)
 +			xc_mode = XC_SERIAL;
 +		kcons_info.write = kcons_write_dom0;
-+		if (xc_mode == XC_SERIAL)
-+			kcons_info.flags |= CON_ENABLED;
 +	} else {
 +		if (xc_mode == XC_DEFAULT)
 +			xc_mode = XC_TTY;
@@ -49996,7 +52981,7 @@
 +	int sz;
 +
 +	/* Emergency console is synchronous, so there's nothing to flush. */
-+	if (xen_start_info->flags & SIF_INITDOMAIN)
++	if (is_initial_xendomain())
 +		return;
 +
 +	/* Spin until console data is flushed through to the daemon. */
@@ -50014,7 +52999,8 @@
 +/******************** User-space console driver (/dev/console) ************/
 +
 +#define DRV(_d)         (_d)
-+#define TTY_INDEX(_tty) ((_tty)->index)
++#define DUMMY_TTY(_tty) ((xc_mode != XC_SERIAL) &&		\
++			 ((_tty)->index != (xc_num - 1)))
 +
 +static struct termios *xencons_termios[MAX_NR_CONSOLES];
 +static struct termios *xencons_termios_locked[MAX_NR_CONSOLES];
@@ -50066,7 +53052,7 @@
 +	int sent, sz, work_done = 0;
 +
 +	if (x_char) {
-+		if (xen_start_info->flags & SIF_INITDOMAIN)
++		if (is_initial_xendomain())
 +			kcons_write_dom0(NULL, &x_char, 1);
 +		else
 +			while (x_char)
@@ -50080,7 +53066,7 @@
 +		sz = wp - wc;
 +		if (sz > (wbuf_size - WBUF_MASK(wc)))
 +			sz = wbuf_size - WBUF_MASK(wc);
-+		if (xen_start_info->flags & SIF_INITDOMAIN) {
++		if (is_initial_xendomain()) {
 +			kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz);
 +			wc += sz;
 +		} else {
@@ -50138,7 +53124,7 @@
 +{
 +	unsigned long flags;
 +
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return;
 +
 +	spin_lock_irqsave(&xencons_lock, flags);
@@ -50149,7 +53135,7 @@
 +
 +static void xencons_throttle(struct tty_struct *tty)
 +{
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return;
 +
 +	if (I_IXOFF(tty))
@@ -50158,7 +53144,7 @@
 +
 +static void xencons_unthrottle(struct tty_struct *tty)
 +{
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return;
 +
 +	if (I_IXOFF(tty)) {
@@ -50173,7 +53159,7 @@
 +{
 +	unsigned long flags;
 +
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return;
 +
 +	spin_lock_irqsave(&xencons_lock, flags);
@@ -50198,7 +53184,7 @@
 +	int i;
 +	unsigned long flags;
 +
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return count;
 +
 +	spin_lock_irqsave(&xencons_lock, flags);
@@ -50219,7 +53205,7 @@
 +{
 +	unsigned long flags;
 +
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return;
 +
 +	spin_lock_irqsave(&xencons_lock, flags);
@@ -50231,7 +53217,7 @@
 +{
 +	unsigned long flags;
 +
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return;
 +
 +	spin_lock_irqsave(&xencons_lock, flags);
@@ -50243,7 +53229,7 @@
 +{
 +	unsigned long orig_jiffies = jiffies;
 +
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return;
 +
 +	while (DRV(tty->driver)->chars_in_buffer(tty)) {
@@ -50262,7 +53248,7 @@
 +{
 +	unsigned long flags;
 +
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return 0;
 +
 +	spin_lock_irqsave(&xencons_lock, flags);
@@ -50279,21 +53265,30 @@
 +{
 +	unsigned long flags;
 +
-+	if (TTY_INDEX(tty) != 0)
++	if (DUMMY_TTY(tty))
 +		return;
 +
-+	if (tty->count == 1) {
-+		tty->closing = 1;
-+		tty_wait_until_sent(tty, 0);
-+		if (DRV(tty->driver)->flush_buffer != NULL)
-+			DRV(tty->driver)->flush_buffer(tty);
-+		if (tty->ldisc.flush_buffer != NULL)
-+			tty->ldisc.flush_buffer(tty);
-+		tty->closing = 0;
-+		spin_lock_irqsave(&xencons_lock, flags);
-+		xencons_tty = NULL;
-+		spin_unlock_irqrestore(&xencons_lock, flags);
++	mutex_lock(&tty_mutex);
++
++	if (tty->count != 1) {
++		mutex_unlock(&tty_mutex);
++		return;
 +	}
++
++	/* Prevent other threads from re-opening this tty. */
++	set_bit(TTY_CLOSING, &tty->flags);
++	mutex_unlock(&tty_mutex);
++
++	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 = {
@@ -50335,8 +53330,7 @@
 +	DRV(xencons_driver)->init_termios    = tty_std_termios;
 +	DRV(xencons_driver)->flags           =
 +		TTY_DRIVER_REAL_RAW |
-+		TTY_DRIVER_RESET_TERMIOS |
-+		TTY_DRIVER_NO_DEVFS;
++		TTY_DRIVER_RESET_TERMIOS;
 +	DRV(xencons_driver)->termios         = xencons_termios;
 +	DRV(xencons_driver)->termios_locked  = xencons_termios_locked;
 +
@@ -50346,8 +53340,8 @@
 +		DRV(xencons_driver)->name_base   = 0 + xc_num;
 +	} else {
 +		DRV(xencons_driver)->name        = "tty";
-+		DRV(xencons_driver)->minor_start = xc_num;
-+		DRV(xencons_driver)->name_base   = xc_num;
++		DRV(xencons_driver)->minor_start = 1;
++		DRV(xencons_driver)->name_base   = 1;
 +	}
 +
 +	tty_set_operations(xencons_driver, &xencons_ops);
@@ -50362,9 +53356,7 @@
 +		return rc;
 +	}
 +
-+	tty_register_device(xencons_driver, 0, NULL);
-+
-+	if (xen_start_info->flags & SIF_INITDOMAIN) {
++	if (is_initial_xendomain()) {
 +		xencons_priv_irq = bind_virq_to_irqhandler(
 +			VIRQ_CONSOLE,
 +			0,
@@ -50376,8 +53368,7 @@
 +	}
 +
 +	printk("Xen virtual console successfully installed as %s%d\n",
-+	       DRV(xencons_driver)->name,
-+	       DRV(xencons_driver)->name_base );
++	       DRV(xencons_driver)->name, xc_num);
 +
 +	return 0;
 +}
@@ -50385,15 +53376,15 @@
 +module_init(xencons_init);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/console/Makefile linux-2.6.17-xen/drivers/xen/console/Makefile
---- linux-2.6.17/drivers/xen/console/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/console/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/console/Makefile linux-2.6.18-rc5-xen/drivers/xen/console/Makefile
+--- linux-2.6.18-rc5/drivers/xen/console/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/console/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,2 @@
 +
 +obj-y	:= console.o xencons_ring.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/console/xencons_ring.c linux-2.6.17-xen/drivers/xen/console/xencons_ring.c
---- linux-2.6.17/drivers/xen/console/xencons_ring.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/console/xencons_ring.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/console/xencons_ring.c linux-2.6.18-rc5-xen/drivers/xen/console/xencons_ring.c
+--- linux-2.6.18-rc5/drivers/xen/console/xencons_ring.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/console/xencons_ring.c	2006-09-01 00:09:11.000000000 +0200
 @@ -0,0 +1,141 @@
 +/* 
 + * This program is free software; you can redistribute it and/or
@@ -50449,13 +53440,13 @@
 +
 +static inline struct xencons_interface *xencons_interface(void)
 +{
-+	return mfn_to_virt(xen_start_info->console_mfn);
++	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_evtchn);
++	notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
 +}
 +
 +int xencons_ring_send(const char *data, unsigned len)
@@ -50513,11 +53504,11 @@
 +		unbind_from_irqhandler(xencons_irq, NULL);
 +	xencons_irq = 0;
 +
-+	if (!xen_start_info->console_evtchn)
++	if (!xen_start_info->console.domU.evtchn)
 +		return 0;
 +
 +	err = bind_evtchn_to_irqhandler(
-+		xen_start_info->console_evtchn,
++		xen_start_info->console.domU.evtchn,
 +		handle_input, 0, "xencons", NULL);
 +	if (err <= 0) {
 +		printk(KERN_ERR "XEN console request irq failed %i\n", err);
@@ -50536,11 +53527,11 @@
 +{
 +	(void)xencons_ring_init();
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/cpu_hotplug.c linux-2.6.17-xen/drivers/xen/core/cpu_hotplug.c
---- linux-2.6.17/drivers/xen/core/cpu_hotplug.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/cpu_hotplug.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/cpu_hotplug.c linux-2.6.18-rc5-xen/drivers/xen/core/cpu_hotplug.c
+--- linux-2.6.18-rc5/drivers/xen/core/cpu_hotplug.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/cpu_hotplug.c	2006-09-01 00:09:11.000000000 +0200
 @@ -0,0 +1,188 @@
-+#include <linux/config.h>
++
 +#include <linux/init.h>
 +#include <linux/kernel.h>
 +#include <linux/sched.h>
@@ -50634,8 +53625,8 @@
 +		.flags = XBWF_new_thread };
 +	(void)register_xenbus_watch(&cpu_watch);
 +
-+	if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
-+		for_each_cpu(i)
++	if (!is_initial_xendomain()) {
++		for_each_possible_cpu(i)
 +			vcpu_hotplug(i);
 +		printk(KERN_INFO "Brought up %ld CPUs\n",
 +		       (long)num_online_cpus());
@@ -50681,7 +53672,7 @@
 +			if (err) {
 +				printk(KERN_CRIT "Failed to take all CPUs "
 +				       "down: %d.\n", err);
-+				for_each_cpu(i)
++				for_each_possible_cpu(i)
 +					vcpu_hotplug(i);
 +				return err;
 +			}
@@ -50696,12 +53687,12 @@
 +{
 +	int cpu;
 +
-+	for_each_cpu(cpu)
++	for_each_possible_cpu(cpu)
 +		cpu_initialize_context(cpu);
 +
 +	unlock_cpu_hotplug();
 +
-+	for_each_cpu(cpu)
++	for_each_possible_cpu(cpu)
 +		vcpu_hotplug(cpu);
 +}
 +
@@ -50728,10 +53719,10 @@
 +{
 +	xenbus_allowed_cpumask = cpu_present_map;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/evtchn.c linux-2.6.17-xen/drivers/xen/core/evtchn.c
---- linux-2.6.17/drivers/xen/core/evtchn.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/evtchn.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,853 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/evtchn.c linux-2.6.18-rc5-xen/drivers/xen/core/evtchn.c
+--- linux-2.6.18-rc5/drivers/xen/core/evtchn.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/evtchn.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,868 @@
 +/******************************************************************************
 + * evtchn.c
 + * 
@@ -50764,7 +53755,6 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/module.h>
 +#include <linux/irq.h>
 +#include <linux/interrupt.h>
@@ -51207,6 +54197,17 @@
 +	rebind_irq_to_cpu(irq, tcpu);
 +}
 +
++static int retrigger(unsigned int irq)
++{
++	int evtchn = evtchn_from_irq(irq);
++	shared_info_t *s = HYPERVISOR_shared_info;
++	if (!VALID_EVTCHN(evtchn))
++		return 1;
++	BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0]));
++	synch_set_bit(evtchn, &s->evtchn_pending[0]);
++	return 1;
++}
++
 +/*
 + * Interface to generic handling in irq.c
 + */
@@ -51265,14 +54266,17 @@
 +}
 +
 +static struct hw_interrupt_type dynirq_type = {
-+	"Dynamic-irq",
-+	startup_dynirq,
-+	shutdown_dynirq,
-+	enable_dynirq,
-+	disable_dynirq,
-+	ack_dynirq,
-+	end_dynirq,
-+	set_affinity_irq
++	.typename	= "Dynamic-irq",
++	.startup	= startup_dynirq,
++	.shutdown	= shutdown_dynirq,
++	.enable		= enable_dynirq,
++	.disable	= disable_dynirq,
++	.ack		= ack_dynirq,
++	.end		= end_dynirq,
++#ifdef CONFIG_SMP
++	.set_affinity	= set_affinity_irq,
++#endif
++	.retrigger	= retrigger,
 +};
 +
 +static inline void pirq_unmask_notify(int pirq)
@@ -51390,14 +54394,17 @@
 +}
 +
 +static struct hw_interrupt_type pirq_type = {
-+	"Phys-irq",
-+	startup_pirq,
-+	shutdown_pirq,
-+	enable_pirq,
-+	disable_pirq,
-+	ack_pirq,
-+	end_pirq,
-+	set_affinity_irq
++	.typename	= "Phys-irq",
++	.startup	= startup_pirq,
++	.shutdown	= shutdown_pirq,
++	.enable		= enable_pirq,
++	.disable	= disable_pirq,
++	.ack		= ack_pirq,
++	.end		= end_pirq,
++#ifdef CONFIG_SMP
++	.set_affinity	= set_affinity_irq,
++#endif
++	.retrigger	= retrigger,
 +};
 +
 +int irq_ignore_unhandled(unsigned int irq)
@@ -51411,7 +54418,7 @@
 +	return !!(irq_status.flags & XENIRQSTAT_shared);
 +}
 +
-+void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i)
++void resend_irq_on_evtchn(unsigned int i)
 +{
 +	int evtchn = evtchn_from_irq(i);
 +	shared_info_t *s = HYPERVISOR_shared_info;
@@ -51565,7 +54572,7 @@
 +		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;
++		irq_desc[dynirq_to_irq(i)].chip    = &dynirq_type;
 +	}
 +
 +	/* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
@@ -51574,20 +54581,19 @@
 +
 +#ifdef RTC_IRQ
 +		/* If not domain 0, force our RTC driver to fail its probe. */
-+		if ((i == RTC_IRQ) &&
-+		    !(xen_start_info->flags & SIF_INITDOMAIN))
++		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;
++		irq_desc[pirq_to_irq(i)].chip    = &pirq_type;
 +	}
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/features.c linux-2.6.17-xen/drivers/xen/core/features.c
---- linux-2.6.17/drivers/xen/core/features.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/features.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/features.c linux-2.6.18-rc5-xen/drivers/xen/core/features.c
+--- linux-2.6.18-rc5/drivers/xen/core/features.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/features.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,30 @@
 +/******************************************************************************
 + * features.c
@@ -51619,10 +54625,10 @@
 +			xen_features[i*32+j] = !!(fi.submap & 1<<j);
 +	}
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/gnttab.c linux-2.6.17-xen/drivers/xen/core/gnttab.c
---- linux-2.6.17/drivers/xen/core/gnttab.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/gnttab.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,442 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/gnttab.c linux-2.6.18-rc5-xen/drivers/xen/core/gnttab.c
+--- linux-2.6.18-rc5/drivers/xen/core/gnttab.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/gnttab.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,483 @@
 +/******************************************************************************
 + * gnttab.c
 + *
@@ -51656,7 +54662,6 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/module.h>
 +#include <linux/sched.h>
 +#include <linux/mm.h>
@@ -51666,6 +54671,8 @@
 +#include <asm/pgtable.h>
 +#include <asm/uaccess.h>
 +#include <asm/synch_bitops.h>
++#include <asm/io.h>
++#include <xen/interface/memory.h>
 +
 +/* External tools reserve first few grant table entries. */
 +#define NR_RESERVED_ENTRIES 8
@@ -51975,6 +54982,8 @@
 +}
 +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)
@@ -52035,17 +55044,53 @@
 +
 +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;
 +}
 +
-+static int __init gnttab_init(void)
++#endif /* !CONFIG_XEN */
++
++int __init gnttab_init(void)
 +{
 +	int i;
 +
@@ -52064,11 +55109,13 @@
 +	return 0;
 +}
 +
++#ifdef CONFIG_XEN
 +core_initcall(gnttab_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/hypervisor_sysfs.c linux-2.6.17-xen/drivers/xen/core/hypervisor_sysfs.c
---- linux-2.6.17/drivers/xen/core/hypervisor_sysfs.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/hypervisor_sysfs.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,60 @@
++#endif
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/hypervisor_sysfs.c linux-2.6.18-rc5-xen/drivers/xen/core/hypervisor_sysfs.c
+--- linux-2.6.18-rc5/drivers/xen/core/hypervisor_sysfs.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/hypervisor_sysfs.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,59 @@
 +/*
 + *  copyright (c) 2006 IBM Corporation
 + *  Authored by: Mike D. Day <ncmike at us.ibm.com>
@@ -52078,7 +55125,6 @@
 + *  published by the Free Software Foundation.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/kobject.h>
@@ -52129,9 +55175,9 @@
 +
 +device_initcall(hypervisor_subsys_init);
 +EXPORT_SYMBOL_GPL(hypervisor_subsys);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/Makefile linux-2.6.17-xen/drivers/xen/core/Makefile
---- linux-2.6.17/drivers/xen/core/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/Makefile linux-2.6.18-rc5-xen/drivers/xen/core/Makefile
+--- linux-2.6.18-rc5/drivers/xen/core/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,13 @@
 +#
 +# Makefile for the linux kernel.
@@ -52146,10 +55192,10 @@
 +obj-$(CONFIG_XEN_SKBUFF)	+= skbuff.o
 +obj-$(CONFIG_XEN_REBOOT)	+= reboot.o
 +obj-$(CONFIG_XEN_SMPBOOT)	+= smpboot.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/reboot.c linux-2.6.17-xen/drivers/xen/core/reboot.c
---- linux-2.6.17/drivers/xen/core/reboot.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/reboot.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,364 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/reboot.c linux-2.6.18-rc5-xen/drivers/xen/core/reboot.c
+--- linux-2.6.18-rc5/drivers/xen/core/reboot.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/reboot.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,384 @@
 +#define __KERNEL_SYSCALLS__
 +#include <linux/version.h>
 +#include <linux/kernel.h>
@@ -52171,14 +55217,6 @@
 +#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);
-+#endif
-+
 +extern void ctrl_alt_del(void);
 +
 +#define SHUTDOWN_INVALID  -1
@@ -52191,6 +55229,14 @@
 + */
 +#define SHUTDOWN_HALT      4
 +
++#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. */
@@ -52212,10 +55258,8 @@
 +{
 +	/* We really want to get pending console data out before we die. */
 +	xencons_force_flush();
-+#if defined(__i386__) || defined(__x86_64__)
 +	if (pm_power_off)
 +		pm_power_off();
-+#endif
 +	HYPERVISOR_shutdown(SHUTDOWN_poweroff);
 +}
 +
@@ -52224,6 +55268,7 @@
 +EXPORT_SYMBOL(machine_halt);
 +EXPORT_SYMBOL(machine_power_off);
 +
++#endif /* defined(__i386__) || defined(__x86_64__) */
 +
 +/******************************************************************************
 + * Stop/pickle callback handling.
@@ -52234,6 +55279,8 @@
 +static void __shutdown_handler(void *unused);
 +static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
 +
++#if defined(__i386__) || defined(__x86_64__)
++
 +/* 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
@@ -52251,24 +55298,71 @@
 +	mmdrop(mm);
 +}
 +
-+static int __do_suspend(void *ignore)
++static void pre_suspend(void)
 +{
-+	int i, j, k, fpp, err;
++	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
++
++static int __do_suspend(void *ignore)
++{
++	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)
@@ -52278,21 +55372,13 @@
 +
 +	preempt_disable();
 +
-+#ifdef __i386__
-+	kmem_cache_shrink(pgd_cache);
-+#endif
 +	mm_pin_all();
-+
-+	__cli();
++	local_irq_disable();
 +	preempt_enable();
 +
 +	gnttab_suspend();
 +
-+	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_mfn = mfn_to_pfn(xen_start_info->console_mfn);
++	pre_suspend();
 +
 +	/*
 +	 * We'll stop somewhere inside this hypercall. When it returns,
@@ -52302,27 +55388,7 @@
 +
 +	shutting_down = SHUTDOWN_INVALID;
 +
-+	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;
++	post_suspend();
 +
 +	gnttab_resume();
 +
@@ -52332,7 +55398,7 @@
 +
 +	switch_idle_mm();
 +
-+	__sti();
++	local_irq_enable();
 +
 +	xencons_resume();
 +
@@ -52514,12 +55580,11 @@
 +}
 +
 +subsys_initcall(setup_shutdown_event);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/skbuff.c linux-2.6.17-xen/drivers/xen/core/skbuff.c
---- linux-2.6.17/drivers/xen/core/skbuff.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/skbuff.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,141 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/skbuff.c linux-2.6.18-rc5-xen/drivers/xen/core/skbuff.c
+--- linux-2.6.18-rc5/drivers/xen/core/skbuff.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/skbuff.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,139 @@
 +
-+#include <linux/config.h>
 +#include <linux/module.h>
 +#include <linux/version.h>
 +#include <linux/kernel.h>
@@ -52641,8 +55706,7 @@
 +	for (order = 0; order <= MAX_SKBUFF_ORDER; order++) {
 +		size = PAGE_SIZE << order;
 +		sprintf(name[order], "xen-skb-%lu", size);
-+		if (is_running_on_xen() &&
-+		    (xen_start_info->flags & SIF_PRIVILEGED))
++		if (is_running_on_xen() && is_initial_xendomain())
 +			skbuff_order_cachep[order] = kmem_cache_create(
 +				name[order], size, size, 0,
 +				skbuff_ctor, skbuff_dtor);
@@ -52659,10 +55723,10 @@
 +core_initcall(skbuff_init);
 +
 +EXPORT_SYMBOL(__dev_alloc_skb);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/smpboot.c linux-2.6.17-xen/drivers/xen/core/smpboot.c
---- linux-2.6.17/drivers/xen/core/smpboot.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/smpboot.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,433 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/smpboot.c linux-2.6.18-rc5-xen/drivers/xen/core/smpboot.c
+--- linux-2.6.18-rc5/drivers/xen/core/smpboot.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/smpboot.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,429 @@
 +/*
 + *	Xen SMP booting functions
 + *
@@ -52671,7 +55735,6 @@
 + */
 +
 +#include <linux/module.h>
-+#include <linux/config.h>
 +#include <linux/init.h>
 +#include <linux/kernel.h>
 +#include <linux/mm.h>
@@ -52704,15 +55767,13 @@
 +
 +/* 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);
++EXPORT_SYMBOL(smp_num_siblings);
 +#if defined(__i386__)
 +int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
 +#elif defined(__x86_64__)
 +u8 cpu_llc_id[NR_CPUS] __cpuinitdata  = {[0 ... NR_CPUS-1] = BAD_APICID};
 +#endif
++EXPORT_SYMBOL(cpu_llc_id);
 +
 +cpumask_t cpu_online_map;
 +EXPORT_SYMBOL(cpu_online_map);
@@ -52736,6 +55797,7 @@
 +void *xquad_portio;
 +
 +cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
++EXPORT_SYMBOL(cpu_sibling_map);
 +cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
 +EXPORT_SYMBOL(cpu_core_map);
 +
@@ -52764,8 +55826,8 @@
 +static inline void
 +set_cpu_sibling_map(int cpu)
 +{
-+	phys_proc_id[cpu] = cpu;
-+	cpu_core_id[cpu]  = 0;
++	cpu_data[cpu].phys_proc_id = cpu;
++	cpu_data[cpu].cpu_core_id = 0;
 +
 +	cpu_sibling_map[cpu] = cpumask_of_cpu(cpu);
 +	cpu_core_map[cpu]    = cpumask_of_cpu(cpu);
@@ -52918,7 +55980,14 @@
 +
 +	xen_smp_intr_init(0);
 +
-+	for_each_cpu_mask (cpu, cpu_possible_map) {
++	/* 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_possible_cpu (cpu) {
 +		if (cpu == 0)
 +			continue;
 +
@@ -52929,7 +55998,8 @@
 +#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);
++			printk(KERN_CRIT "CPU%d failed to allocate GDT\n",
++			       cpu);
 +			continue;
 +		}
 +		gdt_descr->size = GDT_SIZE;
@@ -52957,7 +56027,7 @@
 +		irq_ctx_init(cpu);
 +
 +#ifdef CONFIG_HOTPLUG_CPU
-+		if (xen_start_info->flags & SIF_INITDOMAIN)
++		if (is_initial_xendomain())
 +			cpu_set(cpu, cpu_present_map);
 +#else
 +		cpu_set(cpu, cpu_present_map);
@@ -52968,12 +56038,6 @@
 +
 +	init_xenbus_allowed_cpumask();
 +
-+	/* Currently, Xen gives no dynamic NUMA/HT info. */
-+	for (cpu = 1; cpu < NR_CPUS; cpu++) {
-+		cpu_sibling_map[cpu] = cpumask_of_cpu(cpu);
-+		cpu_core_map[cpu]    = cpumask_of_cpu(cpu);
-+	}
-+
 +#ifdef CONFIG_X86_IO_APIC
 +	/*
 +	 * Here we can be sure that there is an IO-APIC in the system. Let's
@@ -53005,8 +56069,8 @@
 +static void
 +remove_siblinginfo(int cpu)
 +{
-+	phys_proc_id[cpu] = BAD_APICID;
-+	cpu_core_id[cpu]  = BAD_APICID;
++	cpu_data[cpu].phys_proc_id = BAD_APICID;
++	cpu_data[cpu].cpu_core_id = BAD_APICID;
 +
 +	cpus_clear(cpu_sibling_map[cpu]);
 +	cpus_clear(cpu_core_map[cpu]);
@@ -53040,10 +56104,8 @@
 +
 +	xen_smp_intr_exit(cpu);
 +
-+#ifdef __i386__
 +	if (num_online_cpus() == 1)
 +		alternatives_smp_switch(0);
-+#endif
 +}
 +
 +#else /* !CONFIG_HOTPLUG_CPU */
@@ -53068,10 +56130,8 @@
 +	if (rc)
 +		return rc;
 +
-+#ifdef __i386__
 +	if (num_online_cpus() == 1)
 +		alternatives_smp_switch(1);
-+#endif
 +
 +	/* This must be done before setting cpu_online_map */
 +	set_cpu_sibling_map(cpu);
@@ -53096,12 +56156,11 @@
 +	return -EINVAL;
 +}
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/xen_proc.c linux-2.6.17-xen/drivers/xen/core/xen_proc.c
---- linux-2.6.17/drivers/xen/core/xen_proc.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/xen_proc.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,19 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/xen_proc.c linux-2.6.18-rc5-xen/drivers/xen/core/xen_proc.c
+--- linux-2.6.18-rc5/drivers/xen/core/xen_proc.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/xen_proc.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,18 @@
 +
-+#include <linux/config.h>
 +#include <linux/proc_fs.h>
 +#include <xen/xen_proc.h>
 +
@@ -53119,10 +56178,10 @@
 +{
 +	remove_proc_entry(name, xen_base);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/core/xen_sysfs.c linux-2.6.17-xen/drivers/xen/core/xen_sysfs.c
---- linux-2.6.17/drivers/xen/core/xen_sysfs.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/core/xen_sysfs.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,379 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/core/xen_sysfs.c linux-2.6.18-rc5-xen/drivers/xen/core/xen_sysfs.c
+--- linux-2.6.18-rc5/drivers/xen/core/xen_sysfs.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/core/xen_sysfs.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,378 @@
 +/*
 + *  copyright (c) 2006 IBM Corporation
 + *  Authored by: Mike D. Day <ncmike at us.ibm.com>
@@ -53132,7 +56191,6 @@
 + *  published by the Free Software Foundation.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/err.h>
 +#include <linux/kernel.h>
 +#include <linux/module.h>
@@ -53502,10 +56560,10 @@
 +
 +module_init(hyper_sysfs_init);
 +module_exit(hyper_sysfs_exit);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/evtchn/evtchn.c linux-2.6.17-xen/drivers/xen/evtchn/evtchn.c
---- linux-2.6.17/drivers/xen/evtchn/evtchn.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/evtchn/evtchn.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,458 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/evtchn/evtchn.c linux-2.6.18-rc5-xen/drivers/xen/evtchn/evtchn.c
+--- linux-2.6.18-rc5/drivers/xen/evtchn/evtchn.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/evtchn/evtchn.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,456 @@
 +/******************************************************************************
 + * evtchn.c
 + * 
@@ -53539,7 +56597,6 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/module.h>
 +#include <linux/kernel.h>
 +#include <linux/sched.h>
@@ -53930,7 +56987,6 @@
 +	.minor        = EVTCHN_MINOR,
 +	.name         = "evtchn",
 +	.fops         = &evtchn_fops,
-+	.devfs_name   = "misc/evtchn",
 +};
 +
 +static int __init evtchn_init(void)
@@ -53964,16 +57020,16 @@
 +module_exit(evtchn_cleanup);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/evtchn/Makefile linux-2.6.17-xen/drivers/xen/evtchn/Makefile
---- linux-2.6.17/drivers/xen/evtchn/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/evtchn/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/evtchn/Makefile linux-2.6.18-rc5-xen/drivers/xen/evtchn/Makefile
+--- linux-2.6.18-rc5/drivers/xen/evtchn/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/evtchn/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,2 @@
 +
 +obj-y	:= evtchn.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/Kconfig linux-2.6.17-xen/drivers/xen/Kconfig
---- linux-2.6.17/drivers/xen/Kconfig	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/Kconfig	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,248 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/Kconfig linux-2.6.18-rc5-xen/drivers/xen/Kconfig
+--- linux-2.6.18-rc5/drivers/xen/Kconfig	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/Kconfig	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,260 @@
 +#
 +# This Kconfig describe xen options
 +#
@@ -53989,7 +57045,7 @@
 +if XEN
 +config XEN_INTERFACE_VERSION
 +	hex
-+	default 0x00030202
++	default 0x00030203
 +
 +menu "XEN"
 +
@@ -54009,6 +57065,11 @@
 +	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
@@ -54016,46 +57077,6 @@
 +          Support for backend device drivers that provide I/O services
 +          to other virtual machines.
 +
-+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.0 will be re-assigned to 00:01.0.
-+
-+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.
-+
-+endchoice
-+
-+config XEN_PCIDEV_BE_DEBUG
-+	bool "PCI Backend Debugging"
-+	depends on XEN_PCIDEV_BACKEND
-+	default n
-+
 +config XEN_BLKDEV_BACKEND
 +	tristate "Block-device backend driver"
 +        depends on XEN_BACKEND
@@ -54065,10 +57086,17 @@
 +	  block devices to other guests via a high-performance shared-memory
 +	  interface.
 +
-+config XEN_XENBUS_DEV
-+	bool
-+	depends on PROC_FS
-+	default y
++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"
@@ -54100,6 +57128,55 @@
 +	  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
@@ -54107,15 +57184,6 @@
 +	help
 +	  The TPM-device backend driver
 +
-+config XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
-+	bool "TPM backend closes upon vTPM failure"
-+	depends on XEN_TPMDEV_BACKEND
-+	default n
-+	help
-+	  The TPM backend closes the channel if the vTPM in userspace indicates
-+	  a failure. The corresponding domain's channel will be closed.
-+	  Say Y if you want this feature.
-+
 +config XEN_BLKDEV_FRONTEND
 +	tristate "Block-device frontend driver"
 +	depends on XEN
@@ -54159,7 +57227,7 @@
 +	depends on SYSFS
 +	default y
 +	help
-+		Xen hypervisor attributes will show up under /sys/hypervisor/.
++	  Xen hypervisor attributes will show up under /sys/hypervisor/.
 +
 +choice
 +	prompt "Xen version compatibility"
@@ -54222,10 +57290,10 @@
 +	depends on SMP
 +
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/Makefile linux-2.6.17-xen/drivers/xen/Makefile
---- linux-2.6.17/drivers/xen/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/Makefile	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,16 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/Makefile linux-2.6.18-rc5-xen/drivers/xen/Makefile
+--- linux-2.6.18-rc5/drivers/xen/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/Makefile	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,17 @@
 +obj-y	+= core/
 +obj-y	+= console/
 +obj-y	+= evtchn/
@@ -54236,16 +57304,17 @@
 +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/
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netback/common.h linux-2.6.17-xen/drivers/xen/netback/common.h
---- linux-2.6.17/drivers/xen/netback/common.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netback/common.h	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,124 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netback/common.h linux-2.6.18-rc5-xen/drivers/xen/netback/common.h
+--- linux-2.6.18-rc5/drivers/xen/netback/common.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netback/common.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,141 @@
 +/******************************************************************************
 + * arch/xen/drivers/netif/backend/common.h
 + * 
@@ -54277,7 +57346,6 @@
 +#ifndef __NETIF__BACKEND__COMMON_H__
 +#define __NETIF__BACKEND__COMMON_H__
 +
-+#include <linux/config.h>
 +#include <linux/version.h>
 +#include <linux/module.h>
 +#include <linux/interrupt.h>
@@ -54294,6 +57362,7 @@
 +#include <xen/interface/grant_table.h>
 +#include <xen/gnttab.h>
 +#include <xen/driver_util.h>
++#include <asm/hypercall.h>
 +
 +#define DPRINTK(_f, _a...)			\
 +	pr_debug("(file=%s, line=%d) " _f,	\
@@ -54312,9 +57381,9 @@
 +
 +	/* Physical parameters of the comms window. */
 +	grant_handle_t   tx_shmem_handle;
-+	grant_ref_t      tx_shmem_ref; 
++	grant_ref_t      tx_shmem_ref;
 +	grant_handle_t   rx_shmem_handle;
-+	grant_ref_t      rx_shmem_ref; 
++	grant_ref_t      rx_shmem_ref;
 +	unsigned int     evtchn;
 +	unsigned int     irq;
 +
@@ -54324,6 +57393,13 @@
 +	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;
 +
@@ -54334,8 +57410,6 @@
 +	struct timer_list credit_timeout;
 +
 +	/* Miscellaneous private stuff. */
-+	enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
-+	int active;
 +	struct list_head list;  /* scheduling list */
 +	atomic_t         refcnt;
 +	struct net_device *dev;
@@ -54369,11 +57443,23 @@
 +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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netback/interface.c linux-2.6.17-xen/drivers/xen/netback/interface.c
---- linux-2.6.17/drivers/xen/netback/interface.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netback/interface.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,314 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netback/interface.c linux-2.6.18-rc5-xen/drivers/xen/netback/interface.c
+--- linux-2.6.18-rc5/drivers/xen/netback/interface.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netback/interface.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,339 @@
 +/******************************************************************************
 + * arch/xen/drivers/netif/backend/interface.c
 + * 
@@ -54412,46 +57498,75 @@
 +
 +static void __netif_up(netif_t *netif)
 +{
-+	struct net_device *dev = netif->dev;
-+	netif_tx_lock_bh(dev);
-+	netif->active = 1;
-+	netif_tx_unlock_bh(dev);
 +	enable_irq(netif->irq);
 +	netif_schedule_work(netif);
 +}
 +
 +static void __netif_down(netif_t *netif)
 +{
-+	struct net_device *dev = netif->dev;
 +	disable_irq(netif->irq);
-+	netif_tx_lock_bh(dev);
-+	netif->active = 0;
-+	netif_tx_unlock_bh(dev);
 +	netif_deschedule_work(netif);
 +}
 +
 +static int net_open(struct net_device *dev)
 +{
 +	netif_t *netif = netdev_priv(dev);
-+	if (netif->status == CONNECTED)
++	if (netif_carrier_ok(dev))
 +		__netif_up(netif);
-+	netif_start_queue(dev);
 +	return 0;
 +}
 +
 +static int net_close(struct net_device *dev)
 +{
 +	netif_t *netif = netdev_priv(dev);
-+	netif_stop_queue(dev);
-+	if (netif->status == CONNECTED)
++	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, u8 be_mac[ETH_ALEN])
@@ -54468,11 +57583,12 @@
 +		return ERR_PTR(-ENOMEM);
 +	}
 +
++	netif_carrier_off(dev);
++
 +	netif = netdev_priv(dev);
 +	memset(netif, 0, sizeof(*netif));
 +	netif->domid  = domid;
 +	netif->handle = handle;
-+	netif->status = DISCONNECTED;
 +	atomic_set(&netif->refcnt, 1);
 +	init_waitqueue_head(&netif->waiting_to_free);
 +	netif->dev = dev;
@@ -54485,12 +57601,16 @@
 +	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);
 +
-+	/* Disable queuing. */
-+	dev->tx_queue_len = 0;
++	/*
++	 * Reduce default TX queuelen so that each guest interface only
++	 * allows it to eat around 6.4MB of host memory.
++	 */
++	dev->tx_queue_len = 100;
 +
 +	for (i = 0; i < ETH_ALEN; i++)
 +		if (be_mac[i] != 0)
@@ -54631,11 +57751,9 @@
 +	netif->rx_req_cons_peek = 0;
 +
 +	netif_get(netif);
-+	wmb(); /* Other CPUs see new state before interface is started. */
 +
 +	rtnl_lock();
-+	netif->status = CONNECTED;
-+	wmb();
++	netif_carrier_on(netif->dev);
 +	if (netif_running(netif->dev))
 +		__netif_up(netif);
 +	rtnl_unlock();
@@ -54671,26 +57789,19 @@
 +
 +void netif_disconnect(netif_t *netif)
 +{
-+	switch (netif->status) {
-+	case CONNECTED:
++	if (netif_carrier_ok(netif->dev)) {
 +		rtnl_lock();
-+		netif->status = DISCONNECTING;
-+		wmb();
++		netif_carrier_off(netif->dev);
 +		if (netif_running(netif->dev))
 +			__netif_down(netif);
 +		rtnl_unlock();
 +		netif_put(netif);
-+		/* fall through */
-+	case DISCONNECTED:
-+		netif_free(netif);
-+		break;
-+	default:
-+		BUG();
 +	}
++	netif_free(netif);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netback/loopback.c linux-2.6.17-xen/drivers/xen/netback/loopback.c
---- linux-2.6.17/drivers/xen/netback/loopback.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netback/loopback.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netback/loopback.c linux-2.6.18-rc5-xen/drivers/xen/netback/loopback.c
+--- linux-2.6.18-rc5/drivers/xen/netback/loopback.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netback/loopback.c	2006-09-01 00:09:11.000000000 +0200
 @@ -0,0 +1,260 @@
 +/******************************************************************************
 + * netback/loopback.c
@@ -54739,7 +57850,6 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/module.h>
 +#include <linux/netdevice.h>
 +#include <linux/inetdevice.h>
@@ -54823,6 +57933,7 @@
 +	.set_sg = ethtool_op_set_sg,
 +	.get_tso = ethtool_op_get_tso,
 +	.set_tso = ethtool_op_set_tso,
++	.get_link = ethtool_op_get_link,
 +};
 +
 +/*
@@ -54911,7 +58022,7 @@
 +	return err;
 +}
 +
-+static void __init clean_loopback(int i)
++static void __exit clean_loopback(int i)
 +{
 +	struct net_device *dev1, *dev2;
 +	char dev_name[IFNAMSIZ];
@@ -54952,19 +58063,19 @@
 +module_exit(loopback_exit);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netback/Makefile linux-2.6.17-xen/drivers/xen/netback/Makefile
---- linux-2.6.17/drivers/xen/netback/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netback/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netback/Makefile linux-2.6.18-rc5-xen/drivers/xen/netback/Makefile
+--- linux-2.6.18-rc5/drivers/xen/netback/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netback/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netback/netback.c linux-2.6.17-xen/drivers/xen/netback/netback.c
---- linux-2.6.17/drivers/xen/netback/netback.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netback/netback.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,1107 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netback/netback.c linux-2.6.18-rc5-xen/drivers/xen/netback/netback.c
+--- linux-2.6.18-rc5/drivers/xen/netback/netback.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netback/netback.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,1498 @@
 +/******************************************************************************
 + * drivers/xen/netback/netback.c
 + * 
@@ -55004,20 +58115,27 @@
 +#include "common.h"
 +#include <xen/balloon.h>
 +#include <xen/interface/memory.h>
++#include <asm/page.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 int  make_rx_response(netif_t *netif, 
-+			     u16      id, 
-+			     s8       st,
-+			     u16      offset,
-+			     u16      size,
-+			     u16      flags);
++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);
@@ -55030,14 +58148,12 @@
 +#define MAX_PENDING_REQS 256
 +
 +static struct sk_buff_head rx_queue;
-+static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
-+static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
-+static gnttab_transfer_t grant_rx_op[NET_RX_RING_SIZE];
-+static unsigned char rx_notify[NR_IRQS];
 +
 +static unsigned long mmap_vstart;
 +#define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE))
 +
++static void *rx_mmap_area;
++
 +#define PKT_PROT_LEN 64
 +
 +static struct {
@@ -55066,25 +58182,28 @@
 +#define MAX_MFN_ALLOC 64
 +static unsigned long mfn_list[MAX_MFN_ALLOC];
 +static unsigned int alloc_index = 0;
-+static DEFINE_SPINLOCK(mfn_lock);
 +
-+static unsigned long alloc_mfn(void)
++static inline unsigned long alloc_mfn(void)
++{
++	return mfn_list[--alloc_index];
++}
++
++static int check_mfn(int nr)
 +{
-+	unsigned long mfn = 0, flags;
 +	struct xen_memory_reservation reservation = {
-+		.nr_extents   = MAX_MFN_ALLOC,
 +		.extent_order = 0,
 +		.domid        = DOMID_SELF
 +	};
-+	set_xen_guest_handle(reservation.extent_start, mfn_list);
-+	spin_lock_irqsave(&mfn_lock, flags);
-+	if ( unlikely(alloc_index == 0) )
-+		alloc_index = HYPERVISOR_memory_op(
-+			XENMEM_increase_reservation, &reservation);
-+	if ( alloc_index != 0 )
-+		mfn = mfn_list[--alloc_index];
-+	spin_unlock_irqrestore(&mfn_lock, flags);
-+	return mfn;
++
++	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)
@@ -55106,6 +58225,123 @@
 +	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);
++	if (unlikely(!nskb))
++		goto err;
++
++	skb_reserve(nskb, 16);
++	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 | 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);
++}
++
 +int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
 +{
 +	netif_t *netif = netdev_priv(dev);
@@ -55113,30 +58349,24 @@
 +	BUG_ON(skb->dev != dev);
 +
 +	/* Drop the packet if the target domain has no receive buffers. */
-+	if (!netif->active || 
-+	    (netif->rx_req_cons_peek == netif->rx.sring->req_prod) ||
-+	    ((netif->rx_req_cons_peek - netif->rx.rsp_prod_pvt) ==
-+	     NET_RX_RING_SIZE))
++	if (unlikely(!netif_running(dev) || !netif_carrier_ok(dev)))
 +		goto drop;
 +
-+	/*
-+	 * We do not copy the packet unless:
-+	 *  1. The data is shared; or
-+	 *  2. The data is not allocated from our special cache.
-+	 * NB. We also couldn't cope with fragmented packets, but we won't get
-+	 *     any because we not advertise the NETIF_F_SG feature.
-+	 */
-+	if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) {
-+		int hlen = skb->data - skb->head;
-+		int ret;
-+		struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len);
++	if (unlikely(netbk_queue_full(netif))) {
++		/* Not a BUG_ON() -- misbehaving netfront can trigger this. */
++		if (netbk_can_queue(dev))
++			DPRINTK("Queue full but not stopped!\n");
++		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;
-+		skb_reserve(nskb, hlen);
-+		__skb_put(nskb, skb->len);
-+		ret = skb_copy_bits(skb, -hlen, nskb->data - hlen,
-+				     skb->len + hlen);
-+		BUG_ON(ret);
 +		/* Copy only the header fields we use in this driver. */
 +		nskb->dev = skb->dev;
 +		nskb->ip_summed = skb->ip_summed;
@@ -55145,9 +58375,18 @@
 +		skb = nskb;
 +	}
 +
-+	netif->rx_req_cons_peek++;
++	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);
++	}
++
 +	skb_queue_tail(&rx_queue, skb);
 +	tasklet_schedule(&net_rx_tasklet);
 +
@@ -55170,7 +58409,7 @@
 +/* 
 + * Add following to poll() function in NAPI driver (Tigon3 is example):
 + *  if ( xen_network_done() )
-+ *      tg3_enable_ints(tp); 
++ *      tg3_enable_ints(tp);
 + */
 +int xen_network_done(void)
 +{
@@ -55178,148 +58417,371 @@
 +}
 +#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->source.domid = DOMID_SELF;
++		copy_gop->source.offset = offset;
++		copy_gop->source.u.gmfn = old_mfn;
++		copy_gop->dest.domid = netif->domid;
++		copy_gop->dest.offset = 0;
++		copy_gop->dest.u.ref = req->gref;
++		copy_gop->len = size;
++		copy_gop->flags = GNTCOPY_dest_gref;
++	} 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",
++					gop->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; 
++	netif_t *netif = NULL;
 +	s8 status;
-+	u16 size, id, irq, flags;
++	u16 id, irq, flags;
++	netif_rx_response_t *resp;
 +	multicall_entry_t *mcl;
-+	mmu_update_t *mmu;
-+	gnttab_transfer_t *gop;
-+	unsigned long vdata, old_mfn, new_mfn;
 +	struct sk_buff_head rxq;
 +	struct sk_buff *skb;
-+	u16 notify_list[NET_RX_RING_SIZE];
 +	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);
 +
-+	mcl = rx_mcl;
-+	mmu = rx_mmu;
-+	gop = grant_rx_op;
++	count = 0;
 +
 +	while ((skb = skb_dequeue(&rx_queue)) != NULL) {
-+		netif   = netdev_priv(skb->dev);
-+		vdata   = (unsigned long)skb->data;
-+		old_mfn = virt_to_mfn(vdata);
++		nr_frags = skb_shinfo(skb)->nr_frags;
++		*(int *)skb->cb = nr_frags;
 +
-+		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
++		if (!xen_feature(XENFEAT_auto_translated_physmap) &&
++		    check_mfn(nr_frags + 1)) {
 +			/* Memory squeeze? Back off for an arbitrary while. */
-+			if ((new_mfn = alloc_mfn()) == 0) {
-+				if ( net_ratelimit() )
-+					WPRINTK("Memory squeeze in netback "
-+						"driver.\n");
-+				mod_timer(&net_timer, jiffies + HZ);
-+				skb_queue_head(&rx_queue, skb);
-+				break;
-+			}
-+			/*
-+			 * 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(
-+				__pa(skb->data) >> PAGE_SHIFT,
-+				new_mfn);
-+
-+			MULTI_update_va_mapping(mcl, vdata,
-+						pfn_pte_ma(new_mfn,
-+							   PAGE_KERNEL), 0);
-+			mcl++;
-+
-+			mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
-+				MMU_MACHPHYS_UPDATE;
-+			mmu->val = __pa(vdata) >> PAGE_SHIFT;
-+			mmu++;
++			if ( net_ratelimit() )
++				WPRINTK("Memory squeeze in netback "
++					"driver.\n");
++			mod_timer(&net_timer, jiffies + HZ);
++			skb_queue_head(&rx_queue, skb);
++			break;
 +		}
 +
-+		gop->mfn = old_mfn;
-+		gop->domid = netif->domid;
-+		gop->ref = RING_GET_REQUEST(
-+			&netif->rx, netif->rx.req_cons)->gref;
-+		netif->rx.req_cons++;
-+		gop++;
++		netbk_gop_skb(skb, &npo);
++
++		count += nr_frags + 1;
 +
 +		__skb_queue_tail(&rxq, skb);
 +
 +		/* Filled the batch queue? */
-+		if ((gop - grant_rx_op) == ARRAY_SIZE(grant_rx_op))
++		if (count + MAX_SKB_FRAGS >= NET_RX_RING_SIZE)
 +			break;
 +	}
 +
-+	if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+		if (mcl == rx_mcl)
-+			return;
++	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;
 +
-+		if (mmu - rx_mmu) {
-+			mcl->op = __HYPERVISOR_mmu_update;
-+			mcl->args[0] = (unsigned long)rx_mmu;
-+			mcl->args[1] = mmu - rx_mmu;
-+			mcl->args[2] = 0;
-+			mcl->args[3] = DOMID_SELF;
-+			mcl++;
-+		}
++		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;
++	}
 +
-+		ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
-+		BUG_ON(ret != 0);
++	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;
 +	}
 +
-+	ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, 
-+					gop - grant_rx_op);
++	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);
 +
-+	mcl = rx_mcl;
-+	gop = grant_rx_op;
 +	while ((skb = __skb_dequeue(&rxq)) != NULL) {
-+		netif   = netdev_priv(skb->dev);
-+		size    = skb->tail - skb->data;
++		nr_frags = *(int *)skb->cb;
 +
-+		atomic_set(&(skb_shinfo(skb)->dataref), 1);
-+		skb_shinfo(skb)->nr_frags = 0;
-+		skb_shinfo(skb)->frag_list = NULL;
++		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 += size;
++		netif->stats.tx_bytes += skb->len;
 +		netif->stats.tx_packets++;
 +
-+		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+			/* The update_va_mapping() must not fail. */
-+			BUG_ON(mcl->result != 0);
-+			mcl++;
-+		}
++		status = netbk_check_gop(nr_frags, netif->domid, &npo);
++
++		id = meta[npo.meta_cons].id;
++		flags = nr_frags ? NETRXF_more_data : 0;
 +
-+		/* Check the reassignment error code. */
-+		status = NETIF_RSP_OKAY;
-+		if (gop->status != 0) { 
-+			DPRINTK("Bad status %d from grant transfer to DOM%u\n",
-+				gop->status, netif->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; 
-+		}
-+		irq = netif->irq;
-+		id = RING_GET_REQUEST(&netif->rx, netif->rx.rsp_prod_pvt)->id;
-+		flags = 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 (make_rx_response(netif, id, status,
-+				     (unsigned long)skb->data & ~PAGE_MASK,
-+				     size, flags) &&
-+		    (rx_notify[irq] == 0)) {
++
++		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) &&
++		    !netbk_queue_full(netif))
++			netif_wake_queue(netif->dev);
++
 +		netif_put(netif);
 +		dev_kfree_skb(skb);
-+		gop++;
++		npo.meta_cons += nr_frags + 1;
 +	}
 +
 +	while (notify_nr != 0) {
@@ -55370,7 +58832,9 @@
 +		return;
 +
 +	spin_lock_irq(&net_schedule_list_lock);
-+	if (!__on_net_schedule_list(netif) && netif->active) {
++	if (!__on_net_schedule_list(netif) &&
++	    likely(netif_running(netif->dev) &&
++		   netif_carrier_ok(netif->dev))) {
 +		list_add_tail(&netif->list, &net_schedule_list);
 +		netif_get(netif);
 +	}
@@ -55463,9 +58927,9 @@
 +
 +	do {
 +		make_tx_response(netif, txp, NETIF_RSP_ERROR);
-+		if (++cons >= end)
++		if (cons >= end)
 +			break;
-+		txp = RING_GET_REQUEST(&netif->tx, cons);
++		txp = RING_GET_REQUEST(&netif->tx, cons++);
 +	} while (1);
 +	netif->tx.req_cons = cons;
 +	netif_schedule_work(netif);
@@ -55658,6 +59122,29 @@
 +	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)
 +{
@@ -55731,11 +59218,11 @@
 +		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, 0);
++				netbk_tx_err(netif, &txreq, i);
 +				continue;
 +			}
-+			i = netif->tx.req_cons;
 +		}
 +
 +		ret = netbk_count_requests(netif, &txreq, work_to_do);
@@ -55754,7 +59241,7 @@
 +		if (unlikely(txreq.size < ETH_HLEN)) {
 +			DPRINTK("Bad packet size: %d\n", txreq.size);
 +			netbk_tx_err(netif, &txreq, i);
-+			continue; 
++			continue;
 +		}
 +
 +		/* No crossing a page as the payload mustn't fragment. */
@@ -55786,20 +59273,11 @@
 +			struct netif_extra_info *gso;
 +			gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
 +
-+			/* Currently on TCPv4 S.O. is supported. */
-+			if (gso->u.gso.type != XEN_NETIF_GSO_TCPV4) {
-+				DPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
++			if (netbk_set_skb_gso(skb, gso)) {
 +				kfree_skb(skb);
 +				netbk_tx_err(netif, &txreq, i);
-+				break;
++				continue;
 +			}
-+
-+			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;
 +		}
 +
 +		gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
@@ -55819,6 +59297,9 @@
 +			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);
@@ -55921,11 +59402,22 @@
 +	netif_idx_release(pending_idx);
 +}
 +
++static void netif_rx_page_release(struct page *page)
++{
++	/* Ready for next use. */
++	init_page_count(page);
++}
++
 +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_queue_stopped(netif->dev) && !netbk_queue_full(netif))
++		netif_wake_queue(netif->dev);
++
 +	return IRQ_HANDLED;
 +}
 +
@@ -55959,16 +59451,15 @@
 +#endif
 +}
 +
-+static int make_rx_response(netif_t *netif, 
-+			    u16      id, 
-+			    s8       st,
-+			    u16      offset,
-+			    u16      size,
-+			    u16      flags)
++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;
-+	int notify;
 +
 +	resp = RING_GET_RESPONSE(&netif->rx, i);
 +	resp->offset     = offset;
@@ -55979,9 +59470,8 @@
 +		resp->status = (s16)st;
 +
 +	netif->rx.rsp_prod_pvt = ++i;
-+	RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, notify);
 +
-+	return notify;
++	return resp;
 +}
 +
 +#ifdef NETBE_DEBUG_INTERRUPT
@@ -56037,7 +59527,9 @@
 +	net_timer.function = net_alarm;
 +    
 +	page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
-+	BUG_ON(page == NULL);
++	if (page == NULL)
++		return -ENOMEM;
++
 +	mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
 +
 +	for (i = 0; i < MAX_PENDING_REQS; i++) {
@@ -56046,6 +59538,16 @@
 +		SetPageForeign(page, netif_page_release);
 +	}
 +
++	page = balloon_alloc_empty_page_range(NET_RX_RING_SIZE);
++	BUG_ON(page == NULL);
++	rx_mmap_area = pfn_to_kaddr(page_to_pfn(page));
++
++	for (i = 0; i < NET_RX_RING_SIZE; i++) {
++		page = virt_to_page(rx_mmap_area + (i * PAGE_SIZE));
++		init_page_count(page);
++		SetPageForeign(page, netif_rx_page_release);
++	}
++
 +	pending_cons = 0;
 +	pending_prod = MAX_PENDING_REQS;
 +	for (i = 0; i < MAX_PENDING_REQS; i++)
@@ -56072,10 +59574,10 @@
 +module_init(netback_init);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netback/xenbus.c linux-2.6.17-xen/drivers/xen/netback/xenbus.c
---- linux-2.6.17/drivers/xen/netback/xenbus.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netback/xenbus.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,404 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netback/xenbus.c linux-2.6.18-rc5-xen/drivers/xen/netback/xenbus.c
+--- linux-2.6.18-rc5/drivers/xen/netback/xenbus.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netback/xenbus.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,461 @@
 +/*  Xenbus code for netif backend
 +    Copyright (C) 2005 Rusty Russell <rusty at rustcorp.com.au>
 +    Copyright (C) 2005 XenSource Ltd
@@ -56179,13 +59681,18 @@
 +			goto abort_transaction;
 +		}
 +
-+#if 0 /* KAF: After the protocol is finalised. */
-+		err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
++		err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4",
++				    "%d", 1);
 +		if (err) {
-+			message = "writing feature-tso";
++			message = "writing feature-gso-tcpv4";
++			goto abort_transaction;
++		}
++
++		err = xenbus_printf(xbt, dev->nodename, "feature-rx-copy", "%d", 1);
++		if (err) {
++			message = "writing feature-copying";
 +			goto abort_transaction;
 +		}
-+#endif
 +
 +		err = xenbus_transaction_end(xbt, 0);
 +	} while (err == -EAGAIN);
@@ -56307,10 +59814,25 @@
 +
 +	switch (frontend_state) {
 +	case XenbusStateInitialising:
++		if (dev->state == XenbusStateClosing) {
++			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:
++		if (!be->netif) {
++			/* reconnect: setup be->netif */
++			backend_changed(&be->backend_watch, NULL, 0);
++		}
 +		maybe_connect(be);
 +		break;
 +
@@ -56318,14 +59840,13 @@
 +		xenbus_switch_state(dev, XenbusStateClosing);
 +		break;
 +
++	case XenbusStateUnknown:
 +	case XenbusStateClosed:
 +		if (be->netif != NULL)
 +			kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
 +		device_unregister(&dev->dev);
 +		break;
 +
-+	case XenbusStateUnknown:
-+	case XenbusStateInitWait:
 +	default:
 +		xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
 +				 frontend_state);
@@ -56428,8 +59949,9 @@
 +{
 +	struct xenbus_device *dev = be->dev;
 +	unsigned long tx_ring_ref, rx_ring_ref;
-+	unsigned int evtchn;
++	unsigned int evtchn, rx_copy;
 +	int err;
++	int val;
 +
 +	DPRINTK("");
 +
@@ -56444,6 +59966,43 @@
 +		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 (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;
++	}
++
 +	/* Map the shared frame, irq etc. */
 +	err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
 +	if (err) {
@@ -56480,9 +60039,9 @@
 +{
 +	xenbus_register_backend(&netback);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netfront/Kconfig linux-2.6.17-xen/drivers/xen/netfront/Kconfig
---- linux-2.6.17/drivers/xen/netfront/Kconfig	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netfront/Kconfig	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netfront/Kconfig linux-2.6.18-rc5-xen/drivers/xen/netfront/Kconfig
+--- linux-2.6.18-rc5/drivers/xen/netfront/Kconfig	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netfront/Kconfig	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,6 @@
 +
 +config XENNET
@@ -56490,18 +60049,18 @@
 +	depends on NETDEVICES && ARCH_XEN
 +	help
 +	  Network driver for Xen
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netfront/Makefile linux-2.6.17-xen/drivers/xen/netfront/Makefile
---- linux-2.6.17/drivers/xen/netfront/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netfront/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netfront/Makefile linux-2.6.18-rc5-xen/drivers/xen/netfront/Makefile
+--- linux-2.6.18-rc5/drivers/xen/netfront/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netfront/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,4 @@
 +
 +obj-$(CONFIG_XEN_NETDEV_FRONTEND)	:= xennet.o
 +
 +xennet-objs := netfront.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/netfront/netfront.c linux-2.6.17-xen/drivers/xen/netfront/netfront.c
---- linux-2.6.17/drivers/xen/netfront/netfront.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/netfront/netfront.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,1599 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/netfront/netfront.c linux-2.6.18-rc5-xen/drivers/xen/netfront/netfront.c
+--- linux-2.6.18-rc5/drivers/xen/netfront/netfront.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/netfront/netfront.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,2067 @@
 +/******************************************************************************
 + * Virtual network driver for conversing with remote driver backends.
 + *
@@ -56533,7 +60092,6 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/module.h>
 +#include <linux/version.h>
 +#include <linux/kernel.h>
@@ -56550,11 +60108,12 @@
 +#include <linux/ethtool.h>
 +#include <linux/in.h>
 +#include <linux/if_ether.h>
++#include <linux/io.h>
 +#include <net/sock.h>
 +#include <net/pkt_sched.h>
 +#include <net/arp.h>
 +#include <net/route.h>
-+#include <asm/io.h>
++#include <asm/hypercall.h>
 +#include <asm/uaccess.h>
 +#include <xen/evtchn.h>
 +#include <xen/xenbus.h>
@@ -56562,22 +60121,32 @@
 +#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>
 +
++#define RX_COPY_THRESHOLD 256
++
++/* If we don't have GSO, fake things up so that we never try to use it. */
++#ifndef NETIF_F_GSO
++#define netif_needs_gso(dev, skb)	0
++#define dev_disable_gso_features(dev)	((void)0)
++#else
++#define HAVE_GSO			1
++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;
++}
++#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)
 +
-+static inline void init_skb_shinfo(struct sk_buff *skb)
-+{
-+	atomic_set(&(skb_shinfo(skb)->dataref), 1);
-+	skb_shinfo(skb)->nr_frags = 0;
-+	skb_shinfo(skb)->frag_list = NULL;
-+}
-+
 +struct netfront_info {
 +	struct list_head list;
 +	struct net_device *netdev;
@@ -56592,6 +60161,7 @@
 +
 +	unsigned int handle;
 +	unsigned int evtchn, irq;
++	unsigned int copying_receiver;
 +
 +	/* Receive-ring batched refills. */
 +#define RX_MIN_TARGET 8
@@ -56603,17 +60173,17 @@
 +	struct timer_list rx_refill_timer;
 +
 +	/*
-+	 * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
-+	 * array is an index into a chain of free entries.
++	 * {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+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_TX_RING_SIZE + 1];
++	grant_ref_t grant_rx_ref[NET_TX_RING_SIZE];
 +
 +	struct xenbus_device *xbdev;
 +	int tx_ring_ref;
@@ -56625,8 +60195,13 @@
 +	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,rx}_skbs[].
++ * Access macros for acquiring freeing slots in tx_skbs[].
 + */
 +
 +static inline void add_id_to_freelist(struct sk_buff **list, unsigned short id)
@@ -56642,6 +60217,29 @@
 +	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)
@@ -56652,7 +60250,7 @@
 +
 +static int talk_to_backend(struct xenbus_device *, struct netfront_info *);
 +static int setup_device(struct xenbus_device *, struct netfront_info *);
-+static struct net_device *create_netdev(int, struct xenbus_device *);
++static struct net_device *create_netdev(int, int, struct xenbus_device *);
 +
 +static void netfront_closing(struct xenbus_device *);
 +
@@ -56694,6 +60292,7 @@
 +	struct net_device *netdev;
 +	struct netfront_info *info;
 +	unsigned int handle;
++	unsigned feature_rx_copy;
 +
 +	err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle);
 +	if (err != 1) {
@@ -56701,7 +60300,22 @@
 +		return err;
 +	}
 +
-+	netdev = create_netdev(handle, dev);
++#ifndef CONFIG_XEN
++	err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-copy", "%u",
++			   &feature_rx_copy);
++	if (err != 1) {
++		xenbus_dev_fatal(dev, err, "reading feature-rx-copy");
++		return err;
++	}
++	if (!feature_rx_copy) {
++		xenbus_dev_fatal(dev, 0, "need a copy-capable backend");
++		return -EINVAL;
++	}
++#else
++	feature_rx_copy = 0;
++#endif
++
++	netdev = create_netdev(handle, feature_rx_copy, dev);
 +	if (IS_ERR(netdev)) {
 +		err = PTR_ERR(netdev);
 +		xenbus_dev_fatal(dev, err, "creating netdev");
@@ -56807,6 +60421,33 @@
 +		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;
++	}
++
++	err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
++	if (err) {
++		message = "writing feature-sg";
++		goto abort_transaction;
++	}
++
++#ifdef HAVE_GSO
++	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)
@@ -56878,7 +60519,8 @@
 +
 +	memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
 +	err = bind_evtchn_to_irqhandler(info->evtchn, netif_int,
-+					SA_SAMPLE_RANDOM, netdev->name, netdev);
++					SA_SAMPLE_RANDOM, netdev->name,
++					netdev);
 +	if (err < 0)
 +		goto fail;
 +	info->irq = err;
@@ -56957,8 +60599,14 @@
 +
 +	memset(&np->stats, 0, sizeof(np->stats));
 +
-+	network_alloc_rx_buffers(dev);
-+	np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
++	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);
 +
@@ -56987,8 +60635,7 @@
 +	struct netfront_info *np = netdev_priv(dev);
 +	struct sk_buff *skb;
 +
-+	if (unlikely(!netif_carrier_ok(dev)))
-+		return;
++	BUG_ON(!netif_carrier_ok(dev));
 +
 +	do {
 +		prod = np->tx.sring->rsp_prod;
@@ -57050,10 +60697,15 @@
 +	unsigned short id;
 +	struct netfront_info *np = netdev_priv(dev);
 +	struct sk_buff *skb;
-+	int i, batch_target;
++	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;
@@ -57067,28 +60719,41 @@
 +	batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
 +	for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
 +		/*
-+		 * Subtract dev_alloc_skb headroom (16 bytes) and shared info
-+		 * tailroom then round down to SKB_DATA_ALIGN boundary.
++		 * 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 = __dev_alloc_skb(
-+			((PAGE_SIZE - sizeof(struct skb_shared_info)) &
-+			 (-SKB_DATA_ALIGN(1))) - 16,
-+			GFP_ATOMIC|__GFP_NOWARN);
-+		if (skb == NULL) {
++		skb = alloc_skb(RX_COPY_THRESHOLD + 16,
++				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));
-+			return;
++			break;
 +		}
++
++		skb_reserve(skb, 16); /* 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 (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)) &&
@@ -57096,69 +60761,93 @@
 +		np->rx_target = np->rx_max_target;
 +
 + refill:
-+	for (i = 0; ; i++) {
++	for (nr_flips = i = 0; ; i++) {
 +		if ((skb = __skb_dequeue(&np->rx_batch)) == NULL)
 +			break;
 +
 +		skb->dev = dev;
 +
-+		id = get_id_from_freelist(np->rx_skbs);
++		id = xennet_rxidx(req_prod + i);
 +
++		BUG_ON(np->rx_skbs[id]);
 +		np->rx_skbs[id] = skb;
 +
-+		RING_GET_REQUEST(&np->rx, req_prod + i)->id = id;
 +		ref = gnttab_claim_grant_reference(&np->gref_rx_head);
 +		BUG_ON((signed short)ref < 0);
 +		np->grant_rx_ref[id] = ref;
-+		gnttab_grant_foreign_transfer_ref(ref,
-+						  np->xbdev->otherend_id,
-+						  __pa(skb->head)>>PAGE_SHIFT);
-+		RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
-+		np->rx_pfn_array[i] = virt_to_mfn(skb->head);
++
++		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,
++							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)) {
-+			/* Remove this page before passing back to Xen. */
-+			set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
-+					    INVALID_P2M_ENTRY);
-+			MULTI_update_va_mapping(np->rx_mcl+i,
-+						(unsigned long)skb->head,
-+						__pte(0), 0);
++			/* 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();
 +	}
 +
-+	/* 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   = i;
-+	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");
-+
 +	/* Above is a suitable barrier to ensure backend will see requests. */
 +	np->rx.req_prod_pvt = req_prod + i;
-+	RING_PUSH_REQUESTS(&np->rx);
++ 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,
@@ -57278,10 +60967,13 @@
 +
 +	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
 +
-+	if (skb_shinfo(skb)->gso_size) {
++#ifdef HAVE_GSO
++	if (skb_is_gso(skb)) {
 +		struct netif_extra_info *gso = (struct netif_extra_info *)
 +			RING_GET_REQUEST(&np->tx, ++i);
 +
@@ -57291,12 +60983,15 @@
 +			tx->flags |= NETTXF_extra_info;
 +
 +		gso->u.gso.size = skb_shinfo(skb)->gso_size;
-+		gso->u.gso.type = XEN_NETIF_GSO_TCPV4;
++		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;
 +
@@ -57332,30 +61027,272 @@
 +	unsigned long flags;
 +
 +	spin_lock_irqsave(&np->tx_lock, flags);
-+	network_tx_buf_gc(dev);
-+	spin_unlock_irqrestore(&np->tx_lock, flags);
 +
-+	if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx) &&
-+	    likely(netif_running(dev)))
-+		netif_rx_schedule(dev);
++	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);
++			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) {
++			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;
++	}
++
++	*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_GSO
++	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;
++#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, *nskb;
-+	struct netif_rx_response *rx;
++	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 mmu_update *mmu = np->rx_mmu;
-+	struct multicall_entry *mcl = np->rx_mcl;
++	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 long mfn;
-+	grant_ref_t ref;
++	unsigned int len;
++	int pages_flipped = 0;
++	int err;
 +
 +	spin_lock(&np->rx_lock);
 +
@@ -57365,6 +61302,8 @@
 +	}
 +
 +	skb_queue_head_init(&rxq);
++	skb_queue_head_init(&errq);
++	skb_queue_head_init(&tmpq);
 +
 +	if ((budget = *pbudget) > dev->quota)
 +		budget = dev->quota;
@@ -57373,150 +61312,126 @@
 +
 +	for (i = np->rx.rsp_cons, work_done = 0;
 +	     (i != rp) && (work_done < budget);
-+	     i++, work_done++) {
-+		rx = RING_GET_RESPONSE(&np->rx, i);
++	     np->rx.rsp_cons = ++i, work_done++) {
++		memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx));
++		memset(extras, 0, sizeof(extras));
 +
-+		/*
-+		 * 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 = np->grant_rx_ref[rx->id]) == GRANT_INVALID_REF) {
-+			WPRINTK("Bad rx response id %d.\n", rx->id);
-+			work_done--;
-+			continue;
-+		}
++		err = xennet_get_responses(np, &rinfo, rp, &tmpq,
++					   &pages_flipped);
 +
-+		/* Memory pressure, insufficient buffer headroom, ... */
-+		if ((mfn = gnttab_end_foreign_transfer_ref(ref)) == 0) {
-+			if (net_ratelimit())
-+				WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n",
-+					rx->id, rx->status);
-+			RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id =
-+				rx->id;
-+			RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref =
-+				ref;
-+			np->rx.req_prod_pvt++;
-+			RING_PUSH_REQUESTS(&np->rx);
++		if (unlikely(err)) {
++err:
++			i = np->rx.rsp_cons + skb_queue_len(&tmpq) - 1;
 +			work_done--;
++			while ((skb = __skb_dequeue(&tmpq)))
++				__skb_queue_tail(&errq, skb);
++			np->stats.rx_errors++;
 +			continue;
 +		}
 +
-+		gnttab_release_grant_reference(&np->gref_rx_head, ref);
-+		np->grant_rx_ref[rx->id] = GRANT_INVALID_REF;
++		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];
 +
-+		skb = np->rx_skbs[rx->id];
-+		add_id_to_freelist(np->rx_skbs, rx->id);
++			if (unlikely(xennet_set_skb_gso(skb, gso))) {
++				__skb_queue_head(&tmpq, skb);
++				goto err;
++			}
++		}
 +
-+		/* NB. We handle skb overflow later. */
-+		skb->data = skb->head + rx->offset;
-+		skb->len  = rx->status;
-+		skb->tail = skb->data + skb->len;
++		skb->nh.raw = (void *)skb_shinfo(skb)->frags[0].page;
++		skb->h.raw = skb->nh.raw + rx->offset;
 +
-+		/*
-+		 * 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;
-+			skb->proto_data_valid = 1;
++		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->ip_summed = CHECKSUM_NONE;
-+			skb->proto_data_valid = 0;
++			skb_shinfo(skb)->frags[0].page = NULL;
++			skb_shinfo(skb)->nr_frags = 0;
 +		}
-+		skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank);
 +
-+		np->stats.rx_packets++;
-+		np->stats.rx_bytes += rx->status;
++		i = xennet_fill_frags(np, skb, &tmpq);
 +
-+		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-+			/* Remap the page. */
-+			MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
-+						pfn_pte_ma(mfn, PAGE_KERNEL),
-+						0);
-+			mcl++;
-+			mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
-+				| MMU_MACHPHYS_UPDATE;
-+			mmu->val = __pa(skb->head) >> PAGE_SHIFT;
-+			mmu++;
++		/*
++		 * 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;
 +
-+			set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
-+					    mfn);
-+		}
++		/*
++		 * 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);
 +	}
 +
-+	/* Some pages are no longer absent... */
-+	balloon_update_driver_allowance(-work_done);
-+
-+	/* Do all the remapping work, and M2P updates, in one big hypercall. */
-+	if (likely((mcl - np->rx_mcl) != 0)) {
-+		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++;
-+		(void)HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
-+	}
++	if (pages_flipped) {
++		/* Some pages are no longer absent... */
++		balloon_update_driver_allowance(-pages_flipped);
 +
-+	while ((skb = __skb_dequeue(&rxq)) != NULL) {
-+		if (skb->len > (dev->mtu + ETH_HLEN + 4)) {
-+			if (net_ratelimit())
-+				printk(KERN_INFO "Received packet too big for "
-+				       "MTU (%d > %d)\n",
-+				       skb->len - ETH_HLEN - 4, dev->mtu);
-+			skb->len  = 0;
-+			skb->tail = skb->data;
-+			init_skb_shinfo(skb);
-+			dev_kfree_skb(skb);
-+			continue;
++		/* 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);
 +		}
++	}
 +
-+		/*
-+		 * Enough room in skbuff for the data we were passed? Also,
-+		 * Linux expects at least 16 bytes headroom in each rx buffer.
-+		 */
-+		if (unlikely(skb->tail > skb->end) ||
-+		    unlikely((skb->data - skb->head) < 16)) {
-+			if (net_ratelimit()) {
-+				if (skb->tail > skb->end)
-+					printk(KERN_INFO "Received packet "
-+					       "is %zd bytes beyond tail.\n",
-+					       skb->tail - skb->end);
-+				else
-+					printk(KERN_INFO "Received packet "
-+					       "is %zd bytes before head.\n",
-+					       16 - (skb->data - skb->head));
-+			}
++	while ((skb = __skb_dequeue(&errq)))
++		kfree_skb(skb);
 +
-+			nskb = __dev_alloc_skb(skb->len + 2,
-+					       GFP_ATOMIC|__GFP_NOWARN);
-+			if (nskb != NULL) {
-+				skb_reserve(nskb, 2);
-+				skb_put(nskb, skb->len);
-+				memcpy(nskb->data, skb->data, skb->len);
-+				/* Copy any other fields we already set up. */
-+				nskb->dev = skb->dev;
-+				nskb->ip_summed = skb->ip_summed;
-+				nskb->proto_data_valid = skb->proto_data_valid;
-+				nskb->proto_csum_blank = skb->proto_csum_blank;
-+			}
++	while ((skb = __skb_dequeue(&rxq)) != NULL) {
++		struct page *page = (struct page *)skb->nh.raw;
++		void *vaddr = page_address(page);
 +
-+			/* Reinitialise and then destroy the old skbuff. */
-+			skb->len  = 0;
-+			skb->tail = skb->data;
-+			init_skb_shinfo(skb);
-+			dev_kfree_skb(skb);
++		memcpy(skb->data, vaddr + (skb->h.raw - skb->nh.raw),
++		       skb_headlen(skb));
 +
-+			/* Switch old for new, if we copied the buffer. */
-+			if ((skb = nskb) == NULL)
-+				continue;
-+		}
++		if (page != skb_shinfo(skb)->frags[0].page)
++			__free_page(page);
 +
-+		/* Set the shinfo area, which is hidden behind the data. */
-+		init_skb_shinfo(skb);
 +		/* Ethernet work: Delayed to here as it peeks the header. */
 +		skb->protocol = eth_type_trans(skb, dev);
 +
@@ -57525,8 +61440,6 @@
 +		dev->last_rx = jiffies;
 +	}
 +
-+	np->rx.rsp_cons = i;
-+
 +	/* 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) >
@@ -57554,6 +61467,111 @@
 +	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)
 +{
@@ -57598,24 +61616,33 @@
 +
 +static int xennet_set_tso(struct net_device *dev, u32 data)
 +{
++#ifdef HAVE_GSO
 +	if (data) {
 +		struct netfront_info *np = netdev_priv(dev);
 +		int val;
 +
-+		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-tso",
-+				 "%d", &val) < 0)
++		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
++				 "feature-gso-tcpv4", "%d", &val) < 0)
 +			val = 0;
-+#if 0 /* KAF: After the protocol is finalised. */
 +		if (!val)
-+#endif
 +			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))
 +		xennet_set_tso(dev, 1);
 +}
@@ -57625,6 +61652,8 @@
 +	struct netfront_info *np = netdev_priv(dev);
 +	int i, requeue_idx;
 +	struct sk_buff *skb;
++	grant_ref_t ref;
++	netif_rx_request_t *req;
 +
 +	xennet_set_features(dev);
 +
@@ -57632,43 +61661,42 @@
 +	spin_lock(&np->rx_lock);
 +
 +	/*
-+         * Recovery procedure:
++	 * 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. */
-+	for (requeue_idx = 0, 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);
-+	}
++	netif_release_tx_bufs(np);
 +
 +	/* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
-+	for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) {
-+		if ((unsigned long)np->rx_skbs[i] < PAGE_OFFSET)
++	for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) {
++		if (!np->rx_skbs[i])
 +			continue;
-+		gnttab_grant_foreign_transfer_ref(
-+			np->grant_rx_ref[i], np->xbdev->otherend_id,
-+			__pa(np->rx_skbs[i]->data) >> PAGE_SHIFT);
-+		RING_GET_REQUEST(&np->rx, requeue_idx)->gref =
-+			np->grant_rx_ref[i];
-+		RING_GET_REQUEST(&np->rx, requeue_idx)->id = i;
++
++		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,
++				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;
-+	RING_PUSH_REQUESTS(&np->rx);
 +
 +	/*
 +	 * Step 3: All public and private state should now be sane.  Get
@@ -57688,6 +61716,8 @@
 +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);
 +}
@@ -57700,6 +61730,7 @@
 +	.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
@@ -57845,13 +61876,8 @@
 +{
 +}
 +
-+/** Create a network device.
-+ * @param handle device handle
-+ * @param val return parameter for created device
-+ * @return 0 on success, error code otherwise
-+ */
-+static struct net_device * __devinit create_netdev(int handle,
-+						   struct xenbus_device *dev)
++static struct net_device * __devinit
++create_netdev(int handle, int copying_receiver, struct xenbus_device *dev)
 +{
 +	int i, err = 0;
 +	struct net_device *netdev = NULL;
@@ -57864,9 +61890,10 @@
 +		return ERR_PTR(-ENOMEM);
 +	}
 +
-+	np                = netdev_priv(netdev);
-+	np->handle        = handle;
-+	np->xbdev         = dev;
++	np                   = netdev_priv(netdev);
++	np->handle           = handle;
++	np->xbdev            = dev;
++	np->copying_receiver = copying_receiver;
 +
 +	netif_carrier_off(netdev);
 +
@@ -57888,8 +61915,8 @@
 +		np->grant_tx_ref[i] = GRANT_INVALID_REF;
 +	}
 +
-+	for (i = 0; i <= NET_RX_RING_SIZE; i++) {
-+		np->rx_skbs[i] = (void *)((unsigned long) i+1);
++	for (i = 0; i < NET_RX_RING_SIZE; i++) {
++		np->rx_skbs[i] = NULL;
 +		np->grant_rx_ref[i] = GRANT_INVALID_REF;
 +	}
 +
@@ -58080,7 +62107,7 @@
 +	if (!is_running_on_xen())
 +		return -ENODEV;
 +
-+	if (xen_start_info->flags & SIF_INITDOMAIN)
++	if (is_initial_xendomain())
 +		return 0;
 +
 +	IPRINTK("Initialising virtual ethernet driver.\n");
@@ -58101,10 +62128,10 @@
 +module_exit(netif_exit);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/conf_space.c linux-2.6.17-xen/drivers/xen/pciback/conf_space.c
---- linux-2.6.17/drivers/xen/pciback/conf_space.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/conf_space.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,403 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space.c linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space.c	2006-08-06 23:45:53.000000000 +0200
+@@ -0,0 +1,425 @@
 +/*
 + * PCI Backend - Functions for creating a virtual configuration space for
 + *               exported PCI Devices.
@@ -58120,9 +62147,7 @@
 +#include <linux/pci.h>
 +#include "pciback.h"
 +#include "conf_space.h"
-+
-+static int permissive = 0;
-+module_param(permissive, bool, 0644);
++#include "conf_space_quirks.h"
 +
 +#define DEFINE_PCI_CONFIG(op,size,type) 			\
 +int pciback_##op##_config_##size 				\
@@ -58188,7 +62213,7 @@
 +	case 4:
 +		if (field->u.dw.write)
 +			ret = field->u.dw.write(dev, offset, value,
-+					        entry->data);
++						entry->data);
 +		break;
 +	}
 +	return ret;
@@ -58364,42 +62389,62 @@
 +		 * 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 (permissive) {
++		if (dev_data->permissive) {
 +			switch (size) {
 +			case 1:
 +				err = pci_write_config_byte(dev, offset,
-+							    (u8)value);
++							    (u8) value);
 +				break;
 +			case 2:
 +				err = pci_write_config_word(dev, offset,
-+							    (u16)value);
++							    (u16) value);
 +				break;
 +			case 4:
 +				err = pci_write_config_dword(dev, offset,
-+							     (u32)value);
++							     (u32) value);
 +				break;
 +			}
 +		} else if (!dev_data->warned_on_write) {
 +			dev_data->warned_on_write = 1;
-+			dev_warn(&dev->dev, "Driver wrote to a read-only "
-+				 "configuration space field!\n");
-+			dev_warn(&dev->dev, "Write at offset 0x%x size %d\n",
-+				offset, size);
-+			dev_warn(&dev->dev, "This may be harmless, but if\n");
-+			dev_warn(&dev->dev, "you have problems with your "
-+				 "device:\n");
-+			dev_warn(&dev->dev, "1) see the permissive "
-+				 "attribute in sysfs.\n");
-+			dev_warn(&dev->dev, "2) report problems to the "
-+				 "xen-devel mailing list along\n");
-+			dev_warn(&dev->dev, "   with details of your device "
-+				 "obtained from lspci.\n");
++			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);
@@ -58445,6 +62490,10 @@
 +	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;
@@ -58495,6 +62544,10 @@
 +		goto out;
 +
 +	err = pciback_config_capability_add_fields(dev);
++	if (err)
++		goto out;
++
++	err = pciback_config_quirks_init(dev);
 +
 +      out:
 +	return err;
@@ -58502,15 +62555,11 @@
 +
 +int pciback_config_init(void)
 +{
-+	int err;
-+
-+	err = pciback_config_capability_init();
-+
-+	return err;
++	return pciback_config_capability_init();
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/conf_space_capability.c linux-2.6.17-xen/drivers/xen/pciback/conf_space_capability.c
---- linux-2.6.17/drivers/xen/pciback/conf_space_capability.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/conf_space_capability.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space_capability.c linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_capability.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space_capability.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_capability.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,71 @@
 +/*
 + * PCI Backend - Handles the virtual fields found on the capability lists
@@ -58583,9 +62632,9 @@
 +
 +	return 0;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/conf_space_capability.h linux-2.6.17-xen/drivers/xen/pciback/conf_space_capability.h
---- linux-2.6.17/drivers/xen/pciback/conf_space_capability.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/conf_space_capability.h	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space_capability.h linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_capability.h
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space_capability.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_capability.h	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,23 @@
 +/*
 + * PCI Backend - Data structures for special overlays for structures on
@@ -58610,9 +62659,9 @@
 +};
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/conf_space_capability_pm.c linux-2.6.17-xen/drivers/xen/pciback/conf_space_capability_pm.c
---- linux-2.6.17/drivers/xen/pciback/conf_space_capability_pm.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/conf_space_capability_pm.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space_capability_pm.c linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_capability_pm.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space_capability_pm.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_capability_pm.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,113 @@
 +/*
 + * PCI Backend - Configuration space overlay for power management
@@ -58727,9 +62776,9 @@
 +	.capability = PCI_CAP_ID_PM,
 +	.fields = caplist_pm,
 +};
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/conf_space_capability_vpd.c linux-2.6.17-xen/drivers/xen/pciback/conf_space_capability_vpd.c
---- linux-2.6.17/drivers/xen/pciback/conf_space_capability_vpd.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/conf_space_capability_vpd.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space_capability_vpd.c linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_capability_vpd.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space_capability_vpd.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_capability_vpd.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,42 @@
 +/*
 + * PCI Backend - Configuration space overlay for Vital Product Data
@@ -58773,10 +62822,10 @@
 +	.capability = PCI_CAP_ID_VPD,
 +	.fields = caplist_vpd,
 +};
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/conf_space.h linux-2.6.17-xen/drivers/xen/pciback/conf_space.h
---- linux-2.6.17/drivers/xen/pciback/conf_space.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/conf_space.h	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,123 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space.h linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space.h
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space.h	2006-08-06 23:45:53.000000000 +0200
+@@ -0,0 +1,126 @@
 +/*
 + * PCI Backend - Common data structures for overriding the configuration space
 + *
@@ -58812,11 +62861,13 @@
 + * values.
 + */
 +struct config_field {
-+	unsigned int     offset;
-+	unsigned int     size;
-+	conf_field_init  init;
++	unsigned int offset;
++	unsigned int size;
++	unsigned int mask;
++	conf_field_init init;
 +	conf_field_reset reset;
-+	conf_field_free  release;
++	conf_field_free release;
++	void (*clean) (struct config_field * field);
 +	union {
 +		struct {
 +			conf_dword_write write;
@@ -58831,6 +62882,7 @@
 +			conf_byte_read read;
 +		} b;
 +	} u;
++	struct list_head list;
 +};
 +
 +struct config_field_entry {
@@ -58900,9 +62952,9 @@
 +int pciback_config_capability_add_fields(struct pci_dev *dev);
 +
 +#endif				/* __XEN_PCIBACK_CONF_SPACE_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/conf_space_header.c linux-2.6.17-xen/drivers/xen/pciback/conf_space_header.c
---- linux-2.6.17/drivers/xen/pciback/conf_space_header.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/conf_space_header.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space_header.c linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_header.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space_header.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_header.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,299 @@
 +/*
 + * PCI Backend - Handles the virtual fields in the configuration space headers.
@@ -59203,26 +63255,199 @@
 +      out:
 +	return err;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/Makefile linux-2.6.17-xen/drivers/xen/pciback/Makefile
---- linux-2.6.17/drivers/xen/pciback/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/Makefile	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,13 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space_quirks.c linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_quirks.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space_quirks.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_quirks.c	2006-08-06 23:45:53.000000000 +0200
+@@ -0,0 +1,128 @@
++/*
++ * PCI Backend - Handle special overlays for broken devices.
++ *
++ * Author: Ryan Wilson <hap9 at epoch.ncsc.mil>
++ * Author: Chris Bookholt <hap10 at 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/conf_space_quirks.h linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_quirks.h
+--- linux-2.6.18-rc5/drivers/xen/pciback/conf_space_quirks.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/conf_space_quirks.h	2006-08-06 23:45:53.000000000 +0200
+@@ -0,0 +1,35 @@
++/*
++ * PCI Backend - Data structures for special overlays for broken devices.
++ *
++ * Ryan Wilson <hap9 at epoch.ncsc.mil>
++ * Chris Bookholt <hap10 at 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/Makefile linux-2.6.18-rc5-xen/drivers/xen/pciback/Makefile
+--- linux-2.6.18-rc5/drivers/xen/pciback/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/Makefile	2006-08-14 15:07:21.000000000 +0200
+@@ -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_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 -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/passthrough.c linux-2.6.17-xen/drivers/xen/pciback/passthrough.c
---- linux-2.6.17/drivers/xen/pciback/passthrough.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/passthrough.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/passthrough.c linux-2.6.18-rc5-xen/drivers/xen/pciback/passthrough.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/passthrough.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/passthrough.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,157 @@
 +/*
 + * PCI Backend - Provides restricted access to the real PCI bus topology
@@ -59381,10 +63606,10 @@
 +	kfree(dev_data);
 +	pdev->pci_dev_data = NULL;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/pciback.h linux-2.6.17-xen/drivers/xen/pciback/pciback.h
---- linux-2.6.17/drivers/xen/pciback/pciback.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/pciback.h	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,91 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/pciback.h linux-2.6.18-rc5-xen/drivers/xen/pciback/pciback.h
+--- linux-2.6.18-rc5/drivers/xen/pciback/pciback.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/pciback.h	2006-08-06 23:45:53.000000000 +0200
+@@ -0,0 +1,93 @@
 +/*
 + * PCI Backend Common Data Structures & Function Declarations
 + *
@@ -59431,6 +63656,7 @@
 +
 +struct pciback_dev_data {
 +	struct list_head config_fields;
++	int permissive;
 +	int warned_on_write;
 +};
 +
@@ -59448,6 +63674,7 @@
 +/* 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,
@@ -59476,9 +63703,9 @@
 +
 +extern int verbose_request;
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/pciback_ops.c linux-2.6.17-xen/drivers/xen/pciback/pciback_ops.c
---- linux-2.6.17/drivers/xen/pciback/pciback_ops.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/pciback_ops.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/pciback_ops.c linux-2.6.18-rc5-xen/drivers/xen/pciback/pciback_ops.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/pciback_ops.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/pciback_ops.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,95 @@
 +/*
 + * PCI Backend Operations - respond to PCI requests from Frontend
@@ -59575,14 +63802,15 @@
 +
 +	return IRQ_HANDLED;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/pci_stub.c linux-2.6.17-xen/drivers/xen/pciback/pci_stub.c
---- linux-2.6.17/drivers/xen/pciback/pci_stub.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/pci_stub.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,690 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/pci_stub.c linux-2.6.18-rc5-xen/drivers/xen/pciback/pci_stub.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/pci_stub.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/pci_stub.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,916 @@
 +/*
 + * PCI Stub Driver - Grabs devices in backend to be exported later
 + *
-+ *   Author: Ryan Wilson <hap9 at epoch.ncsc.mil>
++ * Ryan Wilson <hap9 at epoch.ncsc.mil>
++ * Chris Bookholt <hap10 at epoch.ncsc.mil>
 + */
 +#include <linux/module.h>
 +#include <linux/init.h>
@@ -59591,6 +63819,8 @@
 +#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);
@@ -59612,6 +63842,7 @@
 +	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
 + */
@@ -59657,6 +63888,7 @@
 +
 +	/* 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);
@@ -59676,6 +63908,32 @@
 +	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)
 +{
@@ -59761,6 +64019,7 @@
 +	 * (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);
@@ -59781,6 +64040,10 @@
 +		    && 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;
@@ -59973,6 +64236,8 @@
 +
 +	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;
@@ -60052,6 +64317,19 @@
 +	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;
@@ -60104,6 +64382,46 @@
 +	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)
 +{
@@ -60168,6 +64486,137 @@
 +
 +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;
@@ -60212,6 +64661,8 @@
 +	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;
@@ -60261,6 +64712,8 @@
 +	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);
 +}
@@ -60269,9 +64722,164 @@
 +module_exit(pciback_cleanup);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/vpci.c linux-2.6.17-xen/drivers/xen/pciback/vpci.c
---- linux-2.6.17/drivers/xen/pciback/vpci.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/vpci.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/slot.c linux-2.6.18-rc5-xen/drivers/xen/pciback/slot.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/slot.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/slot.c	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,151 @@
++/*
++ * PCI Backend - Provides a Virtual PCI bus (with real devices)
++ *               to the frontend
++ *
++ *   Author: Ryan Wilson <hap9 at epoch.ncsc.mil> (vpci.c)
++ *   Author: Tristan Gingold <tristan.gingold at 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/vpci.c linux-2.6.18-rc5-xen/drivers/xen/pciback/vpci.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/vpci.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/vpci.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,204 @@
 +/*
 + * PCI Backend - Provides a Virtual PCI bus (with real devices)
@@ -60477,10 +65085,10 @@
 +	kfree(vpci_dev);
 +	pdev->pci_dev_data = NULL;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pciback/xenbus.c linux-2.6.17-xen/drivers/xen/pciback/xenbus.c
---- linux-2.6.17/drivers/xen/pciback/xenbus.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pciback/xenbus.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,454 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pciback/xenbus.c linux-2.6.18-rc5-xen/drivers/xen/pciback/xenbus.c
+--- linux-2.6.18-rc5/drivers/xen/pciback/xenbus.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pciback/xenbus.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,458 @@
 +/*
 + * PCI Backend Xenbus Setup - handles setup with frontend and xend
 + *
@@ -60664,6 +65272,7 @@
 +		xenbus_switch_state(xdev, XenbusStateClosing);
 +		break;
 +
++	case XenbusStateUnknown:
 +	case XenbusStateClosed:
 +		dev_dbg(&xdev->dev, "frontend is gone! unregister device\n");
 +		device_unregister(&xdev->dev);
@@ -60928,6 +65537,9 @@
 +
 +int __init pciback_xenbus_register(void)
 +{
++	if (!is_running_on_xen())
++		return -ENODEV;
++
 +	return xenbus_register_backend(&xenbus_pciback_driver);
 +}
 +
@@ -60935,9 +65547,9 @@
 +{
 +	xenbus_unregister_driver(&xenbus_pciback_driver);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pcifront/Makefile linux-2.6.17-xen/drivers/xen/pcifront/Makefile
---- linux-2.6.17/drivers/xen/pcifront/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pcifront/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pcifront/Makefile linux-2.6.18-rc5-xen/drivers/xen/pcifront/Makefile
+--- linux-2.6.18-rc5/drivers/xen/pcifront/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pcifront/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,7 @@
 +obj-y += pcifront.o
 +
@@ -60946,9 +65558,9 @@
 +ifeq ($(CONFIG_XEN_PCIDEV_FE_DEBUG),y)
 +EXTRA_CFLAGS += -DDEBUG
 +endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pcifront/pci.c linux-2.6.17-xen/drivers/xen/pcifront/pci.c
---- linux-2.6.17/drivers/xen/pcifront/pci.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pcifront/pci.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pcifront/pci.c linux-2.6.18-rc5-xen/drivers/xen/pcifront/pci.c
+--- linux-2.6.18-rc5/drivers/xen/pcifront/pci.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pcifront/pci.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,46 @@
 +/*
 + * PCI Frontend Operations - ensure only one PCI frontend runs at a time
@@ -60996,9 +65608,9 @@
 +
 +	spin_unlock(&pcifront_dev_lock);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pcifront/pcifront.h linux-2.6.17-xen/drivers/xen/pcifront/pcifront.h
---- linux-2.6.17/drivers/xen/pcifront/pcifront.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pcifront/pcifront.h	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pcifront/pcifront.h linux-2.6.18-rc5-xen/drivers/xen/pcifront/pcifront.h
+--- linux-2.6.18-rc5/drivers/xen/pcifront/pcifront.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pcifront/pcifront.h	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,40 @@
 +/*
 + * PCI Frontend - Common data structures & function declarations
@@ -61040,10 +65652,10 @@
 +void pcifront_free_roots(struct pcifront_device *pdev);
 +
 +#endif	/* __XEN_PCIFRONT_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pcifront/pci_op.c linux-2.6.17-xen/drivers/xen/pcifront/pci_op.c
---- linux-2.6.17/drivers/xen/pcifront/pci_op.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pcifront/pci_op.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,272 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pcifront/pci_op.c linux-2.6.18-rc5-xen/drivers/xen/pcifront/pci_op.c
+--- linux-2.6.18-rc5/drivers/xen/pcifront/pci_op.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pcifront/pci_op.c	2006-08-06 23:45:53.000000000 +0200
+@@ -0,0 +1,273 @@
 +/*
 + * PCI Frontend Operations - Communicates with frontend
 + *
@@ -61151,7 +65763,7 @@
 +		.size   = size,
 +	};
 +	struct pcifront_sd *sd = bus->sysdata;
-+	struct pcifront_device *pdev = sd->pdev;
++	struct pcifront_device *pdev = pcifront_get_pdev(sd);
 +
 +	if (verbose_request)
 +		dev_info(&pdev->xdev->dev,
@@ -61190,7 +65802,7 @@
 +		.value  = val,
 +	};
 +	struct pcifront_sd *sd = bus->sysdata;
-+	struct pcifront_device *pdev = sd->pdev;
++	struct pcifront_device *pdev = pcifront_get_pdev(sd);
 +
 +	if (verbose_request)
 +		dev_info(&pdev->xdev->dev,
@@ -61253,12 +65865,13 @@
 +		err = -ENOMEM;
 +		goto err_out;
 +	}
-+	sd->domain = domain;
-+	sd->pdev = pdev;
++	pcifront_init_sd(sd, domain, pdev);
 +
-+	b = pci_scan_bus_parented(&pdev->xdev->dev, bus, &pcifront_bus_ops, sd);
++	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");
++		dev_err(&pdev->xdev->dev,
++			"Error creating PCI Frontend Bus!\n");
 +		err = -ENOMEM;
 +		goto err_out;
 +	}
@@ -61284,17 +65897,17 @@
 +{
 +	struct pci_dev *dev;
 +
-+	spin_lock(&pci_bus_lock);
++	down_write(&pci_bus_sem);
 +	while (!list_empty(&bus->devices)) {
 +		dev = container_of(bus->devices.next, struct pci_dev, bus_list);
-+		spin_unlock(&pci_bus_lock);
++		up_write(&pci_bus_sem);
 +
 +		dev_dbg(&dev->dev, "removing device\n");
 +		pci_remove_bus_device(dev);
 +
-+		spin_lock(&pci_bus_lock);
++		down_write(&pci_bus_sem);
 +	}
-+	spin_unlock(&pci_bus_lock);
++	up_write(&pci_bus_sem);
 +}
 +
 +void pcifront_free_roots(struct pcifront_device *pdev)
@@ -61316,10 +65929,10 @@
 +		kfree(bus_entry);
 +	}
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/pcifront/xenbus.c linux-2.6.17-xen/drivers/xen/pcifront/xenbus.c
---- linux-2.6.17/drivers/xen/pcifront/xenbus.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/pcifront/xenbus.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,294 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/pcifront/xenbus.c linux-2.6.18-rc5-xen/drivers/xen/pcifront/xenbus.c
+--- linux-2.6.18-rc5/drivers/xen/pcifront/xenbus.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/pcifront/xenbus.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,295 @@
 +/*
 + * PCI Frontend Xenbus Setup - handles setup with backend (imports page/evtchn)
 + *
@@ -61329,6 +65942,7 @@
 +#include <linux/init.h>
 +#include <linux/mm.h>
 +#include <xen/xenbus.h>
++#include <xen/gnttab.h>
 +#include "pcifront.h"
 +
 +#define INVALID_GRANT_REF (0)
@@ -61546,6 +66160,7 @@
 +		pcifront_try_disconnect(pdev);
 +		break;
 +
++	case XenbusStateUnknown:
 +	case XenbusStateClosed:
 +		dev_warn(&xdev->dev, "backend went away!\n");
 +		pcifront_try_disconnect(pdev);
@@ -61605,25 +66220,24 @@
 +
 +static int __init pcifront_init(void)
 +{
-+	int err = 0;
-+
-+	err = xenbus_register_frontend(&xenbus_pcifront_driver);
++	if (!is_running_on_xen())
++		return -ENODEV;
 +
-+	return err;
++	return xenbus_register_frontend(&xenbus_pcifront_driver);
 +}
 +
 +/* Initialize after the Xen PCI Frontend Stub is initialized */
 +subsys_initcall(pcifront_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/privcmd/Makefile linux-2.6.17-xen/drivers/xen/privcmd/Makefile
---- linux-2.6.17/drivers/xen/privcmd/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/privcmd/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/privcmd/Makefile linux-2.6.18-rc5-xen/drivers/xen/privcmd/Makefile
+--- linux-2.6.18-rc5/drivers/xen/privcmd/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/privcmd/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,2 @@
 +
 +obj-$(CONFIG_XEN_PRIVCMD)	:= privcmd.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/privcmd/privcmd.c linux-2.6.17-xen/drivers/xen/privcmd/privcmd.c
---- linux-2.6.17/drivers/xen/privcmd/privcmd.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/privcmd/privcmd.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,285 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/privcmd/privcmd.c linux-2.6.18-rc5-xen/drivers/xen/privcmd/privcmd.c
+--- linux-2.6.18-rc5/drivers/xen/privcmd/privcmd.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/privcmd/privcmd.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,266 @@
 +/******************************************************************************
 + * privcmd.c
 + * 
@@ -61632,7 +66246,6 @@
 + * Copyright (c) 2002-2004, K A Fraser, B Dragovic
 + */
 +
-+#include <linux/config.h>
 +#include <linux/kernel.h>
 +#include <linux/sched.h>
 +#include <linux/slab.h>
@@ -61661,9 +66274,6 @@
 +static struct proc_dir_entry *privcmd_intf;
 +static struct proc_dir_entry *capabilities_intf;
 +
-+#define NR_HYPERCALLS 64
-+static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
-+
 +static int privcmd_ioctl(struct inode *inode, struct file *file,
 +			 unsigned int cmd, unsigned long data)
 +{
@@ -61677,12 +66287,6 @@
 +		if (copy_from_user(&hypercall, udata, sizeof(hypercall)))
 +			return -EFAULT;
 +
-+		/* Check hypercall number for validity. */
-+		if (hypercall.op >= NR_HYPERCALLS)
-+			return -EINVAL;
-+		if (!test_bit(hypercall.op, hypercall_permission_map))
-+			return -EINVAL;
-+
 +#if defined(__i386__)
 +		__asm__ __volatile__ (
 +			"pushl %%ebx; pushl %%ecx; pushl %%edx; "
@@ -61734,7 +66338,6 @@
 +	}
 +	break;
 +
-+#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
 +	case IOCTL_PRIVCMD_MMAP: {
 +#define PRIVCMD_MMAP_SZ 32
 +		privcmd_mmap_t mmapcmd;
@@ -61742,6 +66345,9 @@
 +		privcmd_mmap_entry_t __user *p;
 +		int i, rc;
 +
++		if (!is_initial_xendomain())
++			return -EPERM;
++
 +		if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd)))
 +			return -EFAULT;
 +
@@ -61788,9 +66394,12 @@
 +		privcmd_mmapbatch_t m;
 +		struct vm_area_struct *vma = NULL;
 +		xen_pfn_t __user *p;
-+		unsigned long addr, mfn; 
++		unsigned long addr, mfn;
 +		int i;
 +
++		if (!is_initial_xendomain())
++			return -EPERM;
++
 +		if (copy_from_user(&m, udata, sizeof(m))) {
 +			ret = -EFAULT;
 +			goto batch_err;
@@ -61841,7 +66450,6 @@
 +		break;
 +	}
 +	break;
-+#endif
 +
 +	default:
 +		ret = -EINVAL;
@@ -61855,7 +66463,7 @@
 +static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
 +{
 +	/* DONTCOPY is essential for Xen as copy_page_range is broken. */
-+	vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
++	vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
 +
 +	return 0;
 +}
@@ -61872,7 +66480,7 @@
 +	int len = 0;
 +	*page = 0;
 +
-+	if (xen_start_info->flags & SIF_INITDOMAIN)
++	if (is_initial_xendomain())
 +		len = sprintf( page, "control_d\n" );
 +
 +	*eof = 1;
@@ -61884,19 +66492,6 @@
 +	if (!is_running_on_xen())
 +		return -ENODEV;
 +
-+	/* Set of hypercalls that privileged applications may execute. */
-+	set_bit(__HYPERVISOR_acm_op,           hypercall_permission_map);
-+	set_bit(__HYPERVISOR_dom0_op,          hypercall_permission_map);
-+	set_bit(__HYPERVISOR_event_channel_op, hypercall_permission_map);
-+	set_bit(__HYPERVISOR_memory_op,        hypercall_permission_map);
-+	set_bit(__HYPERVISOR_mmu_update,       hypercall_permission_map);
-+	set_bit(__HYPERVISOR_mmuext_op,        hypercall_permission_map);
-+	set_bit(__HYPERVISOR_xen_version,      hypercall_permission_map);
-+	set_bit(__HYPERVISOR_sched_op,         hypercall_permission_map);
-+	set_bit(__HYPERVISOR_sched_op_compat,  hypercall_permission_map);
-+	set_bit(__HYPERVISOR_event_channel_op_compat,
-+		hypercall_permission_map);
-+
 +	privcmd_intf = create_xen_proc_entry("privcmd", 0400);
 +	if (privcmd_intf != NULL)
 +		privcmd_intf->proc_fops = &privcmd_file_ops;
@@ -61909,10 +66504,10 @@
 +}
 +
 +__initcall(privcmd_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/tpmback/common.h linux-2.6.17-xen/drivers/xen/tpmback/common.h
---- linux-2.6.17/drivers/xen/tpmback/common.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/tpmback/common.h	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,85 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/tpmback/common.h linux-2.6.18-rc5-xen/drivers/xen/tpmback/common.h
+--- linux-2.6.18-rc5/drivers/xen/tpmback/common.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/tpmback/common.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,84 @@
 +/******************************************************************************
 + * drivers/xen/tpmback/common.h
 + */
@@ -61920,7 +66515,6 @@
 +#ifndef __NETIF__BACKEND__COMMON_H__
 +#define __NETIF__BACKEND__COMMON_H__
 +
-+#include <linux/config.h>
 +#include <linux/version.h>
 +#include <linux/module.h>
 +#include <linux/interrupt.h>
@@ -61998,9 +66592,9 @@
 +#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
 +
 +#endif /* __TPMIF__BACKEND__COMMON_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/tpmback/interface.c linux-2.6.17-xen/drivers/xen/tpmback/interface.c
---- linux-2.6.17/drivers/xen/tpmback/interface.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/tpmback/interface.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/tpmback/interface.c linux-2.6.18-rc5-xen/drivers/xen/tpmback/interface.c
+--- linux-2.6.18-rc5/drivers/xen/tpmback/interface.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/tpmback/interface.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,177 @@
 + /*****************************************************************************
 + * drivers/xen/tpmback/interface.c
@@ -62179,18 +66773,18 @@
 +{
 +	kmem_cache_destroy(tpmif_cachep);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/tpmback/Makefile linux-2.6.17-xen/drivers/xen/tpmback/Makefile
---- linux-2.6.17/drivers/xen/tpmback/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/tpmback/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/tpmback/Makefile linux-2.6.18-rc5-xen/drivers/xen/tpmback/Makefile
+--- linux-2.6.18-rc5/drivers/xen/tpmback/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/tpmback/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,4 @@
 +
 +obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmbk.o
 +
 +tpmbk-y += tpmback.o interface.o xenbus.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/tpmback/tpmback.c linux-2.6.17-xen/drivers/xen/tpmback/tpmback.c
---- linux-2.6.17/drivers/xen/tpmback/tpmback.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/tpmback/tpmback.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,983 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/tpmback/tpmback.c linux-2.6.18-rc5-xen/drivers/xen/tpmback/tpmback.c
+--- linux-2.6.18-rc5/drivers/xen/tpmback/tpmback.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/tpmback/tpmback.c	2006-08-06 23:45:53.000000000 +0200
+@@ -0,0 +1,944 @@
 +/******************************************************************************
 + * drivers/xen/tpmback/tpmback.c
 + *
@@ -62248,7 +66842,6 @@
 +
 +enum {
 +	PACKET_FLAG_DISCARD_RESPONSE = 1,
-+	PACKET_FLAG_CHECK_RESPONSESTATUS = 2,
 +};
 +
 +/* local variables */
@@ -62394,21 +66987,6 @@
 +	kfree(pak);
 +}
 +
-+static int packet_set(struct packet *pak,
-+		      const unsigned char *buffer, u32 size)
-+{
-+	int rc = 0;
-+	unsigned char *buf = kmalloc(size, GFP_KERNEL);
-+
-+	if (buf) {
-+		pak->data_buffer = buf;
-+		memcpy(buf, buffer, size);
-+		pak->data_len = size;
-+	} else {
-+		rc = -ENOMEM;
-+	}
-+	return rc;
-+}
 +
 +/*
 + * Write data to the shared memory and send it to the FE.
@@ -62418,29 +66996,6 @@
 +{
 +	int rc = 0;
 +
-+	if ((pak->flags & PACKET_FLAG_CHECK_RESPONSESTATUS)) {
-+#ifdef CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
-+		u32 res;
-+
-+		if (copy_from_buffer(&res,
-+				     &data[2 + 4], sizeof (res),
-+				     isuserbuffer)) {
-+			return -EFAULT;
-+		}
-+
-+		if (res != 0) {
-+			/*
-+			 * Close down this device. Should have the
-+			 * FE notified about closure.
-+			 */
-+			if (!pak->tpmif) {
-+				return -EFAULT;
-+			}
-+			pak->tpmif->status = DISCONNECTING;
-+		}
-+#endif
-+	}
-+
 +	if (0 != (pak->flags & PACKET_FLAG_DISCARD_RESPONSE)) {
 +		/* Don't send a respone to this packet. Just acknowledge it. */
 +		rc = size;
@@ -63045,11 +67600,11 @@
 +	 */
 +	if (pak == packet_find_packet(&dataex.pending_pak, pak) ||
 +	    pak == packet_find_packet(&dataex.current_pak, pak)) {
-+		list_del(&pak->next);
 +		if ((pak->flags & PACKET_FLAG_DISCARD_RESPONSE) == 0) {
 +			tpm_send_fail_message(pak, pak->req_tag);
 +		}
-+		packet_free(pak);
++		/* discard future responses */
++		pak->flags |= PACKET_FLAG_DISCARD_RESPONSE;
 +	}
 +
 +	write_unlock_irqrestore(&dataex.pak_lock, flags);
@@ -63174,10 +67729,10 @@
 +}
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/tpmback/xenbus.c linux-2.6.17-xen/drivers/xen/tpmback/xenbus.c
---- linux-2.6.17/drivers/xen/tpmback/xenbus.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/tpmback/xenbus.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,291 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/tpmback/xenbus.c linux-2.6.18-rc5-xen/drivers/xen/tpmback/xenbus.c
+--- linux-2.6.18-rc5/drivers/xen/tpmback/xenbus.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/tpmback/xenbus.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,287 @@
 +/*  Xenbus code for tpmif backend
 +    Copyright (C) 2005 IBM Corporation
 +    Copyright (C) 2005 Rusty Russell <rusty at rustcorp.com.au>
@@ -63214,7 +67769,6 @@
 +
 +	/* watch front end for changes */
 +	struct xenbus_watch backend_watch;
-+	enum xenbus_state frontend_state;
 +};
 +
 +static void maybe_connect(struct backend_info *be);
@@ -63323,8 +67877,6 @@
 +	struct backend_info *be = dev->dev.driver_data;
 +	int err;
 +
-+	be->frontend_state = frontend_state;
-+
 +	switch (frontend_state) {
 +	case XenbusStateInitialising:
 +	case XenbusStateInitialised:
@@ -63342,13 +67894,12 @@
 +		be->instance = -1;
 +		break;
 +
++	case XenbusStateUnknown:
 +	case XenbusStateClosed:
 +		device_unregister(&be->dev->dev);
 +		tpmback_remove(dev);
 +		break;
 +
-+	case XenbusStateUnknown:
-+	case XenbusStateInitWait:
 +	default:
 +		xenbus_dev_fatal(dev, -EINVAL,
 +				 "saw state %d at frontend",
@@ -63469,11 +68020,11 @@
 +{
 +	xenbus_unregister_driver(&tpmback);
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/util.c linux-2.6.17-xen/drivers/xen/util.c
---- linux-2.6.17/drivers/xen/util.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/util.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/util.c linux-2.6.18-rc5-xen/drivers/xen/util.c
+--- linux-2.6.18-rc5/drivers/xen/util.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/util.c	2006-08-14 15:07:21.000000000 +0200
 @@ -0,0 +1,70 @@
-+#include <linux/config.h>
++
 +#include <linux/mm.h>
 +#include <linux/module.h>
 +#include <linux/slab.h>
@@ -63543,9 +68094,9 @@
 +	preempt_enable();
 +}
 +EXPORT_SYMBOL_GPL(unlock_vm_area);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/xenbus/Makefile linux-2.6.17-xen/drivers/xen/xenbus/Makefile
---- linux-2.6.17/drivers/xen/xenbus/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/xenbus/Makefile	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/xenbus/Makefile linux-2.6.18-rc5-xen/drivers/xen/xenbus/Makefile
+--- linux-2.6.18-rc5/drivers/xen/xenbus/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/xenbus/Makefile	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,12 @@
 +obj-y	+= xenbus.o
 +obj-$(CONFIG_XEN_BACKEND) += xenbus_be.o
@@ -63559,9 +68110,9 @@
 +xenbus-objs += xenbus_xs.o
 +xenbus-objs += xenbus_probe.o
 +obj-$(CONFIG_XEN_XENBUS_DEV) += xenbus_dev.o
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/xenbus/xenbus_backend_client.c linux-2.6.17-xen/drivers/xen/xenbus/xenbus_backend_client.c
---- linux-2.6.17/drivers/xen/xenbus/xenbus_backend_client.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/xenbus/xenbus_backend_client.c	2006-08-14 15:58:06.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_backend_client.c linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_backend_client.c
+--- linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_backend_client.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_backend_client.c	2006-07-20 15:57:17.000000000 +0200
 @@ -0,0 +1,135 @@
 +/******************************************************************************
 + * Backend-client-facing interface for the Xenbus driver.  In other words, the
@@ -63698,10 +68249,10 @@
 +EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
 +
 +MODULE_LICENSE("Dual BSD/GPL");
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/xenbus/xenbus_client.c linux-2.6.17-xen/drivers/xen/xenbus/xenbus_client.c
---- linux-2.6.17/drivers/xen/xenbus/xenbus_client.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/xenbus/xenbus_client.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,281 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_client.c linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_client.c
+--- linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_client.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_client.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,278 @@
 +/******************************************************************************
 + * Client-facing interface for the Xenbus driver.  In other words, the
 + * interface between the Xenbus and the device-specific code, be it the
@@ -63739,9 +68290,6 @@
 +#include <xen/xenbus.h>
 +#include <xen/driver_util.h>
 +
-+/* xenbus_probe.c */
-+extern char *kasprintf(const char *fmt, ...);
-+
 +#define DPRINTK(fmt, args...) \
 +    pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
 +
@@ -63774,7 +68322,7 @@
 +					const char **, unsigned int))
 +{
 +	int err;
-+	char *state = kasprintf("%s/%s", path, path2);
++	char *state = kasprintf(GFP_KERNEL, "%s/%s", path, path2);
 +	if (!state) {
 +		xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
 +		return -ENOMEM;
@@ -63835,7 +68383,7 @@
 + */
 +static char *error_path(struct xenbus_device *dev)
 +{
-+	return kasprintf("error/%s", dev->nodename);
++	return kasprintf(GFP_KERNEL, "error/%s", dev->nodename);
 +}
 +
 +
@@ -63978,15 +68526,15 @@
 +	enum xenbus_state result;
 +	int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
 +	if (err)
-+		result = XenbusStateClosed;
++		result = XenbusStateUnknown;
 +
 +	return result;
 +}
 +EXPORT_SYMBOL_GPL(xenbus_read_driver_state);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/xenbus/xenbus_comms.c linux-2.6.17-xen/drivers/xen/xenbus/xenbus_comms.c
---- linux-2.6.17/drivers/xen/xenbus/xenbus_comms.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/xenbus/xenbus_comms.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,208 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_comms.c linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_comms.c
+--- linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_comms.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_comms.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,203 @@
 +/******************************************************************************
 + * xenbus_comms.c
 + *
@@ -64036,11 +68584,6 @@
 +
 +DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
 +
-+static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
-+{
-+	return mfn_to_virt(xen_start_info->store_mfn);
-+}
-+
 +static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
 +{
 +	if (unlikely(xenstored_ready == 0)) {
@@ -64079,7 +68622,7 @@
 +
 +int xb_write(const void *data, unsigned len)
 +{
-+	struct xenstore_domain_interface *intf = xenstore_domain_interface();
++	struct xenstore_domain_interface *intf = xen_store_interface;
 +	XENSTORE_RING_IDX cons, prod;
 +	int rc;
 +
@@ -64118,7 +68661,7 @@
 +		intf->req_prod += avail;
 +
 +		/* This implies mb() before other side sees interrupt. */
-+		notify_remote_via_evtchn(xen_start_info->store_evtchn);
++		notify_remote_via_evtchn(xen_store_evtchn);
 +	}
 +
 +	return 0;
@@ -64126,7 +68669,7 @@
 +
 +int xb_read(void *data, unsigned len)
 +{
-+	struct xenstore_domain_interface *intf = xenstore_domain_interface();
++	struct xenstore_domain_interface *intf = xen_store_interface;
 +	XENSTORE_RING_IDX cons, prod;
 +	int rc;
 +
@@ -64169,7 +68712,7 @@
 +		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_start_info->store_evtchn);
++		notify_remote_via_evtchn(xen_store_evtchn);
 +	}
 +
 +	return 0;
@@ -64184,7 +68727,7 @@
 +		unbind_from_irqhandler(xenbus_irq, &xb_waitq);
 +
 +	err = bind_evtchn_to_irqhandler(
-+		xen_start_info->store_evtchn, wake_waiting,
++		xen_store_evtchn, wake_waiting,
 +		0, "xenbus", &xb_waitq);
 +	if (err <= 0) {
 +		printk(KERN_ERR "XENBUS request irq failed %i\n", err);
@@ -64195,10 +68738,10 @@
 +
 +	return 0;
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/xenbus/xenbus_comms.h linux-2.6.17-xen/drivers/xen/xenbus/xenbus_comms.h
---- linux-2.6.17/drivers/xen/xenbus/xenbus_comms.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/xenbus/xenbus_comms.h	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,43 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_comms.h linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_comms.h
+--- linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_comms.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_comms.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,45 @@
 +/*
 + * Private include for xenbus communications.
 + * 
@@ -64240,12 +68783,14 @@
 +int xb_read(void *data, unsigned len);
 +int xs_input_avail(void);
 +extern wait_queue_head_t xb_waitq;
++extern struct xenstore_domain_interface *xen_store_interface;
++extern int xen_store_evtchn;
 +
 +#endif /* _XENBUS_COMMS_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/xenbus/xenbus_dev.c linux-2.6.17-xen/drivers/xen/xenbus/xenbus_dev.c
---- linux-2.6.17/drivers/xen/xenbus/xenbus_dev.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/xenbus/xenbus_dev.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,245 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_dev.c linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_dev.c
+--- linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_dev.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_dev.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,356 @@
 +/*
 + * xenbus_dev.c
 + * 
@@ -64280,7 +68825,6 @@
 + * IN THE SOFTWARE.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/kernel.h>
 +#include <linux/errno.h>
 +#include <linux/uio.h>
@@ -64306,6 +68850,9 @@
 +	/* In-progress transaction. */
 +	struct list_head transactions;
 +
++	/* Active watches. */
++	struct list_head watches;
++
 +	/* Partial request. */
 +	unsigned int len;
 +	union {
@@ -64318,6 +68865,8 @@
 +	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;
@@ -64348,14 +68897,60 @@
 +{
 +	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)
@@ -64364,6 +68959,9 @@
 +	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;
@@ -64417,6 +69015,56 @@
 +		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;
 +	}
@@ -64429,7 +69077,7 @@
 +{
 +	struct xenbus_dev_data *u;
 +
-+	if (xen_start_info->store_evtchn == 0)
++	if (xen_store_evtchn == 0)
 +		return -ENOENT;
 +
 +	nonseekable_open(inode, filp);
@@ -64439,8 +69087,11 @@
 +		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;
@@ -64450,6 +69101,7 @@
 +{
 +	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);
@@ -64457,6 +69109,12 @@
 +		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;
@@ -64480,7 +69138,7 @@
 +	.poll = xenbus_dev_poll,
 +};
 +
-+static int __init
++int __init
 +xenbus_dev_init(void)
 +{
 +	xenbus_dev_intf = create_xen_proc_entry("xenbus", 0400);
@@ -64489,12 +69147,10 @@
 +
 +	return 0;
 +}
-+
-+__initcall(xenbus_dev_init);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/xenbus/xenbus_probe.c linux-2.6.17-xen/drivers/xen/xenbus/xenbus_probe.c
---- linux-2.6.17/drivers/xen/xenbus/xenbus_probe.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/xenbus/xenbus_probe.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,1107 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_probe.c linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_probe.c
+--- linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_probe.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_probe.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,1149 @@
 +/******************************************************************************
 + * Talks to Xen Store to figure out what devices we have.
 + *
@@ -64542,19 +69198,35 @@
 +
 +#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"
 +
++int xen_store_evtchn;
++struct xenstore_domain_interface *xen_store_interface;
++static unsigned long xen_store_mfn;
++
 +extern struct mutex xenwatch_mutex;
 +
 +static BLOCKING_NOTIFIER_HEAD(xenstore_notifier_list);
 +
++static void wait_for_devices(struct xenbus_driver *xendrv);
++
++static int xenbus_probe_frontend(const char *type, const char *name);
++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);
++
++static int xenbus_dev_probe(struct device *_dev);
++static int xenbus_dev_remove(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)
@@ -64638,7 +69310,9 @@
 +	}
 +	if (strlen(xendev->otherend) == 0 ||
 +	    !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
-+		xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
++		xenbus_dev_fatal(xendev, -ENOENT,
++				 "unable to read other end from %s.  "
++				 "missing or inaccessible.",
 +				 xendev->nodename);
 +		free_otherend_details(xendev);
 +		return -ENOENT;
@@ -64661,15 +69335,16 @@
 +
 +
 +/* Bus type for frontend drivers. */
-+static int xenbus_probe_frontend(const char *type, const char *name);
 +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,
++		.name     = "xen",
++		.match    = xenbus_match,
++		.probe    = xenbus_dev_probe,
++		.remove   = xenbus_dev_remove,
 +	},
 +	.dev = {
 +		.bus_id = "xen",
@@ -64714,18 +69389,17 @@
 +	return 0;
 +}
 +
-+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);
 +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,
-+		.uevent = xenbus_uevent_backend,
++		.name     = "xen-backend",
++		.match    = xenbus_match,
++		.probe    = xenbus_dev_probe,
++		.remove   = xenbus_dev_remove,
++		.uevent   = xenbus_uevent_backend,
 +	},
 +	.dev = {
 +		.bus_id = "xen-backend",
@@ -64892,8 +69566,6 @@
 +	drv->driver.name = drv->name;
 +	drv->driver.bus = &bus->bus;
 +	drv->driver.owner = drv->owner;
-+	drv->driver.probe = xenbus_dev_probe;
-+	drv->driver.remove = xenbus_dev_remove;
 +
 +	mutex_lock(&xenwatch_mutex);
 +	ret = driver_register(&drv->driver);
@@ -64903,9 +69575,18 @@
 +
 +int xenbus_register_frontend(struct xenbus_driver *drv)
 +{
++	int ret;
++
 +	drv->read_otherend_details = read_backend_details;
 +
-+	return xenbus_register_driver_common(drv, &xenbus_frontend);
++	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);
 +
@@ -64992,27 +69673,6 @@
 +		kfree(to_xenbus_device(dev));
 +}
 +
-+/* Simplified asprintf. */
-+char *kasprintf(const char *fmt, ...)
-+{
-+	va_list ap;
-+	unsigned int len;
-+	char *p, dummy[1];
-+
-+	va_start(ap, fmt);
-+	/* FIXME: vsnprintf has a bug, NULL should work */
-+	len = vsnprintf(dummy, 0, fmt, ap);
-+	va_end(ap);
-+
-+	p = kmalloc(len + 1, GFP_KERNEL);
-+	if (!p)
-+		return NULL;
-+	va_start(ap, fmt);
-+	vsprintf(p, fmt, ap);
-+	va_end(ap);
-+	return p;
-+}
-+
 +static ssize_t xendev_show_nodename(struct device *dev,
 +				    struct device_attribute *attr, char *buf)
 +{
@@ -65088,7 +69748,7 @@
 +	char *nodename;
 +	int err;
 +
-+	nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
++	nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_frontend.root, type, name);
 +	if (!nodename)
 +		return -ENOMEM;
 +
@@ -65107,7 +69767,7 @@
 +	char *nodename;
 +	int err;
 +
-+	nodename = kasprintf("%s/%s", dir, name);
++	nodename = kasprintf(GFP_KERNEL, "%s/%s", dir, name);
 +	if (!nodename)
 +		return -ENOMEM;
 +
@@ -65128,7 +69788,7 @@
 +
 +	DPRINTK("");
 +
-+	nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
++	nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", xenbus_backend.root, type, domid);
 +	if (!nodename)
 +		return -ENOMEM;
 +
@@ -65234,7 +69894,7 @@
 +	rootlen = strsep_len(node, '/', bus->levels);
 +	if (rootlen < 0)
 +		return;
-+	root = kasprintf("%.*s", rootlen, node);
++	root = kasprintf(GFP_KERNEL, "%.*s", rootlen, node);
 +	if (!root)
 +		return;
 +
@@ -65324,7 +69984,7 @@
 +			printk(KERN_WARNING
 +			       "xenbus: resume %s failed: %i\n", 
 +			       dev->bus_id, err);
-+			return err; 
++			return err;
 +		}
 +	}
 +
@@ -65336,7 +69996,7 @@
 +		return err;
 +	}
 +
-+	return 0; 
++	return 0;
 +}
 +
 +void xenbus_suspend(void)
@@ -65412,8 +70072,7 @@
 +	if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
 +		return -EINVAL;
 +
-+	if (remap_pfn_range(vma, vma->vm_start,
-+			    mfn_to_pfn(xen_start_info->store_mfn),
++	if (remap_pfn_range(vma, vma->vm_start, mfn_to_pfn(xen_store_mfn),
 +			    size, vma->vm_page_prot))
 +		return -EAGAIN;
 +
@@ -65425,7 +70084,7 @@
 +{
 +	int len;
 +
-+	len  = sprintf(page, "0x%p", mfn_to_virt(xen_start_info->store_mfn));
++	len  = sprintf(page, "0x%p", xen_store_interface);
 +	*eof = 1;
 +	return len;
 +}
@@ -65435,16 +70094,15 @@
 +{
 +	int len;
 +
-+	len  = sprintf(page, "%d", xen_start_info->store_evtchn);
++	len  = sprintf(page, "%d", xen_store_evtchn);
 +	*eof = 1;
 +	return len;
 +}
 +#endif
 +
-+
 +static int __init xenbus_probe_init(void)
 +{
-+	int err = 0, dom0;
++	int err = 0;
 +	unsigned long page = 0;
 +
 +	DPRINTK("");
@@ -65459,9 +70117,7 @@
 +	/*
 +	 * Domain0 doesn't have a store_evtchn or store_mfn yet.
 +	 */
-+	dom0 = (xen_start_info->store_evtchn == 0);
-+
-+	if (dom0) {
++	if (is_initial_xendomain()) {
 +		struct evtchn_alloc_unbound alloc_unbound;
 +
 +		/* Allocate page. */
@@ -65469,7 +70125,7 @@
 +		if (!page)
 +			return -ENOMEM;
 +
-+		xen_start_info->store_mfn =
++		xen_store_mfn = xen_start_info->store_mfn =
 +			pfn_to_mfn(virt_to_phys((void *)page) >>
 +				   PAGE_SHIFT);
 +
@@ -65482,7 +70138,8 @@
 +		if (err == -ENOSYS)
 +			goto err;
 +		BUG_ON(err);
-+		xen_start_info->store_evtchn = alloc_unbound.port;
++		xen_store_evtchn = xen_start_info->store_evtchn =
++			alloc_unbound.port;
 +
 +#ifdef CONFIG_PROC_FS
 +		/* And finally publish the above info in /proc/xen */
@@ -65498,8 +70155,23 @@
 +		if (xsd_port_intf)
 +			xsd_port_intf->read_proc = xsd_port_read;
 +#endif
-+	} else
++		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();
@@ -65513,7 +70185,7 @@
 +	device_register(&xenbus_frontend.dev);
 +	device_register(&xenbus_backend.dev);
 +
-+	if (!dom0)
++	if (!is_initial_xendomain())
 +		xenbus_probe(NULL);
 +
 +	return 0;
@@ -65533,10 +70205,13 @@
 +
 +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
@@ -65545,18 +70220,27 @@
 +	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(void)
++static int exists_disconnected_device(struct device_driver *drv)
 +{
-+	return bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
++	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? */
@@ -65571,6 +70255,9 @@
 +	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
@@ -65585,27 +70272,38 @@
 + * boot slightly, but of course needs tools or manual intervention to set up
 + * those flags correctly.
 + */
-+static int __init wait_for_devices(void)
++static void wait_for_devices(struct xenbus_driver *xendrv)
 +{
 +	unsigned long timeout = jiffies + 10*HZ;
++	struct device_driver *drv = xendrv ? &xendrv->driver : NULL;
 +
-+	if (!is_running_on_xen())
-+		return -ENODEV;
++	if (!ready_to_wait_for_devices || !is_running_on_xen())
++		return;
 +
-+	while (time_before(jiffies, timeout) && exists_disconnected_device())
++	while (exists_disconnected_device(drv)) {
++		if (time_after(jiffies, timeout))
++			break;
 +		schedule_timeout_interruptible(HZ/10);
++	}
 +
-+	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
++	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(wait_for_devices);
-diff -urN -x .hg -x .hgtags linux-2.6.17/drivers/xen/xenbus/xenbus_xs.c linux-2.6.17-xen/drivers/xen/xenbus/xenbus_xs.c
---- linux-2.6.17/drivers/xen/xenbus/xenbus_xs.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/drivers/xen/xenbus/xenbus_xs.c	2006-08-14 15:58:06.000000000 +0200
-@@ -0,0 +1,846 @@
++late_initcall(boot_wait_for_devices);
++#endif
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_xs.c linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_xs.c
+--- linux-2.6.18-rc5/drivers/xen/xenbus/xenbus_xs.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/drivers/xen/xenbus/xenbus_xs.c	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,853 @@
 +/******************************************************************************
 + * xenbus_xs.c
 + *
@@ -65653,9 +70351,6 @@
 +#include <xen/xenbus.h>
 +#include "xenbus_comms.h"
 +
-+/* xenbus_probe.c */
-+extern char *kasprintf(const char *fmt, ...);
-+
 +struct xs_stored_msg {
 +	struct list_head list;
 +
@@ -65897,9 +70592,9 @@
 +	char *buffer;
 +
 +	if (strlen(name) == 0)
-+		buffer = kasprintf("%s", dir);
++		buffer = kasprintf(GFP_KERNEL, "%s", dir);
 +	else
-+		buffer = kasprintf("%s/%s", dir, name);
++		buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name);
 +	return (!buffer) ? ERR_PTR(-ENOMEM) : buffer;
 +}
 +
@@ -66273,7 +70968,17 @@
 +
 +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);
 +}
 +
@@ -66308,154 +71013,1509 @@
 +	if (current->pid != xenwatch_pid)
 +		do_exit(0);
 +
-+	return 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/CHANGES linux-2.6.18-rc5-xen/fs/cifs/CHANGES
+--- linux-2.6.18-rc5/fs/cifs/CHANGES	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/CHANGES	2006-09-01 00:09:11.000000000 +0200
+@@ -1,3 +1,13 @@
++Version 1.45
++------------
++Do not time out lockw calls when using posix extensions. Do not
++time out requests if server still responding reasonably fast
++on requests on other threads.  Improve POSIX locking emulation,
++(lock cancel now works, and unlock of merged range works even
++to Windows servers now).  Fix oops on mount to lanman servers
++(win9x, os/2 etc.) when null password.  Do not send listxattr
++(SMB to query all EAs) if nouser_xattr specified.
++
+ Version 1.44
+ ------------
+ Rewritten sessionsetup support, including support for legacy SMB
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/cifsencrypt.c linux-2.6.18-rc5-xen/fs/cifs/cifsencrypt.c
+--- linux-2.6.18-rc5/fs/cifs/cifsencrypt.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/cifsencrypt.c	2006-09-01 00:09:11.000000000 +0200
+@@ -277,7 +277,8 @@
+ 		return;
+ 
+ 	memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
+-	strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE);
++	if(ses->password)
++		strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE);
+ 
+ 	if((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0)
+ 		if(extended_security & CIFSSEC_MAY_PLNTXT) {
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/cifsfs.c linux-2.6.18-rc5-xen/fs/cifs/cifsfs.c
+--- linux-2.6.18-rc5/fs/cifs/cifsfs.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/cifsfs.c	2006-09-01 00:09:11.000000000 +0200
+@@ -402,7 +402,6 @@
+ };
+ #endif
+ 
+-#ifdef CONFIG_CIFS_EXPERIMENTAL
+ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
+ {
+ 	struct cifs_sb_info *cifs_sb;
+@@ -422,7 +421,7 @@
+ 		tcon->tidStatus = CifsExiting;
+ 	up(&tcon->tconSem);
+ 
+-	/* cancel_brl_requests(tcon); */
++	/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
+ 	/* cancel_notify_requests(tcon); */
+ 	if(tcon->ses && tcon->ses->server)
+ 	{
+@@ -438,7 +437,6 @@
+ 
+ 	return;
+ }
+-#endif	
+ 
+ static int cifs_remount(struct super_block *sb, int *flags, char *data)
+ {
+@@ -457,9 +455,7 @@
+    unless later we add lazy close of inodes or unless the kernel forgets to call
+    us with the same number of releases (closes) as opens */
+ 	.show_options = cifs_show_options,
+-#ifdef CONFIG_CIFS_EXPERIMENTAL
+ 	.umount_begin   = cifs_umount_begin,
+-#endif
+ 	.remount_fs = cifs_remount,
+ };
+ 
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/cifsfs.h linux-2.6.18-rc5-xen/fs/cifs/cifsfs.h
+--- linux-2.6.18-rc5/fs/cifs/cifsfs.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/cifsfs.h	2006-09-01 00:09:11.000000000 +0200
+@@ -100,5 +100,5 @@
+ extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
+ extern int cifs_ioctl (struct inode * inode, struct file * filep,
+ 		       unsigned int command, unsigned long arg);
+-#define CIFS_VERSION   "1.44"
++#define CIFS_VERSION   "1.45"
+ #endif				/* _CIFSFS_H */
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/cifsglob.h linux-2.6.18-rc5-xen/fs/cifs/cifsglob.h
+--- linux-2.6.18-rc5/fs/cifs/cifsglob.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/cifsglob.h	2006-09-01 00:09:11.000000000 +0200
+@@ -3,6 +3,7 @@
+  *
+  *   Copyright (C) International Business Machines  Corp., 2002,2006
+  *   Author(s): Steve French (sfrench at us.ibm.com)
++ *              Jeremy Allison (jra at samba.org)
+  *
+  *   This library is free software; you can redistribute it and/or modify
+  *   it under the terms of the GNU Lesser General Public License as published
+@@ -158,7 +159,8 @@
+ 	/* 16th byte of RFC1001 workstation name is always null */
+ 	char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
+ 	__u32 sequence_number; /* needed for CIFS PDU signature */
+-	char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; 
++	char mac_signing_key[CIFS_SESS_KEY_SIZE + 16];
++	unsigned long lstrp; /* when we got last response from this server */
+ };
+ 
+ /*
+@@ -266,14 +268,14 @@
+ };
+ 
+ /*
+- * This info hangs off the cifsFileInfo structure.  This is used to track
+- * byte stream locks on the file
++ * This info hangs off the cifsFileInfo structure, pointed to by llist.
++ * This is used to track byte stream locks on the file
+  */
+ struct cifsLockInfo {
+-	struct cifsLockInfo *next;
+-	int start;
+-	int length;
+-	int type;
++	struct list_head llist;	/* pointer to next cifsLockInfo */
++	__u64 offset;
++	__u64 length;
++	__u8 type;
+ };
+ 
+ /*
+@@ -304,6 +306,8 @@
+ 	/* lock scope id (0 if none) */
+ 	struct file * pfile; /* needed for writepage */
+ 	struct inode * pInode; /* needed for oplock break */
++	struct semaphore lock_sem;
++	struct list_head llist; /* list of byte range locks we have. */
+ 	unsigned closePend:1;	/* file is marked to close */
+ 	unsigned invalidHandle:1;  /* file closed via session abend */
+ 	atomic_t wrtPending;   /* handle in use - defer close */
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/cifsproto.h linux-2.6.18-rc5-xen/fs/cifs/cifsproto.h
+--- linux-2.6.18-rc5/fs/cifs/cifsproto.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/cifsproto.h	2006-09-01 00:09:11.000000000 +0200
+@@ -50,6 +50,10 @@
+ extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
+ 			struct kvec *, int /* nvec to send */, 
+ 			int * /* type of buf returned */ , const int long_op);
++extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *,
++				struct smb_hdr * /* input */ ,
++				struct smb_hdr * /* out */ ,
++				int * /* bytes returned */);
+ extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
+ extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
+ extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/cifssmb.c linux-2.6.18-rc5-xen/fs/cifs/cifssmb.c
+--- linux-2.6.18-rc5/fs/cifs/cifssmb.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/cifssmb.c	2006-09-01 00:09:11.000000000 +0200
+@@ -477,7 +477,7 @@
+ 		/* BB get server time for time conversions and add
+ 		code to use it and timezone since this is not UTC */	
+ 
+-		if (rsp->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
++		if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
+ 			memcpy(server->cryptKey, rsp->EncryptionKey,
+ 				CIFS_CRYPTO_KEY_SIZE);
+ 		} else if (server->secMode & SECMODE_PW_ENCRYPT) {
+@@ -1460,8 +1460,13 @@
+ 	pSMB->hdr.smb_buf_length += count;
+ 	pSMB->ByteCount = cpu_to_le16(count);
+ 
+-	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
++	if (waitFlag) {
++		rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
++			(struct smb_hdr *) pSMBr, &bytes_returned);
++	} else {
++		rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ 			 (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
++	}
+ 	cifs_stats_inc(&tcon->num_locks);
+ 	if (rc) {
+ 		cFYI(1, ("Send error in Lock = %d", rc));
+@@ -1484,6 +1489,7 @@
+ 	char *data_offset;
+ 	struct cifs_posix_lock *parm_data;
+ 	int rc = 0;
++	int timeout = 0;
+ 	int bytes_returned = 0;
+ 	__u16 params, param_offset, offset, byte_count, count;
+ 
+@@ -1503,7 +1509,6 @@
+ 	pSMB->MaxSetupCount = 0;
+ 	pSMB->Reserved = 0;
+ 	pSMB->Flags = 0;
+-	pSMB->Timeout = 0;
+ 	pSMB->Reserved2 = 0;
+ 	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
+ 	offset = param_offset + params;
+@@ -1529,8 +1534,13 @@
+ 			(((char *) &pSMB->hdr.Protocol) + offset);
+ 
+ 	parm_data->lock_type = cpu_to_le16(lock_type);
+-	if(waitFlag)
++	if(waitFlag) {
++		timeout = 3;  /* blocking operation, no timeout */
+ 		parm_data->lock_flags = cpu_to_le16(1);
++		pSMB->Timeout = cpu_to_le32(-1);
++	} else
++		pSMB->Timeout = 0;
++
+ 	parm_data->pid = cpu_to_le32(current->tgid);
+ 	parm_data->start = cpu_to_le64(pLockData->fl_start);
+ 	parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
+@@ -1541,8 +1551,14 @@
+ 	pSMB->Reserved4 = 0;
+ 	pSMB->hdr.smb_buf_length += byte_count;
+ 	pSMB->ByteCount = cpu_to_le16(byte_count);
+-	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+-			(struct smb_hdr *) pSMBr, &bytes_returned, 0);
++	if (waitFlag) {
++		rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
++			(struct smb_hdr *) pSMBr, &bytes_returned);
++	} else {
++		rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
++			(struct smb_hdr *) pSMBr, &bytes_returned, timeout);
++	}
++
+ 	if (rc) {
+ 		cFYI(1, ("Send error in Posix Lock = %d", rc));
+ 	} else if (get_flag) {
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/connect.c linux-2.6.18-rc5-xen/fs/cifs/connect.c
+--- linux-2.6.18-rc5/fs/cifs/connect.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/connect.c	2006-09-01 00:09:11.000000000 +0200
+@@ -182,6 +182,7 @@
+ 
+ 	while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
+ 	{
++		try_to_freeze();
+ 		if(server->protocolType == IPV6) {
+ 			rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
+ 		} else {
+@@ -612,6 +613,10 @@
+ #ifdef CONFIG_CIFS_STATS2
+ 				mid_entry->when_received = jiffies;
+ #endif
++				/* so we do not time out requests to  server
++				which is still responding (since server could
++				be busy but not dead) */
++				server->lstrp = jiffies;
+ 				break;
+ 			}
+ 		}
+@@ -1266,33 +1271,35 @@
+ 
+ 	read_lock(&GlobalSMBSeslock);
+ 	list_for_each(tmp, &GlobalTreeConnectionList) {
+-		cFYI(1, ("Next tcon - "));
++		cFYI(1, ("Next tcon"));
+ 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+ 		if (tcon->ses) {
+ 			if (tcon->ses->server) {
+ 				cFYI(1,
+-				     (" old ip addr: %x == new ip %x ?",
++				     ("old ip addr: %x == new ip %x ?",
+ 				      tcon->ses->server->addr.sockAddr.sin_addr.
+ 				      s_addr, new_target_ip_addr));
+ 				if (tcon->ses->server->addr.sockAddr.sin_addr.
+ 				    s_addr == new_target_ip_addr) {
+-	/* BB lock tcon and server and tcp session and increment use count here? */
++	/* BB lock tcon, server and tcp session and increment use count here? */
+ 					/* found a match on the TCP session */
+ 					/* BB check if reconnection needed */
+-					cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
++					cFYI(1,("IP match, old UNC: %s new: %s",
+ 					      tcon->treeName, uncName));
+ 					if (strncmp
+ 					    (tcon->treeName, uncName,
+ 					     MAX_TREE_SIZE) == 0) {
+ 						cFYI(1,
+-						     ("Matched UNC, old user: %s == new: %s ?",
++						     ("and old usr: %s new: %s",
+ 						      tcon->treeName, uncName));
+ 						if (strncmp
+ 						    (tcon->ses->userName,
+ 						     userName,
+ 						     MAX_USERNAME_SIZE) == 0) {
+ 							read_unlock(&GlobalSMBSeslock);
+-							return tcon;/* also matched user (smb session)*/
++							/* matched smb session
++							(user name */
++							return tcon;
+ 						}
+ 					}
+ 				}
+@@ -1969,7 +1976,18 @@
+ 				}
+ 					
+ 				cFYI(1,("Negotiate caps 0x%x",(int)cap));
+-
++#ifdef CONFIG_CIFS_DEBUG2
++				if(cap & CIFS_UNIX_FCNTL_CAP)
++					cFYI(1,("FCNTL cap"));
++				if(cap & CIFS_UNIX_EXTATTR_CAP)
++					cFYI(1,("EXTATTR cap"));
++				if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
++					cFYI(1,("POSIX path cap"));
++				if(cap & CIFS_UNIX_XATTR_CAP)
++					cFYI(1,("XATTR cap"));
++				if(cap & CIFS_UNIX_POSIX_ACL_CAP)
++					cFYI(1,("POSIX ACL cap"));
++#endif /* CIFS_DEBUG2 */
+ 				if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
+ 					cFYI(1,("setting capabilities failed"));
+ 				}
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/dir.c linux-2.6.18-rc5-xen/fs/cifs/dir.c
+--- linux-2.6.18-rc5/fs/cifs/dir.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/dir.c	2006-09-01 00:09:11.000000000 +0200
+@@ -267,6 +267,10 @@
+ 			pCifsFile->invalidHandle = FALSE;
+ 			pCifsFile->closePend     = FALSE;
+ 			init_MUTEX(&pCifsFile->fh_sem);
++			init_MUTEX(&pCifsFile->lock_sem);
++			INIT_LIST_HEAD(&pCifsFile->llist);
++			atomic_set(&pCifsFile->wrtPending,0);
++
+ 			/* set the following in open now 
+ 				pCifsFile->pfile = file; */
+ 			write_lock(&GlobalSMBSeslock);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/file.c linux-2.6.18-rc5-xen/fs/cifs/file.c
+--- linux-2.6.18-rc5/fs/cifs/file.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/file.c	2006-09-01 00:09:11.000000000 +0200
+@@ -5,6 +5,7 @@
+  * 
+  *   Copyright (C) International Business Machines  Corp., 2002,2003
+  *   Author(s): Steve French (sfrench at us.ibm.com)
++ *              Jeremy Allison (jra at samba.org)
+  *
+  *   This library is free software; you can redistribute it and/or modify
+  *   it under the terms of the GNU Lesser General Public License as published
+@@ -47,6 +48,8 @@
+ 	private_data->netfid = netfid;
+ 	private_data->pid = current->tgid;	
+ 	init_MUTEX(&private_data->fh_sem);
++	init_MUTEX(&private_data->lock_sem);
++	INIT_LIST_HEAD(&private_data->llist);
+ 	private_data->pfile = file; /* needed for writepage */
+ 	private_data->pInode = inode;
+ 	private_data->invalidHandle = FALSE;
+@@ -473,6 +476,8 @@
+ 	cifs_sb = CIFS_SB(inode->i_sb);
+ 	pTcon = cifs_sb->tcon;
+ 	if (pSMBFile) {
++		struct cifsLockInfo *li, *tmp;
++
+ 		pSMBFile->closePend = TRUE;
+ 		if (pTcon) {
+ 			/* no sense reconnecting to close a file that is
+@@ -496,6 +501,16 @@
+ 						  pSMBFile->netfid);
+ 			}
+ 		}
++
++		/* Delete any outstanding lock records.
++		   We'll lose them when the file is closed anyway. */
++		down(&pSMBFile->lock_sem);
++		list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) {
++			list_del(&li->llist);
++			kfree(li);
++		}
++		up(&pSMBFile->lock_sem);
++
+ 		write_lock(&GlobalSMBSeslock);
+ 		list_del(&pSMBFile->flist);
+ 		list_del(&pSMBFile->tlist);
+@@ -570,6 +585,21 @@
+ 	return rc;
+ }
+ 
++static int store_file_lock(struct cifsFileInfo *fid, __u64 len,
++				__u64 offset, __u8 lockType)
++{
++	struct cifsLockInfo *li = kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
++	if (li == NULL)
++		return -ENOMEM;
++	li->offset = offset;
++	li->length = len;
++	li->type = lockType;
++	down(&fid->lock_sem);
++	list_add(&li->llist, &fid->llist);
++	up(&fid->lock_sem);
++	return 0;
++}
++
+ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
+ {
+ 	int rc, xid;
+@@ -581,6 +611,7 @@
+ 	struct cifsTconInfo *pTcon;
+ 	__u16 netfid;
+ 	__u8 lockType = LOCKING_ANDX_LARGE_FILES;
++	int posix_locking;
+ 
+ 	length = 1 + pfLock->fl_end - pfLock->fl_start;
+ 	rc = -EACCES;
+@@ -639,15 +670,14 @@
+ 	}
+ 	netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
+ 
++	posix_locking = (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
++			(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability));
+ 
+ 	/* BB add code here to normalize offset and length to
+ 	account for negative length which we can not accept over the
+ 	wire */
+ 	if (IS_GETLK(cmd)) {
+-		if(experimEnabled && 
+-		   (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
+-		   (CIFS_UNIX_FCNTL_CAP & 
+-			le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
++		if(posix_locking) {
+ 			int posix_lock_type;
+ 			if(lockType & LOCKING_ANDX_SHARED_LOCK)
+ 				posix_lock_type = CIFS_RDLCK;
+@@ -683,10 +713,15 @@
+ 		FreeXid(xid);
+ 		return rc;
+ 	}
+-	if (experimEnabled &&
+-		(cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
+-		(CIFS_UNIX_FCNTL_CAP &
+-			 le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
++
++	if (!numLock && !numUnlock) {
++		/* if no lock or unlock then nothing
++		to do since we do not know what it is */
++		FreeXid(xid);
++		return -EOPNOTSUPP;
++	}
++
++	if (posix_locking) {
+ 		int posix_lock_type;
+ 		if(lockType & LOCKING_ANDX_SHARED_LOCK)
+ 			posix_lock_type = CIFS_RDLCK;
+@@ -695,18 +730,46 @@
+ 		
+ 		if(numUnlock == 1)
+ 			posix_lock_type = CIFS_UNLCK;
+-		else if(numLock == 0) {
+-			/* if no lock or unlock then nothing
+-			to do since we do not know what it is */
+-			FreeXid(xid);
+-			return -EOPNOTSUPP;
+-		}
++
+ 		rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
+ 				      length, pfLock,
+ 				      posix_lock_type, wait_flag);
+-	} else
+-		rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
+-				numUnlock, numLock, lockType, wait_flag);
++	} else {
++		struct cifsFileInfo *fid = (struct cifsFileInfo *)file->private_data;
++
++		if (numLock) {
++			rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
++					0, numLock, lockType, wait_flag);
++
++			if (rc == 0) {
++				/* For Windows locks we must store them. */
++				rc = store_file_lock(fid, length,
++						pfLock->fl_start, lockType);
++			}
++		} else if (numUnlock) {
++			/* For each stored lock that this unlock overlaps
++			   completely, unlock it. */
++			int stored_rc = 0;
++			struct cifsLockInfo *li, *tmp;
++
++			down(&fid->lock_sem);
++			list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
++				if (pfLock->fl_start <= li->offset &&
++						length >= li->length) {
++					stored_rc = CIFSSMBLock(xid, pTcon, netfid,
++							li->length, li->offset,
++							1, 0, li->type, FALSE);
++					if (stored_rc)
++						rc = stored_rc;
++
++					list_del(&li->llist);
++					kfree(li);
++				}
++			}
++		up(&fid->lock_sem);
++		}
++	}
++
+ 	if (pfLock->fl_flags & FL_POSIX)
+ 		posix_lock_file_wait(file, pfLock);
+ 	FreeXid(xid);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/netmisc.c linux-2.6.18-rc5-xen/fs/cifs/netmisc.c
+--- linux-2.6.18-rc5/fs/cifs/netmisc.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/netmisc.c	2006-09-01 00:09:11.000000000 +0200
+@@ -72,6 +72,7 @@
+ 	{ERRinvlevel,-EOPNOTSUPP},
+ 	{ERRdirnotempty, -ENOTEMPTY},
+ 	{ERRnotlocked, -ENOLCK},
++	{ERRcancelviolation, -ENOLCK},
+ 	{ERRalreadyexists, -EEXIST},
+ 	{ERRmoredata, -EOVERFLOW},
+ 	{ERReasnotsupported,-EOPNOTSUPP},
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/readdir.c linux-2.6.18-rc5-xen/fs/cifs/readdir.c
+--- linux-2.6.18-rc5/fs/cifs/readdir.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/readdir.c	2006-09-01 00:09:11.000000000 +0200
+@@ -556,7 +556,7 @@
+ 		FIND_FILE_STANDARD_INFO * pFindData =
+ 			(FIND_FILE_STANDARD_INFO *)current_entry;
+ 		filename = &pFindData->FileName[0];
+-		len = le32_to_cpu(pFindData->FileNameLength);
++		len = pFindData->FileNameLength;
+ 	} else {
+ 		cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level));
+ 	}
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/README linux-2.6.18-rc5-xen/fs/cifs/README
+--- linux-2.6.18-rc5/fs/cifs/README	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/README	2006-09-01 00:09:11.000000000 +0200
+@@ -408,7 +408,7 @@
+   user_xattr    Allow getting and setting user xattrs as OS/2 EAs (extended
+ 		attributes) to the server (default) e.g. via setfattr 
+ 		and getfattr utilities. 
+-  nouser_xattr  Do not allow getfattr/setfattr to get/set xattrs 
++  nouser_xattr  Do not allow getfattr/setfattr to get/set/list xattrs 
+   mapchars      Translate six of the seven reserved characters (not backslash)
+ 			*?<>|:
+ 		to the remap range (above 0xF000), which also
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/sess.c linux-2.6.18-rc5-xen/fs/cifs/sess.c
+--- linux-2.6.18-rc5/fs/cifs/sess.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/sess.c	2006-09-01 00:09:11.000000000 +0200
+@@ -372,7 +372,7 @@
+ 
+ 		/* no capabilities flags in old lanman negotiation */
+ 
+-		pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE; 
++		pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); 
+ 		/* BB calculate hash with password */
+ 		/* and copy into bcc */
+ 
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/smberr.h linux-2.6.18-rc5-xen/fs/cifs/smberr.h
+--- linux-2.6.18-rc5/fs/cifs/smberr.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/smberr.h	2006-09-01 00:09:11.000000000 +0200
+@@ -95,6 +95,7 @@
+ #define ERRinvlevel		124
+ #define ERRdirnotempty		145
+ #define ERRnotlocked		158
++#define ERRcancelviolation	173
+ #define ERRalreadyexists	183
+ #define ERRbadpipe		230
+ #define ERRpipebusy		231
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/transport.c linux-2.6.18-rc5-xen/fs/cifs/transport.c
+--- linux-2.6.18-rc5/fs/cifs/transport.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/transport.c	2006-09-01 00:09:11.000000000 +0200
+@@ -3,7 +3,8 @@
+  *
+  *   Copyright (C) International Business Machines  Corp., 2002,2005
+  *   Author(s): Steve French (sfrench at us.ibm.com)
+- *
++ *   Jeremy Allison (jra at samba.org) 2006.
++ *    
+  *   This library is free software; you can redistribute it and/or modify
+  *   it under the terms of the GNU Lesser General Public License as published
+  *   by the Free Software Foundation; either version 2.1 of the License, or
+@@ -36,7 +37,7 @@
+ extern kmem_cache_t *cifs_oplock_cachep;
+ 
+ static struct mid_q_entry *
+-AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
++AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
+ {
+ 	struct mid_q_entry *temp;
+ 
+@@ -203,6 +204,10 @@
+ 		rc = 0;
+ 	}
+ 
++	/* Don't want to modify the buffer as a
++	   side effect of this call. */
++	smb_buffer->smb_buf_length = smb_buf_length;
++
+ 	return rc;
+ }
+ 
+@@ -217,6 +222,7 @@
+ 	unsigned int len = iov[0].iov_len;
+ 	unsigned int total_len;
+ 	int first_vec = 0;
++	unsigned int smb_buf_length = smb_buffer->smb_buf_length;
+ 	
+ 	if(ssocket == NULL)
+ 		return -ENOTSOCK; /* BB eventually add reconnect code here */
+@@ -293,36 +299,15 @@
+ 	} else
+ 		rc = 0;
+ 
++	/* Don't want to modify the buffer as a
++	   side effect of this call. */
++	smb_buffer->smb_buf_length = smb_buf_length;
++
+ 	return rc;
+ }
+ 
+-int
+-SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 
+-	     struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 
+-	     const int long_op)
++static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
+ {
+-	int rc = 0;
+-	unsigned int receive_len;
+-	unsigned long timeout;
+-	struct mid_q_entry *midQ;
+-	struct smb_hdr *in_buf = iov[0].iov_base;
+-	
+-	*pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
+-
+-	if ((ses == NULL) || (ses->server == NULL)) {
+-		cifs_small_buf_release(in_buf);
+-		cERROR(1,("Null session"));
+-		return -EIO;
+-	}
+-
+-	if(ses->server->tcpStatus == CifsExiting) {
+-		cifs_small_buf_release(in_buf);
+-		return -ENOENT;
+-	}
+-
+-	/* Ensure that we do not send more than 50 overlapping requests 
+-	   to the same server. We may make this configurable later or
+-	   use ses->maxReq */
+ 	if(long_op == -1) {
+ 		/* oplock breaks must not be held up */
+ 		atomic_inc(&ses->server->inFlight);
+@@ -345,53 +330,140 @@
+ 			} else {
+ 				if(ses->server->tcpStatus == CifsExiting) {
+ 					spin_unlock(&GlobalMid_Lock);
+-					cifs_small_buf_release(in_buf);
+ 					return -ENOENT;
+ 				}
+ 
+-			/* can not count locking commands against total since
+-			   they are allowed to block on server */
++				/* can not count locking commands against total since
++				   they are allowed to block on server */
+ 					
+-				if(long_op < 3) {
+ 				/* update # of requests on the wire to server */
++				if (long_op < 3)
+ 					atomic_inc(&ses->server->inFlight);
+-				}
+ 				spin_unlock(&GlobalMid_Lock);
+ 				break;
+ 			}
+ 		}
+ 	}
+-	/* make sure that we sign in the same order that we send on this socket 
+-	   and avoid races inside tcp sendmsg code that could cause corruption
+-	   of smb data */
+-
+-	down(&ses->server->tcpSem); 
++	return 0;
++}
+ 
++static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
++			struct mid_q_entry **ppmidQ)
++{
+ 	if (ses->server->tcpStatus == CifsExiting) {
+-		rc = -ENOENT;
+-		goto out_unlock2;
++		return -ENOENT;
+ 	} else if (ses->server->tcpStatus == CifsNeedReconnect) {
+ 		cFYI(1,("tcp session dead - return to caller to retry"));
+-		rc = -EAGAIN;
+-		goto out_unlock2;
++		return -EAGAIN;
+ 	} else if (ses->status != CifsGood) {
+ 		/* check if SMB session is bad because we are setting it up */
+ 		if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 
+ 			(in_buf->Command != SMB_COM_NEGOTIATE)) {
+-			rc = -EAGAIN;
+-			goto out_unlock2;
++			return -EAGAIN;
+ 		} /* else ok - we are setting up session */
+ 	}
+-	midQ = AllocMidQEntry(in_buf, ses);
+-	if (midQ == NULL) {
++	*ppmidQ = AllocMidQEntry(in_buf, ses);
++	if (*ppmidQ == NULL) {
++		return -ENOMEM;
++	}
++	return 0;
++}
++
++static int wait_for_response(struct cifsSesInfo *ses, 
++			struct mid_q_entry *midQ,
++			unsigned long timeout,
++			unsigned long time_to_wait)
++{
++	unsigned long curr_timeout;
++
++	for (;;) {
++		curr_timeout = timeout + jiffies;
++		wait_event(ses->server->response_q,
++			(!(midQ->midState == MID_REQUEST_SUBMITTED)) || 
++			time_after(jiffies, curr_timeout) || 
++			((ses->server->tcpStatus != CifsGood) &&
++			 (ses->server->tcpStatus != CifsNew)));
++
++		if (time_after(jiffies, curr_timeout) &&
++			(midQ->midState == MID_REQUEST_SUBMITTED) &&
++			((ses->server->tcpStatus == CifsGood) ||
++			 (ses->server->tcpStatus == CifsNew))) {
++
++			unsigned long lrt;
++
++			/* We timed out. Is the server still
++			   sending replies ? */
++			spin_lock(&GlobalMid_Lock);
++			lrt = ses->server->lstrp;
++			spin_unlock(&GlobalMid_Lock);
++
++			/* Calculate time_to_wait past last receive time.
++			 Although we prefer not to time out if the 
++			 server is still responding - we will time
++			 out if the server takes more than 15 (or 45 
++			 or 180) seconds to respond to this request
++			 and has not responded to any request from 
++			 other threads on the client within 10 seconds */
++			lrt += time_to_wait;
++			if (time_after(jiffies, lrt)) {
++				/* No replies for time_to_wait. */
++				cERROR(1,("server not responding"));
++				return -1;
++			}
++		} else {
++			return 0;
++		}
++	}
++}
++
++int
++SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 
++	     struct kvec *iov, int n_vec, int * pRespBufType /* ret */, 
++	     const int long_op)
++{
++	int rc = 0;
++	unsigned int receive_len;
++	unsigned long timeout;
++	struct mid_q_entry *midQ;
++	struct smb_hdr *in_buf = iov[0].iov_base;
++	
++	*pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
++
++	if ((ses == NULL) || (ses->server == NULL)) {
++		cifs_small_buf_release(in_buf);
++		cERROR(1,("Null session"));
++		return -EIO;
++	}
++
++	if(ses->server->tcpStatus == CifsExiting) {
++		cifs_small_buf_release(in_buf);
++		return -ENOENT;
++	}
++
++	/* Ensure that we do not send more than 50 overlapping requests 
++	   to the same server. We may make this configurable later or
++	   use ses->maxReq */
++
++	rc = wait_for_free_request(ses, long_op);
++	if (rc) {
++		cifs_small_buf_release(in_buf);
++		return rc;
++	}
++
++	/* make sure that we sign in the same order that we send on this socket 
++	   and avoid races inside tcp sendmsg code that could cause corruption
++	   of smb data */
++
++	down(&ses->server->tcpSem); 
++
++	rc = allocate_mid(ses, in_buf, &midQ);
++	if (rc) {
+ 		up(&ses->server->tcpSem);
+ 		cifs_small_buf_release(in_buf);
+-		/* If not lock req, update # of requests on wire to server */
+-		if(long_op < 3) {
+-			atomic_dec(&ses->server->inFlight); 
+-			wake_up(&ses->server->request_q);
+-		}
+-		return -ENOMEM;
++		/* Update # of requests on wire to server */
++		atomic_dec(&ses->server->inFlight); 
++		wake_up(&ses->server->request_q);
++		return rc;
+ 	}
+ 
+  	rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
+@@ -406,32 +478,23 @@
+ 	atomic_dec(&ses->server->inSend);
+ 	midQ->when_sent = jiffies;
+ #endif
+-	if(rc < 0) {
+-		DeleteMidQEntry(midQ);
+-		up(&ses->server->tcpSem);
+-		cifs_small_buf_release(in_buf);
+-		/* If not lock req, update # of requests on wire to server */
+-		if(long_op < 3) {
+-			atomic_dec(&ses->server->inFlight); 
+-			wake_up(&ses->server->request_q);
+-		}
+-		return rc;
+-	} else {
+-		up(&ses->server->tcpSem);
+-		cifs_small_buf_release(in_buf);
+-	}
++
++	up(&ses->server->tcpSem);
++	cifs_small_buf_release(in_buf);
++
++	if(rc < 0)
++		goto out;
+ 
+ 	if (long_op == -1)
+-		goto cifs_no_response_exit2;
++		goto out;
+ 	else if (long_op == 2) /* writes past end of file can take loong time */
+ 		timeout = 180 * HZ;
+ 	else if (long_op == 1)
+ 		timeout = 45 * HZ; /* should be greater than 
+ 			servers oplock break timeout (about 43 seconds) */
+-	else if (long_op > 2) {
+-		timeout = MAX_SCHEDULE_TIMEOUT;
+-	} else
++	else
+ 		timeout = 15 * HZ;
++
+ 	/* wait for 15 seconds or until woken up due to response arriving or 
+ 	   due to last connection to this server being unmounted */
+ 	if (signal_pending(current)) {
+@@ -441,19 +504,7 @@
+ 	}   
+ 
+ 	/* No user interrupts in wait - wreaks havoc with performance */
+-	if(timeout != MAX_SCHEDULE_TIMEOUT) {
+-		timeout += jiffies;
+-		wait_event(ses->server->response_q,
+-			(!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
+-			time_after(jiffies, timeout) || 
+-			((ses->server->tcpStatus != CifsGood) &&
+-			 (ses->server->tcpStatus != CifsNew)));
+-	} else {
+-		wait_event(ses->server->response_q,
+-			(!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
+-			((ses->server->tcpStatus != CifsGood) &&
+-			 (ses->server->tcpStatus != CifsNew)));
+-	}
++	wait_for_response(ses, midQ, timeout, 10 * HZ);
+ 
+ 	spin_lock(&GlobalMid_Lock);
+ 	if (midQ->resp_buf) {
+@@ -481,11 +532,9 @@
+ 		}
+ 		spin_unlock(&GlobalMid_Lock);
+ 		DeleteMidQEntry(midQ);
+-		/* If not lock req, update # of requests on wire to server */
+-		if(long_op < 3) {
+-			atomic_dec(&ses->server->inFlight); 
+-			wake_up(&ses->server->request_q);
+-		}
++		/* Update # of requests on wire to server */
++		atomic_dec(&ses->server->inFlight); 
++		wake_up(&ses->server->request_q);
+ 		return rc;
+ 	}
+   
+@@ -536,24 +585,12 @@
+ 			cFYI(1,("Bad MID state?"));
+ 		}
+ 	}
+-cifs_no_response_exit2:
+-	DeleteMidQEntry(midQ);
+-
+-	if(long_op < 3) {
+-		atomic_dec(&ses->server->inFlight); 
+-		wake_up(&ses->server->request_q);
+-	}
+ 
+-	return rc;
++out:
+ 
+-out_unlock2:
+-	up(&ses->server->tcpSem);
+-	cifs_small_buf_release(in_buf);
+-	/* If not lock req, update # of requests on wire to server */
+-	if(long_op < 3) {
+-		atomic_dec(&ses->server->inFlight); 
+-		wake_up(&ses->server->request_q);
+-	}
++	DeleteMidQEntry(midQ);
++	atomic_dec(&ses->server->inFlight); 
++	wake_up(&ses->server->request_q);
+ 
+ 	return rc;
+ }
+@@ -583,85 +620,34 @@
+ 	/* Ensure that we do not send more than 50 overlapping requests 
+ 	   to the same server. We may make this configurable later or
+ 	   use ses->maxReq */
+-	if(long_op == -1) {
+-		/* oplock breaks must not be held up */
+-		atomic_inc(&ses->server->inFlight);
+-	} else {
+-		spin_lock(&GlobalMid_Lock); 
+-		while(1) {        
+-			if(atomic_read(&ses->server->inFlight) >= 
+-					cifs_max_pending){
+-				spin_unlock(&GlobalMid_Lock);
+-#ifdef CONFIG_CIFS_STATS2
+-				atomic_inc(&ses->server->num_waiters);
+-#endif
+-				wait_event(ses->server->request_q,
+-					atomic_read(&ses->server->inFlight)
+-					 < cifs_max_pending);
+-#ifdef CONFIG_CIFS_STATS2
+-				atomic_dec(&ses->server->num_waiters);
+-#endif
+-				spin_lock(&GlobalMid_Lock);
+-			} else {
+-				if(ses->server->tcpStatus == CifsExiting) {
+-					spin_unlock(&GlobalMid_Lock);
+-					return -ENOENT;
+-				}
+ 
+-			/* can not count locking commands against total since
+-			   they are allowed to block on server */
+-					
+-				if(long_op < 3) {
+-				/* update # of requests on the wire to server */
+-					atomic_inc(&ses->server->inFlight);
+-				}
+-				spin_unlock(&GlobalMid_Lock);
+-				break;
+-			}
+-		}
+-	}
++	rc = wait_for_free_request(ses, long_op);
++	if (rc)
++		return rc;
++
+ 	/* make sure that we sign in the same order that we send on this socket 
+ 	   and avoid races inside tcp sendmsg code that could cause corruption
+ 	   of smb data */
+ 
+ 	down(&ses->server->tcpSem); 
+ 
+-	if (ses->server->tcpStatus == CifsExiting) {
+-		rc = -ENOENT;
+-		goto out_unlock;
+-	} else if (ses->server->tcpStatus == CifsNeedReconnect) {
+-		cFYI(1,("tcp session dead - return to caller to retry"));
+-		rc = -EAGAIN;
+-		goto out_unlock;
+-	} else if (ses->status != CifsGood) {
+-		/* check if SMB session is bad because we are setting it up */
+-		if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 
+-			(in_buf->Command != SMB_COM_NEGOTIATE)) {
+-			rc = -EAGAIN;
+-			goto out_unlock;
+-		} /* else ok - we are setting up session */
+-	}
+-	midQ = AllocMidQEntry(in_buf, ses);
+-	if (midQ == NULL) {
++	rc = allocate_mid(ses, in_buf, &midQ);
++	if (rc) {
+ 		up(&ses->server->tcpSem);
+-		/* If not lock req, update # of requests on wire to server */
+-		if(long_op < 3) {
+-			atomic_dec(&ses->server->inFlight); 
+-			wake_up(&ses->server->request_q);
+-		}
+-		return -ENOMEM;
++		/* Update # of requests on wire to server */
++		atomic_dec(&ses->server->inFlight); 
++		wake_up(&ses->server->request_q);
++		return rc;
+ 	}
+ 
+ 	if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
+-		up(&ses->server->tcpSem);
+ 		cERROR(1, ("Illegal length, greater than maximum frame, %d",
+ 			in_buf->smb_buf_length));
+ 		DeleteMidQEntry(midQ);
+-		/* If not lock req, update # of requests on wire to server */
+-		if(long_op < 3) {
+-			atomic_dec(&ses->server->inFlight); 
+-			wake_up(&ses->server->request_q);
+-		}
++		up(&ses->server->tcpSem);
++		/* Update # of requests on wire to server */
++		atomic_dec(&ses->server->inFlight); 
++		wake_up(&ses->server->request_q);
+ 		return -EIO;
+ 	}
+ 
+@@ -677,27 +663,19 @@
+ 	atomic_dec(&ses->server->inSend);
+ 	midQ->when_sent = jiffies;
+ #endif
+-	if(rc < 0) {
+-		DeleteMidQEntry(midQ);
+-		up(&ses->server->tcpSem);
+-		/* If not lock req, update # of requests on wire to server */
+-		if(long_op < 3) {
+-			atomic_dec(&ses->server->inFlight); 
+-			wake_up(&ses->server->request_q);
+-		}
+-		return rc;
+-	} else
+-		up(&ses->server->tcpSem);
++	up(&ses->server->tcpSem);
++
++	if(rc < 0)
++		goto out;
++
+ 	if (long_op == -1)
+-		goto cifs_no_response_exit;
++		goto out;
+ 	else if (long_op == 2) /* writes past end of file can take loong time */
+ 		timeout = 180 * HZ;
+ 	else if (long_op == 1)
+ 		timeout = 45 * HZ; /* should be greater than 
+ 			servers oplock break timeout (about 43 seconds) */
+-	else if (long_op > 2) {
+-		timeout = MAX_SCHEDULE_TIMEOUT;
+-	} else
++	else
+ 		timeout = 15 * HZ;
+ 	/* wait for 15 seconds or until woken up due to response arriving or 
+ 	   due to last connection to this server being unmounted */
+@@ -708,19 +686,7 @@
+ 	}   
+ 
+ 	/* No user interrupts in wait - wreaks havoc with performance */
+-	if(timeout != MAX_SCHEDULE_TIMEOUT) {
+-		timeout += jiffies;
+-		wait_event(ses->server->response_q,
+-			(!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
+-			time_after(jiffies, timeout) || 
+-			((ses->server->tcpStatus != CifsGood) &&
+-			 (ses->server->tcpStatus != CifsNew)));
+-	} else {
+-		wait_event(ses->server->response_q,
+-			(!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
+-			((ses->server->tcpStatus != CifsGood) &&
+-			 (ses->server->tcpStatus != CifsNew)));
+-	}
++	wait_for_response(ses, midQ, timeout, 10 * HZ);
+ 
+ 	spin_lock(&GlobalMid_Lock);
+ 	if (midQ->resp_buf) {
+@@ -748,11 +714,9 @@
+ 		}
+ 		spin_unlock(&GlobalMid_Lock);
+ 		DeleteMidQEntry(midQ);
+-		/* If not lock req, update # of requests on wire to server */
+-		if(long_op < 3) {
+-			atomic_dec(&ses->server->inFlight); 
+-			wake_up(&ses->server->request_q);
+-		}
++		/* Update # of requests on wire to server */
++		atomic_dec(&ses->server->inFlight); 
++		wake_up(&ses->server->request_q);
+ 		return rc;
+ 	}
+   
+@@ -799,23 +763,253 @@
+ 			cERROR(1,("Bad MID state?"));
+ 		}
+ 	}
+-cifs_no_response_exit:
++
++out:
++
+ 	DeleteMidQEntry(midQ);
++	atomic_dec(&ses->server->inFlight); 
++	wake_up(&ses->server->request_q);
+ 
+-	if(long_op < 3) {
+-		atomic_dec(&ses->server->inFlight); 
+-		wake_up(&ses->server->request_q);
+-	}
++	return rc;
 +}
 +
-+static int xenwatch_thread(void *unused)
++/* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
+ 
++static int
++send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
++		struct mid_q_entry *midQ)
 +{
-+	struct list_head *ent;
-+	struct xs_stored_msg *msg;
-+
-+	for (;;) {
-+		wait_event_interruptible(watch_events_waitq,
-+					 !list_empty(&watch_events));
++	int rc = 0;
++	struct cifsSesInfo *ses = tcon->ses;
++	__u16 mid = in_buf->Mid;
 +
-+		if (kthread_should_stop())
-+			break;
++	header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
++	in_buf->Mid = mid;
++	down(&ses->server->tcpSem); 
++	rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
++	if (rc) {
++		up(&ses->server->tcpSem);
++		return rc;
++	}
++	rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
++	      (struct sockaddr *) &(ses->server->addr.sockAddr));
++	up(&ses->server->tcpSem);
+ 	return rc;
++}
 +
-+		mutex_lock(&xenwatch_mutex);
++/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
++   blocking lock to return. */
 +
-+		spin_lock(&watch_events_lock);
-+		ent = watch_events.next;
-+		if (ent != &watch_events)
-+			list_del(ent);
-+		spin_unlock(&watch_events_lock);
++static int
++send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
++			struct smb_hdr *in_buf,
++			struct smb_hdr *out_buf)
++{
++	int bytes_returned;
++	struct cifsSesInfo *ses = tcon->ses;
++	LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
 +
-+		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);
-+		}
++	/* We just modify the current in_buf to change
++	   the type of lock from LOCKING_ANDX_SHARED_LOCK
++	   or LOCKING_ANDX_EXCLUSIVE_LOCK to
++	   LOCKING_ANDX_CANCEL_LOCK. */
 +
-+		mutex_unlock(&xenwatch_mutex);
-+	}
++	pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
++	pSMB->Timeout = 0;
++	pSMB->hdr.Mid = GetNextMid(ses->server);
 +
-+	return 0;
++	return SendReceive(xid, ses, in_buf, out_buf,
++			&bytes_returned, 0);
 +}
-+
-+static int process_msg(void)
+ 
+-out_unlock:
++int
++SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
++	    struct smb_hdr *in_buf, struct smb_hdr *out_buf,
++	    int *pbytes_returned)
 +{
-+	struct xs_stored_msg *msg;
-+	char *body;
-+	int err;
-+
-+	msg = kmalloc(sizeof(*msg), GFP_KERNEL);
-+	if (msg == NULL)
-+		return -ENOMEM;
++	int rc = 0;
++	int rstart = 0;
++	unsigned int receive_len;
++	struct mid_q_entry *midQ;
++	struct cifsSesInfo *ses;
 +
-+	err = xb_read(&msg->hdr, sizeof(msg->hdr));
-+	if (err) {
-+		kfree(msg);
-+		return err;
++	if (tcon == NULL || tcon->ses == NULL) {
++		cERROR(1,("Null smb session"));
++		return -EIO;
 +	}
++	ses = tcon->ses;
 +
-+	body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
-+	if (body == NULL) {
-+		kfree(msg);
-+		return -ENOMEM;
++	if(ses->server == NULL) {
++		cERROR(1,("Null tcp session"));
++		return -EIO;
 +	}
 +
-+	err = xb_read(body, msg->hdr.len);
-+	if (err) {
-+		kfree(body);
-+		kfree(msg);
-+		return err;
-+	}
-+	body[msg->hdr.len] = '\0';
++	if(ses->server->tcpStatus == CifsExiting)
++		return -ENOENT;
 +
-+	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);
-+		}
++	/* Ensure that we do not send more than 50 overlapping requests 
++	   to the same server. We may make this configurable later or
++	   use ses->maxReq */
 +
-+		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);
++	rc = wait_for_free_request(ses, 3);
++	if (rc)
++		return rc;
++
++	/* make sure that we sign in the same order that we send on this socket 
++	   and avoid races inside tcp sendmsg code that could cause corruption
++	   of smb data */
++
++	down(&ses->server->tcpSem); 
++
++	rc = allocate_mid(ses, in_buf, &midQ);
++	if (rc) {
++		up(&ses->server->tcpSem);
++		return rc;
 +	}
 +
-+	return 0;
-+}
++	if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
++		up(&ses->server->tcpSem);
++		cERROR(1, ("Illegal length, greater than maximum frame, %d",
++			in_buf->smb_buf_length));
++		DeleteMidQEntry(midQ);
++		return -EIO;
++	}
 +
-+static int xenbus_thread(void *unused)
-+{
-+	int err;
++	rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
 +
-+	for (;;) {
-+		err = process_msg();
-+		if (err)
-+			printk(KERN_WARNING "XENBUS error %d while reading "
-+			       "message\n", err);
-+		if (kthread_should_stop())
-+			break;
++	midQ->midState = MID_REQUEST_SUBMITTED;
++#ifdef CONFIG_CIFS_STATS2
++	atomic_inc(&ses->server->inSend);
++#endif
++	rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
++		      (struct sockaddr *) &(ses->server->addr.sockAddr));
++#ifdef CONFIG_CIFS_STATS2
++	atomic_dec(&ses->server->inSend);
++	midQ->when_sent = jiffies;
++#endif
+ 	up(&ses->server->tcpSem);
+-	/* If not lock req, update # of requests on wire to server */
+-	if(long_op < 3) {
+-		atomic_dec(&ses->server->inFlight); 
+-		wake_up(&ses->server->request_q);
++
++	if(rc < 0) {
++		DeleteMidQEntry(midQ);
++		return rc;
 +	}
 +
-+	return 0;
-+}
++	/* Wait for a reply - allow signals to interrupt. */
++	rc = wait_event_interruptible(ses->server->response_q,
++		(!(midQ->midState == MID_REQUEST_SUBMITTED)) || 
++		((ses->server->tcpStatus != CifsGood) &&
++		 (ses->server->tcpStatus != CifsNew)));
++
++	/* Were we interrupted by a signal ? */
++	if ((rc == -ERESTARTSYS) &&
++		(midQ->midState == MID_REQUEST_SUBMITTED) &&
++		((ses->server->tcpStatus == CifsGood) ||
++		 (ses->server->tcpStatus == CifsNew))) {
++
++		if (in_buf->Command == SMB_COM_TRANSACTION2) {
++			/* POSIX lock. We send a NT_CANCEL SMB to cause the
++			   blocking lock to return. */
++
++			rc = send_nt_cancel(tcon, in_buf, midQ);
++			if (rc) {
++				DeleteMidQEntry(midQ);
++				return rc;
++			}
++		} else {
++			/* Windows lock. We send a LOCKINGX_CANCEL_LOCK
++			   to cause the blocking lock to return. */
 +
-+int xs_init(void)
-+{
-+	int err;
-+	struct task_struct *task;
++			rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
 +
-+	INIT_LIST_HEAD(&xs_state.reply_list);
-+	spin_lock_init(&xs_state.reply_lock);
-+	init_waitqueue_head(&xs_state.reply_waitq);
++			/* If we get -ENOLCK back the lock may have
++			   already been removed. Don't exit in this case. */
++			if (rc && rc != -ENOLCK) {
++				DeleteMidQEntry(midQ);
++				return rc;
++			}
++		}
 +
-+	mutex_init(&xs_state.request_mutex);
-+	init_rwsem(&xs_state.suspend_mutex);
++		/* Wait 5 seconds for the response. */
++		if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ)==0) {
++			/* We got the response - restart system call. */
++			rstart = 1;
++		}
++	}
 +
-+	/* Initialize the shared memory rings to talk to xenstored */
-+	err = xb_init_comms();
-+	if (err)
-+		return err;
++	spin_lock(&GlobalMid_Lock);
++	if (midQ->resp_buf) {
++		spin_unlock(&GlobalMid_Lock);
++		receive_len = midQ->resp_buf->smb_buf_length;
++	} else {
++		cERROR(1,("No response for cmd %d mid %d",
++			  midQ->command, midQ->mid));
++		if(midQ->midState == MID_REQUEST_SUBMITTED) {
++			if(ses->server->tcpStatus == CifsExiting)
++				rc = -EHOSTDOWN;
++			else {
++				ses->server->tcpStatus = CifsNeedReconnect;
++				midQ->midState = MID_RETRY_NEEDED;
++			}
++		}
 +
-+	task = kthread_run(xenwatch_thread, NULL, "xenwatch");
-+	if (IS_ERR(task))
-+		return PTR_ERR(task);
-+	xenwatch_pid = task->pid;
++		if (rc != -EHOSTDOWN) {
++			if(midQ->midState == MID_RETRY_NEEDED) {
++				rc = -EAGAIN;
++				cFYI(1,("marking request for retry"));
++			} else {
++				rc = -EIO;
++			}
++		}
++		spin_unlock(&GlobalMid_Lock);
++		DeleteMidQEntry(midQ);
++		return rc;
+ 	}
++  
++	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
++		cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
++			receive_len, xid));
++		rc = -EIO;
++	} else {		/* rcvd frame is ok */
++
++		if (midQ->resp_buf && out_buf
++		    && (midQ->midState == MID_RESPONSE_RECEIVED)) {
++			out_buf->smb_buf_length = receive_len;
++			memcpy((char *)out_buf + 4,
++			       (char *)midQ->resp_buf + 4,
++			       receive_len);
++
++			dump_smb(out_buf, 92);
++			/* convert the length into a more usable form */
++			if((receive_len > 24) &&
++			   (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
++					SECMODE_SIGN_ENABLED))) {
++				rc = cifs_verify_signature(out_buf,
++						ses->server->mac_signing_key,
++						midQ->sequence_number+1);
++				if(rc) {
++					cERROR(1,("Unexpected SMB signature"));
++					/* BB FIXME add code to kill session */
++				}
++			}
 +
-+	task = kthread_run(xenbus_thread, NULL, "xenbus");
-+	if (IS_ERR(task))
-+		return PTR_ERR(task);
++			*pbytes_returned = out_buf->smb_buf_length;
 +
-+	return 0;
-+}
-diff -urN -x .hg -x .hgtags linux-2.6.17/fs/Kconfig linux-2.6.17-xen/fs/Kconfig
---- linux-2.6.17/fs/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/fs/Kconfig	2006-08-14 15:58:06.000000000 +0200
-@@ -842,6 +842,7 @@
++			/* BB special case reconnect tid and uid here? */
++			rc = map_smb_to_linux_error(out_buf);
+ 
++			/* convert ByteCount if necessary */
++			if (receive_len >=
++			    sizeof (struct smb_hdr) -
++			    4 /* do not count RFC1001 header */  +
++			    (2 * out_buf->WordCount) + 2 /* bcc */ )
++				BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
++		} else {
++			rc = -EIO;
++			cERROR(1,("Bad MID state?"));
++		}
++	}
++	DeleteMidQEntry(midQ);
++	if (rstart && rc == -EACCES)
++		return -ERESTARTSYS;
+ 	return rc;
+ }
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/cifs/xattr.c linux-2.6.18-rc5-xen/fs/cifs/xattr.c
+--- linux-2.6.18-rc5/fs/cifs/xattr.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/cifs/xattr.c	2006-09-01 00:09:11.000000000 +0200
+@@ -330,11 +330,15 @@
+ 	sb = direntry->d_inode->i_sb;
+ 	if(sb == NULL)
+ 		return -EIO;
+-	xid = GetXid();
+ 
+ 	cifs_sb = CIFS_SB(sb);
+ 	pTcon = cifs_sb->tcon;
+ 
++	if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
++		return -EOPNOTSUPP;
++
++	xid = GetXid();
++
+ 	full_path = build_path_from_dentry(direntry);
+ 	if(full_path == NULL) {
+ 		FreeXid(xid);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/fs/Kconfig linux-2.6.18-rc5-xen/fs/Kconfig
+--- linux-2.6.18-rc5/fs/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/fs/Kconfig	2006-09-01 00:09:11.000000000 +0200
+@@ -865,6 +865,7 @@
  config HUGETLBFS
  	bool "HugeTLB file system support"
  	depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
@@ -66463,22 +72523,64 @@
  	help
  	  hugetlbfs is a filesystem backing for HugeTLB pages, based on
  	  ramfs. For architectures that support it, say Y here and read
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/a.out.h linux-2.6.17-xen/include/asm-i386/a.out.h
---- linux-2.6.17/include/asm-i386/a.out.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-i386/a.out.h	2006-08-14 15:58:14.000000000 +0200
-@@ -19,7 +19,7 @@
- 
- #ifdef __KERNEL__
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-arm/arch-pxa/ssp.h linux-2.6.18-rc5-xen/include/asm-arm/arch-pxa/ssp.h
+--- linux-2.6.18-rc5/include/asm-arm/arch-pxa/ssp.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-arm/arch-pxa/ssp.h	2006-09-01 00:09:11.000000000 +0200
+@@ -40,8 +40,8 @@
+ };
  
--#define STACK_TOP	TASK_SIZE
-+#define STACK_TOP	(TASK_SIZE - 3*PAGE_SIZE)
+ int ssp_write_word(struct ssp_dev *dev, u32 data);
+-int ssp_read_word(struct ssp_dev *dev);
+-void ssp_flush(struct ssp_dev *dev);
++int ssp_read_word(struct ssp_dev *dev, u32 *data);
++int ssp_flush(struct ssp_dev *dev);
+ void ssp_enable(struct ssp_dev *dev);
+ void ssp_disable(struct ssp_dev *dev);
+ void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-arm/hardware/ssp.h linux-2.6.18-rc5-xen/include/asm-arm/hardware/ssp.h
+--- linux-2.6.18-rc5/include/asm-arm/hardware/ssp.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-arm/hardware/ssp.h	2006-09-01 00:09:11.000000000 +0200
+@@ -16,8 +16,8 @@
+ };
  
- #endif
+ int ssp_write_word(u16 data);
+-int ssp_read_word(void);
+-void ssp_flush(void);
++int ssp_read_word(u16 *data);
++int ssp_flush(void);
+ void ssp_enable(void);
+ void ssp_disable(void);
+ void ssp_save_state(struct ssp_state *ssp);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-arm/io.h linux-2.6.18-rc5-xen/include/asm-arm/io.h
+--- linux-2.6.18-rc5/include/asm-arm/io.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-arm/io.h	2006-09-01 00:09:11.000000000 +0200
+@@ -291,5 +291,12 @@
+  */
+ #define xlate_dev_kmem_ptr(p)	p
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/apic.h linux-2.6.17-xen/include/asm-i386/apic.h
---- linux-2.6.17/include/asm-i386/apic.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-i386/apic.h	2006-08-14 15:58:14.000000000 +0200
-@@ -132,10 +132,12 @@
++/*
++ * Register ISA memory and port locations for glibc iopl/inb/outb
++ * emulation.
++ */
++extern void register_isa_ports(unsigned int mmio, unsigned int io,
++			       unsigned int io_shift);
++
+ #endif	/* __KERNEL__ */
+ #endif	/* __ASM_ARM_IO_H */
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-generic/vmlinux.lds.h linux-2.6.18-rc5-xen/include/asm-generic/vmlinux.lds.h
+--- linux-2.6.18-rc5/include/asm-generic/vmlinux.lds.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-generic/vmlinux.lds.h	2006-09-01 00:09:11.000000000 +0200
+@@ -194,3 +194,6 @@
+ 		.stab.index 0 : { *(.stab.index) }			\
+ 		.stab.indexstr 0 : { *(.stab.indexstr) }		\
+ 		.comment 0 : { *(.comment) }
++
++#define NOTES								\
++		.notes : { *(.note.*) } :note
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/apic.h linux-2.6.18-rc5-xen/include/asm-i386/apic.h
+--- linux-2.6.18-rc5/include/asm-i386/apic.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-i386/apic.h	2006-07-20 15:57:26.000000000 +0200
+@@ -119,10 +119,12 @@
  
  extern int disable_timer_pin_1;
  
@@ -66491,31 +72593,10 @@
  
  extern int timer_over_8254;
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/elf.h linux-2.6.17-xen/include/asm-i386/elf.h
---- linux-2.6.17/include/asm-i386/elf.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-i386/elf.h	2006-08-14 15:58:14.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/fixmap.h linux-2.6.17-xen/include/asm-i386/fixmap.h
---- linux-2.6.17/include/asm-i386/fixmap.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-i386/fixmap.h	2006-08-14 15:58:14.000000000 +0200
-@@ -20,7 +20,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/fixmap.h linux-2.6.18-rc5-xen/include/asm-i386/fixmap.h
+--- linux-2.6.18-rc5/include/asm-i386/fixmap.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-i386/fixmap.h	2006-07-31 23:43:29.000000000 +0200
+@@ -19,7 +19,7 @@
   * Leave one empty page between vmalloc'ed areas and
   * the start of the fixmap.
   */
@@ -66524,15 +72605,7 @@
  
  #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 @@
+@@ -94,6 +94,8 @@
  extern void __set_fixmap (enum fixed_addresses idx,
  					unsigned long phys, pgprot_t flags);
  
@@ -66541,24 +72614,9 @@
  #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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-default/mach_traps.h linux-2.6.17-xen/include/asm-i386/mach-default/mach_traps.h
---- linux-2.6.17/include/asm-i386/mach-default/mach_traps.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-i386/mach-default/mach_traps.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-default/mach_traps.h linux-2.6.18-rc5-xen/include/asm-i386/mach-default/mach_traps.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-default/mach_traps.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-default/mach_traps.h	2006-07-20 15:57:26.000000000 +0200
 @@ -15,6 +15,18 @@
  	outb(reason, 0x61);
  }
@@ -66578,9 +72636,9 @@
  static inline unsigned char get_nmi_reason(void)
  {
  	return inb(0x61);
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/agp.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/agp.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/agp.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/agp.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/agp.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/agp.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/agp.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/agp.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,37 @@
 +#ifndef AGP_H
 +#define AGP_H 1
@@ -66619,9 +72677,9 @@
 +	dma_free_coherent(NULL,PAGE_SIZE<<(order),(table),virt_to_bus(table))
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/desc.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/desc.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/desc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/desc.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/desc.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/desc.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/desc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/desc.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,164 @@
 +#ifndef __ARCH_DESC_H
 +#define __ARCH_DESC_H
@@ -66787,10 +72845,10 @@
 +#endif /* !__ASSEMBLY__ */
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/dma-mapping.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/dma-mapping.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/dma-mapping.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/dma-mapping.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,154 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/dma-mapping.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/dma-mapping.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/dma-mapping.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/dma-mapping.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,151 @@
 +#ifndef _ASM_I386_DMA_MAPPING_H
 +#define _ASM_I386_DMA_MAPPING_H
 +
@@ -66799,7 +72857,6 @@
 + * documentation.
 + */
 +
-+#include <linux/config.h>
 +#include <linux/mm.h>
 +#include <asm/cache.h>
 +#include <asm/io.h>
@@ -66913,7 +72970,6 @@
 +	return 0;
 +}
 +
-+#ifdef __i386__
 +static inline int
 +dma_get_cache_alignment(void)
 +{
@@ -66921,7 +72977,6 @@
 +	 * maximum possible, to be safe */
 +	return (1 << INTERNODE_CACHE_SHIFT);
 +}
-+#endif
 +
 +#define dma_is_consistent(d)	(1)
 +
@@ -66945,9 +73000,9 @@
 +				  dma_addr_t device_addr, size_t size);
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/fixmap.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/fixmap.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/fixmap.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/fixmap.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/fixmap.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/fixmap.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/fixmap.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/fixmap.h	2006-07-31 23:43:29.000000000 +0200
 @@ -0,0 +1,156 @@
 +/*
 + * fixmap.h: compile-time virtual memory allocation
@@ -66964,7 +73019,6 @@
 +#ifndef _ASM_FIXMAP_H
 +#define _ASM_FIXMAP_H
 +
-+#include <linux/config.h>
 +
 +/* used by vmalloc.c, vsyscall.lds.S.
 + *
@@ -67004,6 +73058,7 @@
 + */
 +enum fixed_addresses {
 +	FIX_HOLE,
++	FIX_VDSO,
 +#ifdef CONFIG_X86_LOCAL_APIC
 +	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
 +#endif
@@ -67105,9 +73160,9 @@
 +
 +#endif /* !__ASSEMBLY__ */
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/floppy.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/floppy.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/floppy.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/floppy.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/floppy.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/floppy.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/floppy.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/floppy.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,147 @@
 +/*
 + * Architecture specific parts of the Floppy driver
@@ -67199,8 +73254,8 @@
 +
 +static int fd_request_irq(void)
 +{
-+	return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
-+					   "floppy", NULL);
++	return request_irq(FLOPPY_IRQ, floppy_hardint,
++			   IRQF_DISABLED, "floppy", NULL);
 +}
 +
 +static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
@@ -67256,10 +73311,10 @@
 +#define EXTRA_FLOPPY_PARAMS
 +
 +#endif /* __ASM_XEN_I386_FLOPPY_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/highmem.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/highmem.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/highmem.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/highmem.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,81 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/highmem.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/highmem.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/highmem.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/highmem.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,80 @@
 +/*
 + * highmem.h: virtual kernel memory mappings for high memory
 + *
@@ -67282,7 +73337,6 @@
 +
 +#ifdef __KERNEL__
 +
-+#include <linux/config.h>
 +#include <linux/interrupt.h>
 +#include <linux/threads.h>
 +#include <asm/kmap_types.h>
@@ -67341,10 +73395,10 @@
 +#endif /* __KERNEL__ */
 +
 +#endif /* _ASM_HIGHMEM_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/hw_irq.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/hw_irq.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/hw_irq.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,77 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/hw_irq.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/hw_irq.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/hw_irq.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,72 @@
 +#ifndef _ASM_HW_IRQ_H
 +#define _ASM_HW_IRQ_H
 +
@@ -67359,7 +73413,6 @@
 + *	<tomsoft at informatik.tu-chemnitz.de>
 + */
 +
-+#include <linux/config.h>
 +#include <linux/profile.h>
 +#include <asm/atomic.h>
 +#include <asm/irq.h>
@@ -67367,6 +73420,8 @@
 +
 +struct hw_interrupt_type;
 +
++#define NMI_VECTOR		0x02
++
 +/*
 + * Various low-level irq details needed by irq.c, process.c,
 + * time.c, io_apic.c and smp.c
@@ -67415,17 +73470,11 @@
 +
 +#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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/hypercall.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/hypercall.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/hypercall.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/hypercall.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,372 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/hypercall.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/hypercall.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/hypercall.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/hypercall.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,389 @@
 +/******************************************************************************
 + * hypercall.h
 + * 
@@ -67470,11 +73519,21 @@
 +#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 (				\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)		\
 +		: "=a" (__res)			\
 +		:				\
 +		: "memory" );			\
@@ -67485,7 +73544,7 @@
 +({								\
 +	long __res, __ign1;					\
 +	asm volatile (						\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=b" (__ign1)			\
 +		: "1" ((long)(a1))				\
 +		: "memory" );					\
@@ -67496,7 +73555,7 @@
 +({								\
 +	long __res, __ign1, __ign2;				\
 +	asm volatile (						\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=b" (__ign1), "=c" (__ign2)	\
 +		: "1" ((long)(a1)), "2" ((long)(a2))		\
 +		: "memory" );					\
@@ -67507,7 +73566,7 @@
 +({								\
 +	long __res, __ign1, __ign2, __ign3;			\
 +	asm volatile (						\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=b" (__ign1), "=c" (__ign2), 	\
 +		"=d" (__ign3)					\
 +		: "1" ((long)(a1)), "2" ((long)(a2)),		\
@@ -67520,7 +73579,7 @@
 +({								\
 +	long __res, __ign1, __ign2, __ign3, __ign4;		\
 +	asm volatile (						\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=b" (__ign1), "=c" (__ign2),	\
 +		"=d" (__ign3), "=S" (__ign4)			\
 +		: "1" ((long)(a1)), "2" ((long)(a2)),		\
@@ -67533,7 +73592,7 @@
 +({								\
 +	long __res, __ign1, __ign2, __ign3, __ign4, __ign5;	\
 +	asm volatile (						\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=b" (__ign1), "=c" (__ign2),	\
 +		"=d" (__ign3), "=S" (__ign4), "=D" (__ign5)	\
 +		: "1" ((long)(a1)), "2" ((long)(a2)),		\
@@ -67782,6 +73841,13 @@
 +	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)
@@ -67798,10 +73864,10 @@
 +
 +
 +#endif /* __HYPERCALL_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/hypervisor.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/hypervisor.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/hypervisor.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/hypervisor.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,226 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/hypervisor.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/hypervisor.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/hypervisor.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/hypervisor.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,234 @@
 +/******************************************************************************
 + * hypervisor.h
 + * 
@@ -67837,7 +73903,6 @@
 +#ifndef __HYPERVISOR_H__
 +#define __HYPERVISOR_H__
 +
-+#include <linux/config.h>
 +#include <linux/types.h>
 +#include <linux/kernel.h>
 +#include <linux/version.h>
@@ -67862,6 +73927,11 @@
 +
 +/* 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. */
@@ -67991,16 +74061,24 @@
 +    mcl->args[0] = va;
 +#if defined(CONFIG_X86_64)
 +    mcl->args[1] = new_val.pte;
-+    mcl->args[2] = flags;
 +#elif defined(CONFIG_X86_PAE)
 +    mcl->args[1] = new_val.pte_low;
 +    mcl->args[2] = new_val.pte_high;
-+    mcl->args[3] = flags;
 +#else
 +    mcl->args[1] = new_val.pte_low;
 +    mcl->args[2] = 0;
-+    mcl->args[3] = flags;
 +#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
@@ -68012,30 +74090,25 @@
 +    mcl->args[0] = va;
 +#if defined(CONFIG_X86_64)
 +    mcl->args[1] = new_val.pte;
-+    mcl->args[2] = flags;
-+    mcl->args[3] = domid;
 +#elif defined(CONFIG_X86_PAE)
 +    mcl->args[1] = new_val.pte_low;
 +    mcl->args[2] = new_val.pte_high;
-+    mcl->args[3] = flags;
-+    mcl->args[4] = domid;
 +#else
 +    mcl->args[1] = new_val.pte_low;
 +    mcl->args[2] = 0;
-+    mcl->args[3] = flags;
-+    mcl->args[4] = domid;
 +#endif
++    mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
++    mcl->args[MULTI_UVMDOMID_INDEX] = domid;
 +}
 +
 +#endif /* __HYPERVISOR_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/io.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/io.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/io.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/io.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,390 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/io.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/io.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/io.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/io.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,389 @@
 +#ifndef _ASM_IO_H
 +#define _ASM_IO_H
 +
-+#include <linux/config.h>
 +#include <linux/string.h>
 +#include <linux/compiler.h>
 +
@@ -68422,14 +74495,97 @@
 +#define ARCH_HAS_DEV_MEM
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/kmap_types.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/kmap_types.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/kmap_types.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/kmap_types.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,32 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/irqflags.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/irqflags.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/irqflags.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/irqflags.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,80 @@
++/*
++ * include/asm-i386/irqflags.h
++ *
++ * IRQ flags handling
++ *
++ * This file gets included from lowlevel asm headers too, to provide
++ * wrapped versions of the local_irq_*() APIs, based on the
++ * raw_local_irq_*() functions from the lowlevel headers.
++ */
++#ifndef _ASM_IRQFLAGS_H
++#define _ASM_IRQFLAGS_H
++
++#ifndef __ASSEMBLY__
++
++#define raw_local_save_flags(flags) \
++		do { (flags) = __raw_local_save_flags(); } while (0)
++
++unsigned long __raw_local_save_flags(void);
++void raw_local_irq_restore(unsigned long flags);
++void raw_local_irq_disable(void);
++void raw_local_irq_enable(void);
++
++/*
++ * Used in the idle loop; sti takes one instruction cycle
++ * to complete:
++ */
++void raw_safe_halt(void);
++
++/*
++ * Used when interrupts are already enabled or to
++ * shutdown the processor:
++ */
++void halt(void);
++
++static inline int raw_irqs_disabled_flags(unsigned long flags)
++{
++	return flags != 0;
++}
++
++int raw_irqs_disabled(void);
++
++/*
++ * For spinlocks, etc:
++ */
++unsigned long __raw_local_irq_save(void);
++#define raw_local_irq_save(flags) \
++		do { (flags) = __raw_local_irq_save(); } while (0)
++
++#endif /* __ASSEMBLY__ */
++
++/*
++ * Do the CPU's IRQ-state tracing from assembly code. We call a
++ * C function, so save all the C-clobbered registers:
++ */
++#ifdef CONFIG_TRACE_IRQFLAGS
++
++# define TRACE_IRQS_ON				\
++	pushl %eax;				\
++	pushl %ecx;				\
++	pushl %edx;				\
++	call trace_hardirqs_on;			\
++	popl %edx;				\
++	popl %ecx;				\
++	popl %eax;
++
++# define TRACE_IRQS_OFF				\
++	pushl %eax;				\
++	pushl %ecx;				\
++	pushl %edx;				\
++	call trace_hardirqs_off;		\
++	popl %edx;				\
++	popl %ecx;				\
++	popl %eax;
++
++#else
++# define TRACE_IRQS_ON
++# define TRACE_IRQS_OFF
++#endif
++
++#endif
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/kmap_types.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/kmap_types.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/kmap_types.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/kmap_types.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,31 @@
 +#ifndef _ASM_KMAP_TYPES_H
 +#define _ASM_KMAP_TYPES_H
 +
-+#include <linux/config.h>
 +
 +#ifdef CONFIG_DEBUG_HIGHMEM
 +# define D(n) __KM_FENCE_##n ,
@@ -68458,14 +74614,177 @@
 +#undef D
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/mmu_context.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/mmu_context.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/mmu_context.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/maddr.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/maddr.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/maddr.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/maddr.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,160 @@
++#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)
++
++#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;
++}
++
++
++#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)
++
++#endif /* !CONFIG_XEN */
++
++/* 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
++
++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;
++}
++
++/* 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/mmu_context.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/mmu_context.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/mmu_context.h	2006-08-14 15:07:21.000000000 +0200
 @@ -0,0 +1,108 @@
 +#ifndef __I386_SCHED_H
 +#define __I386_SCHED_H
 +
-+#include <linux/config.h>
 +#include <asm/desc.h>
 +#include <asm/atomic.h>
 +#include <asm/pgalloc.h>
@@ -68515,7 +74834,8 @@
 +	struct mmuext_op _op[2], *op = _op;
 +
 +	if (likely(prev != next)) {
-+		BUG_ON(!test_bit(PG_pinned, &virt_to_page(next->pgd)->flags));
++		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);
@@ -68570,10 +74890,10 @@
 +}
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/mmu.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/mmu.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/mmu.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/mmu.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,25 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/mmu.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/mmu.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/mmu.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/mmu.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,29 @@
 +#ifndef __i386_MMU_H
 +#define __i386_MMU_H
 +
@@ -68588,6 +74908,10 @@
 +	int size;
 +	struct semaphore sem;
 +	void *ldt;
++	void *vdso;
++#ifdef CONFIG_XEN
++	int has_foreign_mappings;
++#endif
 +} mm_context_t;
 +
 +/* mm/memory.c:exit_mmap hook */
@@ -68599,10 +74923,10 @@
 +#define arch_dup_mmap(mm, oldmm) ((void)(oldmm), _arch_dup_mmap(mm))
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/page.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/page.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/page.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/page.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,336 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/page.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/page.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/page.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/page.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,220 @@
 +#ifndef _I386_PAGE_H
 +#define _I386_PAGE_H
 +
@@ -68617,7 +74941,6 @@
 +#ifdef __KERNEL__
 +#ifndef __ASSEMBLY__
 +
-+#include <linux/config.h>
 +#include <linux/string.h>
 +#include <linux/types.h>
 +#include <linux/kernel.h>
@@ -68642,145 +74965,28 @@
 +
 +#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)
-+
-+/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
-+#define INVALID_P2M_ENTRY	(~0UL)
-+#define FOREIGN_FRAME_BIT	(1UL<<31)
-+#define FOREIGN_FRAME(m)	((m) | FOREIGN_FRAME_BIT)
-+
-+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;
-+}
++#include <asm/mmx.h>
 +
-+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;
-+}
++#define clear_page(page)	mmx_clear_page((void *)(page))
++#define copy_page(to,from)	mmx_copy_page(to,from)
 +
-+/* 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;
++
++#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
 +
-+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;
-+}
++#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..
@@ -68792,6 +74998,8 @@
 +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)}); })
@@ -68832,6 +75040,8 @@
 +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) ? machine_to_phys((x).pte_low) : \
 +			 (x).pte_low)
@@ -68857,9 +75067,6 @@
 +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
 +#endif
 +
-+#define pgprot_val(x)	((x).pgprot)
-+
-+#define __pte_ma(x)	((pte_t) { (x) } )
 +#define __pgprot(x)	((pgprot_t) { (x) } )
 +
 +#endif /* !__ASSEMBLY__ */
@@ -68882,6 +75089,8 @@
 +
 +#ifndef __ASSEMBLY__
 +
++struct vm_area_struct;
++
 +/*
 + * This much address space is reserved for vmalloc() and iomap()
 + * as well as fixmap mappings.
@@ -68931,23 +75140,21 @@
 +#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 __HAVE_ARCH_GATE_AREA 1
-+
-+#endif /* __KERNEL__ */
-+
 +#include <asm-generic/memory_model.h>
 +#include <asm-generic/page.h>
 +
++#define __HAVE_ARCH_GATE_AREA 1
++#endif /* __KERNEL__ */
++
 +#endif /* _I386_PAGE_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/param.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/param.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/param.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/param.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,24 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/param.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/param.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/param.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/param.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,23 @@
 +#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() */
@@ -68967,14 +75174,13 @@
 +#define COMMAND_LINE_SIZE 256
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/pci.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pci.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/pci.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pci.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,154 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pci.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pci.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pci.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pci.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,153 @@
 +#ifndef __i386_PCI_H
 +#define __i386_PCI_H
 +
-+#include <linux/config.h>
 +
 +#ifdef __KERNEL__
 +#include <linux/mm.h>		/* for struct page */
@@ -69125,14 +75331,13 @@
 +#define pcibios_scan_all_fns(a, b)	1
 +
 +#endif /* __i386_PCI_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/pgalloc.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgalloc.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgalloc.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,64 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgalloc.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgalloc.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgalloc.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,63 @@
 +#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 */
@@ -69193,9 +75398,9 @@
 +#define check_pgt_cache()	do { } while (0)
 +
 +#endif /* _I386_PGALLOC_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,21 @@
 +#ifndef _I386_PGTABLE_2LEVEL_DEFS_H
 +#define _I386_PGTABLE_2LEVEL_DEFS_H
@@ -69218,10 +75423,10 @@
 +#define PTRS_PER_PTE	1024
 +
 +#endif /* _I386_PGTABLE_2LEVEL_DEFS_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable-2level.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable-2level.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable-2level.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable-2level.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,88 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable-2level.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable-2level.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable-2level.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable-2level.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,87 @@
 +#ifndef _I386_PGTABLE_2LEVEL_H
 +#define _I386_PGTABLE_2LEVEL_H
 +
@@ -69269,7 +75474,6 @@
 +
 +#define pte_none(x)		(!(x).pte_low)
 +#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
-+#define pfn_pte_ma(pfn, prot)	__pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 +#define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 +
 +/*
@@ -69310,9 +75514,9 @@
 +void vmalloc_sync_all(void);
 +
 +#endif /* _I386_PGTABLE_2LEVEL_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,25 @@
 +#ifndef _I386_PGTABLE_3LEVEL_DEFS_H
 +#define _I386_PGTABLE_3LEVEL_DEFS_H
@@ -69339,10 +75543,10 @@
 +#define PTRS_PER_PTE	512
 +
 +#endif /* _I386_PGTABLE_3LEVEL_DEFS_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable-3level.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable-3level.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable-3level.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable-3level.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,197 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable-3level.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable-3level.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable-3level.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable-3level.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,185 @@
 +#ifndef _I386_PGTABLE_3LEVEL_H
 +#define _I386_PGTABLE_3LEVEL_H
 +
@@ -69464,7 +75668,7 @@
 +	ptep->pte_high = 0;
 +}
 +
-+#define pmd_clear(xp)do { set_pmd(xp, __pmd(0)); } while (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)
 +{
@@ -69496,18 +75700,6 @@
 +
 +extern unsigned long long __supported_pte_mask;
 +
-+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;
-+}
-+
 +static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
 +{
 +	return pfn_pte_ma(pfn_to_mfn(page_nr), pgprot);
@@ -69540,14 +75732,13 @@
 +#define vmalloc_sync_all() ((void)0)
 +
 +#endif /* _I386_PGTABLE_3LEVEL_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/pgtable.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/pgtable.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,509 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/pgtable.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/pgtable.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,508 @@
 +#ifndef _I386_PGTABLE_H
 +#define _I386_PGTABLE_H
 +
-+#include <linux/config.h>
 +#include <asm/hypervisor.h>
 +
 +/*
@@ -70053,10 +76244,10 @@
 +#include <asm-generic/pgtable.h>
 +
 +#endif /* _I386_PGTABLE_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/processor.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/processor.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/processor.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/processor.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,753 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/processor.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/processor.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/processor.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/processor.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,741 @@
 +/*
 + * include/asm-i386/processor.h
 + *
@@ -70076,7 +76267,6 @@
 +#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 <linux/cpumask.h>
@@ -70132,8 +76322,12 @@
 +	cpumask_t llc_shared_map;	/* cpus sharing the last level cache */
 +#endif
 +	unsigned char x86_max_cores;	/* cpuid returned max cores value */
-+	unsigned char booted_cores;	/* number of cores as seen by OS */
 +	unsigned char apicid;
++#ifdef CONFIG_SMP
++	unsigned char booted_cores;	/* number of cores as seen by OS */
++	__u8 phys_proc_id; 		/* Physical processor id. */
++	__u8 cpu_core_id;  		/* Core id */
++#endif
 +} __attribute__((__aligned__(SMP_CACHE_BYTES)));
 +
 +#define X86_VENDOR_INTEL 0
@@ -70167,14 +76361,13 @@
 +#define current_cpu_data boot_cpu_data
 +#endif
 +
-+extern	int phys_proc_id[NR_CPUS];
-+extern	int cpu_core_id[NR_CPUS];
 +extern	int cpu_llc_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);
++extern unsigned short num_cache_leaves;
 +
 +#ifdef CONFIG_X86_HT
 +extern void detect_ht(struct cpuinfo_x86 *c);
@@ -70621,7 +76814,7 @@
 +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);
++void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack);
 +
 +unsigned long get_wchan(struct task_struct *p);
 +
@@ -70795,24 +76988,10 @@
 +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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/ptrace.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/ptrace.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/ptrace.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/ptrace.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/ptrace.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/ptrace.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/ptrace.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/ptrace.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,90 @@
 +#ifndef _I386_PTRACE_H
 +#define _I386_PTRACE_H
@@ -70904,9 +77083,9 @@
 +#endif /* __KERNEL__ */
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/scatterlist.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/scatterlist.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/scatterlist.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/scatterlist.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/scatterlist.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/scatterlist.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/scatterlist.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/scatterlist.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,22 @@
 +#ifndef _I386_SCATTERLIST_H
 +#define _I386_SCATTERLIST_H
@@ -70930,9 +77109,9 @@
 +#define ISA_DMA_THRESHOLD (0x00ffffff)
 +
 +#endif /* !(_I386_SCATTERLIST_H) */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/segment.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/segment.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/segment.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/segment.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/segment.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/segment.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/segment.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/segment.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,117 @@
 +#ifndef _ASM_SEGMENT_H
 +#define _ASM_SEGMENT_H
@@ -71051,10 +77230,10 @@
 +#define IDT_ENTRIES 256
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/setup.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/setup.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/setup.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/setup.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,64 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/setup.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/setup.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/setup.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/setup.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,79 @@
 +/*
 + *	Just a place holder. We don't want to have to test x86 before
 + *	we include stuff
@@ -71116,13 +77295,28 @@
 +#define EDD_MBR_SIGNATURE ((unsigned int *) (PARAM+EDD_MBR_SIG_BUF))
 +#define EDD_BUF     ((struct edd_info *) (PARAM+EDDBUF))
 +
++/*
++ * Do NOT EVER look at the BIOS memory size location.
++ * It does not work on many machines.
++ */
++#define LOWMEMSIZE()	(0x9f000)
++
++struct e820entry;
++
++char * __init machine_specific_memory_setup(void);
++
++int __init copy_e820_map(struct e820entry * biosmap, int nr_map);
++int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map);
++void __init add_memory_region(unsigned long long start,
++			      unsigned long long size, int type);
++
 +#endif /* __ASSEMBLY__ */
 +
 +#endif /* _i386_SETUP_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/smp.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/smp.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/smp.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/smp.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,104 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/smp.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/smp.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/smp.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/smp.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,103 @@
 +#ifndef __ASM_SMP_H
 +#define __ASM_SMP_H
 +
@@ -71130,7 +77324,6 @@
 + * 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>
@@ -71227,17 +77420,16 @@
 +
 +#endif
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/spinlock.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/spinlock.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/spinlock.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/spinlock.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,200 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/spinlock.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/spinlock.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/spinlock.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/spinlock.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,199 @@
 +#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>
 +
 +/*
@@ -71431,15 +77623,13 @@
 +}
 +
 +#endif /* __ASM_SPINLOCK_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/swiotlb.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/swiotlb.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/swiotlb.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/swiotlb.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,43 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/swiotlb.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/swiotlb.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/swiotlb.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/swiotlb.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,41 @@
 +#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,
@@ -71478,10 +77668,10 @@
 +#endif
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/synch_bitops.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/synch_bitops.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/synch_bitops.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/synch_bitops.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,143 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/synch_bitops.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/synch_bitops.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/synch_bitops.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/synch_bitops.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,141 @@
 +#ifndef __XEN_SYNCH_BITOPS_H__
 +#define __XEN_SYNCH_BITOPS_H__
 +
@@ -71491,8 +77681,6 @@
 + * 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)
@@ -71625,14 +77813,13 @@
 +#define synch_cmpxchg_subword synch_cmpxchg
 +
 +#endif /* __XEN_SYNCH_BITOPS_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/system.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/system.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/system.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/system.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,578 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/system.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/system.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/system.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/system.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,489 @@
 +#ifndef __ASM_SYSTEM_H
 +#define __ASM_SYSTEM_H
 +
-+#include <linux/config.h>
 +#include <linux/kernel.h>
 +#include <asm/segment.h>
 +#include <asm/cpufeature.h>
@@ -71722,10 +77909,6 @@
 +#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__( \
@@ -71734,12 +77917,12 @@
 +	__dummy; \
 +})
 +#define write_cr0(x) \
-+	__asm__ __volatile__("movl %0,%%cr0": :"r" (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));
++	__asm__ __volatile__("movl %0,%%cr2": :"r" (x))
 +
 +#define read_cr3() ({ \
 +	unsigned int __dummy; \
@@ -71762,7 +77945,6 @@
 +		:"=r" (__dummy)); \
 +	__dummy; \
 +})
-+
 +#define read_cr4_safe() ({			      \
 +	unsigned int __dummy;			      \
 +	/* This could fault if %cr4 does not exist */ \
@@ -71776,13 +77958,17 @@
 +})
 +
 +#define write_cr4(x) \
-+	__asm__ __volatile__("movl %0,%%cr4": :"r" (x));
++	__asm__ __volatile__("movl %0,%%cr4": :"r" (x))
++/*
++ * Clear and set 'TS' bit respectively
++ */
++#define clts() (HYPERVISOR_fpu_taskswitch(0))
 +#define stts() (HYPERVISOR_fpu_taskswitch(1))
 +
 +#endif	/* __KERNEL__ */
 +
 +#define wbinvd() \
-+	__asm__ __volatile__ ("wbinvd": : :"memory");
++	__asm__ __volatile__ ("wbinvd": : :"memory")
 +
 +static inline unsigned long get_limit(unsigned long segment)
 +{
@@ -72066,7 +78252,7 @@
 + * 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.
++ * in cases like this where there are no data dependencies.
 + **/
 +
 +#define read_barrier_depends()	do { } while(0)
@@ -72093,94 +78279,7 @@
 +#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; })
++#include <linux/irqflags.h>
 +
 +/*
 + * disable hlt during certain critical i/o operations
@@ -72207,14 +78306,87 @@
 +void default_idle(void);
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/tlbflush.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/tlbflush.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/tlbflush.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/tlbflush.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,102 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/timer.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/timer.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/timer.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/timer.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,70 @@
++#ifndef _ASMi386_TIMER_H
++#define _ASMi386_TIMER_H
++#include <linux/init.h>
++#include <linux/pm.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 unsigned long read_timer_tsc(void);
++extern void init_cpu_khz(void);
++extern int recalibrate_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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/tlbflush.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/tlbflush.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/tlbflush.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/tlbflush.h	2006-07-20 15:57:27.000000000 +0200
+@@ -0,0 +1,101 @@
 +#ifndef _I386_TLBFLUSH_H
 +#define _I386_TLBFLUSH_H
 +
-+#include <linux/config.h>
 +#include <linux/mm.h>
 +#include <asm/processor.h>
 +
@@ -72313,9 +78485,9 @@
 +}
 +
 +#endif /* _I386_TLBFLUSH_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/asm/vga.h linux-2.6.17-xen/include/asm-i386/mach-xen/asm/vga.h
---- linux-2.6.17/include/asm-i386/mach-xen/asm/vga.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/asm/vga.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/vga.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/vga.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/asm/vga.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/asm/vga.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,20 @@
 +/*
 + *	Access to VGA videoram
@@ -72331,15 +78503,15 @@
 + *	access the videoram directly without any black magic.
 + */
 +
-+#define VGA_MAP_MEM(x) (unsigned long)isa_bus_to_virt(x)
++#define VGA_MAP_MEM(x,s) (unsigned long)isa_bus_to_virt(x)
 +
 +#define vga_readb(x) (*(x))
 +#define vga_writeb(x,y) (*(y) = (x))
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/irq_vectors.h linux-2.6.17-xen/include/asm-i386/mach-xen/irq_vectors.h
---- linux-2.6.17/include/asm-i386/mach-xen/irq_vectors.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/irq_vectors.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/irq_vectors.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/irq_vectors.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/irq_vectors.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/irq_vectors.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,125 @@
 +/*
 + * This file should contain #defines for all of the interrupt vector
@@ -72466,9 +78638,9 @@
 +#define irq_to_dynirq(_x)	((_x) - DYNIRQ_BASE)
 +
 +#endif /* _ASM_IRQ_VECTORS_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/mach_traps.h linux-2.6.17-xen/include/asm-i386/mach-xen/mach_traps.h
---- linux-2.6.17/include/asm-i386/mach-xen/mach_traps.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/mach_traps.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/mach_traps.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/mach_traps.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/mach_traps.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/mach_traps.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,33 @@
 +/*
 + *  include/asm-xen/asm-i386/mach-xen/mach_traps.h
@@ -72503,124 +78675,19 @@
 +static inline void reassert_nmi(void) {}
 +
 +#endif /* !_MACH_TRAPS_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/setup_arch_post.h linux-2.6.17-xen/include/asm-i386/mach-xen/setup_arch_post.h
---- linux-2.6.17/include/asm-i386/mach-xen/setup_arch_post.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/setup_arch_post.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,101 @@
-+/**
-+ * 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;
-+	struct callback_register event = {
-+		.type = CALLBACKTYPE_event,
-+		.address = { __KERNEL_CS, (unsigned long)hypervisor_callback },
-+	};
-+	struct callback_register failsafe = {
-+		.type = CALLBACKTYPE_failsafe,
-+		.address = { __KERNEL_CS, (unsigned long)failsafe_callback },
-+	};
-+	struct callback_register 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);
-+	if (ret == -ENOSYS)
-+		ret = HYPERVISOR_set_callbacks(
-+			event.address.cs, event.address.eip,
-+			failsafe.address.cs, failsafe.address.eip);
-+	BUG_ON(ret);
-+
-+	ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
-+	if (ret == -ENOSYS) {
-+		struct xennmi_callback cb;
-+
-+		cb.handler_address = nmi_cb.address.eip;
-+		HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
-+	}
-+
-+	if (HYPERVISOR_xen_version(XENVER_platform_parameters,
-+				   &pp) == 0)
-+		set_fixaddr_top(pp.virt_start - PAGE_SIZE);
-+
-+	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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/mach-xen/setup_arch_pre.h linux-2.6.17-xen/include/asm-i386/mach-xen/setup_arch_pre.h
---- linux-2.6.17/include/asm-i386/mach-xen/setup_arch_pre.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-i386/mach-xen/setup_arch_pre.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/mach-xen/setup_arch.h linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/setup_arch.h
+--- linux-2.6.18-rc5/include/asm-i386/mach-xen/setup_arch.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-i386/mach-xen/setup_arch.h	2006-09-01 00:09:11.000000000 +0200
 @@ -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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/page.h linux-2.6.17-xen/include/asm-i386/page.h
---- linux-2.6.17/include/asm-i386/page.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-i386/page.h	2006-08-14 15:58:15.000000000 +0200
-@@ -121,7 +121,7 @@
++void __init machine_specific_arch_setup(void);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/page.h linux-2.6.18-rc5-xen/include/asm-i386/page.h
+--- linux-2.6.18-rc5/include/asm-i386/page.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-i386/page.h	2006-07-20 15:57:27.000000000 +0200
+@@ -122,7 +122,7 @@
  
  #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
  #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
@@ -72629,18 +78696,9 @@
  #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)
-@@ -137,6 +137,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/memory_model.h>
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/pgtable-2level-defs.h linux-2.6.17-xen/include/asm-i386/pgtable-2level-defs.h
---- linux-2.6.17/include/asm-i386/pgtable-2level-defs.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-i386/pgtable-2level-defs.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/pgtable-2level-defs.h linux-2.6.18-rc5-xen/include/asm-i386/pgtable-2level-defs.h
+--- linux-2.6.18-rc5/include/asm-i386/pgtable-2level-defs.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-i386/pgtable-2level-defs.h	2006-07-20 15:57:27.000000000 +0200
 @@ -1,6 +1,8 @@
  #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
  #define _I386_PGTABLE_2LEVEL_DEFS_H
@@ -72650,9 +78708,9 @@
  /*
   * traditional i386 two-level paging structure:
   */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-i386/pgtable-3level-defs.h linux-2.6.17-xen/include/asm-i386/pgtable-3level-defs.h
---- linux-2.6.17/include/asm-i386/pgtable-3level-defs.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-i386/pgtable-3level-defs.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-i386/pgtable-3level-defs.h linux-2.6.18-rc5-xen/include/asm-i386/pgtable-3level-defs.h
+--- linux-2.6.18-rc5/include/asm-i386/pgtable-3level-defs.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-i386/pgtable-3level-defs.h	2006-07-20 15:57:27.000000000 +0200
 @@ -1,6 +1,8 @@
  #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
  #define _I386_PGTABLE_3LEVEL_DEFS_H
@@ -72662,28 +78720,18 @@
  /*
   * PGDIR_SHIFT determines what a top-level page table entry can map
   */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/agp.h linux-2.6.17-xen/include/asm-ia64/agp.h
---- linux-2.6.17/include/asm-ia64/agp.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/agp.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/agp.h linux-2.6.18-rc5-xen/include/asm-ia64/agp.h
+--- linux-2.6.18-rc5/include/asm-ia64/agp.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/agp.h	2006-08-14 15:07:21.000000000 +0200
 @@ -19,13 +19,44 @@
  #define flush_agp_cache()		mb()
  
  /* Convert a physical address to an address suitable for the GART. */
-+#ifndef CONFIG_XEN_IA64_DOM0_VP
- #define phys_to_gart(x) (x)
- #define gart_to_phys(x) (x)
-+#else
++#ifdef CONFIG_XEN
 +#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_IA64_DOM0_VP
- #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
++
++/* GATT allocation. Returns/accepts GATT kernel virtual address. */
 +#include <asm/hypervisor.h>
 +static inline char*
 +alloc_gatt_pages(unsigned int order)
@@ -72707,32 +78755,65 @@
 +	xen_destroy_contiguous_region((unsigned long)table, order);
 +	free_pages((unsigned long)table, order);
 +}
-+#endif /* CONFIG_XEN_IA64_DOM0_VP */
++#else	/* CONFIG_XEN */
++/* Convert a physical address to an address suitable for the GART. */
+ #define phys_to_gart(x) (x)
+ #define gart_to_phys(x) (x)
+ 
+ /* GATT allocation. Returns/accepts GATT kernel virtual address. */
+-#define alloc_gatt_pages(order)		\
+-	((char *)__get_free_pages(GFP_KERNEL, (order)))
+-#define free_gatt_pages(table, order)	\
+-	free_pages((unsigned long)(table), (order))
++#define alloc_gatt_pages(order)         \
++        ((char *)__get_free_pages(GFP_KERNEL, (order)))
++#define free_gatt_pages(table, order)   \
++        free_pages((unsigned long)(table), (order))
++#endif	/* CONFIG_XEN */
  
  #endif /* _ASM_IA64_AGP_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/dma-mapping.h linux-2.6.17-xen/include/asm-ia64/dma-mapping.h
---- linux-2.6.17/include/asm-ia64/dma-mapping.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/dma-mapping.h	2006-08-14 15:58:15.000000000 +0200
-@@ -7,7 +7,14 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/dma-mapping.h linux-2.6.18-rc5-xen/include/asm-ia64/dma-mapping.h
+--- linux-2.6.18-rc5/include/asm-ia64/dma-mapping.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/dma-mapping.h	2006-08-14 15:07:21.000000000 +0200
+@@ -7,19 +7,68 @@
   */
- #include <linux/config.h>
  #include <asm/machvec.h>
-+#ifdef CONFIG_XEN_IA64_DOM0_VP
+ 
+-#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
+-#define dma_free_noncoherent	platform_dma_free_coherent
+-#define dma_map_single		platform_dma_map_single
+-#define dma_map_sg		platform_dma_map_sg
+-#define dma_unmap_single	platform_dma_unmap_single
+-#define dma_unmap_sg		platform_dma_unmap_sg
+-#define dma_sync_single_for_cpu	platform_dma_sync_single_for_cpu
+-#define dma_sync_sg_for_cpu	platform_dma_sync_sg_for_cpu
++#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
++#define dma_free_noncoherent    platform_dma_free_coherent
++#define dma_map_single          platform_dma_map_single
++#define dma_map_sg              platform_dma_map_sg
++#define dma_unmap_single        platform_dma_unmap_single
++#define dma_unmap_sg            platform_dma_unmap_sg
++#define dma_sync_single_for_cpu platform_dma_sync_single_for_cpu
++#define dma_sync_sg_for_cpu     platform_dma_sync_sg_for_cpu
+ #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
++#define dma_sync_sg_for_device  platform_dma_sync_sg_for_device
++#define dma_mapping_error       platform_dma_mapping_error
++
++
++#else /* 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_IA64_DOM0_VP
- #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,
@@ -72771,15 +78852,15 @@
 +		swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
 +	flush_write_buffers();
 +}
-+#endif
++#endif /* CONFIG_XEN */
  
  #define dma_map_page(dev, pg, off, size, dir)				\
  	dma_map_single(dev, page_address(pg) + (off), (size), (dir))
-@@ -62,4 +109,29 @@
+@@ -61,4 +110,29 @@
  
  #define dma_is_consistent(dma_handle)	(1)	/* all we do is coherent memory... */
  
-+#ifdef CONFIG_XEN_IA64_DOM0_VP
++#ifdef CONFIG_XEN
 +/* arch/i386/kernel/swiotlb.o requires */
 +void contiguous_bitmap_init(unsigned long end_pfn);
 +
@@ -72792,6 +78873,9 @@
 +		mask = *hwdev->dma_mask;
 +	return (addr & ~mask) != 0;
 +}
++#else
++#define contiguous_bitmap_init(end_pfn)	((void)end_pfn)
++#endif
 +
 +static inline int
 +range_straddles_page_boundary(void *p, size_t size)
@@ -72800,20 +78884,17 @@
 +	return (((((unsigned long)p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
 +	        !test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap));
 +}
-+#else
-+#define contiguous_bitmap_init(end_pfn)	((void)end_pfn)
-+#endif
 +
  #endif /* _ASM_IA64_DMA_MAPPING_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/fixmap.h linux-2.6.17-xen/include/asm-ia64/fixmap.h
---- linux-2.6.17/include/asm-ia64/fixmap.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-ia64/fixmap.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/fixmap.h linux-2.6.18-rc5-xen/include/asm-ia64/fixmap.h
+--- linux-2.6.18-rc5/include/asm-ia64/fixmap.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-ia64/fixmap.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,2 @@
 +#define clear_fixmap(x)	do {} while (0)
 +#define	set_fixmap(x,y)	do {} while (0)
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/gcc_intrin.h linux-2.6.17-xen/include/asm-ia64/gcc_intrin.h
---- linux-2.6.17/include/asm-ia64/gcc_intrin.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/gcc_intrin.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/gcc_intrin.h linux-2.6.18-rc5-xen/include/asm-ia64/gcc_intrin.h
+--- linux-2.6.18-rc5/include/asm-ia64/gcc_intrin.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/gcc_intrin.h	2006-07-20 15:57:27.000000000 +0200
 @@ -26,7 +26,7 @@
  
  register unsigned long ia64_r13 asm ("r13") __attribute_used__;
@@ -73003,9 +79084,9 @@
 +#define __ia64_get_psr_i()	(__ia64_getreg(_IA64_REG_PSR) & 0x4000UL)
 +
  #endif /* _ASM_IA64_GCC_INTRIN_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/hw_irq.h linux-2.6.17-xen/include/asm-ia64/hw_irq.h
---- linux-2.6.17/include/asm-ia64/hw_irq.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/hw_irq.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/hw_irq.h linux-2.6.18-rc5-xen/include/asm-ia64/hw_irq.h
+--- linux-2.6.18-rc5/include/asm-ia64/hw_irq.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/hw_irq.h	2006-07-31 23:43:29.000000000 +0200
 @@ -15,7 +15,11 @@
  #include <asm/ptrace.h>
  #include <asm/smp.h>
@@ -73018,24 +79099,23 @@
  
  /*
   * 0 special
-@@ -89,6 +93,13 @@
- static inline void
- hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
+@@ -99,6 +103,12 @@
+ 
+ static inline void ia64_resend_irq(unsigned int vector)
  {
 +#ifdef CONFIG_XEN
-+	extern void resend_irq_on_evtchn(struct hw_interrupt_type *h,
-+					 unsigned int i);
++	extern void resend_irq_on_evtchn(unsigned int i);
 +	if (is_running_on_xen())
-+		resend_irq_on_evtchn(h, vector);
++		resend_irq_on_evtchn(vector);
 +	else
 +#endif /* CONFIG_XEN */
  	platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
  }
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/hypercall.h linux-2.6.17-xen/include/asm-ia64/hypercall.h
---- linux-2.6.17/include/asm-ia64/hypercall.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-ia64/hypercall.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,533 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/hypercall.h linux-2.6.18-rc5-xen/include/asm-ia64/hypercall.h
+--- linux-2.6.18-rc5/include/asm-ia64/hypercall.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-ia64/hypercall.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,496 @@
 +/******************************************************************************
 + * hypercall.h
 + * 
@@ -73233,14 +79313,6 @@
 +    return _hypercall2(int, multicall, call_list, nr_calls);
 +}
 +
-+#ifndef CONFIG_XEN_IA64_DOM0_VP
-+static inline int
-+HYPERVISOR_memory_op(
-+    unsigned int cmd, void *arg)
-+{
-+    return _hypercall2(int, memory_op, cmd, arg);
-+}
-+#else
 +//XXX xen/ia64 copy_from_guest() is broken.
 +//    This is a temporal work around until it is fixed.
 +static inline int
@@ -73268,7 +79340,6 @@
 +    }
 +    /* NOTREACHED */
 +}
-+#endif
 +
 +static inline int
 +HYPERVISOR_event_channel_op(
@@ -73326,12 +79397,8 @@
 +{
 +    return _hypercall3(int, grant_table_op, cmd, uop, count);
 +}
-+#ifndef CONFIG_XEN_IA64_DOM0_VP
-+#define HYPERVISOR_grant_table_op(cmd, uop, count) \
-+	____HYPERVISOR_grant_table_op((cmd), (uop), (count))
-+#else
++
 +int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
-+#endif
 +
 +static inline int
 +HYPERVISOR_vcpu_op(
@@ -73340,23 +79407,7 @@
 +    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);
-+
-+	if (rc == -ENOSYS)
-+		rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
-+				 SHUTDOWN_suspend, srec);
-+
-+	return rc;
-+}
++extern int HYPERVISOR_suspend(unsigned long srec);
 +
 +static inline int
 +HYPERVISOR_callback_op(
@@ -73373,7 +79424,6 @@
 +	irq_exit();				\
 +})
 +
-+#ifdef CONFIG_XEN_IA64_DOM0_VP
 +#include <linux/err.h>
 +#include <asm/xen/privop.h>
 +
@@ -73561,18 +79611,11 @@
 +// for balloon driver
 +#define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
 +
-+#else
-+#define HYPERVISOR_ioremap(ioaddr, size)		(ioaddr)
-+#define HYPERVISOR_phystomach(gpfn)			(gpfn)
-+#define HYPERVISOR_machtophys(mfn)			(mfn)
-+#define HYPERVISOR_zap_physmap(gpfn, extent_order)	(0)
-+#define HYPERVISOR_add_physmap(gpfn, mfn, flags)	(0)
-+#endif
 +#endif /* __HYPERCALL_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/hypervisor.h linux-2.6.17-xen/include/asm-ia64/hypervisor.h
---- linux-2.6.17/include/asm-ia64/hypervisor.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-ia64/hypervisor.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,207 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/hypervisor.h linux-2.6.18-rc5-xen/include/asm-ia64/hypervisor.h
+--- linux-2.6.18-rc5/include/asm-ia64/hypervisor.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-ia64/hypervisor.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,192 @@
 +/******************************************************************************
 + * hypervisor.h
 + * 
@@ -73617,7 +79660,6 @@
 +#endif
 +
 +#ifdef CONFIG_XEN
-+#include <linux/config.h>
 +#include <linux/types.h>
 +#include <linux/kernel.h>
 +#include <linux/version.h>
@@ -73634,6 +79676,8 @@
 +extern shared_info_t *HYPERVISOR_shared_info;
 +extern start_info_t *xen_start_info;
 +
++#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
++
 +void force_evtchn_callback(void);
 +
 +/* Turn jiffies into Xen system time. XXX Implement me. */
@@ -73702,11 +79746,6 @@
 +
 +// for drivers/xen/privcmd/privcmd.c
 +#define machine_to_phys_mapping 0
-+#ifndef CONFIG_XEN_IA64_DOM0_VP
-+#define direct_remap_pfn_range(a,b,c,d,e,f) remap_pfn_range(a,b,c,d,e)
-+#define	pfn_to_mfn(x)	(x)
-+#define	mfn_to_pfn(x)	(x)
-+#else
 +struct vm_area_struct;
 +int direct_remap_pfn_range(struct vm_area_struct *vma,
 +			   unsigned long address,
@@ -73717,7 +79756,6 @@
 +struct file;
 +int privcmd_mmap(struct file * file, struct vm_area_struct * vma);
 +#define HAVE_ARCH_PRIVCMD_MMAP
-+#endif
 +
 +// for drivers/xen/balloon/balloon.c
 +#ifdef CONFIG_XEN_SCRUB_PAGES
@@ -73729,12 +79767,7 @@
 +#define __pte_ma(_x)	((pte_t) {(_x)})
 +#define phys_to_machine_mapping_valid(_x)	(1)
 +#define pfn_pte_ma(_x,_y)	__pte_ma(0)
-+#ifndef CONFIG_XEN_IA64_DOM0_VP //XXX
-+#define set_phys_to_machine(_x,_y)	do {} while (0)
-+#define xen_machphys_update(_x,_y)	do {} while (0)
-+#endif
 +
-+#ifdef CONFIG_XEN_IA64_DOM0_VP
 +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,
@@ -73768,11 +79801,6 @@
 +	mcl->result = 0;
 +}
 +
-+#else
-+#define xen_create_contiguous_region(vstart, order, address_bits)	(0)
-+#define xen_destroy_contiguous_region(vstart, order)	do {} while (0)
-+#endif
-+
 +// for debug
 +asmlinkage int xprintk(const char *fmt, ...);
 +#define xprintd(fmt, ...)	xprintk("%s:%d " fmt, __func__, __LINE__, \
@@ -73780,9 +79808,9 @@
 +#endif /* CONFIG_XEN */
 +
 +#endif /* __HYPERVISOR_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/intel_intrin.h linux-2.6.17-xen/include/asm-ia64/intel_intrin.h
---- linux-2.6.17/include/asm-ia64/intel_intrin.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/intel_intrin.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/intel_intrin.h linux-2.6.18-rc5-xen/include/asm-ia64/intel_intrin.h
+--- linux-2.6.18-rc5/include/asm-ia64/intel_intrin.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/intel_intrin.h	2006-07-20 15:57:27.000000000 +0200
 @@ -16,8 +16,10 @@
  		 	 * intrinsic
  		 	 */
@@ -73906,9 +79934,9 @@
  #define __builtin_trap()	__break(0);
  
  #endif /* _ASM_IA64_INTEL_INTRIN_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/io.h linux-2.6.17-xen/include/asm-ia64/io.h
---- linux-2.6.17/include/asm-ia64/io.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/io.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/io.h linux-2.6.18-rc5-xen/include/asm-ia64/io.h
+--- linux-2.6.18-rc5/include/asm-ia64/io.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/io.h	2006-08-14 15:07:21.000000000 +0200
 @@ -66,9 +66,11 @@
  #define PIO_RESERVED		__IA64_UNCACHED_OFFSET
  #define HAVE_ARCH_PIO_SIZE
@@ -73921,17 +79949,17 @@
  #include <asm/system.h>
  #include <asm-generic/iomap.h>
  
-@@ -95,9 +97,41 @@
+@@ -96,9 +98,41 @@
   * 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_IA64_DOM0_VP
++#ifndef CONFIG_XEN
  #define bus_to_virt	phys_to_virt
  #define virt_to_bus	virt_to_phys
  #define page_to_bus	page_to_phys
 +#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
 +#define page_to_pseudophys(page)	page_to_phys(page)
-+#else
++#else /* CONFIG_XEN */
 +#define bus_to_virt(bus)	\
 +	phys_to_virt(machine_to_phys_for_dma(bus))
 +#define virt_to_bus(virt)	\
@@ -73959,42 +79987,13 @@
 +	(((bvec_to_bus((vec1)) + (vec1)->bv_len) == bvec_to_bus((vec2))) && \
 +	 ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) ==		\
 +	  bvec_to_pseudophys((vec2))))
-+#endif
++#endif /* CONFIG_XEN */
  
  # endif /* KERNEL */
  
-@@ -416,14 +450,26 @@
- # define outl_p		outl
- #endif
- 
--extern void __iomem * ioremap(unsigned long offset, unsigned long size);
--extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
-+/*
-+ * An "address" in IO memory space is not clearly either an integer or a pointer. We will
-+ * accept both, thus the casts.
-+ *
-+ * On ia-64, we access the physical I/O memory space through the uncached kernel region.
-+ */
-+static inline void __iomem *
-+ioremap (unsigned long offset, unsigned long size)
-+{
-+	offset = HYPERVISOR_ioremap(offset, size);
-+	return (void __iomem *) (__IA64_UNCACHED_OFFSET | (offset));
-+}
- 
- static inline void
- iounmap (volatile void __iomem *addr)
- {
- }
- 
-+#define ioremap_nocache(o,s)	ioremap(o,s)
-+
- /* Use normal IO mappings for DMI */
- #define dmi_ioremap ioremap
- #define dmi_iounmap(x,l) iounmap(x)
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/iosapic.h linux-2.6.17-xen/include/asm-ia64/iosapic.h
---- linux-2.6.17/include/asm-ia64/iosapic.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/iosapic.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/iosapic.h linux-2.6.18-rc5-xen/include/asm-ia64/iosapic.h
+--- linux-2.6.18-rc5/include/asm-ia64/iosapic.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/iosapic.h	2006-07-20 15:57:27.000000000 +0200
 @@ -53,6 +53,7 @@
  
  #define NR_IOSAPICS			256
@@ -74011,9 +80010,9 @@
  
  static inline void iosapic_eoi(char __iomem *iosapic, u32 vector)
  {
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/irq.h linux-2.6.17-xen/include/asm-ia64/irq.h
---- linux-2.6.17/include/asm-ia64/irq.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/irq.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/irq.h linux-2.6.18-rc5-xen/include/asm-ia64/irq.h
+--- linux-2.6.18-rc5/include/asm-ia64/irq.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/irq.h	2006-07-20 15:57:27.000000000 +0200
 @@ -11,8 +11,39 @@
   * 02/29/00     D.Mosberger	moved most things into hw_irq.h
   */
@@ -74044,45 +80043,130 @@
 +#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 dynirq_to_irq(_x)	((_x) + DYNIRQ_BASE)
++#define irq_to_dynirq(_x)	((_x) - DYNIRQ_BASE)
++
++#define RESCHEDULE_VECTOR	0
++#define IPI_VECTOR		1
++#define NR_IPIS			2
++#endif /* CONFIG_XEN */
+ 
+ static __inline__ int
+ irq_canonicalize (int irq)
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/machvec.h linux-2.6.18-rc5-xen/include/asm-ia64/machvec.h
+--- linux-2.6.18-rc5/include/asm-ia64/machvec.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/machvec.h	2006-08-14 15:07:21.000000000 +0200
+@@ -260,6 +260,21 @@
+ #  error Unknown configuration.  Update asm-ia64/machvec.h.
+ # endif /* CONFIG_IA64_GENERIC */
+ 
++#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 /* CONFIG_XEN */
+ /*
+  * Declare default routines which aren't declared anywhere else:
+  */
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/maddr.h linux-2.6.18-rc5-xen/include/asm-ia64/maddr.h
+--- linux-2.6.18-rc5/include/asm-ia64/maddr.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-ia64/maddr.h	2006-09-01 00:09:11.000000000 +0200
+@@ -0,0 +1,81 @@
++#ifndef _ASM_IA64_MADDR_H
++#define _ASM_IA64_MADDR_H
++
++#ifndef __ASSEMBLY__
++#ifdef CONFIG_XEN
++
++#define INVALID_P2M_ENTRY	(~0UL)
++
++#include <linux/kernel.h>
++#include <asm/hypervisor.h>
++#include <xen/features.h>	// to compile netback, netfront
++typedef unsigned long maddr_t;	// to compile netback, netfront
++
++
++/* XXX xen page size != page size */
++
++static inline unsigned long
++pfn_to_mfn_for_dma(unsigned long pfn)
++{
++	unsigned long mfn;
++	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;
++}
++
++#define set_phys_to_machine(pfn, mfn) do { } while (0)
++#define xen_machphys_update(mfn, pfn) do { } while (0)
++
++/* 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 mfn_to_virt(mfn)		(__va((mfn) << PAGE_SHIFT))
++#define pfn_to_mfn(pfn)			(pfn)
++#define virt_to_mfn(virt)		(__pa(virt) >> PAGE_SHIFT)
++#define virt_to_machine(virt)		__pa(virt) // for tpmfront.c
++
++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;
++}
 +
-+#define RESCHEDULE_VECTOR	0
-+#define IPI_VECTOR		1
-+#define NR_IPIS			2
 +#endif /* CONFIG_XEN */
- 
- /*
-  * IRQ line status macro IRQ_PER_CPU is used
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/machvec.h linux-2.6.17-xen/include/asm-ia64/machvec.h
---- linux-2.6.17/include/asm-ia64/machvec.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/machvec.h	2006-08-14 15:58:15.000000000 +0200
-@@ -257,6 +257,21 @@
- #  error Unknown configuration.  Update asm-ia64/machvec.h.
- # endif /* CONFIG_IA64_GENERIC */
- 
-+#ifdef CONFIG_XEN_IA64_DOM0_VP
-+# 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 /* __ASSEMBLY__ */
 +
- /*
-  * Declare default routines which aren't declared anywhere else:
-  */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/meminit.h linux-2.6.17-xen/include/asm-ia64/meminit.h
---- linux-2.6.17/include/asm-ia64/meminit.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/meminit.h	2006-08-14 15:58:15.000000000 +0200
-@@ -17,10 +17,15 @@
++#endif /* _ASM_IA64_MADDR_H */
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/meminit.h linux-2.6.18-rc5-xen/include/asm-ia64/meminit.h
+--- linux-2.6.18-rc5/include/asm-ia64/meminit.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/meminit.h	2006-09-01 00:09:11.000000000 +0200
+@@ -16,10 +16,15 @@
   * 	- command line string
   * 	- kernel code & data
   * 	- Kernel memory map built from EFI memory map
@@ -74098,10 +80182,10 @@
  
  struct rsvd_region {
  	unsigned long start;	/* virtual address of beginning of element */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/page.h linux-2.6.17-xen/include/asm-ia64/page.h
---- linux-2.6.17/include/asm-ia64/page.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/page.h	2006-08-14 15:58:15.000000000 +0200
-@@ -127,7 +127,6 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/page.h linux-2.6.18-rc5-xen/include/asm-ia64/page.h
+--- linux-2.6.18-rc5/include/asm-ia64/page.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/page.h	2006-09-01 00:09:11.000000000 +0200
+@@ -126,7 +126,6 @@
  # define pfn_valid(pfn)		(((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
  #endif
  
@@ -74109,28 +80193,16 @@
  #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
  #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
  
-@@ -229,4 +228,127 @@
+@@ -228,4 +227,53 @@
  					 (((current->personality & READ_IMPLIES_EXEC) != 0)	\
  					  ? VM_EXEC : 0))
  
 +#ifndef __ASSEMBLY__
 +#ifdef CONFIG_XEN
 +
-+#define INVALID_P2M_ENTRY	(~0UL)
-+
-+#ifndef CONFIG_XEN_IA64_DOM0_VP
-+
-+#define virt_to_machine(v) __pa(v)
-+#define machine_to_virt(m) __va(m)
-+#define virt_to_mfn(v)	((__pa(v)) >> PAGE_SHIFT)
-+#define mfn_to_virt(m)	(__va((m) << PAGE_SHIFT))
-+
-+#else
-+
 +#include <linux/kernel.h>
 +#include <asm/hypervisor.h>
 +#include <xen/features.h>	// to compile netback, netfront
-+typedef unsigned long maddr_t;	// to compile netback, netfront
 +
 +/*
 + * XXX hack!
@@ -74169,77 +80241,15 @@
 +})
 +#define HAVE_ARCH_FREE_PAGE
 +
-+/* XXX xen page size != page size */
-+
-+static inline unsigned long
-+pfn_to_mfn_for_dma(unsigned long pfn)
-+{
-+	unsigned long mfn;
-+	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;
-+}
-+
-+#define set_phys_to_machine(pfn, mfn) do { } while (0)
-+#define xen_machphys_update(mfn, pfn) do { } while (0)
-+
-+/* 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 mfn_to_virt(mfn)		(__va((mfn) << PAGE_SHIFT))
-+#define pfn_to_mfn(pfn)			(pfn)
-+#define virt_to_mfn(virt)		(__pa(virt) >> PAGE_SHIFT)
-+#define virt_to_machine(virt)		__pa(virt) // for tpmfront.c
-+
-+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_valid(pfn))
-+		return INVALID_P2M_ENTRY;
-+	return pfn;
-+}
++#include <asm/maddr.h>
 +
-+#endif /* CONFIG_XEN_IA64_DOM0_VP */
 +#endif /* CONFIG_XEN */
 +#endif /* __ASSEMBLY__ */
 +
  #endif /* _ASM_IA64_PAGE_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/pal.h linux-2.6.17-xen/include/asm-ia64/pal.h
---- linux-2.6.17/include/asm-ia64/pal.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/pal.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/pal.h linux-2.6.18-rc5-xen/include/asm-ia64/pal.h
+--- linux-2.6.18-rc5/include/asm-ia64/pal.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/pal.h	2006-09-01 00:09:11.000000000 +0200
 @@ -82,6 +82,7 @@
  #ifndef __ASSEMBLY__
  
@@ -74248,10 +80258,10 @@
  #include <asm/fpu.h>
  
  /*
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/pgalloc.h linux-2.6.17-xen/include/asm-ia64/pgalloc.h
---- linux-2.6.17/include/asm-ia64/pgalloc.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/pgalloc.h	2006-08-14 15:58:15.000000000 +0200
-@@ -126,7 +126,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/pgalloc.h linux-2.6.18-rc5-xen/include/asm-ia64/pgalloc.h
+--- linux-2.6.18-rc5/include/asm-ia64/pgalloc.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/pgalloc.h	2006-07-20 15:57:27.000000000 +0200
+@@ -125,7 +125,7 @@
  static inline void
  pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, struct page *pte)
  {
@@ -74260,9 +80270,9 @@
  }
  
  static inline void
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/privop.h linux-2.6.17-xen/include/asm-ia64/privop.h
---- linux-2.6.17/include/asm-ia64/privop.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-ia64/privop.h	2006-08-14 15:58:15.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/privop.h linux-2.6.18-rc5-xen/include/asm-ia64/privop.h
+--- linux-2.6.18-rc5/include/asm-ia64/privop.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-ia64/privop.h	2006-07-20 15:57:27.000000000 +0200
 @@ -0,0 +1,59 @@
 +#ifndef _ASM_IA64_PRIVOP_H
 +#define _ASM_IA64_PRIVOP_H
@@ -74323,10 +80333,10 @@
 +#endif /* !__ASSEMBLY */
 +
 +#endif /* _ASM_IA64_PRIVOP_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/processor.h linux-2.6.17-xen/include/asm-ia64/processor.h
---- linux-2.6.17/include/asm-ia64/processor.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/processor.h	2006-08-14 15:58:15.000000000 +0200
-@@ -19,6 +19,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/processor.h linux-2.6.18-rc5-xen/include/asm-ia64/processor.h
+--- linux-2.6.18-rc5/include/asm-ia64/processor.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/processor.h	2006-07-20 15:57:27.000000000 +0200
+@@ -18,6 +18,7 @@
  #include <asm/kregs.h>
  #include <asm/ptrace.h>
  #include <asm/ustack.h>
@@ -74334,10 +80344,10 @@
  
  #define IA64_NUM_DBG_REGS	8
  /*
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/synch_bitops.h linux-2.6.17-xen/include/asm-ia64/synch_bitops.h
---- linux-2.6.17/include/asm-ia64/synch_bitops.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-ia64/synch_bitops.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,63 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/synch_bitops.h linux-2.6.18-rc5-xen/include/asm-ia64/synch_bitops.h
+--- linux-2.6.18-rc5/include/asm-ia64/synch_bitops.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-ia64/synch_bitops.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,61 @@
 +#ifndef __XEN_SYNCH_BITOPS_H__
 +#define __XEN_SYNCH_BITOPS_H__
 +
@@ -74347,8 +80357,6 @@
 + * 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)
@@ -74401,10 +80409,10 @@
 +#define synch_cmpxchg_subword synch_cmpxchg
 +
 +#endif /* __XEN_SYNCH_BITOPS_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/system.h linux-2.6.17-xen/include/asm-ia64/system.h
---- linux-2.6.17/include/asm-ia64/system.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-ia64/system.h	2006-08-14 15:58:15.000000000 +0200
-@@ -125,7 +125,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/system.h linux-2.6.18-rc5-xen/include/asm-ia64/system.h
+--- linux-2.6.18-rc5/include/asm-ia64/system.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-ia64/system.h	2006-09-01 00:09:11.000000000 +0200
+@@ -123,7 +123,7 @@
  #define __local_irq_save(x)			\
  do {						\
  	ia64_stop();				\
@@ -74413,7 +80421,7 @@
  	ia64_stop();				\
  	ia64_rsm(IA64_PSR_I);			\
  } while (0)
-@@ -173,7 +173,7 @@
+@@ -171,7 +171,7 @@
  #endif /* !CONFIG_IA64_DEBUG_IRQ */
  
  #define local_irq_enable()	({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
@@ -74422,10 +80430,10 @@
  
  #define irqs_disabled()				\
  ({						\
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-ia64/xen/privop.h linux-2.6.17-xen/include/asm-ia64/xen/privop.h
---- linux-2.6.17/include/asm-ia64/xen/privop.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-ia64/xen/privop.h	2006-08-14 15:58:15.000000000 +0200
-@@ -0,0 +1,277 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-ia64/xen/privop.h linux-2.6.18-rc5-xen/include/asm-ia64/xen/privop.h
+--- linux-2.6.18-rc5/include/asm-ia64/xen/privop.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-ia64/xen/privop.h	2006-08-06 23:45:53.000000000 +0200
+@@ -0,0 +1,304 @@
 +#ifndef _ASM_IA64_XEN_PRIVOP_H
 +#define _ASM_IA64_XEN_PRIVOP_H
 +
@@ -74438,11 +80446,20 @@
 + */
 +
 +
-+#include <asm/xen/asm-xsi-offsets.h>
 +#include <xen/interface/arch-ia64.h>
 +
 +#define IA64_PARAVIRTUALIZED
 +
++#if 0
++#undef XSI_BASE
++/* At 1 MB, before per-cpu space but still addressable using addl instead
++   of movl. */
++#define XSI_BASE				0xfffffffffff00000
++#endif
++
++/* 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
@@ -74467,6 +80484,23 @@
 +#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__
@@ -74509,15 +80543,16 @@
 + * 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			\
-+	(*(uint64_t *)(XSI_PSR_I_ADDR))
++	(*XEN_MAPPEDREGS->interrupt_mask_addr)
 +#define xen_get_virtual_psr_i()		\
-+	(!(*(uint8_t *)(XSI_PSR_I)))
++	(!XSI_PSR_I)
 +#define xen_set_virtual_psr_i(_val)	\
-+	({ *(uint8_t *)(XSI_PSR_I) = (uint8_t)(_val) ? 0:1; })
++	({ XSI_PSR_I = (uint8_t)(_val) ? 0 : 1; })
 +#define xen_set_virtual_psr_ic(_val)	\
-+	({ *(int *)(XSI_PSR_IC) = _val ? 1:0; })
-+#define xen_get_virtual_pend()		(*(int *)(XSI_PEND))
++	({ XEN_MAPPEDREGS->interrupt_collection_enabled = _val ? 1 : 0; })
++#define xen_get_virtual_pend()		(XEN_MAPPEDREGS->pending_interruption)
 +
 +/* Hyperprivops are "break" instructions with a well-defined API.
 + * In particular, the virtual psr.ic bit must be off; in this way
@@ -74703,10 +80738,10 @@
 +#define	ia64_pal_call_static		xen_pal_call_static
 +
 +#endif /* _ASM_IA64_XEN_PRIVOP_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-um/page.h linux-2.6.17-xen/include/asm-um/page.h
---- linux-2.6.17/include/asm-um/page.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-um/page.h	2006-08-14 15:58:19.000000000 +0200
-@@ -115,7 +115,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-um/page.h linux-2.6.18-rc5-xen/include/asm-um/page.h
+--- linux-2.6.18-rc5/include/asm-um/page.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-um/page.h	2006-07-20 15:57:32.000000000 +0200
+@@ -114,7 +114,7 @@
  extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
  #define HAVE_ARCH_VALIDATE
  
@@ -74715,12 +80750,12 @@
  #define HAVE_ARCH_FREE_PAGE
  
  #include <asm-generic/memory_model.h>
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/apic.h linux-2.6.17-xen/include/asm-x86_64/apic.h
---- linux-2.6.17/include/asm-x86_64/apic.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-x86_64/apic.h	2006-08-14 15:58:20.000000000 +0200
-@@ -105,11 +105,13 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/apic.h linux-2.6.18-rc5-xen/include/asm-x86_64/apic.h
+--- linux-2.6.18-rc5/include/asm-x86_64/apic.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/apic.h	2006-07-20 15:57:32.000000000 +0200
+@@ -98,11 +98,13 @@
+ extern int disable_timer_pin_1;
  
- extern void setup_threshold_lvt(unsigned long lvt_off);
  
 +#ifndef CONFIG_XEN
  void smp_send_timer_broadcast_ipi(void);
@@ -74732,21 +80767,9 @@
  
  #endif /* CONFIG_X86_LOCAL_APIC */
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/hw_irq.h linux-2.6.17-xen/include/asm-x86_64/hw_irq.h
---- linux-2.6.17/include/asm-x86_64/hw_irq.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/asm-x86_64/hw_irq.h	2006-08-14 15:58:20.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/arch_hooks.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/arch_hooks.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/arch_hooks.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/arch_hooks.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/arch_hooks.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/arch_hooks.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/arch_hooks.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/arch_hooks.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,27 @@
 +#ifndef _ASM_ARCH_HOOKS_H
 +#define _ASM_ARCH_HOOKS_H
@@ -74775,9 +80798,9 @@
 +extern void mca_nmi_hook(void);
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/bootsetup.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/bootsetup.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/bootsetup.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/bootsetup.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/bootsetup.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/bootsetup.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/bootsetup.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/bootsetup.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,42 @@
 +
 +#ifndef _X86_64_BOOTSETUP_H
@@ -74821,9 +80844,9 @@
 +#define RAMDISK_LOAD_FLAG		0x4000	
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/desc.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/desc.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/desc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/desc.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/desc.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/desc.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/desc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/desc.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,263 @@
 +/* Written 2000 by Andi Kleen */ 
 +#ifndef __ARCH_DESC_H
@@ -75088,10 +81111,10 @@
 +#endif /* !__ASSEMBLY__ */
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/dma-mapping.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/dma-mapping.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/dma-mapping.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/dma-mapping.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,191 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/dma-mapping.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/dma-mapping.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/dma-mapping.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/dma-mapping.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,208 @@
 +#ifndef _X8664_DMA_MAPPING_H
 +#define _X8664_DMA_MAPPING_H 1
 +
@@ -75100,7 +81123,6 @@
 + * documentation.
 + */
 +
-+#include <linux/config.h>
 +
 +#include <asm/scatterlist.h>
 +#include <asm/io.h>
@@ -75151,6 +81173,13 @@
 +extern int iommu_merge;
 +
 +#if 0
++static inline int valid_dma_direction(int dma_direction)
++{
++	return ((dma_direction == DMA_BIDIRECTIONAL) ||
++		(dma_direction == DMA_TO_DEVICE) ||
++		(dma_direction == DMA_FROM_DEVICE));
++}
++
 +static inline int dma_mapping_error(dma_addr_t dma_addr)
 +{
 +	if (dma_ops->mapping_error)
@@ -75168,6 +81197,7 @@
 +dma_map_single(struct device *hwdev, void *ptr, size_t size,
 +	       int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	return dma_ops->map_single(hwdev, ptr, size, direction);
 +}
 +
@@ -75175,6 +81205,7 @@
 +dma_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
 +		 int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	dma_ops->unmap_single(dev, addr, size, direction);
 +}
 +
@@ -75187,6 +81218,7 @@
 +dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
 +			size_t size, int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	if (dma_ops->sync_single_for_cpu)
 +		dma_ops->sync_single_for_cpu(hwdev, dma_handle, size,
 +					     direction);
@@ -75197,6 +81229,7 @@
 +dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
 +			   size_t size, int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	if (dma_ops->sync_single_for_device)
 +		dma_ops->sync_single_for_device(hwdev, dma_handle, size,
 +						direction);
@@ -75207,6 +81240,7 @@
 +dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
 +			      unsigned long offset, size_t size, int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	if (dma_ops->sync_single_range_for_cpu) {
 +		dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, size, direction);
 +	}
@@ -75218,6 +81252,7 @@
 +dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
 +				 unsigned long offset, size_t size, int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	if (dma_ops->sync_single_range_for_device)
 +		dma_ops->sync_single_range_for_device(hwdev, dma_handle,
 +						      offset, size, direction);
@@ -75229,6 +81264,7 @@
 +dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
 +		    int nelems, int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	if (dma_ops->sync_sg_for_cpu)
 +		dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction);
 +	flush_write_buffers();
@@ -75238,6 +81274,7 @@
 +dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
 +		       int nelems, int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	if (dma_ops->sync_sg_for_device) {
 +		dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction);
 +	}
@@ -75248,6 +81285,7 @@
 +static inline int
 +dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	return dma_ops->map_sg(hwdev, sg, nents, direction);
 +}
 +
@@ -75255,6 +81293,7 @@
 +dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
 +	     int direction)
 +{
++	BUG_ON(!valid_dma_direction(direction));
 +	dma_ops->unmap_sg(hwdev, sg, nents, direction);
 +}
 +
@@ -75277,15 +81316,16 @@
 +}
 +
 +extern struct device fallback_dev;
-+extern int panic_on_overflow;
 +#endif
 +
++extern int panic_on_overflow;
++
 +#endif /* _X8664_DMA_MAPPING_H */
 +
 +#include <asm-i386/mach-xen/asm/dma-mapping.h>
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/dmi.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/dmi.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/dmi.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/dmi.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/dmi.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/dmi.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/dmi.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/dmi.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,29 @@
 +#ifndef _ASM_DMI_H
 +#define _ASM_DMI_H 1
@@ -75316,9 +81356,9 @@
 +#define dmi_iounmap bt_iounmap
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/e820.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/e820.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/e820.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/e820.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/e820.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/e820.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/e820.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/e820.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,64 @@
 +/*
 + * structures and definitions for the int 15, ax=e820 memory map
@@ -75384,10 +81424,10 @@
 +#endif/*!__ASSEMBLY__*/
 +
 +#endif/*__E820_HEADER*/
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/fixmap.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/fixmap.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/fixmap.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/fixmap.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,114 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/fixmap.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/fixmap.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/fixmap.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/fixmap.h	2006-07-20 15:57:32.000000000 +0200
+@@ -0,0 +1,113 @@
 +/*
 + * fixmap.h: compile-time virtual memory allocation
 + *
@@ -75401,7 +81441,6 @@
 +#ifndef _ASM_FIXMAP_H
 +#define _ASM_FIXMAP_H
 +
-+#include <linux/config.h>
 +#include <linux/kernel.h>
 +#include <asm/apicdef.h>
 +#include <xen/gnttab.h>
@@ -75502,9 +81541,9 @@
 +}
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/floppy.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/floppy.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/floppy.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/floppy.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/floppy.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/floppy.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/floppy.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/floppy.h	2006-09-01 00:09:12.000000000 +0200
 @@ -0,0 +1,206 @@
 +/*
 + * Architecture specific parts of the Floppy driver
@@ -75642,8 +81681,8 @@
 +
 +static int fd_request_irq(void)
 +{
-+	return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
-+					   "floppy", NULL);
++	return request_irq(FLOPPY_IRQ, floppy_hardint,
++			   IRQF_DISABLED, "floppy", NULL);
 +}
 +
 +#if 0
@@ -75712,10 +81751,10 @@
 +#define EXTRA_FLOPPY_PARAMS
 +
 +#endif /* __ASM_XEN_X86_64_FLOPPY_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/hw_irq.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/hw_irq.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/hw_irq.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,145 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/hw_irq.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/hw_irq.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/hw_irq.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/hw_irq.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,136 @@
 +#ifndef _ASM_HW_IRQ_H
 +#define _ASM_HW_IRQ_H
 +
@@ -75730,12 +81769,9 @@
 + *	<tomsoft at 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>
@@ -75850,21 +81886,15 @@
 +	"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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/hypercall.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/hypercall.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/hypercall.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/hypercall.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,372 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/hypercall.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/hypercall.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/hypercall.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/hypercall.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,389 @@
 +/******************************************************************************
 + * hypercall.h
 + * 
@@ -75913,11 +81943,21 @@
 +#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 (				\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)		\
 +		: "=a" (__res)			\
 +		:				\
 +		: "memory" );			\
@@ -75928,7 +81968,7 @@
 +({								\
 +	long __res, __ign1;					\
 +	asm volatile (						\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=D" (__ign1)			\
 +		: "1" ((long)(a1))				\
 +		: "memory" );					\
@@ -75939,7 +81979,7 @@
 +({								\
 +	long __res, __ign1, __ign2;				\
 +	asm volatile (						\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=D" (__ign1), "=S" (__ign2)	\
 +		: "1" ((long)(a1)), "2" ((long)(a2))		\
 +		: "memory" );					\
@@ -75950,7 +81990,7 @@
 +({								\
 +	long __res, __ign1, __ign2, __ign3;			\
 +	asm volatile (						\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=D" (__ign1), "=S" (__ign2), 	\
 +		"=d" (__ign3)					\
 +		: "1" ((long)(a1)), "2" ((long)(a2)),		\
@@ -75964,7 +82004,7 @@
 +	long __res, __ign1, __ign2, __ign3;			\
 +	asm volatile (						\
 +		"movq %7,%%r10; "				\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=D" (__ign1), "=S" (__ign2),	\
 +		"=d" (__ign3)					\
 +		: "1" ((long)(a1)), "2" ((long)(a2)),		\
@@ -75978,7 +82018,7 @@
 +	long __res, __ign1, __ign2, __ign3;			\
 +	asm volatile (						\
 +		"movq %7,%%r10; movq %8,%%r8; "			\
-+		"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
++		HYPERCALL_STR(name)				\
 +		: "=a" (__res), "=D" (__ign1), "=S" (__ign2),	\
 +		"=d" (__ign3)					\
 +		: "1" ((long)(a1)), "2" ((long)(a2)),		\
@@ -76222,6 +82262,13 @@
 +	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)
@@ -76237,20 +82284,19 @@
 +}
 +
 +#endif /* __HYPERCALL_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/hypervisor.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/hypervisor.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/hypervisor.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/hypervisor.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/hypervisor.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/hypervisor.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/hypervisor.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/hypervisor.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,2 @@
 +
 +#include <asm-i386/mach-xen/asm/hypervisor.h>
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/io.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/io.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/io.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/io.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,328 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/io.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/io.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/io.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/io.h	2006-07-20 15:57:32.000000000 +0200
+@@ -0,0 +1,327 @@
 +#ifndef _ASM_IO_H
 +#define _ASM_IO_H
 +
-+#include <linux/config.h>
 +#include <asm/fixmap.h>
 +
 +/*
@@ -76575,10 +82621,79 @@
 +#define ARCH_HAS_DEV_MEM
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/irq.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/irq.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/irq.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/irq.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,39 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/irqflags.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/irqflags.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/irqflags.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/irqflags.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,65 @@
++/*
++ * include/asm-x86_64/irqflags.h
++ *
++ * IRQ flags handling
++ *
++ * This file gets included from lowlevel asm headers too, to provide
++ * wrapped versions of the local_irq_*() APIs, based on the
++ * raw_local_irq_*() functions from the lowlevel headers.
++ */
++#ifndef _ASM_IRQFLAGS_H
++#define _ASM_IRQFLAGS_H
++
++#ifndef __ASSEMBLY__
++/*
++ * Interrupt control:
++ */
++
++unsigned long __raw_local_save_flags(void);
++#define raw_local_save_flags(flags) \
++		do { (flags) = __raw_local_save_flags(); } while (0)
++
++void raw_local_irq_restore(unsigned long flags);
++void raw_local_irq_disable(void);
++void raw_local_irq_enable(void);
++
++static inline int raw_irqs_disabled_flags(unsigned long flags)
++{
++	return flags != 0;
++}
++
++/*
++ * For spinlocks, etc.:
++ */
++
++unsigned long __raw_local_irq_save(void);
++
++#define raw_local_irq_save(flags) \
++		do { (flags) = __raw_local_irq_save(); } while (0)
++
++int raw_irqs_disabled(void);
++
++/*
++ * Used in the idle loop; sti takes one instruction cycle
++ * to complete:
++ */
++void raw_safe_halt(void);
++
++
++/*
++ * Used when interrupts are already enabled or to
++ * shutdown the processor:
++ */
++void halt(void);
++
++#else /* __ASSEMBLY__: */
++# ifdef CONFIG_TRACE_IRQFLAGS
++#  define TRACE_IRQS_ON		call trace_hardirqs_on_thunk
++#  define TRACE_IRQS_OFF	call trace_hardirqs_off_thunk
++# else
++#  define TRACE_IRQS_ON
++#  define TRACE_IRQS_OFF
++# endif
++#endif
++
++#endif
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/irq.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/irq.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/irq.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/irq.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,38 @@
 +#ifndef _ASM_IRQ_H
 +#define _ASM_IRQ_H
 +
@@ -76591,7 +82706,6 @@
 + *	<tomsoft at informatik.tu-chemnitz.de>
 + */
 +
-+#include <linux/config.h>
 +#include <linux/sched.h>
 +/* include comes from machine specific directory */
 +#include "irq_vectors.h"
@@ -76618,14 +82732,156 @@
 +#define __ARCH_HAS_DO_SOFTIRQ 1
 +
 +#endif /* _ASM_IRQ_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/mmu_context.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/mmu_context.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/mmu_context.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,136 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/maddr.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/maddr.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/maddr.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/maddr.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,139 @@
++#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)
++
++#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;
++}
++
++#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)
++
++#endif /* !CONFIG_XEN */
++
++/* Definitions for machine and pseudophysical addresses. */
++typedef unsigned long paddr_t;
++typedef unsigned long maddr_t;
++
++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;
++}
++
++/* 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/mmu_context.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/mmu_context.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/mmu_context.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/mmu_context.h	2006-07-20 15:57:32.000000000 +0200
+@@ -0,0 +1,135 @@
 +#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>
@@ -76758,10 +83014,10 @@
 +}
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/mmu.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/mmu.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/mmu.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/mmu.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,37 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/mmu.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/mmu.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/mmu.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/mmu.h	2006-08-14 15:07:21.000000000 +0200
+@@ -0,0 +1,38 @@
 +#ifndef __x86_64_MMU_H
 +#define __x86_64_MMU_H
 +
@@ -76781,6 +83037,7 @@
 +	struct semaphore sem; 
 +#ifdef CONFIG_XEN
 +	unsigned pinned:1;
++	unsigned has_foreign_mappings:1;
 +	struct list_head unpinned;
 +#endif
 +} mm_context_t;
@@ -76799,9 +83056,9 @@
 +#endif
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/msr.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/msr.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/msr.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/msr.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/msr.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/msr.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/msr.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/msr.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,399 @@
 +#ifndef X86_64_MSR_H
 +#define X86_64_MSR_H 1
@@ -77202,10 +83459,10 @@
 +#define MSR_P4_U2L_ESCR1 		0x3b1
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/nmi.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/nmi.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/nmi.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/nmi.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,75 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/nmi.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/nmi.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/nmi.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/nmi.h	2006-07-20 15:57:32.000000000 +0200
+@@ -0,0 +1,93 @@
 +/*
 + *  linux/include/asm-i386/nmi.h
 + */
@@ -77213,28 +83470,29 @@
 +#define ASM_NMI_H
 +
 +#include <linux/pm.h>
++#include <asm/io.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. */
@@ -77280,21 +83538,36 @@
 +
 +extern int check_nmi_watchdog(void);
 + 
++extern void setup_apic_nmi_watchdog (void);
++extern int reserve_lapic_nmi(void);
++extern void release_lapic_nmi(void);
++extern void disable_timer_nmi_watchdog(void);
++extern void enable_timer_nmi_watchdog(void);
++extern void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason);
++
++extern void nmi_watchdog_default(void);
++extern int setup_nmi_watchdog(char *);
++
++extern unsigned int nmi_watchdog;
++#define NMI_DEFAULT	-1
++#define NMI_NONE	0
++#define NMI_IO_APIC	1
++#define NMI_LOCAL_APIC	2
++#define NMI_INVALID	3
++
 +#endif /* ASM_NMI_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/page.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/page.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/page.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/page.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,327 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/page.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/page.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/page.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/page.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,208 @@
 +#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>
-+#include <xen/features.h>
 +#endif
 +#include <xen/interface/xen.h> 
 +#include <xen/foreign_page.h>
@@ -77330,7 +83603,7 @@
 +#define EXCEPTION_STACK_ORDER 0
 +#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
 +
-+#define DEBUG_STACK_ORDER EXCEPTION_STACK_ORDER
++#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
 +#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
 +
 +#define IRQSTACK_ORDER 2
@@ -77356,6 +83629,8 @@
 +
 +extern unsigned long end_pfn;
 +
++#include <asm/maddr.h>
++
 +void clear_page(void *);
 +void copy_page(void *, void *);
 +
@@ -77365,118 +83640,6 @@
 +#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr)
 +#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
 +
-+/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
-+#define INVALID_P2M_ENTRY	(~0UL)
-+#define FOREIGN_FRAME_BIT	(1UL<<63)
-+#define FOREIGN_FRAME(m)	((m) | FOREIGN_FRAME_BIT)
-+
-+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;
-+}
-+
-+/* Definitions for machine and pseudophysical addresses. */
-+typedef unsigned long paddr_t;
-+typedef unsigned long maddr_t;
-+
-+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;
-+}
-+
 +/*
 + * These are used to make use of C type-checking..
 + */
@@ -77515,8 +83678,6 @@
 +
 +#define pgprot_val(x)	((x).pgprot)
 +
-+#define __pte_ma(x)     ((pte_t) { (x) } )
-+
 +static inline pte_t __pte(unsigned long x)
 +{
 +	if (x & 1) x = phys_to_machine(x);
@@ -77595,32 +83756,26 @@
 +#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 +#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 +
-+/* 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 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/memory_model.h>
 +#include <asm-generic/page.h>
 +
++#endif /* __KERNEL__ */
++
 +#endif /* _X86_64_PAGE_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/param.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/param.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/param.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/param.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,23 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/param.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/param.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/param.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/param.h	2006-07-20 15:57:32.000000000 +0200
+@@ -0,0 +1,22 @@
 +#ifndef _ASMx86_64_PARAM_H
 +#define _ASMx86_64_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() */
@@ -77639,14 +83794,13 @@
 +#define MAXHOSTNAMELEN	64	/* max length of hostname */
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/pci.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/pci.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/pci.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/pci.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,174 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/pci.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/pci.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/pci.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/pci.h	2006-07-20 15:57:32.000000000 +0200
+@@ -0,0 +1,173 @@
 +#ifndef __x8664_PCI_H
 +#define __x8664_PCI_H
 +
-+#include <linux/config.h>
 +#include <asm/io.h>
 +
 +#ifdef __KERNEL__
@@ -77685,8 +83839,8 @@
 +#include <asm/scatterlist.h>
 +#include <linux/string.h>
 +#include <asm/page.h>
-+#include <linux/dma-mapping.h> /* for have_iommu */
 +
++extern void pci_iommu_alloc(void);
 +extern int iommu_setup(char *opt);
 +
 +/* The PCI address space does equal the physical memory
@@ -77698,7 +83852,7 @@
 + */
 +#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
 +
-+#ifdef CONFIG_GART_IOMMU
++#if defined(CONFIG_IOMMU) || defined(CONFIG_CALGARY_IOMMU)
 +
 +/*
 + * x86-64 always supports DAC, but sometimes it is useful to force
@@ -77817,9 +83971,9 @@
 +#define pcibios_scan_all_fns(a, b)	1
 +
 +#endif /* __x8664_PCI_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/pgalloc.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/pgalloc.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/pgalloc.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/pgalloc.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/pgalloc.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/pgalloc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/pgalloc.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,226 @@
 +#ifndef _X86_64_PGALLOC_H
 +#define _X86_64_PGALLOC_H
@@ -78047,10 +84201,10 @@
 +#define __pud_free_tlb(tlb,x)   pud_free((x))
 +
 +#endif /* _X86_64_PGALLOC_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/pgtable.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/pgtable.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/pgtable.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/pgtable.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,564 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/pgtable.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/pgtable.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/pgtable.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/pgtable.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,558 @@
 +#ifndef _X86_64_PGTABLE_H
 +#define _X86_64_PGTABLE_H
 +
@@ -78259,7 +84413,7 @@
 +#define _PAGE_NX        (1UL<<_PAGE_BIT_NX)
 +
 +#define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
-+#define _KERNPG_TABLE	_PAGE_TABLE
++#define _KERNPG_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
 +
 +#define _PAGE_CHG_MASK	(PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
 +
@@ -78272,22 +84426,21 @@
 +#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 | _PAGE_USER )
++	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
 +#define __PAGE_KERNEL_EXEC \
-+	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_USER )
++	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
 +#define __PAGE_KERNEL_NOCACHE \
-+	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX | _PAGE_USER )
++	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX)
 +#define __PAGE_KERNEL_RO \
-+	(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX | _PAGE_USER )
++	(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
 +#define __PAGE_KERNEL_VSYSCALL \
-+	(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_USER )
++	(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
 +#define __PAGE_KERNEL_VSYSCALL_NOCACHE \
-+	(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD | _PAGE_USER )
++	(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
 +#define __PAGE_KERNEL_LARGE \
-+	(__PAGE_KERNEL | _PAGE_PSE | _PAGE_USER )
++	(__PAGE_KERNEL | _PAGE_PSE)
 +#define __PAGE_KERNEL_LARGE_EXEC \
-+	(__PAGE_KERNEL_EXEC | _PAGE_PSE | _PAGE_USER )
-+
++	(__PAGE_KERNEL_EXEC | _PAGE_PSE)
 +
 +/*
 + * We don't support GLOBAL page in xenolinux64
@@ -78365,7 +84518,6 @@
 +	return pte;
 +}
 +
-+#define pfn_pte_ma(pfn, prot)	__pte_ma((((pfn) << PAGE_SHIFT) | pgprot_val(prot)) & __supported_pte_mask)
 +/*
 + * The following only work if pte_present() is true.
 + * Undefined behaviour if not..
@@ -78451,10 +84603,6 @@
 +/* 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: */
 +
@@ -78477,7 +84625,7 @@
 +   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) & (~PAGE_MASK & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
++#define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_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)
 +
@@ -78615,10 +84763,10 @@
 +#include <asm-generic/pgtable.h>
 +
 +#endif /* _X86_64_PGTABLE_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/processor.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/processor.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/processor.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/processor.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,494 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/processor.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/processor.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/processor.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/processor.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,498 @@
 +/*
 + * include/asm-x86_64/processor.h
 + *
@@ -78633,7 +84781,6 @@
 +#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>
@@ -78691,7 +84838,11 @@
 +	cpumask_t llc_shared_map;	/* cpus sharing the last level cache */
 +#endif
 +	__u8	apicid;
++#ifdef CONFIG_SMP
 +	__u8	booted_cores;	/* number of cores as seen by OS */
++	__u8	phys_proc_id;	/* Physical Processor id. */
++	__u8	cpu_core_id;	/* Core id. */
++#endif
 +} ____cacheline_aligned;
 +
 +#define X86_VENDOR_INTEL 0
@@ -78718,6 +84869,7 @@
 +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);
++extern unsigned short num_cache_leaves;
 +
 +/*
 + * EFLAGS bits
@@ -79113,9 +85265,9 @@
 +#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
 +
 +#endif /* __ASM_X86_64_PROCESSOR_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/ptrace.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/ptrace.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/ptrace.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/ptrace.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/ptrace.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/ptrace.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/ptrace.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/ptrace.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,125 @@
 +#ifndef _X86_64_PTRACE_H
 +#define _X86_64_PTRACE_H
@@ -79242,10 +85394,10 @@
 +#endif
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/smp.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/smp.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/smp.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/smp.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,153 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/smp.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/smp.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/smp.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/smp.h	2006-07-20 15:57:32.000000000 +0200
+@@ -0,0 +1,150 @@
 +#ifndef __ASM_SMP_H
 +#define __ASM_SMP_H
 +
@@ -79253,7 +85405,6 @@
 + * 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>
@@ -79301,8 +85452,6 @@
 +
 +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];
 +extern u8 cpu_llc_id[NR_CPUS];
 +
 +#define SMP_TRAMPOLINE_BASE 0x6000
@@ -79399,20 +85548,19 @@
 +
 +#endif
 +
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/synch_bitops.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/synch_bitops.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/synch_bitops.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/synch_bitops.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/synch_bitops.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/synch_bitops.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/synch_bitops.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/synch_bitops.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,2 @@
 +
 +#include <asm-i386/mach-xen/asm/synch_bitops.h>
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/system.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/system.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/system.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/system.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,428 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/system.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/system.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/system.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/system.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,264 @@
 +#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>
@@ -79427,12 +85575,6 @@
 +#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)
 +
@@ -79455,7 +85597,7 @@
 +		     "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"		  \
++		     LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"	  \
 +		     "movq %%rax,%%rdi\n\t" 					  \
 +		     "jc   ret_from_fork\n\t"					  \
 +		     RESTORE_CONTEXT						    \
@@ -79491,82 +85633,6 @@
 +		".previous"			\
 +		: :"r" (value), "r" (0))
 +
-+#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
 + */
@@ -79732,114 +85798,33 @@
 + * 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 mb() 	asm volatile("mfence":::"memory")
++#define rmb()	asm volatile("lfence":::"memory")
 +
-+#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()
++#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)
 +
-+/* 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; })
++#define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
 +
 +void safe_halt(void);
 +void halt(void);
 +
++#include <linux/irqflags.h>
++
 +void cpu_idle_wait(void);
 +
 +extern unsigned long arch_align_stack(unsigned long sp);
++extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/timer.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/timer.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/timer.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/timer.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/timer.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/timer.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/timer.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/timer.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,67 @@
 +#ifndef _ASMi386_TIMER_H
 +#define _ASMi386_TIMER_H
@@ -79908,14 +85893,13 @@
 +extern struct init_timer_opts timer_pmtmr_init;
 +#endif
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/tlbflush.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/tlbflush.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/tlbflush.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/tlbflush.h	2006-08-14 15:58:20.000000000 +0200
-@@ -0,0 +1,104 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/tlbflush.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/tlbflush.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/tlbflush.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/tlbflush.h	2006-07-20 15:57:32.000000000 +0200
+@@ -0,0 +1,103 @@
 +#ifndef _X8664_TLBFLUSH_H
 +#define _X8664_TLBFLUSH_H
 +
-+#include <linux/config.h>
 +#include <linux/mm.h>
 +#include <asm/processor.h>
 +
@@ -80016,9 +86000,9 @@
 +}
 +
 +#endif /* _X8664_TLBFLUSH_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/vga.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/vga.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/vga.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/vga.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/vga.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/vga.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/vga.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/vga.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,20 @@
 +/*
 + *	Access to VGA videoram
@@ -80034,15 +86018,15 @@
 + *	access the videoram directly without any black magic.
 + */
 +
-+#define VGA_MAP_MEM(x) (unsigned long)isa_bus_to_virt(x)
++#define VGA_MAP_MEM(x,s) (unsigned long)isa_bus_to_virt(x)
 +
 +#define vga_readb(x) (*(x))
 +#define vga_writeb(x,y) (*(y) = (x))
 +
 +#endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/asm/xor.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/xor.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/asm/xor.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/asm/xor.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/xor.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/xor.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/asm/xor.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/asm/xor.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,328 @@
 +/*
 + * x86-64 changes / gcc fixes from Andi Kleen. 
@@ -80372,9 +86356,9 @@
 +   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 -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/irq_vectors.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/irq_vectors.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/irq_vectors.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/irq_vectors.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/irq_vectors.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/irq_vectors.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/irq_vectors.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/irq_vectors.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,123 @@
 +/*
 + * This file should contain #defines for all of the interrupt vector
@@ -80499,9 +86483,9 @@
 +#define irq_to_dynirq(_x)	((_x) - DYNIRQ_BASE)
 +
 +#endif /* _ASM_IRQ_VECTORS_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/mach_time.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/mach_time.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/mach_time.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/mach_time.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/mach_time.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/mach_time.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/mach_time.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/mach_time.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,111 @@
 +/*
 + *  include/asm-i386/mach-default/mach_time.h
@@ -80614,9 +86598,9 @@
 +}
 +
 +#endif /* !_MACH_TIME_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/mach_timer.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/mach_timer.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/mach_timer.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/mach_timer.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/mach_timer.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/mach_timer.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/mach_timer.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/mach_timer.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,48 @@
 +/*
 + *  include/asm-i386/mach-default/mach_timer.h
@@ -80666,9 +86650,9 @@
 +}
 +
 +#endif /* !_MACH_TIMER_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/setup_arch_post.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/setup_arch_post.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/setup_arch_post.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/setup_arch_post.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/setup_arch_post.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/setup_arch_post.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/setup_arch_post.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/setup_arch_post.h	2006-07-20 15:57:32.000000000 +0200
 @@ -0,0 +1,58 @@
 +/**
 + * machine_specific_* - Hooks for machine specific setup.
@@ -80728,31 +86712,113 @@
 +	}
 +#endif
 +}
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/asm-x86_64/mach-xen/setup_arch_pre.h linux-2.6.17-xen/include/asm-x86_64/mach-xen/setup_arch_pre.h
---- linux-2.6.17/include/asm-x86_64/mach-xen/setup_arch_pre.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/asm-x86_64/mach-xen/setup_arch_pre.h	2006-08-14 15:58:20.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/asm-x86_64/mach-xen/setup_arch_pre.h linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/setup_arch_pre.h
+--- linux-2.6.18-rc5/include/asm-x86_64/mach-xen/setup_arch_pre.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/asm-x86_64/mach-xen/setup_arch_pre.h	2006-07-20 15:57:32.000000000 +0200
 @@ -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 -urN -x .hg -x .hgtags linux-2.6.17/include/linux/ethtool.h linux-2.6.17-xen/include/linux/ethtool.h
---- linux-2.6.17/include/linux/ethtool.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/ethtool.h	2006-08-14 15:58:21.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/include/linux/gfp.h linux-2.6.17-xen/include/linux/gfp.h
---- linux-2.6.17/include/linux/gfp.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/gfp.h	2006-08-14 15:58:21.000000000 +0200
-@@ -100,7 +100,11 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/linux/elfnote.h linux-2.6.18-rc5-xen/include/linux/elfnote.h
+--- linux-2.6.18-rc5/include/linux/elfnote.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/linux/elfnote.h	2006-09-01 00:09:12.000000000 +0200
+@@ -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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/linux/gfp.h linux-2.6.18-rc5-xen/include/linux/gfp.h
+--- linux-2.6.18-rc5/include/linux/gfp.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/linux/gfp.h	2006-07-20 15:57:34.000000000 +0200
+@@ -99,7 +99,11 @@
   */
  
  #ifndef HAVE_ARCH_FREE_PAGE
@@ -80765,10 +86831,10 @@
  #endif
  
  extern struct page *
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/linux/highmem.h linux-2.6.17-xen/include/linux/highmem.h
---- linux-2.6.17/include/linux/highmem.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/highmem.h	2006-08-14 15:58:21.000000000 +0200
-@@ -25,10 +25,16 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/linux/highmem.h linux-2.6.18-rc5-xen/include/linux/highmem.h
+--- linux-2.6.18-rc5/include/linux/highmem.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/linux/highmem.h	2006-07-20 15:57:34.000000000 +0200
+@@ -24,10 +24,16 @@
  
  /* declarations for linux/mm/highmem.c */
  unsigned int nr_free_highpages(void);
@@ -80785,12 +86851,12 @@
  
  static inline void *kmap(struct page *page)
  {
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/linux/interrupt.h linux-2.6.17-xen/include/linux/interrupt.h
---- linux-2.6.17/include/linux/interrupt.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/interrupt.h	2006-08-14 15:58:21.000000000 +0200
-@@ -58,6 +58,12 @@
- extern void enable_irq(unsigned int irq);
- #endif
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/linux/interrupt.h linux-2.6.18-rc5-xen/include/linux/interrupt.h
+--- linux-2.6.18-rc5/include/linux/interrupt.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/linux/interrupt.h	2006-07-20 15:57:35.000000000 +0200
+@@ -166,6 +166,12 @@
+ 
+ #endif /* CONFIG_GENERIC_HARDIRQS */
  
 +#ifdef CONFIG_HAVE_IRQ_IGNORE_UNHANDLED
 +int irq_ignore_unhandled(unsigned int irq);
@@ -80801,10 +86867,10 @@
  #ifndef __ARCH_SET_SOFTIRQ_PENDING
  #define set_softirq_pending(x) (local_softirq_pending() = (x))
  #define or_softirq_pending(x)  (local_softirq_pending() |= (x))
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/linux/mm.h linux-2.6.17-xen/include/linux/mm.h
---- linux-2.6.17/include/linux/mm.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/mm.h	2006-08-14 15:58:21.000000000 +0200
-@@ -166,6 +166,9 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/linux/mm.h linux-2.6.18-rc5-xen/include/linux/mm.h
+--- linux-2.6.18-rc5/include/linux/mm.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/linux/mm.h	2006-09-01 00:09:12.000000000 +0200
+@@ -164,6 +164,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 */
@@ -80814,7 +86880,7 @@
  
  #ifndef VM_STACK_DEFAULT_FLAGS		/* arch can override this */
  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
-@@ -1014,6 +1017,13 @@
+@@ -1027,6 +1030,13 @@
  #define FOLL_GET	0x04	/* do get_page on page */
  #define FOLL_ANON	0x08	/* give ZERO_PAGE if no pgtable */
  
@@ -80828,151 +86894,9 @@
  #ifdef CONFIG_PROC_FS
  void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
  #else
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/linux/netdevice.h linux-2.6.17-xen/include/linux/netdevice.h
---- linux-2.6.17/include/linux/netdevice.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/netdevice.h	2006-08-14 15:58:21.000000000 +0200
-@@ -232,6 +232,7 @@
- 	__LINK_STATE_RX_SCHED,
- 	__LINK_STATE_LINKWATCH_PENDING,
- 	__LINK_STATE_DORMANT,
-+	__LINK_STATE_QDISC_RUNNING,
- };
- 
- 
-@@ -307,9 +308,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;
- 
-@@ -398,6 +407,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;
-@@ -406,7 +418,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.
- 	 */
-@@ -532,6 +544,8 @@
- 					 struct net_device *,
- 					 struct packet_type *,
- 					 struct net_device *);
-+	struct sk_buff		*(*gso_segment)(struct sk_buff *skb,
-+						int features);
- 	void			*af_packet_priv;
- 	struct list_head	list;
- };
-@@ -679,7 +693,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);
- 
-@@ -889,11 +904,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 err = spin_trylock(&dev->_xmit_lock);
-+	if (!err)
-+		dev->xmit_lock_owner = smp_processor_id();
-+	return err;
-+}
-+
-+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) */
-@@ -921,6 +968,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
-@@ -940,6 +988,18 @@
- 
- extern void linkwatch_run_queue(void);
- 
-+static inline int skb_gso_ok(struct sk_buff *skb, int features)
-+{
-+	int feature = skb_shinfo(skb)->gso_size ?
-+		      skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
-+	return (features & feature) == feature;
-+}
-+
-+static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
-+{
-+	return !skb_gso_ok(skb, dev->features);
-+}
-+
- #endif /* __KERNEL__ */
- 
- #endif	/* _LINUX_DEV_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/linux/oprofile.h linux-2.6.17-xen/include/linux/oprofile.h
---- linux-2.6.17/include/linux/oprofile.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/oprofile.h	2006-08-14 15:58:22.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/linux/oprofile.h linux-2.6.18-rc5-xen/include/linux/oprofile.h
+--- linux-2.6.18-rc5/include/linux/oprofile.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/linux/oprofile.h	2006-07-20 15:57:35.000000000 +0200
 @@ -16,6 +16,10 @@
  #include <linux/types.h>
  #include <linux/spinlock.h>
@@ -80996,50 +86920,32 @@
  	/* Do any necessary interrupt setup. Optional. */
  	int (*setup)(void);
  	/* Do any necessary interrupt shutdown. Optional. */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/linux/pfn.h linux-2.6.17-xen/include/linux/pfn.h
---- linux-2.6.17/include/linux/pfn.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/pfn.h	2006-08-14 15:58:22.000000000 +0200
-@@ -4,6 +4,6 @@
- #define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
- #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
- #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
--#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
-+#define PFN_PHYS(x)	((unsigned long long)(x) << PAGE_SHIFT)
+@@ -78,6 +87,8 @@
+ /* add a backtrace entry, to be called from the ->backtrace callback */
+ void oprofile_add_trace(unsigned long eip);
  
- #endif
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/linux/skbuff.h linux-2.6.17-xen/include/linux/skbuff.h
---- linux-2.6.17/include/linux/skbuff.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/linux/skbuff.h	2006-08-14 15:58:22.000000000 +0200
-@@ -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,
- };
++/* add a domain switch entry */
++int oprofile_add_domain_switch(int32_t domain_id);
  
-+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 @@
+ /**
+  * Create a file of the given name as a child of the given root, with
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/linux/pci_ids.h linux-2.6.18-rc5-xen/include/linux/pci_ids.h
+--- linux-2.6.18-rc5/include/linux/pci_ids.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/linux/pci_ids.h	2006-09-01 00:09:12.000000000 +0200
+@@ -1726,6 +1726,9 @@
+ #define PCI_VENDOR_ID_DOMEX		0x134a
+ #define PCI_DEVICE_ID_DOMEX_DMX3191D	0x0001
+ 
++#define PCI_VENDOR_ID_INTASHIELD	0x135a
++#define PCI_DEVICE_ID_INTASHIELD_IS200	0x0d80
++
+ #define PCI_VENDOR_ID_QUATECH		0x135C
+ #define PCI_DEVICE_ID_QUATECH_QSC100	0x0010
+ #define PCI_DEVICE_ID_QUATECH_DSC100	0x0020
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/linux/skbuff.h linux-2.6.18-rc5-xen/include/linux/skbuff.h
+--- linux-2.6.18-rc5/include/linux/skbuff.h	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/include/linux/skbuff.h	2006-09-01 00:09:12.000000000 +0200
+@@ -203,6 +203,8 @@
   *	@local_df: allow local fragmentation
   *	@cloned: Head may be cloned (check refcnt to be sure)
   *	@nohdr: Payload reference only, must not modify header
@@ -81048,7 +86954,7 @@
   *	@pkt_type: Packet class
   *	@fclone: skbuff clone status
   *	@ip_summed: Driver fed us an IP checksum
-@@ -265,7 +276,13 @@
+@@ -282,7 +284,13 @@
  				nfctinfo:3;
  	__u8			pkt_type:3,
  				fclone:2,
@@ -81062,7 +86968,7 @@
  	__be16			protocol;
  
  	void			(*destructor)(struct sk_buff *skb);
-@@ -322,7 +339,8 @@
+@@ -345,7 +353,8 @@
  
  extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
  					    unsigned int size,
@@ -81072,143 +86978,28 @@
  extern void	       kfree_skbmem(struct sk_buff *skb);
  extern struct sk_buff *skb_clone(struct sk_buff *skb,
  				 gfp_t priority);
-@@ -1062,7 +1080,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
- 
- /**
-@@ -1161,18 +1179,34 @@
- 	return 0;
+@@ -1086,6 +1095,7 @@
+ 		kfree_skb(skb);
  }
  
-+static inline int __skb_linearize(struct sk_buff *skb)
-+{
-+	return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
-+}
-+
++#ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB
  /**
-  *	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;
+  *	__dev_alloc_skb - allocate an skbuff for receiving
+  *	@length: length to allocate
+@@ -1106,6 +1116,9 @@
+ 		skb_reserve(skb, NET_SKB_PAD);
+ 	return skb;
  }
++#else
++extern struct sk_buff *__dev_alloc_skb(unsigned int length, gfp_t gfp_mask);
++#endif
  
  /**
-@@ -1269,6 +1303,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)
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/net/pkt_sched.h linux-2.6.17-xen/include/net/pkt_sched.h
---- linux-2.6.17/include/net/pkt_sched.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/net/pkt_sched.h	2006-08-14 15:58:23.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/include/net/protocol.h linux-2.6.17-xen/include/net/protocol.h
---- linux-2.6.17/include/net/protocol.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/net/protocol.h	2006-08-14 15:58:23.000000000 +0200
-@@ -37,6 +37,8 @@
- struct net_protocol {
- 	int			(*handler)(struct sk_buff *skb);
- 	void			(*err_handler)(struct sk_buff *skb, u32 info);
-+	struct sk_buff	       *(*gso_segment)(struct sk_buff *skb,
-+					       int features);
- 	int			no_policy;
- };
- 
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/net/sock.h linux-2.6.17-xen/include/net/sock.h
---- linux-2.6.17/include/net/sock.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/net/sock.h	2006-08-14 15:58:23.000000000 +0200
-@@ -1032,9 +1032,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 -urN -x .hg -x .hgtags linux-2.6.17/include/net/tcp.h linux-2.6.17-xen/include/net/tcp.h
---- linux-2.6.17/include/net/tcp.h	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/include/net/tcp.h	2006-08-14 15:58:23.000000000 +0200
-@@ -565,13 +565,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,
-@@ -1076,6 +1076,8 @@
- 
- extern int tcp_v4_destroy_sock(struct sock *sk);
- 
-+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 -urN -x .hg -x .hgtags linux-2.6.17/include/xen/balloon.h linux-2.6.17-xen/include/xen/balloon.h
---- linux-2.6.17/include/xen/balloon.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/balloon.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,63 @@
+  *	dev_alloc_skb - allocate an skbuff for receiving
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/balloon.h linux-2.6.18-rc5-xen/include/xen/balloon.h
+--- linux-2.6.18-rc5/include/xen/balloon.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/balloon.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,67 @@
 +/******************************************************************************
 + * balloon.h
 + *
@@ -81249,20 +87040,24 @@
 + * Inform the balloon driver that it should allow some slop for device-driver
 + * memory activities.
 + */
-+extern void
++void
 +balloon_update_driver_allowance(
 +	long delta);
 +
 +/* Allocate an empty low-memory page range. */
-+extern struct page *
++struct page *
 +balloon_alloc_empty_page_range(
 +	unsigned long nr_pages);
 +
 +/* Deallocate an empty page range, adding to the balloon. */
-+extern void
++void
 +balloon_dealloc_empty_page_range(
 +	struct page *page, unsigned long nr_pages);
 +
++void
++balloon_release_driver_page(
++	struct page *page);
++
 +/*
 + * Prevent the balloon driver from changing the memory reservation during
 + * a driver critical region.
@@ -81272,14 +87067,13 @@
 +#define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags)
 +
 +#endif /* __ASM_BALLOON_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/cpu_hotplug.h linux-2.6.17-xen/include/xen/cpu_hotplug.h
---- linux-2.6.17/include/xen/cpu_hotplug.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/cpu_hotplug.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,44 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/cpu_hotplug.h linux-2.6.18-rc5-xen/include/xen/cpu_hotplug.h
+--- linux-2.6.18-rc5/include/xen/cpu_hotplug.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/cpu_hotplug.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,43 @@
 +#ifndef __XEN_CPU_HOTPLUG_H__
 +#define __XEN_CPU_HOTPLUG_H__
 +
-+#include <linux/config.h>
 +#include <linux/kernel.h>
 +#include <linux/cpumask.h>
 +
@@ -81320,15 +87114,14 @@
 +#endif /* !defined(CONFIG_HOTPLUG_CPU) */
 +
 +#endif /* __XEN_CPU_HOTPLUG_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/driver_util.h linux-2.6.17-xen/include/xen/driver_util.h
---- linux-2.6.17/include/xen/driver_util.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/driver_util.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,16 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/driver_util.h linux-2.6.18-rc5-xen/include/xen/driver_util.h
+--- linux-2.6.18-rc5/include/xen/driver_util.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/driver_util.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,15 @@
 +
 +#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. */
@@ -81340,10 +87133,10 @@
 +extern void unlock_vm_area(struct vm_struct *area);
 +
 +#endif /* __ASM_XEN_DRIVER_UTIL_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/evtchn.h linux-2.6.17-xen/include/xen/evtchn.h
---- linux-2.6.17/include/xen/evtchn.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/evtchn.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,114 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/evtchn.h linux-2.6.18-rc5-xen/include/xen/evtchn.h
+--- linux-2.6.18-rc5/include/xen/evtchn.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/evtchn.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,113 @@
 +/******************************************************************************
 + * evtchn.h
 + * 
@@ -81380,7 +87173,6 @@
 +#ifndef __ASM_EVTCHN_H__
 +#define __ASM_EVTCHN_H__
 +
-+#include <linux/config.h>
 +#include <linux/interrupt.h>
 +#include <asm/hypervisor.h>
 +#include <asm/ptrace.h>
@@ -81458,9 +87250,9 @@
 +extern void notify_remote_via_irq(int irq);
 +
 +#endif /* __ASM_EVTCHN_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/features.h linux-2.6.17-xen/include/xen/features.h
---- linux-2.6.17/include/xen/features.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/features.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/features.h linux-2.6.18-rc5-xen/include/xen/features.h
+--- linux-2.6.18-rc5/include/xen/features.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/features.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,20 @@
 +/******************************************************************************
 + * features.h
@@ -81482,9 +87274,9 @@
 +#define xen_feature(flag)	(xen_features[flag])
 +
 +#endif /* __ASM_XEN_FEATURES_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/foreign_page.h linux-2.6.17-xen/include/xen/foreign_page.h
---- linux-2.6.17/include/xen/foreign_page.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/foreign_page.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/foreign_page.h linux-2.6.18-rc5-xen/include/xen/foreign_page.h
+--- linux-2.6.18-rc5/include/xen/foreign_page.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/foreign_page.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,30 @@
 +/******************************************************************************
 + * foreign_page.h
@@ -81516,10 +87308,10 @@
 +	( (void (*) (struct page *)) (page)->mapping )
 +
 +#endif /* __ASM_XEN_FOREIGN_PAGE_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/gnttab.h linux-2.6.17-xen/include/xen/gnttab.h
---- linux-2.6.17/include/xen/gnttab.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/gnttab.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,151 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/gnttab.h linux-2.6.18-rc5-xen/include/xen/gnttab.h
+--- linux-2.6.18-rc5/include/xen/gnttab.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/gnttab.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,150 @@
 +/******************************************************************************
 + * gnttab.h
 + * 
@@ -81559,7 +87351,6 @@
 +#ifndef __ASM_GNTTAB_H__
 +#define __ASM_GNTTAB_H__
 +
-+#include <linux/config.h>
 +#include <asm/hypervisor.h>
 +#include <xen/interface/grant_table.h>
 +#include <xen/features.h>
@@ -81671,9 +87462,37 @@
 +}
 +
 +#endif /* __ASM_GNTTAB_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/hypervisor_sysfs.h linux-2.6.17-xen/include/xen/hypervisor_sysfs.h
---- linux-2.6.17/include/xen/hypervisor_sysfs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/hypervisor_sysfs.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/hvm.h linux-2.6.18-rc5-xen/include/xen/hvm.h
+--- linux-2.6.18-rc5/include/xen/hvm.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/hvm.h	2006-09-01 00:09:12.000000000 +0200
+@@ -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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/hypervisor_sysfs.h linux-2.6.18-rc5-xen/include/xen/hypervisor_sysfs.h
+--- linux-2.6.18-rc5/include/xen/hypervisor_sysfs.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/hypervisor_sysfs.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,32 @@
 +/*
 + *  copyright (c) 2006 IBM Corporation
@@ -81707,9 +87526,9 @@
 +};
 +
 +#endif /* _HYP_SYSFS_H_ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/acm.h linux-2.6.17-xen/include/xen/interface/acm.h
---- linux-2.6.17/include/xen/interface/acm.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/acm.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/acm.h linux-2.6.18-rc5-xen/include/xen/interface/acm.h
+--- linux-2.6.18-rc5/include/xen/interface/acm.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/acm.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,188 @@
 +/*
 + * acm.h: Xen access control module interface defintions
@@ -81899,9 +87718,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/acm_ops.h linux-2.6.17-xen/include/xen/interface/acm_ops.h
---- linux-2.6.17/include/xen/interface/acm_ops.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/acm_ops.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/acm_ops.h linux-2.6.18-rc5-xen/include/xen/interface/acm_ops.h
+--- linux-2.6.18-rc5/include/xen/interface/acm_ops.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/acm_ops.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,103 @@
 +/*
 + * acm_ops.h: Xen access control module hypervisor commands
@@ -82006,10 +87825,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/arch-ia64.h linux-2.6.17-xen/include/xen/interface/arch-ia64.h
---- linux-2.6.17/include/xen/interface/arch-ia64.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/arch-ia64.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,420 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/arch-ia64.h linux-2.6.18-rc5-xen/include/xen/interface/arch-ia64.h
+--- linux-2.6.18-rc5/include/xen/interface/arch-ia64.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/arch-ia64.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,448 @@
 +/******************************************************************************
 + * arch-ia64/hypervisor-if.h
 + * 
@@ -82019,8 +87838,14 @@
 +#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
@@ -82054,19 +87879,6 @@
 +
 +typedef unsigned long xen_ulong_t;
 +
-+#define MAX_NR_SECTION  32  /* at most 32 memory holes */
-+struct mm_section {
-+    unsigned long start;  /* start of memory hole */
-+    unsigned long end;    /* end of memory hole */
-+};
-+typedef struct mm_section mm_section_t;
-+
-+struct pmt_entry {
-+    unsigned long mfn : 56;
-+    unsigned long type: 8;
-+};
-+typedef struct pmt_entry pmt_entry_t;
-+
 +#define GPFN_MEM          (0UL << 56) /* Guest pfn is normal mem */
 +#define GPFN_FRAME_BUFFER (1UL << 56) /* VGA framebuffer */
 +#define GPFN_LOW_MMIO     (2UL << 56) /* Low MMIO range */
@@ -82108,16 +87920,6 @@
 +#define GFW_START        (4*MEM_G -16*MEM_M)
 +#define GFW_SIZE         (16*MEM_M)
 +
-+/*
-+ * NB. This may become a 64-bit count with no shift. If this happens then the 
-+ * structure size will still be 8 bytes, so no other alignments will change.
-+ */
-+struct tsc_timestamp {
-+    unsigned int  tsc_bits;      /* 0: 32 bits read from the CPU's TSC. */
-+    unsigned int  tsc_bitshift;  /* 4: 'tsc_bits' uses N:N+31 of TSC.   */
-+}; /* 8 bytes */
-+typedef struct tsc_timestamp tsc_timestamp_t;
-+
 +struct pt_fpreg {
 +    union {
 +        unsigned long bits[2];
@@ -82197,7 +87999,7 @@
 +    unsigned long r6;  /* preserved */
 +    unsigned long r7;  /* preserved */
 +    unsigned long eml_unat;    /* used for emulating instruction */
-+    unsigned long rfi_pfs;     /* used for elulating rfi */
++    unsigned long pad0;     /* alignment pad */
 +
 +};
 +typedef struct cpu_user_regs cpu_user_regs_t;
@@ -82297,64 +88099,70 @@
 +             * shared info area now. interrupt_mask_addr is the address
 +             * of evtchn_upcall_mask for current vcpu
 +             */
-+            unsigned long interrupt_mask_addr;
++            unsigned char *interrupt_mask_addr;
 +            int pending_interruption;
 +            int incomplete_regframe; // see SDM vol2 6.8
-+            unsigned long reserved5_1[4];
++            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)
-+            // FIXME: tmp[8] temp'ly being used for virtual psr.pp
 +        };
 +    };
++};
++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 mapped_regs mapped_regs_t;
++typedef struct vpd vpd_t;
 +
 +struct arch_vcpu_info {
 +};
 +typedef struct arch_vcpu_info arch_vcpu_info_t;
 +
-+typedef mapped_regs_t vpd_t;
-+
 +struct arch_shared_info {
-+    unsigned int flags;
++    /* 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;
 +
-+struct arch_initrd_info {
-+    unsigned long start;
-+    unsigned long size;
++typedef unsigned long xen_callback_t;
++
++struct ia64_tr_entry {
++    unsigned long pte;
++    unsigned long itir;
++    unsigned long vadr;
++    unsigned long rid;
 +};
-+typedef struct arch_initrd_info arch_initrd_info_t;
 +
-+typedef unsigned long xen_callback_t;
++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;
++};
 +
-+#define IA64_COMMAND_LINE_SIZE 512
 +struct vcpu_guest_context {
-+#define VGCF_FPU_VALID (1<<0)
-+#define VGCF_VMX_GUEST (1<<1)
-+#define VGCF_IN_KERNEL (1<<2)
++#define VGCF_EXTRA_REGS (1<<1)	/* Get/Set extra regs.  */
 +    unsigned long flags;       /* VGCF_* flags */
-+    unsigned long pt_base;     /* PMT table base */
-+    unsigned long share_io_pg; /* Shared page for I/O emulation */
-+    unsigned long sys_pgnr;    /* System pages out of domain memory */
-+    unsigned long vm_assist;   /* VMASST_TYPE_* bitmap, now none on IPF */
-+
-+    struct cpu_user_regs regs;
-+    struct mapped_regs *privregs;
-+    struct arch_shared_info shared;
-+    struct arch_initrd_info initrd;
-+    char cmdline[IA64_COMMAND_LINE_SIZE];
++
++    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);
@@ -82390,9 +88198,46 @@
 +#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)
++
++/* 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__ */
 +
++/* Address of shared_info in domain virtual space.
++   This is the default address, for compatibility only.  */
++#define XSI_BASE			0xf100000000000000
++
++/* 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
++/* 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
@@ -82417,7 +88262,9 @@
 +#define HYPERPRIVOP_GET_PMD		0x15
 +#define HYPERPRIVOP_GET_EFLAG		0x16
 +#define HYPERPRIVOP_SET_EFLAG		0x17
-+#define HYPERPRIVOP_MAX			0x17
++#define HYPERPRIVOP_RSM_BE		0x18
++#define HYPERPRIVOP_GET_PSR		0x19
++#define HYPERPRIVOP_MAX			0x19
 +
 +#endif /* __HYPERVISOR_IF_IA64_H__ */
 +
@@ -82430,10 +88277,129 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/arch-x86_32.h linux-2.6.17-xen/include/xen/interface/arch-x86_32.h
---- linux-2.6.17/include/xen/interface/arch-x86_32.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/arch-x86_32.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,233 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/arch-powerpc.h linux-2.6.18-rc5-xen/include/xen/interface/arch-powerpc.h
+--- linux-2.6.18-rc5/include/xen/interface/arch-powerpc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/arch-powerpc.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,115 @@
++/*
++ * 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.
++ *
++ * Copyright (C) IBM Corp. 2005, 2006
++ *
++ * Authors: Hollis Blanchard <hollisb at 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__
++
++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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/arch-x86_32.h linux-2.6.18-rc5-xen/include/xen/interface/arch-x86_32.h
+--- linux-2.6.18-rc5/include/xen/interface/arch-x86_32.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/arch-x86_32.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,256 @@
 +/******************************************************************************
 + * arch-x86_32.h
 + * 
@@ -82445,8 +88411,33 @@
 +#ifndef __XEN_PUBLIC_ARCH_X86_32_H__
 +#define __XEN_PUBLIC_ARCH_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
++
++
++/* 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
@@ -82501,9 +88492,6 @@
 +#define FLAT_USER_DS    FLAT_RING3_DS
 +#define FLAT_USER_SS    FLAT_RING3_SS
 +
-+/* And the trap vector is... */
-+#define TRAP_INSTR "int $0x82"
-+
 +/*
 + * Virtual addresses beyond this are not modifiable by guest OSes. The 
 + * machine->physical mapping table starts at this address, read-only.
@@ -82627,6 +88615,7 @@
 +    /* 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;
 +
@@ -82667,10 +88656,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/arch-x86_64.h linux-2.6.17-xen/include/xen/interface/arch-x86_64.h
---- linux-2.6.17/include/xen/interface/arch-x86_64.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/arch-x86_64.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,299 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/arch-x86_64.h linux-2.6.18-rc5-xen/include/xen/interface/arch-x86_64.h
+--- linux-2.6.18-rc5/include/xen/interface/arch-x86_64.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/arch-x86_64.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,322 @@
 +/******************************************************************************
 + * arch-x86_64.h
 + * 
@@ -82682,8 +88671,33 @@
 +#ifndef __XEN_PUBLIC_ARCH_X86_64_H__
 +#define __XEN_PUBLIC_ARCH_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
++
++/* 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
@@ -82753,9 +88767,6 @@
 +#define FLAT_USER_SS32 FLAT_RING3_SS32
 +#define FLAT_USER_SS   FLAT_USER_SS64
 +
-+/* And the trap vector is... */
-+#define TRAP_INSTR "syscall"
-+
 +#define __HYPERVISOR_VIRT_START 0xFFFF800000000000
 +#define __HYPERVISOR_VIRT_END   0xFFFF880000000000
 +#define __MACH2PHYS_VIRT_START  0xFFFF800000000000
@@ -82934,6 +88945,7 @@
 +    /* 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;
 +
@@ -82970,9 +88982,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/callback.h linux-2.6.17-xen/include/xen/interface/callback.h
---- linux-2.6.17/include/xen/interface/callback.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/callback.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/callback.h linux-2.6.18-rc5-xen/include/xen/interface/callback.h
+--- linux-2.6.18-rc5/include/xen/interface/callback.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/callback.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,74 @@
 +/******************************************************************************
 + * callback.h
@@ -83048,10 +89060,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/dom0_ops.h linux-2.6.17-xen/include/xen/interface/dom0_ops.h
---- linux-2.6.17/include/xen/interface/dom0_ops.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/dom0_ops.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,598 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/dom0_ops.h linux-2.6.18-rc5-xen/include/xen/interface/dom0_ops.h
+--- linux-2.6.18-rc5/include/xen/interface/dom0_ops.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/dom0_ops.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,656 @@
 +/******************************************************************************
 + * dom0_ops.h
 + * 
@@ -83072,8 +89084,19 @@
 + * Make sure you increment the interface version whenever you modify this file!
 + * This makes sure that old versions of dom0 tools will stop working in a
 + * well-defined way (rather than crashing the machine, for instance).
++ * 
++ * Separate kernel from tools as the kernel uses a small subset of the dom0
++ * operations and so it is unnecessary to break backward compatibility so
++ * often.
 + */
-+#define DOM0_INTERFACE_VERSION   0x03000001
++#define DOM0_TOOLS_INTERFACE_VERSION  0x13000001
++#define DOM0_KERNEL_INTERFACE_VERSION 0x03000001
++
++#ifdef __XEN_TOOLS__
++#define DOM0_INTERFACE_VERSION DOM0_TOOLS_INTERFACE_VERSION
++#else
++#define DOM0_INTERFACE_VERSION DOM0_KERNEL_INTERFACE_VERSION
++#endif
 +
 +/************************************************************************/
 +
@@ -83216,7 +89239,7 @@
 +
 +struct dom0_getpageframeinfo {
 +    /* IN variables. */
-+    xen_pfn_t mfn;         /* Machine page frame number to query.       */
++    xen_pfn_t gmfn;        /* GMFN to query.                            */
 +    domid_t domain;        /* To which domain does the frame belong?    */
 +    /* OUT variables. */
 +    /* Is the page PINNED to a type? */
@@ -83231,9 +89254,9 @@
 +#define DOM0_READCONSOLE      19
 +struct dom0_readconsole {
 +    /* IN variables. */
-+    uint32_t clear;            /* Non-zero -> clear after reading. */
++    uint32_t clear;                /* Non-zero -> clear after reading. */
++    XEN_GUEST_HANDLE(char) buffer; /* Buffer start */
 +    /* IN/OUT variables. */
-+    XEN_GUEST_HANDLE(char) buffer; /* In: Buffer start; Out: Used buffer start */
 +    uint32_t count;            /* In: Buffer size;  Out: Used buffer size  */
 +};
 +typedef struct dom0_readconsole dom0_readconsole_t;
@@ -83307,20 +89330,54 @@
 + */
 +#define DOM0_SHADOW_CONTROL  25
 +
++/* Disable shadow mode. */
 +#define DOM0_SHADOW_CONTROL_OP_OFF         0
-+#define DOM0_SHADOW_CONTROL_OP_ENABLE_TEST 1
-+#define DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY 2
-+#define DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE 3
 +
-+#define DOM0_SHADOW_CONTROL_OP_FLUSH       10     /* table ops */
++/* Enable shadow mode (mode contains ORed DOM0_SHADOW_ENABLE_* flags). */
++#define DOM0_SHADOW_CONTROL_OP_ENABLE      32
++
++/* Log-dirty bitmap operations. */
++ /* Return the bitmap and clean internal copy for next round. */
 +#define DOM0_SHADOW_CONTROL_OP_CLEAN       11
++ /* Return the bitmap but do not modify internal copy. */
 +#define DOM0_SHADOW_CONTROL_OP_PEEK        12
 +
++/* Memory allocation accessors. */
++#define DOM0_SHADOW_CONTROL_OP_GET_ALLOCATION   30
++#define DOM0_SHADOW_CONTROL_OP_SET_ALLOCATION   31
++
++/* Legacy enable operations. */
++ /* Equiv. to ENABLE with no mode flags. */
++#define DOM0_SHADOW_CONTROL_OP_ENABLE_TEST       1
++ /* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */
++#define DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY   2
++ /* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */
++#define DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE  3
++
++/* Mode flags for DOM0_SHADOW_CONTROL_OP_ENABLE. */
++ /*
++  * Shadow pagetables are refcounted: guest does not use explicit mmu
++  * operations nor write-protect its pagetables.
++  */
++#define DOM0_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 DOM0_SHADOW_ENABLE_LOG_DIRTY (1 << 2)
++ /*
++  * Automatically translate GPFNs into MFNs.
++  */
++#define DOM0_SHADOW_ENABLE_TRANSLATE (1 << 3)
++ /*
++  * Xen does not steal virtual address space from the guest.
++  * Requires HVM support.
++  */
++#define DOM0_SHADOW_ENABLE_EXTERNAL  (1 << 4)
++
 +struct dom0_shadow_control_stats {
 +    uint32_t fault_count;
 +    uint32_t dirty_count;
-+    uint32_t dirty_net_count;
-+    uint32_t dirty_block_count;
 +};
 +typedef struct dom0_shadow_control_stats dom0_shadow_control_stats_t;
 +DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_stats_t);
@@ -83328,11 +89385,17 @@
 +struct dom0_shadow_control {
 +    /* IN variables. */
 +    domid_t        domain;
-+    uint32_t       op;
++    uint32_t       op;       /* DOM0_SHADOW_CONTROL_OP_* */
++
++    /* OP_ENABLE */
++    uint32_t       mode;     /* DOM0_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;
-+    /* IN/OUT variables. */
-+    uint64_t       pages;        /* size of buffer, updated with actual size */
-+    /* OUT variables. */
++    uint64_t       pages;    /* Size of buffer. Updated with actual size. */
 +    struct dom0_shadow_control_stats stats;
 +};
 +typedef struct dom0_shadow_control dom0_shadow_control_t;
@@ -83415,17 +89478,20 @@
 +struct dom0_perfc_desc {
 +    char         name[80];             /* name of perf counter */
 +    uint32_t     nr_vals;              /* number of values for this counter */
-+    uint32_t     vals[64];             /* array of values */
 +};
 +typedef struct dom0_perfc_desc dom0_perfc_desc_t;
 +DEFINE_XEN_GUEST_HANDLE(dom0_perfc_desc_t);
++typedef uint32_t dom0_perfc_val_t;
++DEFINE_XEN_GUEST_HANDLE(dom0_perfc_val_t);
 +
 +struct dom0_perfccontrol {
 +    /* IN variables. */
 +    uint32_t       op;                /*  DOM0_PERFCCONTROL_OP_??? */
 +    /* OUT variables. */
-+    uint32_t       nr_counters;       /*  number of counters */
++    uint32_t       nr_counters;       /*  number of counters description  */
++    uint32_t       nr_vals;			  /*  number of values  */
 +    XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc; /*  counter information (or NULL) */
++    XEN_GUEST_HANDLE(dom0_perfc_val_t) val;   /*  counter values (or NULL)  */
 +};
 +typedef struct dom0_perfccontrol dom0_perfccontrol_t;
 +DEFINE_XEN_GUEST_HANDLE(dom0_perfccontrol_t);
@@ -83563,8 +89629,8 @@
 +
 +#define DOM0_HYPERCALL_INIT   48
 +struct dom0_hypercall_init {
-+    domid_t  domain;          /* domain to be affected */
-+    xen_pfn_t mfn;            /* machine frame to be initialised */
++    domid_t   domain;          /* domain to be affected */
++    xen_pfn_t gmfn;            /* GMFN to be initialised */
 +};
 +typedef struct dom0_hypercall_init dom0_hypercall_init_t;
 +DEFINE_XEN_GUEST_HANDLE(dom0_hypercall_init_t);
@@ -83572,12 +89638,16 @@
 +#define DOM0_DOMAIN_SETUP     49
 +#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 dom0_domain_setup {
 +    domid_t  domain;          /* domain to be affected */
 +    unsigned long flags;      /* XEN_DOMAINSETUP_* */
 +#ifdef __ia64__
 +    unsigned long bp;         /* mpaddr of boot param area */
 +    unsigned long maxmem;	  /* Highest memory address for MDT.  */
++    unsigned long xsi_va;     /* Xen shared_info area virtual address.  */
++    unsigned int hypercall_imm;	/* Break imm for Xen hypercalls.  */
 +#endif
 +} dom0_domain_setup_t;
 +DEFINE_XEN_GUEST_HANDLE(dom0_domain_setup_t);
@@ -83650,9 +89720,146 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/event_channel.h linux-2.6.17-xen/include/xen/interface/event_channel.h
---- linux-2.6.17/include/xen/interface/event_channel.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/event_channel.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/elfnote.h linux-2.6.18-rc5-xen/include/xen/interface/elfnote.h
+--- linux-2.6.18-rc5/include/xen/interface/elfnote.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/elfnote.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,133 @@
++/******************************************************************************
++ * elfnote.h
++ *
++ * Definitions used for the Xen ELF notes.
++ *
++ * 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
++
++#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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/event_channel.h linux-2.6.18-rc5-xen/include/xen/interface/event_channel.h
+--- linux-2.6.18-rc5/include/xen/interface/event_channel.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/event_channel.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,233 @@
 +/******************************************************************************
 + * event_channel.h
@@ -83887,9 +90094,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/features.h linux-2.6.17-xen/include/xen/interface/features.h
---- linux-2.6.17/include/xen/interface/features.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/features.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/features.h linux-2.6.18-rc5-xen/include/xen/interface/features.h
+--- linux-2.6.18-rc5/include/xen/interface/features.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/features.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,53 @@
 +/******************************************************************************
 + * features.h
@@ -83944,10 +90151,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/grant_table.h linux-2.6.17-xen/include/xen/interface/grant_table.h
---- linux-2.6.17/include/xen/interface/grant_table.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/grant_table.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,317 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/grant_table.h linux-2.6.18-rc5-xen/include/xen/interface/grant_table.h
+--- linux-2.6.18-rc5/include/xen/interface/grant_table.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/grant_table.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,362 @@
 +/******************************************************************************
 + * grant_table.h
 + * 
@@ -84095,9 +90302,9 @@
 + * that must be presented later to destroy the mapping(s). On error, <handle>
 + * is a negative status code.
 + * NOTES:
-+ *  1. If GNTPIN_map_for_dev is specified then <dev_bus_addr> is the address
++ *  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 GNTPIN_map_for_host is specified then a mapping will be added at
++ *  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 
@@ -84199,6 +90406,49 @@
 +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.
 + */
@@ -84240,6 +90490,7 @@
 +#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",                                     \
@@ -84251,7 +90502,8 @@
 +    "invalid device address",                   \
 +    "no spare translation slot in the I/O MMU", \
 +    "permission denied",                        \
-+    "bad page"                                  \
++    "bad page",                                 \
++    "copy arguments cross page boundary"        \
 +}
 +
 +#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
@@ -84265,10 +90517,46 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/hvm/hvm_info_table.h linux-2.6.17-xen/include/xen/interface/hvm/hvm_info_table.h
---- linux-2.6.17/include/xen/interface/hvm/hvm_info_table.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/hvm/hvm_info_table.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,24 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/hvm/e820.h linux-2.6.18-rc5-xen/include/xen/interface/hvm/e820.h
+--- linux-2.6.18-rc5/include/xen/interface/hvm/e820.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/hvm/e820.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,32 @@
++#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
++
++/* Xen HVM extended E820 types. */
++#define E820_IO          16
++#define E820_SHARED_PAGE 17
++#define E820_XENSTORE    18
++#define E820_BUFFERED_IO 19
++
++/* 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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/hvm/hvm_info_table.h linux-2.6.18-rc5-xen/include/xen/interface/hvm/hvm_info_table.h
+--- linux-2.6.18-rc5/include/xen/interface/hvm/hvm_info_table.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/hvm/hvm_info_table.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,22 @@
 +/******************************************************************************
 + * hvm/hvm_info_table.h
 + * 
@@ -84287,16 +90575,14 @@
 +    uint32_t    length;
 +    uint8_t     checksum;
 +    uint8_t     acpi_enabled;
-+    uint8_t     apic_enabled;
-+    uint8_t     pae_enabled;
 +    uint32_t    nr_vcpus;
 +};
 +
 +#endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/hvm/ioreq.h linux-2.6.17-xen/include/xen/interface/hvm/ioreq.h
---- linux-2.6.17/include/xen/interface/hvm/ioreq.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/hvm/ioreq.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,93 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/hvm/ioreq.h linux-2.6.18-rc5-xen/include/xen/interface/hvm/ioreq.h
+--- linux-2.6.18-rc5/include/xen/interface/hvm/ioreq.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/hvm/ioreq.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,99 @@
 +/*
 + * ioreq.h: I/O request definitions for device models
 + * Copyright (c) 2004, Intel Corporation.
@@ -84326,7 +90612,6 @@
 +#define STATE_IOREQ_READY       1
 +#define STATE_IOREQ_INPROCESS   2
 +#define STATE_IORESP_READY      3
-+#define STATE_IORESP_HOOK       4
 +
 +#define IOREQ_TYPE_PIO          0 /* pio */
 +#define IOREQ_TYPE_COPY         1 /* mmio ops */
@@ -84369,7 +90654,6 @@
 +    struct ioreq         vp_ioreq;
 +    /* Event channel port */
 +    unsigned int    vp_eport;   /* VMX vcpu uses this to notify DM */
-+    unsigned int    dm_eport;   /* DM uses this to notify VMX vcpu */
 +};
 +typedef struct vcpu_iodata vcpu_iodata_t;
 +
@@ -84379,6 +90663,14 @@
 +};
 +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;
++
 +#endif /* _IOREQ_H_ */
 +
 +/*
@@ -84390,9 +90682,37 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/hvm/vmx_assist.h linux-2.6.17-xen/include/xen/interface/hvm/vmx_assist.h
---- linux-2.6.17/include/xen/interface/hvm/vmx_assist.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/hvm/vmx_assist.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/hvm/params.h linux-2.6.18-rc5-xen/include/xen/interface/hvm/params.h
+--- linux-2.6.18-rc5/include/xen/interface/hvm/params.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/hvm/params.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,24 @@
++#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
++#define __XEN_PUBLIC_HVM_PARAMS_H__
++
++/* Parameter space. */
++#define HVM_PARAM_CALLBACK_IRQ 0
++#define HVM_PARAM_STORE_PFN    1
++#define HVM_PARAM_STORE_EVTCHN 2
++#define HVM_PARAM_APIC_ENABLED 3
++#define HVM_PARAM_PAE_ENABLED  4
++#define HVM_NR_PARAMS          5
++
++/* 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);
++
++#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/hvm/vmx_assist.h linux-2.6.18-rc5-xen/include/xen/interface/hvm/vmx_assist.h
+--- linux-2.6.18-rc5/include/xen/interface/hvm/vmx_assist.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/hvm/vmx_assist.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,98 @@
 +/*
 + * vmx_assist.h: Context definitions for the VMXASSIST world switch.
@@ -84492,9 +90812,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/io/blkif.h linux-2.6.17-xen/include/xen/interface/io/blkif.h
---- linux-2.6.17/include/xen/interface/io/blkif.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/io/blkif.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/io/blkif.h linux-2.6.18-rc5-xen/include/xen/interface/io/blkif.h
+--- linux-2.6.18-rc5/include/xen/interface/io/blkif.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/io/blkif.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,87 @@
 +/******************************************************************************
 + * blkif.h
@@ -84583,9 +90903,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/io/console.h linux-2.6.17-xen/include/xen/interface/io/console.h
---- linux-2.6.17/include/xen/interface/io/console.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/io/console.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/io/console.h linux-2.6.18-rc5-xen/include/xen/interface/io/console.h
+--- linux-2.6.18-rc5/include/xen/interface/io/console.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/io/console.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,33 @@
 +/******************************************************************************
 + * console.h
@@ -84620,10 +90940,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/io/netif.h linux-2.6.17-xen/include/xen/interface/io/netif.h
---- linux-2.6.17/include/xen/interface/io/netif.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/io/netif.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,148 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/io/netif.h linux-2.6.18-rc5-xen/include/xen/interface/io/netif.h
+--- linux-2.6.18-rc5/include/xen/interface/io/netif.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/io/netif.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,166 @@
 +/******************************************************************************
 + * netif.h
 + * 
@@ -84639,10 +90959,11 @@
 +#include "../grant_table.h"
 +
 +/*
-+ * Note that there is *never* any need to notify the backend when
-+ * enqueuing receive requests (struct netif_rx_request). Notifications
-+ * after enqueuing any other type of message should be conditional on
++ * 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).
 + */
 +
 +/*
@@ -84691,7 +91012,7 @@
 +#define XEN_NETIF_EXTRA_FLAG_MORE  (1U<<_XEN_NETIF_EXTRA_FLAG_MORE)
 +
 +/* GSO types - only TCPv4 currently supported. */
-+#define XEN_NETIF_GSO_TCPV4        (1)
++#define XEN_NETIF_GSO_TYPE_TCPV4        (1)
 +
 +/*
 + * This structure needs to fit within both netif_tx_request and
@@ -84713,7 +91034,16 @@
 +             * GSO type. This determines the protocol of the packet and any
 +             * extra features required to segment the packet properly.
 +             */
-+            uint16_t type; /* XEN_NETIF_GSO_* */
++            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];
@@ -84740,6 +91070,14 @@
 +#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  */
@@ -84772,9 +91110,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/io/pciif.h linux-2.6.17-xen/include/xen/interface/io/pciif.h
---- linux-2.6.17/include/xen/interface/io/pciif.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/io/pciif.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/io/pciif.h linux-2.6.18-rc5-xen/include/xen/interface/io/pciif.h
+--- linux-2.6.18-rc5/include/xen/interface/io/pciif.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/io/pciif.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,55 @@
 +/*
 + * PCI Backend/Frontend Common Data Structures & Macros
@@ -84831,9 +91169,9 @@
 +};
 +
 +#endif /* __XEN_PCI_COMMON_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/io/ring.h linux-2.6.17-xen/include/xen/interface/io/ring.h
---- linux-2.6.17/include/xen/interface/io/ring.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/io/ring.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/io/ring.h linux-2.6.18-rc5-xen/include/xen/interface/io/ring.h
+--- linux-2.6.18-rc5/include/xen/interface/io/ring.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/io/ring.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,273 @@
 +/******************************************************************************
 + * ring.h
@@ -85108,9 +91446,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/io/tpmif.h linux-2.6.17-xen/include/xen/interface/io/tpmif.h
---- linux-2.6.17/include/xen/interface/io/tpmif.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/io/tpmif.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/io/tpmif.h linux-2.6.18-rc5-xen/include/xen/interface/io/tpmif.h
+--- linux-2.6.18-rc5/include/xen/interface/io/tpmif.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/io/tpmif.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,59 @@
 +/******************************************************************************
 + * tpmif.h
@@ -85171,9 +91509,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/io/xenbus.h linux-2.6.17-xen/include/xen/interface/io/xenbus.h
---- linux-2.6.17/include/xen/interface/io/xenbus.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/io/xenbus.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/io/xenbus.h linux-2.6.18-rc5-xen/include/xen/interface/io/xenbus.h
+--- linux-2.6.18-rc5/include/xen/interface/io/xenbus.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/io/xenbus.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,45 @@
 +/*****************************************************************************
 + * xenbus.h
@@ -85220,9 +91558,9 @@
 +typedef enum xenbus_state XenbusState;
 +
 +#endif /* _XEN_PUBLIC_IO_XENBUS_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/io/xs_wire.h linux-2.6.17-xen/include/xen/interface/io/xs_wire.h
---- linux-2.6.17/include/xen/interface/io/xs_wire.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/io/xs_wire.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/io/xs_wire.h linux-2.6.18-rc5-xen/include/xen/interface/io/xs_wire.h
+--- linux-2.6.18-rc5/include/xen/interface/io/xs_wire.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/io/xs_wire.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,97 @@
 +/*
 + * Details of the "wire" protocol between Xen Store Daemon and client
@@ -85321,9 +91659,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/memory.h linux-2.6.17-xen/include/xen/interface/memory.h
---- linux-2.6.17/include/xen/interface/memory.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/memory.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/memory.h linux-2.6.18-rc5-xen/include/xen/interface/memory.h
+--- linux-2.6.18-rc5/include/xen/interface/memory.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/memory.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,243 @@
 +/******************************************************************************
 + * memory.h
@@ -85568,9 +91906,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/nmi.h linux-2.6.17-xen/include/xen/interface/nmi.h
---- linux-2.6.17/include/xen/interface/nmi.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/nmi.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/nmi.h linux-2.6.18-rc5-xen/include/xen/interface/nmi.h
+--- linux-2.6.18-rc5/include/xen/interface/nmi.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/nmi.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,60 @@
 +/******************************************************************************
 + * nmi.h
@@ -85632,9 +91970,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/physdev.h linux-2.6.17-xen/include/xen/interface/physdev.h
---- linux-2.6.17/include/xen/interface/physdev.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/physdev.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/physdev.h linux-2.6.18-rc5-xen/include/xen/interface/physdev.h
+--- linux-2.6.18-rc5/include/xen/interface/physdev.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/physdev.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,149 @@
 +
 +#ifndef __XEN_PUBLIC_PHYSDEV_H__
@@ -85785,10 +92123,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/sched_ctl.h linux-2.6.17-xen/include/xen/interface/sched_ctl.h
---- linux-2.6.17/include/xen/interface/sched_ctl.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/sched_ctl.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,69 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/sched_ctl.h linux-2.6.18-rc5-xen/include/xen/interface/sched_ctl.h
+--- linux-2.6.18-rc5/include/xen/interface/sched_ctl.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/sched_ctl.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,56 @@
 +/******************************************************************************
 + * Generic scheduler control interface.
 + *
@@ -85799,7 +92137,6 @@
 +#define __XEN_PUBLIC_SCHED_CTL_H__
 +
 +/* Scheduler types. */
-+#define SCHED_BVT      0
 +#define SCHED_SEDF     4
 +#define SCHED_CREDIT   5
 +
@@ -85814,11 +92151,6 @@
 +struct sched_ctl_cmd {
 +    uint32_t sched_id;
 +    uint32_t direction;
-+    union {
-+        struct bvt_ctl {
-+            uint32_t ctx_allow;
-+        } bvt;
-+    } u;
 +};
 +
 +struct sched_adjdom_cmd {
@@ -85826,13 +92158,6 @@
 +    uint32_t direction;
 +    domid_t  domain;
 +    union {
-+        struct bvt_adjdom {
-+            uint32_t mcu_adv;      /* mcu advance: inverse of weight */
-+            uint32_t warpback;     /* warp? */
-+            int32_t  warpvalue;    /* warp value */
-+            int64_t  warpl;        /* warp limit */
-+            int64_t  warpu;        /* unwarp time requirement */
-+        } bvt;
 +        struct sedf_adjdom {
 +            uint64_t period;
 +            uint64_t slice;
@@ -85858,9 +92183,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/sched.h linux-2.6.17-xen/include/xen/interface/sched.h
---- linux-2.6.17/include/xen/interface/sched.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/sched.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/sched.h linux-2.6.18-rc5-xen/include/xen/interface/sched.h
+--- linux-2.6.18-rc5/include/xen/interface/sched.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/sched.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,103 @@
 +/******************************************************************************
 + * sched.h
@@ -85965,10 +92290,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/trace.h linux-2.6.17-xen/include/xen/interface/trace.h
---- linux-2.6.17/include/xen/interface/trace.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/trace.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,86 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/trace.h linux-2.6.18-rc5-xen/include/xen/interface/trace.h
+--- linux-2.6.18-rc5/include/xen/interface/trace.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/trace.h	2006-07-20 15:57:37.000000000 +0200
+@@ -0,0 +1,87 @@
 +/******************************************************************************
 + * include/public/trace.h
 + * 
@@ -85997,6 +92322,7 @@
 +#define TRC_VMXIO    0x00088000   /* VMX io emulation 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)
@@ -86055,9 +92381,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/vcpu.h linux-2.6.17-xen/include/xen/interface/vcpu.h
---- linux-2.6.17/include/xen/interface/vcpu.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/vcpu.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/vcpu.h linux-2.6.18-rc5-xen/include/xen/interface/vcpu.h
+--- linux-2.6.18-rc5/include/xen/interface/vcpu.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/vcpu.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,121 @@
 +/******************************************************************************
 + * vcpu.h
@@ -86180,10 +92506,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/version.h linux-2.6.17-xen/include/xen/interface/version.h
---- linux-2.6.17/include/xen/interface/version.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/version.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,70 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/version.h linux-2.6.18-rc5-xen/include/xen/interface/version.h
+--- linux-2.6.18-rc5/include/xen/interface/version.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/version.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,73 @@
 +/******************************************************************************
 + * version.h
 + * 
@@ -86243,6 +92569,9 @@
 +/* 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__ */
 +
 +/*
@@ -86254,10 +92583,51 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/xen-compat.h linux-2.6.17-xen/include/xen/interface/xen-compat.h
---- linux-2.6.17/include/xen/interface/xen-compat.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/xen-compat.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,47 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/xencomm.h linux-2.6.18-rc5-xen/include/xen/interface/xencomm.h
+--- linux-2.6.18-rc5/include/xen/interface/xencomm.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/xencomm.h	2006-07-20 15:57:37.000000000 +0200
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2006 Hollis Blanchard <hollisb at 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 _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 -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/xen-compat.h linux-2.6.18-rc5-xen/include/xen/interface/xen-compat.h
+--- linux-2.6.18-rc5/include/xen/interface/xen-compat.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/xen-compat.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,26 @@
 +/******************************************************************************
 + * xen-compat.h
 + * 
@@ -86269,7 +92639,7 @@
 +#ifndef __XEN_PUBLIC_XEN_COMPAT_H__
 +#define __XEN_PUBLIC_XEN_COMPAT_H__
 +
-+#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030202
++#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030203
 +
 +#if defined(__XEN__) || defined(__XEN_TOOLS__)
 +/* Xen is built with matching headers and implements the latest interface. */
@@ -86283,32 +92653,11 @@
 +#error "These header files do not support the requested interface version."
 +#endif
 +
-+/* 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
-+
-+/* Structural guest handles introduced in 0x00030201. */
-+#if __XEN_INTERFACE_VERSION__ < 0x00030201
-+#undef __DEFINE_XEN_GUEST_HANDLE
-+#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
-+    typedef type * __guest_handle_ ## name
-+#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
-+
 +#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/xen.h linux-2.6.17-xen/include/xen/interface/xen.h
---- linux-2.6.17/include/xen/interface/xen.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/xen.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,505 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/xen.h linux-2.6.18-rc5-xen/include/xen/interface/xen.h
+--- linux-2.6.18-rc5/include/xen/interface/xen.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/xen.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,558 @@
 +/******************************************************************************
 + * xen.h
 + * 
@@ -86320,28 +92669,24 @@
 +#ifndef __XEN_PUBLIC_XEN_H__
 +#define __XEN_PUBLIC_XEN_H__
 +
++#include "xen-compat.h"
++
 +#if defined(__i386__)
 +#include "arch-x86_32.h"
 +#elif defined(__x86_64__)
 +#include "arch-x86_64.h"
 +#elif defined(__ia64__)
 +#include "arch-ia64.h"
++#elif defined(__powerpc__)
++#include "arch-powerpc.h"
 +#else
 +#error "Unsupported architecture"
 +#endif
 +
 +/*
-+ * XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS).
++ * HYPERCALLS
 + */
 +
-+/*
-+ * x86_32: EAX = vector; EBX, ECX, EDX, ESI, EDI = args 1, 2, 3, 4, 5.
-+ *         EAX = return value
-+ *         (argument registers may be clobbered on return)
-+ * x86_64: RAX = vector; RDI, RSI, RDX, R10, R8, R9 = args 1, 2, 3, 4, 5, 6. 
-+ *         RAX = return value
-+ *         (argument registers not clobbered on return; RCX, R11 are)
-+ */
 +#define __HYPERVISOR_set_trap_table        0
 +#define __HYPERVISOR_mmu_update            1
 +#define __HYPERVISOR_set_gdt               2
@@ -86375,6 +92720,7 @@
 +#define __HYPERVISOR_xenoprof_op          31
 +#define __HYPERVISOR_event_channel_op     32
 +#define __HYPERVISOR_physdev_op           33
++#define __HYPERVISOR_hvm_op               34
 +
 +/* Architecture-specific hypercall definitions. */
 +#define __HYPERVISOR_arch_0               48
@@ -86386,6 +92732,24 @@
 +#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
++
 +/* 
 + * VIRTUAL INTERRUPTS
 + * 
@@ -86684,7 +93048,11 @@
 +
 +/*
 + * Xen/kernel shared data -- pointer provided in start_info.
-+ * NB. We expect that this struct is smaller than a page.
++ *
++ * 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];
@@ -86770,8 +93138,16 @@
 +    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. */
-+    xen_pfn_t console_mfn;      /* MACHINE page number of console page.   */
-+    uint32_t console_evtchn;    /* Event channel for console messages.    */
++    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.       */
@@ -86782,10 +93158,38 @@
 +};
 +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;
++    uint8_t txt_points;
++    uint16_t txt_mode;
++    uint16_t txt_x;
++    uint16_t txt_y;
++    uint16_t video_width;
++    uint16_t video_height;
++    uint16_t lfb_linelen;
++    uint16_t lfb_depth;
++    unsigned long lfb_base;
++    unsigned long lfb_size;
++    uint8_t red_pos;
++    uint8_t red_size;
++    uint8_t green_pos;
++    uint8_t green_size;
++    uint8_t blue_pos;
++    uint8_t blue_size;
++    uint8_t rsvd_pos;
++    uint8_t rsvd_size;
++} dom0_vga_console_info_t;
++
 +typedef uint64_t cpumap_t;
 +
 +typedef uint8_t xen_domain_handle_t[16];
@@ -86801,8 +93205,6 @@
 +
 +#endif /* !__ASSEMBLY__ */
 +
-+#include "xen-compat.h"
-+
 +#endif /* __XEN_PUBLIC_XEN_H__ */
 +
 +/*
@@ -86814,9 +93216,9 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/interface/xenoprof.h linux-2.6.17-xen/include/xen/interface/xenoprof.h
---- linux-2.6.17/include/xen/interface/xenoprof.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/interface/xenoprof.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/interface/xenoprof.h linux-2.6.18-rc5-xen/include/xen/interface/xenoprof.h
+--- linux-2.6.18-rc5/include/xen/interface/xenoprof.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/interface/xenoprof.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,103 @@
 +/******************************************************************************
 + * xenoprof.h
@@ -86921,10 +93323,10 @@
 + * indent-tabs-mode: nil
 + * End:
 + */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/pcifront.h linux-2.6.17-xen/include/xen/pcifront.h
---- linux-2.6.17/include/xen/pcifront.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/pcifront.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,39 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/pcifront.h linux-2.6.18-rc5-xen/include/xen/pcifront.h
+--- linux-2.6.18-rc5/include/xen/pcifront.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/pcifront.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,76 @@
 +/*
 + * PCI Frontend - arch-dependendent declarations
 + *
@@ -86933,21 +93335,34 @@
 +#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;
 +};
 +
-+struct pci_bus;
++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;
++}
 +
-+#ifdef CONFIG_PCI_DOMAINS
++#if defined(CONFIG_PCI_DOMAINS)
 +static inline int pci_domain_nr(struct pci_bus *bus)
 +{
 +	struct pcifront_sd *sd = bus->sysdata;
@@ -86959,14 +93374,38 @@
 +}
 +#endif /* CONFIG_PCI_DOMAINS */
 +
-+extern spinlock_t pci_bus_lock;
++#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 struct rw_semaphore pci_bus_sem;
 +
 +#endif /* __KERNEL__ */
 +
 +#endif /* __XEN_ASM_PCIFRONT_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/public/evtchn.h linux-2.6.17-xen/include/xen/public/evtchn.h
---- linux-2.6.17/include/xen/public/evtchn.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/public/evtchn.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/public/evtchn.h linux-2.6.18-rc5-xen/include/xen/public/evtchn.h
+--- linux-2.6.18-rc5/include/xen/public/evtchn.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/public/evtchn.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,91 @@
 +/******************************************************************************
 + * evtchn.h
@@ -87059,9 +93498,9 @@
 +	_IOC(_IOC_NONE, 'E', 5, 0)
 +
 +#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/public/privcmd.h linux-2.6.17-xen/include/xen/public/privcmd.h
---- linux-2.6.17/include/xen/public/privcmd.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/public/privcmd.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/public/privcmd.h linux-2.6.18-rc5-xen/include/xen/public/privcmd.h
+--- linux-2.6.18-rc5/include/xen/public/privcmd.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/public/privcmd.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,79 @@
 +/******************************************************************************
 + * privcmd.h
@@ -87142,10 +93581,10 @@
 +	_IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
 +
 +#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/xenbus.h linux-2.6.17-xen/include/xen/xenbus.h
---- linux-2.6.17/include/xen/xenbus.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/xenbus.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,299 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/xenbus.h linux-2.6.18-rc5-xen/include/xen/xenbus.h
+--- linux-2.6.18-rc5/include/xen/xenbus.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/xenbus.h	2006-09-01 00:09:12.000000000 +0200
+@@ -0,0 +1,300 @@
 +/******************************************************************************
 + * xenbus.h
 + *
@@ -87422,7 +93861,7 @@
 +
 +/**
 + * Return the state of the driver rooted at the given store path, or
-+ * XenbusStateClosed if no state can be read.
++ * XenbusStateUnknown if no state can be read.
 + */
 +enum xenbus_state xenbus_read_driver_state(const char *path);
 +
@@ -87443,11 +93882,12 @@
 +void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
 +		      ...);
 +
++int __init xenbus_dev_init(void);
 +
 +#endif /* _XEN_XENBUS_H */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/xencons.h linux-2.6.17-xen/include/xen/xencons.h
---- linux-2.6.17/include/xen/xencons.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/xencons.h	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/xencons.h linux-2.6.18-rc5-xen/include/xen/xencons.h
+--- linux-2.6.18-rc5/include/xen/xencons.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/xencons.h	2006-07-20 15:57:37.000000000 +0200
 @@ -0,0 +1,14 @@
 +#ifndef __ASM_XENCONS_H__
 +#define __ASM_XENCONS_H__
@@ -87463,86 +93903,39 @@
 +int xencons_ring_send(const char *data, unsigned len);
 +
 +#endif /* __ASM_XENCONS_H__ */
-diff -urN -x .hg -x .hgtags linux-2.6.17/include/xen/xen_proc.h linux-2.6.17-xen/include/xen/xen_proc.h
---- linux-2.6.17/include/xen/xen_proc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/include/xen/xen_proc.h	2006-08-14 15:58:23.000000000 +0200
-@@ -0,0 +1,13 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/include/xen/xen_proc.h linux-2.6.18-rc5-xen/include/xen/xen_proc.h
+--- linux-2.6.18-rc5/include/xen/xen_proc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/include/xen/xen_proc.h	2006-08-14 15:07:22.000000000 +0200
+@@ -0,0 +1,12 @@
 +
 +#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 -urN -x .hg -x .hgtags linux-2.6.17/kernel/fork.c linux-2.6.17-xen/kernel/fork.c
---- linux-2.6.17/kernel/fork.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/kernel/fork.c	2006-08-14 15:58:23.000000000 +0200
-@@ -272,6 +272,9 @@
- 		if (retval)
- 			goto out;
- 	}
-+#ifdef arch_dup_mmap
-+	arch_dup_mmap(mm, oldmm);
-+#endif
- 	retval = 0;
- out:
- 	up_write(&mm->mmap_sem);
-diff -urN -x .hg -x .hgtags linux-2.6.17/kernel/irq/manage.c linux-2.6.17-xen/kernel/irq/manage.c
---- linux-2.6.17/kernel/irq/manage.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/kernel/irq/manage.c	2006-08-14 15:58:23.000000000 +0200
-@@ -204,14 +204,10 @@
- 	p = &desc->action;
- 	if ((old = *p) != NULL) {
- 		/* Can't share interrupts unless both agree to */
--		if (!(old->flags & new->flags & SA_SHIRQ))
--			goto mismatch;
--
--#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ)
--		/* All handlers must agree on per-cpuness */
--		if ((old->flags & IRQ_PER_CPU) != (new->flags & IRQ_PER_CPU))
--			goto mismatch;
--#endif
-+		if (!(old->flags & new->flags & SA_SHIRQ)) {
-+			spin_unlock_irqrestore(&desc->lock,flags);
-+			return -EBUSY;
-+		}
- 
- 		/* add new interrupt at end of irq queue */
- 		do {
-@@ -222,10 +218,7 @@
- 	}
- 
- 	*p = new;
--#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ)
--	if (new->flags & SA_PERCPU_IRQ)
--		desc->status |= IRQ_PER_CPU;
--#endif
-+
- 	if (!shared) {
- 		desc->depth = 0;
- 		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT |
-@@ -243,14 +236,6 @@
- 	register_handler_proc(irq, new);
- 
- 	return 0;
--
--mismatch:
--	spin_unlock_irqrestore(&desc->lock, flags);
--	if (!(new->flags & SA_PROBEIRQ)) {
--		printk(KERN_ERR "%s: irq handler mismatch\n", __FUNCTION__);
--		dump_stack();
--	}
--	return -EBUSY;
- }
- 
- /**
-@@ -273,7 +258,6 @@
++
++#endif /* __ASM_XEN_PROC_H__ */
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/kernel/fork.c linux-2.6.18-rc5-xen/kernel/fork.c
+--- linux-2.6.18-rc5/kernel/fork.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/kernel/fork.c	2006-09-01 00:09:12.000000000 +0200
+@@ -275,6 +275,9 @@
+ 		if (retval)
+ 			goto out;
+ 	}
++#ifdef arch_dup_mmap
++	arch_dup_mmap(mm, oldmm);
++#endif
+ 	retval = 0;
+ out:
+ 	up_write(&mm->mmap_sem);
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/kernel/irq/manage.c linux-2.6.18-rc5-xen/kernel/irq/manage.c
+--- linux-2.6.18-rc5/kernel/irq/manage.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/kernel/irq/manage.c	2006-09-01 00:09:12.000000000 +0200
+@@ -350,7 +350,6 @@
  	struct irqaction **p;
  	unsigned long flags;
  
@@ -87550,22 +93943,9 @@
  	if (irq >= NR_IRQS)
  		return;
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/kernel/irq/spurious.c linux-2.6.17-xen/kernel/irq/spurious.c
---- linux-2.6.17/kernel/irq/spurious.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/kernel/irq/spurious.c	2006-08-14 15:58:23.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/kernel/Kconfig.preempt linux-2.6.17-xen/kernel/Kconfig.preempt
---- linux-2.6.17/kernel/Kconfig.preempt	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/kernel/Kconfig.preempt	2006-08-14 15:58:23.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/kernel/Kconfig.preempt linux-2.6.18-rc5-xen/kernel/Kconfig.preempt
+--- linux-2.6.18-rc5/kernel/Kconfig.preempt	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/kernel/Kconfig.preempt	2006-07-20 15:57:37.000000000 +0200
 @@ -35,6 +35,7 @@
  
  config PREEMPT
@@ -87574,37 +93954,23 @@
  	help
  	  This option reduces the latency of the kernel by making
  	  all kernel code (that is not executing in a critical section)
-diff -urN -x .hg -x .hgtags linux-2.6.17/kernel/timer.c linux-2.6.17-xen/kernel/timer.c
---- linux-2.6.17/kernel/timer.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/kernel/timer.c	2006-08-14 15:58:25.000000000 +0200
-@@ -557,6 +557,22 @@
- 	if (time_before(expires, jiffies))
- 		return jiffies;
- 
-+	/*
-+	 * 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 -urN -x .hg -x .hgtags linux-2.6.17/lib/Makefile linux-2.6.17-xen/lib/Makefile
---- linux-2.6.17/lib/Makefile	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/lib/Makefile	2006-08-14 15:58:25.000000000 +0200
-@@ -48,6 +48,9 @@
- obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/lib/Kconfig.debug linux-2.6.18-rc5-xen/lib/Kconfig.debug
+--- linux-2.6.18-rc5/lib/Kconfig.debug	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/lib/Kconfig.debug	2006-09-01 00:09:12.000000000 +0200
+@@ -325,7 +325,7 @@
+ 
+ config UNWIND_INFO
+ 	bool "Compile the kernel with frame unwind information"
+-	depends on !IA64 && !PARISC
++	depends on !IA64 && !PARISC && !X86_64_XEN
+ 	depends on !MODULES || !(MIPS || PPC || SUPERH || V850)
+ 	help
+ 	  If you say Y here the resulting kernel image will be slightly larger
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/lib/Makefile linux-2.6.18-rc5-xen/lib/Makefile
+--- linux-2.6.18-rc5/lib/Makefile	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/lib/Makefile	2006-07-20 15:57:38.000000000 +0200
+@@ -51,6 +51,9 @@
+ obj-$(CONFIG_SMP) += percpu_counter.o
  
  obj-$(CONFIG_SWIOTLB) += swiotlb.o
 +ifneq ($(CONFIG_XEN_IA64_DOM0_NON_VP),y)
@@ -87613,9 +93979,9 @@
  
  hostprogs-y	:= gen_crc32table
  clean-files	:= crc32table.h
-diff -urN -x .hg -x .hgtags linux-2.6.17/mm/highmem.c linux-2.6.17-xen/mm/highmem.c
---- linux-2.6.17/mm/highmem.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/mm/highmem.c	2006-08-14 15:58:25.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/mm/highmem.c linux-2.6.18-rc5-xen/mm/highmem.c
+--- linux-2.6.18-rc5/mm/highmem.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/mm/highmem.c	2006-07-20 15:57:38.000000000 +0200
 @@ -142,6 +142,17 @@
  	return vaddr;
  }
@@ -87634,10 +94000,10 @@
  void fastcall *kmap_high(struct page *page)
  {
  	unsigned long vaddr;
-diff -urN -x .hg -x .hgtags linux-2.6.17/mm/Kconfig linux-2.6.17-xen/mm/Kconfig
---- linux-2.6.17/mm/Kconfig	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/mm/Kconfig	2006-08-14 15:58:25.000000000 +0200
-@@ -126,11 +126,14 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/mm/Kconfig linux-2.6.18-rc5-xen/mm/Kconfig
+--- linux-2.6.18-rc5/mm/Kconfig	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/mm/Kconfig	2006-07-20 15:57:38.000000000 +0200
+@@ -127,11 +127,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.
@@ -87652,20 +94018,19 @@
  	default "4"
  
  #
-diff -urN -x .hg -x .hgtags linux-2.6.17/mm/memory.c linux-2.6.17-xen/mm/memory.c
---- linux-2.6.17/mm/memory.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/mm/memory.c	2006-08-14 15:58:25.000000000 +0200
-@@ -402,7 +402,8 @@
- 	 * and that the resulting page looks ok.
- 	 */
- 	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;
- 	}
- 
-@@ -1017,6 +1018,26 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/mm/memory.c linux-2.6.18-rc5-xen/mm/memory.c
+--- linux-2.6.18-rc5/mm/memory.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/mm/memory.c	2006-09-01 00:09:12.000000000 +0200
+@@ -390,7 +390,7 @@
+ 
+ 	if (unlikely(vma->vm_flags & VM_PFNMAP)) {
+ 		unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT;
+-		if (pfn == vma->vm_pgoff + off)
++		if ((pfn == vma->vm_pgoff + off) || !pfn_valid(pfn))
+ 			return NULL;
+ 		if (!is_cow_mapping(vma->vm_flags))
+ 			return NULL;
+@@ -1030,6 +1030,26 @@
  			continue;
  		}
  
@@ -87692,7 +94057,7 @@
  		if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
  				|| !(vm_flags & vma->vm_flags))
  			return i ? : -EFAULT;
-@@ -1356,6 +1377,102 @@
+@@ -1369,6 +1389,102 @@
  }
  EXPORT_SYMBOL(remap_pfn_range);
  
@@ -87795,10 +94160,10 @@
  /*
   * handle_pte_fault chooses page fault handler according to an entry
   * which was read non-atomically.  Before making any commitment, on
-diff -urN -x .hg -x .hgtags linux-2.6.17/mm/mmap.c linux-2.6.17-xen/mm/mmap.c
---- linux-2.6.17/mm/mmap.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/mm/mmap.c	2006-08-14 15:58:25.000000000 +0200
-@@ -1942,6 +1942,10 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/mm/mmap.c linux-2.6.18-rc5-xen/mm/mmap.c
+--- linux-2.6.18-rc5/mm/mmap.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/mm/mmap.c	2006-07-20 15:57:38.000000000 +0200
+@@ -1950,6 +1950,10 @@
  	unsigned long nr_accounted = 0;
  	unsigned long end;
  
@@ -87809,10 +94174,10 @@
  	lru_add_drain();
  	flush_cache_mm(mm);
  	tlb = tlb_gather_mmu(mm, 1);
-diff -urN -x .hg -x .hgtags linux-2.6.17/mm/page_alloc.c linux-2.6.17-xen/mm/page_alloc.c
---- linux-2.6.17/mm/page_alloc.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/mm/page_alloc.c	2006-08-14 15:58:25.000000000 +0200
-@@ -438,7 +438,8 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/mm/page_alloc.c linux-2.6.18-rc5-xen/mm/page_alloc.c
+--- linux-2.6.18-rc5/mm/page_alloc.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/mm/page_alloc.c	2006-07-20 15:57:39.000000000 +0200
+@@ -443,7 +443,8 @@
  	int i;
  	int reserved = 0;
  
@@ -87820,9 +94185,9 @@
 +	if (arch_free_page(page, order))
 +		return;
  	if (!PageHighMem(page))
- 		mutex_debug_check_no_locks_freed(page_address(page),
- 						 PAGE_SIZE<<order);
-@@ -733,7 +734,8 @@
+ 		debug_check_no_locks_freed(page_address(page),
+ 					   PAGE_SIZE<<order);
+@@ -717,7 +718,8 @@
  	struct per_cpu_pages *pcp;
  	unsigned long flags;
  
@@ -87832,364 +94197,23 @@
  
  	if (PageAnon(page))
  		page->mapping = NULL;
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/atm/clip.c linux-2.6.17-xen/net/atm/clip.c
---- linux-2.6.17/net/atm/clip.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/atm/clip.c	2006-08-14 15:58:25.000000000 +0200
-@@ -98,7 +98,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) {
-@@ -120,9 +120,9 @@
- 			goto out;
- 		}
- 	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);
-+	  "0x%p)\n",entry,clip_vcc);
-+out:
-+	netif_tx_unlock_bh(entry->neigh->dev);
- }
- 
- /* The neighbour entry n->lock is held. */
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/bridge/br_device.c linux-2.6.17-xen/net/bridge/br_device.c
---- linux-2.6.17/net/bridge/br_device.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/bridge/br_device.c	2006-08-14 15:58:25.000000000 +0200
-@@ -145,9 +145,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;
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/net/core/dev.c linux-2.6.18-rc5-xen/net/core/dev.c
+--- linux-2.6.18-rc5/net/core/dev.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/net/core/dev.c	2006-09-01 00:09:13.000000000 +0200
+@@ -118,6 +118,12 @@
+ #include <linux/err.h>
+ #include <linux/ctype.h>
  
- 	br_features_recompute(br);
- 	return 0;
-@@ -184,6 +184,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 -urN -x .hg -x .hgtags linux-2.6.17/net/bridge/br_forward.c linux-2.6.17-xen/net/bridge/br_forward.c
---- linux-2.6.17/net/bridge/br_forward.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/bridge/br_forward.c	2006-08-14 15:58:25.000000000 +0200
-@@ -38,7 +38,7 @@
- int br_dev_queue_push_xmit(struct sk_buff *skb)
- {
- 	/* drop mtu oversized packets except tso */
--	if (packet_length(skb) > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
-+	if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size)
- 		kfree_skb(skb);
- 	else {
- #ifdef CONFIG_BRIDGE_NETFILTER
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/bridge/br_if.c linux-2.6.17-xen/net/bridge/br_if.c
---- linux-2.6.17/net/bridge/br_if.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/bridge/br_if.c	2006-08-14 15:58:25.000000000 +0200
-@@ -372,17 +372,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 -urN -x .hg -x .hgtags linux-2.6.17/net/bridge/br_netfilter.c linux-2.6.17-xen/net/bridge/br_netfilter.c
---- linux-2.6.17/net/bridge/br_netfilter.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/bridge/br_netfilter.c	2006-08-14 15:58:25.000000000 +0200
-@@ -769,7 +769,7 @@
- {
- 	if (skb->protocol == htons(ETH_P_IP) &&
- 	    skb->len > skb->dev->mtu &&
--	    !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
-+	    !skb_shinfo(skb)->gso_size)
- 		return ip_fragment(skb, br_dev_queue_push_xmit);
- 	else
- 		return br_dev_queue_push_xmit(skb);
-@@ -877,8 +877,9 @@
- 	struct sk_buff *skb = *pskb;
- 
- 	if ((out->hard_start_xmit == br_dev_xmit &&
--	     okfn != br_nf_forward_finish &&
--	     okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit)
-+	    okfn != br_nf_forward_finish &&
-+	    okfn != br_nf_local_out_finish &&
-+	    okfn != br_nf_dev_queue_xmit)
- #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- 	    || ((out->priv_flags & IFF_802_1Q_VLAN) &&
- 		VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/core/dev.c linux-2.6.17-xen/net/core/dev.c
---- linux-2.6.17/net/core/dev.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/core/dev.c	2006-08-14 15:58:25.000000000 +0200
-@@ -115,6 +115,13 @@
- #include <net/iw_handler.h>
- #include <asm/current.h>
- #include <linux/audit.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)
-@@ -1041,7 +1048,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;
- 
-@@ -1179,6 +1186,45 @@
- 	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;
-+
-+	BUG_ON(skb_shinfo(skb)->frag_list);
-+	BUG_ON(skb->ip_summed != CHECKSUM_HW);
-+
-+	skb->mac.raw = skb->data;
-+	skb->mac_len = skb->nh.raw - skb->data;
-+	__skb_pull(skb, skb->mac_len);
-+
-+	rcu_read_lock();
-+	list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
-+		if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
-+			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)
-@@ -1215,79 +1261,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);			\
+  *	and the routines to invoke.
+@@ -1391,6 +1397,43 @@
  	}						\
  }
  
@@ -88233,7 +94257,7 @@
  /**
   *	dev_queue_xmit - transmit a buffer
   *	@skb: buffer to transmit
-@@ -1319,9 +1435,19 @@
+@@ -1423,6 +1466,12 @@
  	struct Qdisc *q;
  	int rc = -ENOMEM;
  
@@ -88243,88 +94267,10 @@
 + 	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,
-@@ -1330,25 +1456,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 
-@@ -1382,8 +1509,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.
-@@ -1399,11 +1526,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;
- 				}
-@@ -1422,13 +1546,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;
- }
- 
-@@ -1706,6 +1830,19 @@
+ 	/* GSO will handle the following emulations directly. */
+ 	if (netif_needs_gso(dev, skb))
+ 		goto gso;
+@@ -1796,6 +1845,19 @@
  	}
  #endif
  
@@ -88344,35 +94290,7 @@
  	list_for_each_entry_rcu(ptype, &ptype_all, list) {
  		if (!ptype->dev || ptype->dev == skb->dev) {
  			if (pt_prev) 
-@@ -2785,7 +2922,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);
-@@ -2829,9 +2966,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;
-@@ -3371,7 +3506,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);
-@@ -3403,6 +3537,7 @@
+@@ -3582,6 +3644,7 @@
  EXPORT_SYMBOL(net_enable_timestamp);
  EXPORT_SYMBOL(net_disable_timestamp);
  EXPORT_SYMBOL(dev_get_flags);
@@ -88380,258 +94298,10 @@
  
  #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
  EXPORT_SYMBOL(br_handle_frame_hook);
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/core/dev_mcast.c linux-2.6.17-xen/net/core/dev_mcast.c
---- linux-2.6.17/net/core/dev_mcast.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/core/dev_mcast.c	2006-08-14 15:58:25.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/net/core/ethtool.c linux-2.6.17-xen/net/core/ethtool.c
---- linux-2.6.17/net/core/ethtool.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/core/ethtool.c	2006-08-14 15:58:25.000000000 +0200
-@@ -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);
-@@ -615,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;
-@@ -906,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 -urN -x .hg -x .hgtags linux-2.6.17/net/core/netpoll.c linux-2.6.17-xen/net/core/netpoll.c
---- linux-2.6.17/net/core/netpoll.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/core/netpoll.c	2006-08-14 15:58:25.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/net/core/pktgen.c linux-2.6.17-xen/net/core/pktgen.c
---- linux-2.6.17/net/core/pktgen.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/core/pktgen.c	2006-08-14 15:58:25.000000000 +0200
-@@ -6,7 +6,7 @@
-  *
-  * Alexey Kuznetsov  <kuznet at ms2.inr.ac.ru>
-  * Ben Greear <greearb at candelatech.com>
-- * Jens Låås <jens.laas at data.slu.se>
-+ * Jens Låås <jens.laas at data.slu.se>
-  *
-  * This program is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU General Public License
-@@ -2896,8 +2896,8 @@
- 			pkt_dev->clone_count = 0;	/* reset counter */
- 		}
- 	}
--
--	spin_lock_bh(&odev->xmit_lock);
-+	
-+	netif_tx_lock_bh(odev);
- 	if (!netif_queue_stopped(odev)) {
- 
- 		atomic_inc(&(pkt_dev->skb->users));
-@@ -2942,8 +2942,8 @@
- 		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)) {
- 		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/core/skbuff.c linux-2.6.17-xen/net/core/skbuff.c
---- linux-2.6.17/net/core/skbuff.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/core/skbuff.c	2006-08-14 15:58:25.000000000 +0200
-@@ -140,6 +140,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/net/core/skbuff.c linux-2.6.18-rc5-xen/net/core/skbuff.c
+--- linux-2.6.18-rc5/net/core/skbuff.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/net/core/skbuff.c	2006-09-01 00:09:13.000000000 +0200
+@@ -139,6 +139,7 @@
   *	Buffers may only be allocated from interrupts using a @gfp_mask of
   *	%GFP_ATOMIC.
   */
@@ -88639,20 +94309,7 @@
  struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
  			    int fclone)
  {
-@@ -172,9 +173,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;
- 
-@@ -194,6 +195,7 @@
+@@ -193,6 +194,7 @@
  	skb = NULL;
  	goto out;
  }
@@ -88660,7 +94317,7 @@
  
  /**
   *	alloc_skb_from_cache	-	allocate a network buffer
-@@ -211,14 +213,18 @@
+@@ -210,14 +212,17 @@
   */
  struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
  				     unsigned int size,
@@ -88669,7 +94326,6 @@
 +				     int fclone)
  {
 +	kmem_cache_t *cache;
-+	struct skb_shared_info *shinfo;
  	struct sk_buff *skb;
  	u8 *data;
  
@@ -88682,26 +94338,11 @@
  	if (!skb)
  		goto out;
  
-@@ -235,17 +241,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;
+@@ -241,10 +246,20 @@
+ 	skb_shinfo(skb)->gso_segs = 0;
+ 	skb_shinfo(skb)->gso_type = 0;
+ 	skb_shinfo(skb)->frag_list = NULL;
++
 +	if (fclone) {
 +		struct sk_buff *child = skb + 1;
 +		atomic_t *fclone_ref = (atomic_t *) (child + 1);
@@ -88719,7 +94360,7 @@
  	skb = NULL;
  	goto out;
  }
-@@ -434,6 +453,10 @@
+@@ -464,6 +479,10 @@
  	C(local_df);
  	n->cloned = 1;
  	n->nohdr = 0;
@@ -88730,692 +94371,53 @@
  	C(pkt_type);
  	C(ip_summed);
  	C(priority);
-@@ -527,9 +550,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;
- }
- 
- /**
-@@ -1826,6 +1850,133 @@
- 
- EXPORT_SYMBOL_GPL(skb_pull_rcsum);
- 
-+/**
-+ *	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",
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/decnet/dn_nsp_in.c linux-2.6.17-xen/net/decnet/dn_nsp_in.c
---- linux-2.6.17/net/decnet/dn_nsp_in.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/decnet/dn_nsp_in.c	2006-08-14 15:58:26.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/net/decnet/dn_route.c linux-2.6.17-xen/net/decnet/dn_route.c
---- linux-2.6.17/net/decnet/dn_route.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/decnet/dn_route.c	2006-08-14 15:58:26.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/af_inet.c linux-2.6.17-xen/net/ipv4/af_inet.c
---- linux-2.6.17/net/ipv4/af_inet.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/af_inet.c	2006-08-14 15:58:26.000000000 +0200
-@@ -68,6 +68,7 @@
-  */
- 
- #include <linux/config.h>
-+#include <linux/err.h>
- #include <linux/errno.h>
- #include <linux/types.h>
- #include <linux/socket.h>
-@@ -1096,6 +1097,54 @@
- 
- EXPORT_SYMBOL(inet_sk_rebuild_header);
- 
-+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,
-@@ -1105,6 +1154,7 @@
- static struct net_protocol tcp_protocol = {
- 	.handler =	tcp_v4_rcv,
- 	.err_handler =	tcp_v4_err,
-+	.gso_segment =	tcp_tso_segment,
- 	.no_policy =	1,
- };
- 
-@@ -1150,6 +1200,7 @@
- static struct packet_type ip_packet_type = {
- 	.type = __constant_htons(ETH_P_IP),
- 	.func = ip_rcv,
-+	.gso_segment = inet_gso_segment,
- };
- 
- static int __init inet_init(void)
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/ipcomp.c linux-2.6.17-xen/net/ipv4/ipcomp.c
---- linux-2.6.17/net/ipv4/ipcomp.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/ipcomp.c	2006-08-14 15:58:26.000000000 +0200
-@@ -84,7 +84,7 @@
- static int ipcomp_input(struct xfrm_state *x, 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 -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/ip_output.c linux-2.6.17-xen/net/ipv4/ip_output.c
---- linux-2.6.17/net/ipv4/ip_output.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/ip_output.c	2006-08-14 15:58:26.000000000 +0200
-@@ -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_shinfo(skb)->gso_size)
- 		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_shinfo(skb)->gso_size)
- 			len = size;
- 		else {
- 
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/netfilter/ip_nat_proto_tcp.c linux-2.6.17-xen/net/ipv4/netfilter/ip_nat_proto_tcp.c
---- linux-2.6.17/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-08-14 15:58:26.000000000 +0200
-@@ -129,10 +129,17 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/net/ipv4/netfilter/ip_nat_proto_tcp.c linux-2.6.18-rc5-xen/net/ipv4/netfilter/ip_nat_proto_tcp.c
+--- linux-2.6.18-rc5/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-07-20 15:57:41.000000000 +0200
+@@ -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) {
++	if ((*pskb)->proto_csum_blank)
 +		hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+	} else
++	else
 +#endif
-+	{
 +		hdr->check = ip_nat_cheat_check(~oldip, newip,
  					ip_nat_cheat_check(oldport ^ 0xFFFF,
  							   newport,
  							   hdr->check));
-+	}
- 	return 1;
- }
- 
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/netfilter/ip_nat_proto_udp.c linux-2.6.17-xen/net/ipv4/netfilter/ip_nat_proto_udp.c
---- linux-2.6.17/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-08-14 15:58:26.000000000 +0200
-@@ -113,11 +113,19 @@
- 		newport = tuple->dst.u.udp.port;
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/net/ipv4/netfilter/ip_nat_proto_udp.c linux-2.6.18-rc5-xen/net/ipv4/netfilter/ip_nat_proto_udp.c
+--- linux-2.6.18-rc5/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-07-20 15:57:41.000000000 +0200
+@@ -114,7 +114,12 @@
  		portptr = &hdr->dest;
  	}
--	if (hdr->check) /* 0 is a special case meaning no checksum */
+ 	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) {
++		if ((*pskb)->proto_csum_blank)
 +			hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+		} else
++		else
 +#endif
-+		{
 +			hdr->check = ip_nat_cheat_check(~oldip, newip,
  					ip_nat_cheat_check(*portptr ^ 0xFFFF,
  							   newport,
  							   hdr->check));
-+		}
-+	}
- 	*portptr = newport;
- 	return 1;
- }
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/tcp.c linux-2.6.17-xen/net/ipv4/tcp.c
---- linux-2.6.17/net/ipv4/tcp.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/tcp.c	2006-08-14 15:58:26.000000000 +0200
-@@ -258,6 +258,7 @@
- #include <linux/random.h>
- #include <linux/bootmem.h>
- #include <linux/cache.h>
-+#include <linux/err.h>
- 
- #include <net/icmp.h>
- #include <net/tcp.h>
-@@ -571,7 +572,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;
-@@ -622,14 +623,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);
-@@ -726,9 +723,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);
-@@ -824,7 +819,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;
-@@ -2071,6 +2066,77 @@
- EXPORT_SYMBOL(compat_tcp_getsockopt);
- #endif
- 
-+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 -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/tcp_input.c linux-2.6.17-xen/net/ipv4/tcp_input.c
---- linux-2.6.17/net/ipv4/tcp_input.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/tcp_input.c	2006-08-14 15:58:26.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/tcp_output.c linux-2.6.17-xen/net/ipv4/tcp_output.c
---- linux-2.6.17/net/ipv4/tcp_output.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/tcp_output.c	2006-08-14 15:58:26.000000000 +0200
-@@ -511,15 +511,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;
- 	}
- }
- 
-@@ -910,7 +912,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);
- 	}
-@@ -1720,8 +1722,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;
- 		}
-@@ -1926,8 +1929,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;
-@@ -1959,8 +1963,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);
-@@ -2043,8 +2048,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 */
-@@ -2148,8 +2154,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;
-@@ -2253,8 +2260,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);
-@@ -2289,8 +2297,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 -urN -x .hg -x .hgtags linux-2.6.17/net/ipv4/xfrm4_output.c linux-2.6.17-xen/net/ipv4/xfrm4_output.c
---- linux-2.6.17/net/ipv4/xfrm4_output.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv4/xfrm4_output.c	2006-08-14 15:58:26.000000000 +0200
-@@ -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 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/net/ipv4/xfrm4_output.c linux-2.6.18-rc5-xen/net/ipv4/xfrm4_output.c
+--- linux-2.6.18-rc5/net/ipv4/xfrm4_output.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/net/ipv4/xfrm4_output.c	2006-07-20 15:57:41.000000000 +0200
+@@ -18,6 +18,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 @@
+ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
+ {
+ 	int mtu, ret = 0;
+@@ -48,6 +50,10 @@
  	struct xfrm_state *x = dst->xfrm;
  	int err;
  	
@@ -89426,86 +94428,10 @@
  	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_shinfo(skb)->gso_size)
-+		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 -urN -x .hg -x .hgtags linux-2.6.17/net/ipv6/addrconf.c linux-2.6.17-xen/net/ipv6/addrconf.c
---- linux-2.6.17/net/ipv6/addrconf.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv6/addrconf.c	2006-08-14 15:58:26.000000000 +0200
-@@ -2461,6 +2461,7 @@
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/net/ipv6/addrconf.c linux-2.6.18-rc5-xen/net/ipv6/addrconf.c
+--- linux-2.6.18-rc5/net/ipv6/addrconf.c	2006-08-28 05:41:48.000000000 +0200
++++ linux-2.6.18-rc5-xen/net/ipv6/addrconf.c	2006-09-01 00:09:13.000000000 +0200
+@@ -2514,6 +2514,7 @@
  	spin_lock_bh(&ifp->lock);
  
  	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
@@ -89513,7 +94439,7 @@
  	    !(ifp->flags&IFA_F_TENTATIVE)) {
  		ifp->flags &= ~IFA_F_TENTATIVE;
  		spin_unlock_bh(&ifp->lock);
-@@ -2545,6 +2546,7 @@
+@@ -2598,6 +2599,7 @@
  	if (ifp->idev->cnf.forwarding == 0 &&
  	    ifp->idev->cnf.rtr_solicits > 0 &&
  	    (dev->flags&IFF_LOOPBACK) == 0 &&
@@ -89521,335 +94447,9 @@
  	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
  		struct in6_addr all_routers;
  
-diff -urN -x .hg -x .hgtags linux-2.6.17/net/ipv6/ip6_output.c linux-2.6.17-xen/net/ipv6/ip6_output.c
---- linux-2.6.17/net/ipv6/ip6_output.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv6/ip6_output.c	2006-08-14 15:58:26.000000000 +0200
-@@ -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_shinfo(skb)->gso_size) ||
- 				dst_allfrag(skb->dst))
- 		return ip6_fragment(skb, ip6_output2);
- 	else
-@@ -830,8 +830,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 -urN -x .hg -x .hgtags linux-2.6.17/net/ipv6/ipcomp6.c linux-2.6.17-xen/net/ipv6/ipcomp6.c
---- linux-2.6.17/net/ipv6/ipcomp6.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv6/ipcomp6.c	2006-08-14 15:58:27.000000000 +0200
-@@ -65,7 +65,7 @@
- 
- static int ipcomp6_input(struct xfrm_state *x, 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;
-@@ -76,11 +76,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;
- 
-@@ -159,10 +156,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 -urN -x .hg -x .hgtags linux-2.6.17/net/ipv6/xfrm6_output.c linux-2.6.17-xen/net/ipv6/xfrm6_output.c
---- linux-2.6.17/net/ipv6/xfrm6_output.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/ipv6/xfrm6_output.c	2006-08-14 15:58:27.000000000 +0200
-@@ -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_shinfo(skb)->gso_size)
-+		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 -urN -x .hg -x .hgtags linux-2.6.17/net/sched/sch_generic.c linux-2.6.17-xen/net/sched/sch_generic.c
---- linux-2.6.17/net/sched/sch_generic.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/sched/sch_generic.c	2006-08-14 15:58:27.000000000 +0200
-@@ -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) &&
-@@ -203,7 +215,7 @@
- 				dev_hold(dev);
- 		}
- 	}
--	spin_unlock(&dev->xmit_lock);
-+	netif_tx_unlock(dev);
- 
- 	dev_put(dev);
- }
-@@ -227,17 +239,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)
-@@ -579,10 +591,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)
-@@ -624,6 +643,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 -urN -x .hg -x .hgtags linux-2.6.17/net/sched/sch_teql.c linux-2.6.17-xen/net/sched/sch_teql.c
---- linux-2.6.17/net/sched/sch_teql.c	2006-06-18 03:49:35.000000000 +0200
-+++ linux-2.6.17-xen/net/sched/sch_teql.c	2006-08-14 15:58:27.000000000 +0200
-@@ -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 -urN -x .hg -x .hgtags linux-2.6.17/scripts/Makefile.xen linux-2.6.17-xen/scripts/Makefile.xen
---- linux-2.6.17/scripts/Makefile.xen	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.17-xen/scripts/Makefile.xen	2006-08-14 15:58:28.000000000 +0200
+diff -urN -x .hg -x .hgtags linux-2.6.18-rc5/scripts/Makefile.xen linux-2.6.18-rc5-xen/scripts/Makefile.xen
+--- linux-2.6.18-rc5/scripts/Makefile.xen	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18-rc5-xen/scripts/Makefile.xen	2006-07-20 15:57:42.000000000 +0200
 @@ -0,0 +1,14 @@
 +
 +# cherrypickxen($1 = allobj)



More information about the Kernel-svn-changes mailing list