[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 = µcode_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, ®s->esp);
++ show_trace(NULL, regs, ®s->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(¬ify_page_fault_chain, nb);
++}
++
++int unregister_page_fault_notifier(struct notifier_block *nb)
++{
++ return atomic_notifier_chain_unregister(¬ify_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(¬ify_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(®s->rsp);
++ show_trace(NULL, regs, ®s->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(¬ify_page_fault_chain, nb);
++}
++
++int unregister_page_fault_notifier(struct notifier_block *nb)
++{
++ return atomic_notifier_chain_unregister(¬ify_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(¬ify_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, ®, &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