[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[XenPPC] [linux-ppc-2.6] [ppc-code-merge] merge with linux-2.6.tip-xen.hg



# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID 5c0c59eb5f73e7862590a8adca52bc74171bf2d5
# Parent  760669a37a3a04dd629823cf41a6bc8ee662e224
# Parent  0f9ec4b29f3a25cffcd90e03113f3790e644a3ac
[ppc-code-merge] merge with linux-2.6.tip-xen.hg
---
 arch/ia64/xen/drivers/Makefile              |   22 --
 arch/ia64/xen/drivers/coreMakefile          |   20 -
 arch/ia64/xen/drivers/evtchn_ia64.c         |  261 -------------------------
 arch/ia64/xen/xenconsole.c                  |   19 -
 arch/i386/kernel/head-xen.S                 |    2 
 arch/i386/kernel/process-xen.c              |   14 -
 arch/i386/kernel/time-xen.c                 |   20 +
 arch/i386/kernel/vm86.c                     |    4 
 arch/i386/mm/init-xen.c                     |   14 -
 arch/ia64/Kconfig                           |   36 ++-
 arch/ia64/kernel/iosapic.c                  |   11 -
 arch/ia64/kernel/irq_ia64.c                 |  197 ++++++++++++++++++-
 arch/ia64/kernel/setup.c                    |   21 +-
 arch/ia64/xen/Makefile                      |    2 
 arch/ia64/xen/drivers/xenia64_init.c        |    1 
 arch/ia64/xen/hypervisor.c                  |  285 ++++++++++++++++++++-------
 arch/ia64/xen/xenivt.S                      |   45 +++-
 arch/powerpc/Kconfig                        |    5 
 arch/x86_64/kernel/process-xen.c            |   15 -
 arch/x86_64/kernel/setup-xen.c              |   23 --
 arch/x86_64/kernel/smp-xen.c                |    2 
 arch/x86_64/mm/init-xen.c                   |   43 +++-
 drivers/xen/Kconfig                         |   15 -
 drivers/xen/Makefile                        |    2 
 drivers/xen/balloon/balloon.c               |    6 
 drivers/xen/blkfront/blkfront.c             |   21 +-
 drivers/xen/blkfront/block.h                |    1 
 drivers/xen/blkfront/vbd.c                  |    1 
 drivers/xen/core/Makefile                   |    6 
 drivers/xen/core/cpu_hotplug.c              |    2 
 drivers/xen/core/smpboot.c                  |   20 +
 drivers/xen/netback/loopback.c              |    2 
 drivers/xen/netback/netback.c               |  288 ++++++++++++++++++++++------
 drivers/xen/netback/xenbus.c                |   26 ++
 drivers/xen/netfront/netfront.c             |  173 +++++++++++++---
 drivers/xen/privcmd/privcmd.c               |   12 -
 include/asm-i386/mach-xen/asm/dma-mapping.h |    2 
 include/asm-i386/mach-xen/asm/hypercall.h   |    7 
 include/asm-i386/mach-xen/asm/system.h      |   10 
 include/asm-i386/mach-xen/setup_arch_post.h |    7 
 include/asm-ia64/hw_irq.h                   |    8 
 include/asm-ia64/hypercall.h                |   40 ++-
 include/asm-ia64/hypervisor.h               |    4 
 include/asm-ia64/irq.h                      |   31 +++
 include/asm-ia64/xen/privop.h               |   32 +--
 include/asm-x86_64/mach-xen/asm/hypercall.h |    7 
 include/asm-x86_64/mach-xen/asm/system.h    |    4 
 include/xen/cpu_hotplug.h                   |    6 
 include/xen/interface/arch-ia64.h           |    9 
 include/xen/interface/arch-x86_32.h         |   27 ++
 include/xen/interface/arch-x86_64.h         |   24 +-
 include/xen/interface/callback.h            |   15 +
 include/xen/interface/grant_table.h         |    2 
 include/xen/interface/io/netif.h            |    4 
 include/xen/interface/io/ring.h             |   16 +
 include/xen/interface/memory.h              |   10 
 include/xen/interface/sched_ctl.h           |    2 
 include/xen/interface/xen.h                 |   22 +-
 58 files changed, 1243 insertions(+), 683 deletions(-)

diff -r 760669a37a3a -r 5c0c59eb5f73 arch/i386/kernel/head-xen.S
--- a/arch/i386/kernel/head-xen.S       Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/i386/kernel/head-xen.S       Thu Jun 08 15:10:05 2006 -0400
@@ -173,7 +173,7 @@ ENTRY(cpu_gdt_table)
        .ascii           "|pae_pgdir_above_4gb"
        .ascii           "|supervisor_mode_kernel"
 #ifdef CONFIG_X86_PAE
-       .ascii  ",PAE=yes"
+       .ascii  ",PAE=yes[extended-cr3]"
 #else
        .ascii  ",PAE=no"
 #endif
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/i386/kernel/process-xen.c
--- a/arch/i386/kernel/process-xen.c    Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/i386/kernel/process-xen.c    Thu Jun 08 15:10:05 2006 -0400
@@ -54,6 +54,7 @@
 
 #include <xen/interface/physdev.h>
 #include <xen/interface/vcpu.h>
+#include <xen/cpu_hotplug.h>
 
 #include <linux/err.h>
 
@@ -100,8 +101,6 @@ EXPORT_SYMBOL(enable_hlt);
 EXPORT_SYMBOL(enable_hlt);
 
 /* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-extern void stop_hz_timer(void);
-extern void start_hz_timer(void);
 void xen_idle(void)
 {
        local_irq_disable();
@@ -111,10 +110,7 @@ void xen_idle(void)
        else {
                clear_thread_flag(TIF_POLLING_NRFLAG);
                smp_mb__after_clear_bit();
-               stop_hz_timer();
-               /* Blocking includes an implicit local_irq_enable(). */
-               HYPERVISOR_block();
-               start_hz_timer();
+               safe_halt();
                set_thread_flag(TIF_POLLING_NRFLAG);
        }
 }
@@ -131,11 +127,7 @@ static inline void play_dead(void)
        cpu_clear(smp_processor_id(), cpu_initialized);
        preempt_enable_no_resched();
        HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
-       /* Same as drivers/xen/core/smpboot.c:cpu_bringup(). */
-       cpu_init();
-       touch_softlockup_watchdog();
-       preempt_disable();
-       local_irq_enable();
+       cpu_bringup();
 }
 #else
 static inline void play_dead(void)
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/i386/kernel/time-xen.c
--- a/arch/i386/kernel/time-xen.c       Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/i386/kernel/time-xen.c       Thu Jun 08 15:10:05 2006 -0400
@@ -973,7 +973,7 @@ EXPORT_SYMBOL(jiffies_to_st);
  * stop_hz_timer / start_hz_timer - enter/exit 'tickless mode' on an idle cpu
  * These functions are based on implementations from arch/s390/kernel/time.c
  */
-void stop_hz_timer(void)
+static void stop_hz_timer(void)
 {
        unsigned int cpu = smp_processor_id();
        unsigned long j;
@@ -993,10 +993,26 @@ void stop_hz_timer(void)
        BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
 }
 
-void start_hz_timer(void)
+static void start_hz_timer(void)
 {
        cpu_clear(smp_processor_id(), nohz_cpu_mask);
 }
+
+void safe_halt(void)
+{
+       stop_hz_timer();
+       /* Blocking includes an implicit local_irq_enable(). */
+       HYPERVISOR_block();
+       start_hz_timer();
+}
+EXPORT_SYMBOL(safe_halt);
+
+void halt(void)
+{
+       if (irqs_disabled())
+               HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
+}
+EXPORT_SYMBOL(halt);
 
 /* No locking required. We are only CPU running, and interrupts are off. */
 void time_resume(void)
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/i386/kernel/vm86.c
--- a/arch/i386/kernel/vm86.c   Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/i386/kernel/vm86.c   Thu Jun 08 15:10:05 2006 -0400
@@ -132,7 +132,9 @@ struct pt_regs * fastcall save_v86_state
        current->thread.sysenter_cs = __KERNEL_CS;
        load_esp0(tss, &current->thread);
        current->thread.saved_esp0 = 0;
+#ifndef CONFIG_X86_NO_TSS
        put_cpu();
+#endif
 
        loadsegment(fs, current->thread.saved_fs);
        loadsegment(gs, current->thread.saved_gs);
@@ -310,7 +312,9 @@ static void do_sys_vm86(struct kernel_vm
        if (cpu_has_sep)
                tsk->thread.sysenter_cs = 0;
        load_esp0(tss, &tsk->thread);
+#ifndef CONFIG_X86_NO_TSS
        put_cpu();
+#endif
 
        tsk->thread.screen_bitmap = info->screen_bitmap;
        if (info->flags & VM86_SCREEN_BITMAP)
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/i386/mm/init-xen.c
--- a/arch/i386/mm/init-xen.c   Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/i386/mm/init-xen.c   Thu Jun 08 15:10:05 2006 -0400
@@ -558,15 +558,11 @@ void __init paging_init(void)
 
        kmap_init();
 
-       if (!xen_feature(XENFEAT_auto_translated_physmap) ||
-           xen_start_info->shared_info >= xen_start_info->nr_pages) {
-               /* Switch to the real shared_info page, and clear the
-                * dummy page. */
-               set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-               HYPERVISOR_shared_info =
-                       (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-               memset(empty_zero_page, 0, sizeof(empty_zero_page));
-       }
+       /* Switch to the real shared_info page, and clear the
+        * dummy page. */
+       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+       memset(empty_zero_page, 0, sizeof(empty_zero_page));
 
        /* Setup mapping of lower 1st MB */
        for (i = 0; i < NR_FIX_ISAMAPS; i++)
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/Kconfig
--- a/arch/ia64/Kconfig Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/ia64/Kconfig Thu Jun 08 15:10:05 2006 -0400
@@ -81,7 +81,7 @@ config XEN_IA64_DOM0_VP
 
 config XEN_IA64_DOM0_NON_VP
        bool
-       depends on !(XEN && XEN_IA64_DOM0_VP)
+       depends on XEN && !XEN_IA64_DOM0_VP
        default y
        help
          dom0 P=M model
@@ -535,15 +535,39 @@ source "security/Kconfig"
 
 source "crypto/Kconfig"
 
+#
 # override default values of drivers/xen/Kconfig
-if !XEN_IA64_DOM0_VP
+#
+if XEN
+config XEN_UTIL
+       default n if XEN_IA64_DOM0_VP
+
 config HAVE_ARCH_ALLOC_SKB
-        bool
-        default n
+       default n if !XEN_IA64_DOM0_VP
 
 config HAVE_ARCH_DEV_ALLOC_SKB
-        bool
-        default n
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_BALLOON
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_SKBUFF
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_NETDEV_BACKEND
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_NETDEV_FRONTEND
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_DEVMEM
+       default n
+
+config XEN_REBOOT
+       default n
+
+config XEN_SMPBOOT
+       default n
 endif
 
 source "drivers/xen/Kconfig"
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/kernel/iosapic.c
--- a/arch/ia64/kernel/iosapic.c        Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/ia64/kernel/iosapic.c        Thu Jun 08 15:10:05 2006 -0400
@@ -191,7 +191,7 @@ static inline void xen_iosapic_write(cha
 
 static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int 
reg)
 {
-       if (!running_on_xen) {
+       if (!is_running_on_xen()) {
                writel(reg, iosapic + IOSAPIC_REG_SELECT);
                return readl(iosapic + IOSAPIC_WINDOW);
        } else
@@ -200,7 +200,7 @@ static inline unsigned int iosapic_read(
 
 static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32 
val)
 {
-       if (!running_on_xen) {
+       if (!is_running_on_xen()) {
                writel(reg, iosapic + IOSAPIC_REG_SELECT);
                writel(val, iosapic + IOSAPIC_WINDOW);
        } else
@@ -712,6 +712,11 @@ register_intr (unsigned int gsi, int vec
        iosapic_intr_info[vector].polarity = polarity;
        iosapic_intr_info[vector].dmode    = delivery;
        iosapic_intr_info[vector].trigger  = trigger;
+
+#ifdef CONFIG_XEN
+       if (is_running_on_xen())
+               return 0;
+#endif
 
        if (trigger == IOSAPIC_EDGE)
                irq_type = &irq_type_iosapic_edge;
@@ -1076,7 +1081,7 @@ iosapic_system_init (int system_pcat_com
 
        pcat_compat = system_pcat_compat;
 #ifdef CONFIG_XEN
-       if (running_on_xen)
+       if (is_running_on_xen())
                return;
 #endif
        if (pcat_compat) {
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/kernel/irq_ia64.c
--- a/arch/ia64/kernel/irq_ia64.c       Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/ia64/kernel/irq_ia64.c       Thu Jun 08 15:10:05 2006 -0400
@@ -68,7 +68,7 @@ assign_irq_vector (int irq)
        int pos, vector;
 #ifdef CONFIG_XEN
        extern int xen_assign_irq_vector(int);
-       if (running_on_xen)
+       if (is_running_on_xen())
                return xen_assign_irq_vector(irq);
 #endif /* CONFIG_XEN */
  again:
@@ -229,6 +229,151 @@ static struct irqaction ipi_irqaction = 
 };
 #endif
 
+#ifdef CONFIG_XEN
+#include <xen/evtchn.h>
+#include <xen/interface/callback.h>
+
+static char timer_name[NR_CPUS][15];
+static char ipi_name[NR_CPUS][15];
+static char resched_name[NR_CPUS][15];
+
+struct saved_irq {
+       unsigned int irq;
+       struct irqaction *action;
+};
+/* 16 should be far optimistic value, since only several percpu irqs
+ * are registered early.
+ */
+#define MAX_LATE_IRQ   16
+static struct saved_irq saved_percpu_irqs[MAX_LATE_IRQ];
+static unsigned short late_irq_cnt = 0;
+static unsigned short saved_irq_cnt = 0;
+static int xen_slab_ready = 0;
+
+/* Dummy stub. Though we may check RESCHEDULE_VECTOR before __do_IRQ,
+ * it ends up to issue several memory accesses upon percpu data and
+ * thus adds unnecessary traffic to other paths.
+ */
+static irqreturn_t
+handle_reschedule(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction resched_irqaction = {
+       .handler =      handle_reschedule,
+       .flags =        SA_INTERRUPT,
+       .name =         "RESCHED"
+};
+
+/*
+ * This is xen version percpu irq registration, which needs bind
+ * to xen specific evtchn sub-system. One trick here is that xen
+ * evtchn binding interface depends on kmalloc because related
+ * port needs to be freed at device/cpu down. So we cache the
+ * registration on BSP before slab is ready and then deal them
+ * at later point. For rest instances happening after slab ready,
+ * we hook them to xen evtchn immediately.
+ *
+ * FIXME: MCA is not supported by far, and thus "nomca" boot param is
+ * required.
+ */
+void
+xen_register_percpu_irq (unsigned int irq, struct irqaction *action, int save)
+{
+       char name[15];
+       unsigned int cpu = smp_processor_id();
+       int ret = 0;
+
+       if (xen_slab_ready) {
+               switch (irq) {
+               case IA64_TIMER_VECTOR:
+                       sprintf(timer_name[cpu], "%s%d", action->name, cpu);
+                       ret = bind_virq_to_irqhandler(VIRQ_ITC, cpu,
+                               action->handler, action->flags,
+                               timer_name[cpu], action->dev_id);
+                       printk(KERN_INFO "register VIRQ_ITC (%s) to xen irq 
(%d)\n", name, ret);
+                       break;
+               case IA64_IPI_RESCHEDULE:
+                       sprintf(resched_name[cpu], "%s%d", action->name, cpu);
+                       ret = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR, cpu,
+                               action->handler, action->flags,
+                               resched_name[cpu], action->dev_id);
+                       printk(KERN_INFO "register RESCHEDULE_VECTOR (%s) to 
xen irq (%d)\n", name, ret);
+                       break;
+               case IA64_IPI_VECTOR:
+                       sprintf(ipi_name[cpu], "%s%d", action->name, cpu);
+                       ret = bind_ipi_to_irqhandler(IPI_VECTOR, cpu,
+                               action->handler, action->flags,
+                               ipi_name[cpu], action->dev_id);
+                       printk(KERN_INFO "register IPI_VECTOR (%s) to xen irq 
(%d)\n", name, ret);
+                       break;
+               default:
+                       printk(KERN_WARNING "Percpu irq %d is unsupported by 
xen!\n", irq);
+                       break;
+               }
+               BUG_ON(ret < 0);
+       } 
+
+       /* For BSP, we cache registered percpu irqs, and then re-walk
+        * them when initializing APs
+        */
+       if (!cpu && save) {
+               BUG_ON(saved_irq_cnt == MAX_LATE_IRQ);
+               saved_percpu_irqs[saved_irq_cnt].irq = irq;
+               saved_percpu_irqs[saved_irq_cnt].action = action;
+               saved_irq_cnt++;
+               if (!xen_slab_ready)
+                       late_irq_cnt++;
+       }
+}
+
+static void
+xen_bind_early_percpu_irq (void)
+{
+       int i;
+
+       xen_slab_ready = 1;
+       /* There's no race when accessing this cached array, since only
+        * BSP will face with such step shortly
+        */
+       for (i = 0; i < late_irq_cnt; i++)
+               xen_register_percpu_irq(saved_percpu_irqs[i].irq,
+                       saved_percpu_irqs[i].action, 0);
+}
+
+/* FIXME: There's no obvious point to check whether slab is ready. So
+ * a hack is used here by utilizing a late time hook.
+ */
+extern void (*late_time_init)(void);
+extern char xen_event_callback;
+extern void xen_init_IRQ(void);
+
+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
+void xen_smp_intr_init(void)
+{
+#ifdef CONFIG_SMP
+       unsigned int cpu = smp_processor_id();
+       unsigned int i = 0;
+       struct callback_register event = {
+               .type = CALLBACKTYPE_event,
+               .address = (unsigned long)&xen_event_callback,
+       };
+
+       if (!cpu)
+               return;
+
+       /* This should be piggyback when setup vcpu guest context */
+       BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
+
+       for (i = 0; i < saved_irq_cnt; i++)
+               xen_register_percpu_irq(saved_percpu_irqs[i].irq,
+                       saved_percpu_irqs[i].action, 0);
+#endif /* CONFIG_SMP */
+}
+#endif /* CONFIG_XEN */
+
 void
 register_percpu_irq (ia64_vector vec, struct irqaction *action)
 {
@@ -237,6 +382,10 @@ register_percpu_irq (ia64_vector vec, st
 
        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->status |= IRQ_PER_CPU;
                        desc->handler = &irq_type_ia64_lsapic;
@@ -248,6 +397,21 @@ void __init
 void __init
 init_IRQ (void)
 {
+#ifdef CONFIG_XEN
+       /* Maybe put into platform_irq_init later */
+       if (is_running_on_xen()) {
+               struct callback_register event = {
+                       .type = CALLBACKTYPE_event,
+                       .address = (unsigned long)&xen_event_callback,
+               };
+               xen_init_IRQ();
+               BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
+               late_time_init = xen_bind_early_percpu_irq;
+#ifdef CONFIG_SMP
+               register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
+#endif /* CONFIG_SMP */
+       }
+#endif /* CONFIG_XEN */
        register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
 #ifdef CONFIG_SMP
        register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
@@ -266,10 +430,33 @@ ia64_send_ipi (int cpu, int vector, int 
        unsigned long phys_cpu_id;
 
 #ifdef CONFIG_XEN
-        if (running_on_xen) {
-                extern void xen_send_ipi (int cpu, int vec);
-                xen_send_ipi (cpu, vector);
-                return;
+        if (is_running_on_xen()) {
+               int irq = -1;
+
+               /* TODO: we need to call vcpu_up here */
+               if (unlikely(vector == ap_wakeup_vector)) {
+                       extern void xen_send_ipi (int cpu, int vec);
+                       xen_send_ipi (cpu, vector);
+                       //vcpu_prepare_and_up(cpu);
+                       return;
+               }
+
+               switch(vector) {
+               case IA64_IPI_VECTOR:
+                       irq = per_cpu(ipi_to_irq, cpu)[IPI_VECTOR];
+                       break;
+               case IA64_IPI_RESCHEDULE:
+                       irq = per_cpu(ipi_to_irq, cpu)[RESCHEDULE_VECTOR];
+                       break;
+               default:
+                       printk(KERN_WARNING"Unsupported IPI type 0x%x\n", 
vector);
+                       irq = 0;
+                       break;
+               }               
+       
+               BUG_ON(irq < 0);
+               notify_remote_via_irq(irq);
+               return;
         }
 #endif /* CONFIG_XEN */
 
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/kernel/setup.c
--- a/arch/ia64/kernel/setup.c  Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/ia64/kernel/setup.c  Thu Jun 08 15:10:05 2006 -0400
@@ -248,7 +248,7 @@ reserve_memory (void)
        n++;
 
 #ifdef CONFIG_XEN
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                rsvd_region[n].start = (unsigned 
long)__va((HYPERVISOR_shared_info->arch.start_info_pfn << PAGE_SHIFT));
                rsvd_region[n].end   = rsvd_region[n].start + PAGE_SIZE;
                n++;
@@ -347,8 +347,14 @@ early_console_setup (char *cmdline)
        int earlycons = 0;
 
 #ifdef CONFIG_XEN
-       if (!early_xen_console_setup(cmdline))
+#ifndef CONFIG_IA64_HP_SIM
+       if (is_running_on_xen()) {
+               extern struct console hpsim_cons;
+               hpsim_cons.flags |= CON_BOOT;
+               register_console(&hpsim_cons);
                earlycons++;
+       }
+#endif
 #endif
 #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
        {
@@ -419,7 +425,7 @@ setup_arch (char **cmdline_p)
 {
        unw_init();
 #ifdef CONFIG_XEN
-       if (running_on_xen)
+       if (is_running_on_xen())
                setup_xen_features();
 #endif
 
@@ -500,7 +506,7 @@ setup_arch (char **cmdline_p)
 # endif
        }
 #ifdef CONFIG_XEN
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                extern shared_info_t *HYPERVISOR_shared_info;
                extern int xen_init (void);
 
@@ -911,6 +917,13 @@ cpu_init (void)
        /* size of physical stacked register partition plus 8 bytes: */
        __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
        platform_cpu_init();
+#ifdef CONFIG_XEN
+       /* Need to be moved into platform_cpu_init later */
+       if (is_running_on_xen()) {
+               extern void xen_smp_intr_init(void);
+               xen_smp_intr_init();
+       }
+#endif
        pm_idle = default_idle;
 }
 
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/xen/Makefile
--- a/arch/ia64/xen/Makefile    Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/ia64/xen/Makefile    Thu Jun 08 15:10:05 2006 -0400
@@ -2,7 +2,7 @@
 # Makefile for Xen components
 #
 
-obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o 
xenconsole.o
+obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.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 -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/xen/drivers/xenia64_init.c
--- a/arch/ia64/xen/drivers/xenia64_init.c      Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/ia64/xen/drivers/xenia64_init.c      Thu Jun 08 15:10:05 2006 -0400
@@ -33,7 +33,6 @@ int xen_init(void)
                s->arch.start_info_pfn, xen_start_info->nr_pages,
                xen_start_info->flags);
 
-       evtchn_init();
        initialized = 1;
        return 0;
 }
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/xen/hypervisor.c
--- a/arch/ia64/xen/hypervisor.c        Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/ia64/xen/hypervisor.c        Thu Jun 08 15:10:05 2006 -0400
@@ -314,12 +314,6 @@ gnttab_map_grant_ref_pre(struct gnttab_m
        uint32_t flags;
 
        flags = uop->flags;
-       if (flags & GNTMAP_readonly) {
-#if 0
-               xprintd("GNTMAP_readonly is not supported yet\n");
-#endif
-               flags &= ~GNTMAP_readonly;
-       }
 
        if (flags & GNTMAP_host_map) {
                if (flags & GNTMAP_application_map) {
@@ -360,52 +354,179 @@ struct address_space xen_ia64_foreign_du
 
 ///////////////////////////////////////////////////////////////////////////
 // foreign mapping
+#include <linux/efi.h>
+#include <asm/meminit.h> // for IA64_GRANULE_SIZE, GRANULEROUND{UP,DOWN}()
+
+static unsigned long privcmd_resource_min = 0;
+// Xen/ia64 currently can handle pseudo physical address bits up to
+// (PAGE_SHIFT * 3)
+static unsigned long privcmd_resource_max = GRANULEROUNDDOWN((1UL << 
(PAGE_SHIFT * 3)) - 1);
+static unsigned long privcmd_resource_align = IA64_GRANULE_SIZE;
+
+static unsigned long
+md_end_addr(const efi_memory_desc_t *md)
+{
+       return md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+}
+
+#define XEN_IA64_PRIVCMD_LEAST_GAP_SIZE        (1024 * 1024 * 1024UL)
+static int
+xen_ia64_privcmd_check_size(unsigned long start, unsigned long end)
+{
+       return (start < end &&
+               (end - start) > XEN_IA64_PRIVCMD_LEAST_GAP_SIZE);
+}
+
+static int __init
+xen_ia64_privcmd_init(void)
+{
+       void *efi_map_start, *efi_map_end, *p;
+       u64 efi_desc_size;
+       efi_memory_desc_t *md;
+       unsigned long tmp_min;
+       unsigned long tmp_max;
+       unsigned long gap_size;
+       unsigned long prev_end;
+
+       if (!is_running_on_xen())
+               return -1;
+
+       efi_map_start = __va(ia64_boot_param->efi_memmap);
+       efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+       efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+       // at first check the used highest address
+       for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+               // nothing
+       }
+       md = p - efi_desc_size;
+       privcmd_resource_min = GRANULEROUNDUP(md_end_addr(md));
+       if (xen_ia64_privcmd_check_size(privcmd_resource_min,
+                                       privcmd_resource_max)) {
+               goto out;
+       }
+
+       // the used highest address is too large. try to find the largest gap.
+       tmp_min = privcmd_resource_max;
+       tmp_max = 0;
+       gap_size = 0;
+       prev_end = 0;
+       for (p = efi_map_start;
+            p < efi_map_end - efi_desc_size;
+            p += efi_desc_size) {
+               unsigned long end;
+               efi_memory_desc_t* next;
+               unsigned long next_start;
+
+               md = p;
+               end = md_end_addr(md);
+               if (end > privcmd_resource_max) {
+                       break;
+               }
+               if (end < prev_end) {
+                       // work around. 
+                       // Xen may pass incompletely sorted memory
+                       // descriptors like
+                       // [x, x + length]
+                       // [x, x]
+                       // this order should be reversed.
+                       continue;
+               }
+               next = p + efi_desc_size;
+               next_start = next->phys_addr;
+               if (next_start > privcmd_resource_max) {
+                       next_start = privcmd_resource_max;
+               }
+               if (end < next_start && gap_size < (next_start - end)) {
+                       tmp_min = end;
+                       tmp_max = next_start;
+                       gap_size = tmp_max - tmp_min;
+               }
+               prev_end = end;
+       }
+
+       privcmd_resource_min = GRANULEROUNDUP(tmp_min);
+       if (xen_ia64_privcmd_check_size(privcmd_resource_min, tmp_max)) {
+               privcmd_resource_max = tmp_max;
+               goto out;
+       }
+
+       privcmd_resource_min = tmp_min;
+       privcmd_resource_max = tmp_max;
+       if (!xen_ia64_privcmd_check_size(privcmd_resource_min,
+                                        privcmd_resource_max)) {
+               // Any large enough gap isn't found.
+               // go ahead anyway with the warning hoping that large region
+               // won't be requested.
+               printk(KERN_WARNING "xen privcmd: large enough region for 
privcmd mmap is not found.\n");
+       }
+
+out:
+       printk(KERN_INFO "xen privcmd uses pseudo physical addr range [0x%lx, 
0x%lx] (%ldMB)\n",
+              privcmd_resource_min, privcmd_resource_max, 
+              (privcmd_resource_max - privcmd_resource_min) >> 20);
+       BUG_ON(privcmd_resource_min >= privcmd_resource_max);
+       return 0;
+}
+late_initcall(xen_ia64_privcmd_init);
 
 struct xen_ia64_privcmd_entry {
        atomic_t        map_count;
-       struct page*    page;
+#define INVALID_GPFN   (~0UL)
+       unsigned long   gpfn;
+};
+
+struct xen_ia64_privcmd_range {
+       atomic_t                        ref_count;
+       unsigned long                   pgoff; // in PAGE_SIZE
+       struct resource*                res;
+
+       unsigned long                   num_entries;
+       struct xen_ia64_privcmd_entry   entries[0];
+};
+
+struct xen_ia64_privcmd_vma {
+       struct xen_ia64_privcmd_range*  range;
+
+       unsigned long                   num_entries;
+       struct xen_ia64_privcmd_entry*  entries;
 };
 
 static void
 xen_ia64_privcmd_init_entry(struct xen_ia64_privcmd_entry* entry)
 {
        atomic_set(&entry->map_count, 0);
-       entry->page = NULL;
-}
-
-//TODO alloc_page() to allocate pseudo physical address space is 
-//     waste of memory.
-//     When vti domain is created, qemu maps all of vti domain pages which 
-//     reaches to several hundred megabytes at least.
-//     remove alloc_page().
+       entry->gpfn = INVALID_GPFN;
+}
+
 static int
 xen_ia64_privcmd_entry_mmap(struct vm_area_struct* vma,
                            unsigned long addr,
-                           struct xen_ia64_privcmd_entry* entry,
+                           struct xen_ia64_privcmd_range* privcmd_range,
+                           int i,
                            unsigned long mfn,
                            pgprot_t prot,
                            domid_t domid)
 {
        int error = 0;
-       struct page* page;
+       struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
        unsigned long gpfn;
+       unsigned long flags;
 
        BUG_ON((addr & ~PAGE_MASK) != 0);
        BUG_ON(mfn == INVALID_MFN);
 
-       if (entry->page != NULL) {
+       if (entry->gpfn != INVALID_GPFN) {
                error = -EBUSY;
                goto out;
        }
-       page = alloc_page(GFP_KERNEL);
-       if (page == NULL) {
-               error = -ENOMEM;
-               goto out;
-       }
-       gpfn = page_to_pfn(page);
-
-       error = HYPERVISOR_add_physmap(gpfn, mfn, 0/* prot:XXX */,
-                                      domid);
+       gpfn = (privcmd_range->res->start >> PAGE_SHIFT) + i;
+
+       flags = ASSIGN_writable;
+       if (pgprot_val(prot) == PROT_READ) {
+               flags = ASSIGN_readonly;
+       }
+       error = HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
        if (error != 0) {
                goto out;
        }
@@ -413,15 +534,13 @@ xen_ia64_privcmd_entry_mmap(struct vm_ar
        prot = vma->vm_page_prot;
        error = remap_pfn_range(vma, addr, gpfn, 1 << PAGE_SHIFT, prot);
        if (error != 0) {
-               (void)HYPERVISOR_zap_physmap(gpfn, 0);
-               error = HYPERVISOR_populate_physmap(gpfn, 0, 0);
+               error = HYPERVISOR_zap_physmap(gpfn, 0);
                if (error) {
                        BUG();//XXX
                }
-               __free_page(page);
        } else {
                atomic_inc(&entry->map_count);
-               entry->page = page;
+               entry->gpfn = gpfn;
        }
 
 out:
@@ -429,30 +548,28 @@ out:
 }
 
 static void
-xen_ia64_privcmd_entry_munmap(struct xen_ia64_privcmd_entry* entry)
-{
-       struct page* page = entry->page;
-       unsigned long gpfn = page_to_pfn(page);
+xen_ia64_privcmd_entry_munmap(struct xen_ia64_privcmd_range* privcmd_range,
+                             int i)
+{
+       struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+       unsigned long gpfn = entry->gpfn;
+       //gpfn = (privcmd_range->res->start >> PAGE_SHIFT) +
+       //      (vma->vm_pgoff - privcmd_range->pgoff);
        int error;
 
        error = HYPERVISOR_zap_physmap(gpfn, 0);
        if (error) {
                BUG();//XXX
        }
-
-       error = HYPERVISOR_populate_physmap(gpfn, 0, 0);
-       if (error) {
-               BUG();//XXX
-       }
-
-       entry->page = NULL;
-       __free_page(page);
+       entry->gpfn = INVALID_GPFN;
 }
 
 static int
-xen_ia64_privcmd_entry_open(struct xen_ia64_privcmd_entry* entry)
-{
-       if (entry->page != NULL) {
+xen_ia64_privcmd_entry_open(struct xen_ia64_privcmd_range* privcmd_range,
+                           int i)
+{
+       struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+       if (entry->gpfn != INVALID_GPFN) {
                atomic_inc(&entry->map_count);
        } else {
                BUG_ON(atomic_read(&entry->map_count) != 0);
@@ -460,27 +577,15 @@ xen_ia64_privcmd_entry_open(struct xen_i
 }
 
 static int
-xen_ia64_privcmd_entry_close(struct xen_ia64_privcmd_entry* entry)
-{
-       if (entry->page != NULL && atomic_dec_and_test(&entry->map_count)) {
-               xen_ia64_privcmd_entry_munmap(entry);
-       }
-}
-
-struct xen_ia64_privcmd_range {
-       atomic_t                        ref_count;
-       unsigned long                   pgoff; // in PAGE_SIZE
-
-       unsigned long                   num_entries;
-       struct xen_ia64_privcmd_entry   entries[0];
-};
-
-struct xen_ia64_privcmd_vma {
-       struct xen_ia64_privcmd_range*  range;
-
-       unsigned long                   num_entries;
-       struct xen_ia64_privcmd_entry*  entries;
-};
+xen_ia64_privcmd_entry_close(struct xen_ia64_privcmd_range* privcmd_range,
+                            int i)
+{
+       struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+       if (entry->gpfn != INVALID_GPFN &&
+           atomic_dec_and_test(&entry->map_count)) {
+               xen_ia64_privcmd_entry_munmap(privcmd_range, i);
+       }
+}
 
 static void xen_ia64_privcmd_vma_open(struct vm_area_struct* vma);
 static void xen_ia64_privcmd_vma_close(struct vm_area_struct* vma);
@@ -507,7 +612,7 @@ __xen_ia64_privcmd_vma_open(struct vm_ar
        privcmd_vma->entries = &privcmd_range->entries[entry_offset];
        vma->vm_private_data = privcmd_vma;
        for (i = 0; i < privcmd_vma->num_entries; i++) {
-               xen_ia64_privcmd_entry_open(&privcmd_vma->entries[i]);
+               xen_ia64_privcmd_entry_open(privcmd_range, entry_offset + i);
        }
 
        vma->vm_private_data = privcmd_vma;
@@ -533,10 +638,11 @@ xen_ia64_privcmd_vma_close(struct vm_are
        struct xen_ia64_privcmd_vma* privcmd_vma =
                (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
        struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
+       unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
        unsigned long i;
 
        for (i = 0; i < privcmd_vma->num_entries; i++) {
-               xen_ia64_privcmd_entry_close(&privcmd_vma->entries[i]);
+               xen_ia64_privcmd_entry_close(privcmd_range, entry_offset + i);
        }
        vma->vm_private_data = NULL;
        kfree(privcmd_vma);
@@ -547,9 +653,11 @@ xen_ia64_privcmd_vma_close(struct vm_are
                        struct xen_ia64_privcmd_entry* entry =
                                &privcmd_range->entries[i];
                        BUG_ON(atomic_read(&entry->map_count) != 0);
-                       BUG_ON(entry->page != NULL);
+                       BUG_ON(entry->gpfn != INVALID_GPFN);
                }
 #endif
+               release_resource(privcmd_range->res);
+               kfree(privcmd_range->res);
                vfree(privcmd_range);
        }
 }
@@ -557,13 +665,18 @@ int
 int
 privcmd_mmap(struct file * file, struct vm_area_struct * vma)
 {
-       unsigned long num_entries = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-       struct xen_ia64_privcmd_range* privcmd_range;
-       struct xen_ia64_privcmd_vma* privcmd_vma;
+       int error;
+       unsigned long size = vma->vm_end - vma->vm_start;
+       unsigned long num_entries = size >> PAGE_SHIFT;
+       struct xen_ia64_privcmd_range* privcmd_range = NULL;
+       struct xen_ia64_privcmd_vma* privcmd_vma = NULL;
+       struct resource* res = NULL;
        unsigned long i;
-       BUG_ON(!running_on_xen);
+       BUG_ON(!is_running_on_xen());
 
        BUG_ON(file->private_data != NULL);
+
+       error = -ENOMEM;
        privcmd_range =
                vmalloc(sizeof(*privcmd_range) +
                        sizeof(privcmd_range->entries[0]) * num_entries);
@@ -574,6 +687,18 @@ privcmd_mmap(struct file * file, struct 
        if (privcmd_vma == NULL) {
                goto out_enomem1;
        }
+       res = kzalloc(sizeof(*res), GFP_KERNEL);
+       if (res == NULL) {
+               goto out_enomem1;
+       }
+       res->name = "Xen privcmd mmap";
+       error = allocate_resource(&iomem_resource, res, size,
+                                 privcmd_resource_min, privcmd_resource_max,
+                                 privcmd_resource_align, NULL, NULL);
+       if (error) {
+               goto out_enomem1;
+       }
+       privcmd_range->res = res;
 
        /* DONTCOPY is essential for Xen as copy_page_range is broken. */
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
@@ -589,10 +714,11 @@ privcmd_mmap(struct file * file, struct 
        return 0;
 
 out_enomem1:
+       kfree(res);
        kfree(privcmd_vma);
 out_enomem0:
        vfree(privcmd_range);
-       return -ENOMEM;
+       return error;
 }
 
 int
@@ -605,10 +731,13 @@ direct_remap_pfn_range(struct vm_area_st
 {
        struct xen_ia64_privcmd_vma* privcmd_vma =
                (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
+       struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
+       unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
+
        unsigned long i;
        unsigned long offset;
        int error = 0;
-       BUG_ON(!running_on_xen);
+       BUG_ON(!is_running_on_xen());
 
 #if 0
        if (prot != vm->vm_page_prot) {
@@ -618,9 +747,7 @@ direct_remap_pfn_range(struct vm_area_st
 
        i = (address - vma->vm_start) >> PAGE_SHIFT;
        for (offset = 0; offset < size; offset += PAGE_SIZE) {
-               struct xen_ia64_privcmd_entry* entry =
-                       &privcmd_vma->entries[i];
-               error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & 
PAGE_MASK, entry, mfn, prot, domid);
+               error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & 
PAGE_MASK, privcmd_range, entry_offset + i, mfn, prot, domid);
                if (error != 0) {
                        break;
                }
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/xen/xenivt.S
--- a/arch/ia64/xen/xenivt.S    Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/ia64/xen/xenivt.S    Thu Jun 08 15:10:05 2006 -0400
@@ -206,9 +206,9 @@ ENTRY(vhpt_miss)
        mov r24=r8
        mov r8=r18
        ;;
-(p10)  XEN_HYPER_ITC_D
-       ;;
-(p11)  XEN_HYPER_ITC_I
+(p10)  XEN_HYPER_ITC_I
+       ;;
+(p11)  XEN_HYPER_ITC_D
        ;;
        mov r8=r24
        ;;
@@ -799,7 +799,16 @@ 1: ld8 r18=[r17]
        ;;
 (p6)   cmp.eq p6,p7=r26,r18                    // Only compare if page is 
present
        ;;
+#ifdef CONFIG_XEN
+(p6)   mov r18=r8
+(p6)   mov r8=r25
+       ;;
+(p6)   XEN_HYPER_ITC_D
+       ;;
+(p6)   mov r8=r18
+#else
 (p6)   itc.d r25                               // install updated PTE
+#endif 
        ;;
        /*
         * Tell the assemblers dependency-violation checker that the above 
"itc" instructions
@@ -2038,6 +2047,7 @@ GLOBAL_ENTRY(xen_bsw1)
        ld8 r28=[r30],16; ld8 r29=[r31],16;;
        ld8 r30=[r30]; ld8 r31=[r31];;
        br.ret.sptk.many b0
+END(xen_bsw1)
 #endif
 
        .org ia64_ivt+0x7f00
@@ -2130,5 +2140,32 @@ non_ia32_syscall:
        mov rp=r15
        br.ret.sptk.many rp
 END(dispatch_to_ia32_handler)
-
 #endif /* CONFIG_IA32_SUPPORT */
+
+#ifdef CONFIG_XEN
+       .section .text,"ax"
+GLOBAL_ENTRY(xen_event_callback)
+       mov r31=pr              // prepare to save predicates
+       ;;
+       SAVE_MIN_WITH_COVER     // uses r31; defines r2 and r3
+       ;;
+       movl r3=XSI_PSR_IC
+       mov r14=1
+       ;;
+       st4 [r3]=r14
+       ;;
+       adds r3=8,r2            // set up second base pointer for SAVE_REST
+       srlz.i                  // ensure everybody knows psr.ic is back on
+       ;;
+       SAVE_REST
+       ;;
+       alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group
+       add out0=16,sp          // pass pointer to pt_regs as first arg
+       ;;
+       srlz.d                  // make sure we see the effect of cr.ivr
+       movl r14=ia64_leave_kernel
+       ;;
+       mov rp=r14
+       br.call.sptk.many b6=evtchn_do_upcall
+END(xen_event_callback)
+#endif
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig      Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/powerpc/Kconfig      Thu Jun 08 15:10:05 2006 -0400
@@ -400,9 +400,14 @@ config PPC_XEN
 config PPC_XEN
        bool "Enable Xen compatible kernel"
        depends PPC_MULTIPLATFORM && PPC64 && PPC_MAPLE && PPC_PSERIES && SMP
+       select XEN
        select XEN_PRIVILEGED_GUEST
        select XEN_UNPRIVILEGED_GUEST
        select XEN_XENCOMM
+       reverse XEN_BALLOON
+       reverse XEN_REBOOT
+       reverse XEN_SMPBOOT
+       
        help
          This option will compile a kernel compatible with Xen hypervisor
 
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/x86_64/kernel/process-xen.c
--- a/arch/x86_64/kernel/process-xen.c  Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/x86_64/kernel/process-xen.c  Thu Jun 08 15:10:05 2006 -0400
@@ -60,6 +60,8 @@
 #include <asm/ia32.h>
 #include <asm/idle.h>
 
+#include <xen/cpu_hotplug.h>
+
 asmlinkage extern void ret_from_fork(void);
 
 unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
@@ -111,8 +113,6 @@ void exit_idle(void)
 }
 
 /* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-extern void stop_hz_timer(void);
-extern void start_hz_timer(void);
 void xen_idle(void)
 {
        local_irq_disable();
@@ -122,10 +122,7 @@ void xen_idle(void)
        else {
                clear_thread_flag(TIF_POLLING_NRFLAG);
                smp_mb__after_clear_bit();
-               stop_hz_timer();
-               /* Blocking includes an implicit local_irq_enable(). */
-               HYPERVISOR_block();
-               start_hz_timer();
+               safe_halt();
                set_thread_flag(TIF_POLLING_NRFLAG);
        }
 }
@@ -138,11 +135,7 @@ static inline void play_dead(void)
        cpu_clear(smp_processor_id(), cpu_initialized);
        preempt_enable_no_resched();
        HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
-       /* Same as drivers/xen/core/smpboot.c:cpu_bringup(). */
-       cpu_init();
-       touch_softlockup_watchdog();
-       preempt_disable();
-       local_irq_enable();
+       cpu_bringup();
 }
 #else
 static inline void play_dead(void)
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/x86_64/kernel/setup-xen.c
--- a/arch/x86_64/kernel/setup-xen.c    Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/x86_64/kernel/setup-xen.c    Thu Jun 08 15:10:05 2006 -0400
@@ -693,13 +693,6 @@ void __init setup_arch(char **cmdline_p)
 
        setup_xen_features();
 
-       if (xen_feature(XENFEAT_auto_translated_physmap) &&
-           xen_start_info->shared_info < xen_start_info->nr_pages) {
-               HYPERVISOR_shared_info =
-                       (shared_info_t *)__va(xen_start_info->shared_info);
-               memset(empty_zero_page, 0, sizeof(empty_zero_page));
-       }
-
        HYPERVISOR_vm_assist(VMASST_CMD_enable,
                             VMASST_TYPE_writable_pagetables);
 
@@ -860,14 +853,6 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_XEN
        {
                int i, j, k, fpp;
-               unsigned long va;
-
-               /* 'Initial mapping' of initrd must be destroyed. */
-               for (va = xen_start_info->mod_start;
-                    va < (xen_start_info->mod_start+xen_start_info->mod_len);
-                    va += PAGE_SIZE) {
-                       HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
-               }
 
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* Make sure we have a large enough P->M table. */
@@ -882,14 +867,6 @@ void __init setup_arch(char **cmdline_p)
                                __pa(xen_start_info->mfn_list),
                                PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
                                                sizeof(unsigned long))));
-
-                       /* Destroyed 'initial mapping' of old p2m table. */
-                       for (va = xen_start_info->mfn_list;
-                            va < (xen_start_info->mfn_list +
-                                  (xen_start_info->nr_pages*sizeof(unsigned 
long)));
-                            va += PAGE_SIZE) {
-                               HYPERVISOR_update_va_mapping(va, __pte_ma(0), 
0);
-                       }
 
                        /*
                         * Initialise the list of the frames that specify the
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/x86_64/kernel/smp-xen.c
--- a/arch/x86_64/kernel/smp-xen.c      Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/x86_64/kernel/smp-xen.c      Thu Jun 08 15:10:05 2006 -0400
@@ -488,7 +488,7 @@ static void smp_really_stop_cpu(void *du
 {
        smp_stop_cpu(); 
        for (;;) 
-               asm("hlt"); 
+               halt();
 } 
 
 void smp_send_stop(void)
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/x86_64/mm/init-xen.c
--- a/arch/x86_64/mm/init-xen.c Wed Jun 07 19:53:53 2006 -0400
+++ b/arch/x86_64/mm/init-xen.c Thu Jun 08 15:10:05 2006 -0400
@@ -710,7 +710,34 @@ void __meminit init_memory_mapping(unsig
                        set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
        }
 
-       BUG_ON(!after_bootmem && start_pfn != table_end);
+       if (!after_bootmem) {
+               BUG_ON(start_pfn != table_end);
+
+               /* Re-vector virtual addresses pointing into the initial
+                  mapping to the just-established permanent ones. */
+               xen_start_info = __va(__pa(xen_start_info));
+               xen_start_info->pt_base = (unsigned long)
+                       __va(__pa(xen_start_info->pt_base));
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       phys_to_machine_mapping =
+                               __va(__pa(xen_start_info->mfn_list));
+                       xen_start_info->mfn_list = (unsigned long)
+                               phys_to_machine_mapping;
+               }
+               if (xen_start_info->mod_start)
+                       xen_start_info->mod_start = (unsigned long)
+                               __va(__pa(xen_start_info->mod_start));
+
+               /* Destroy the Xen-created mappings beyond the kernel image as
+                * well as the temporary mappings created above. Prevents
+                * overlap with modules area (if init mapping is very big).
+                */
+               start = PAGE_ALIGN((unsigned long)_end);
+               end   = __START_KERNEL_map + (table_end << PAGE_SHIFT);
+               for (; start < end; start += PAGE_SIZE)
+                       WARN_ON(HYPERVISOR_update_va_mapping(
+                               start, __pte_ma(0), 0));
+       }
 
        __flush_tlb_all();
 }
@@ -796,15 +823,11 @@ void __init paging_init(void)
        free_area_init_node(0, NODE_DATA(0), zones,
                            __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
 
-       if (!xen_feature(XENFEAT_auto_translated_physmap) ||
-           xen_start_info->shared_info >= xen_start_info->nr_pages) {
-               /* Switch to the real shared_info page, and clear the
-                * dummy page. */
-               set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-               HYPERVISOR_shared_info =
-                       (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-               memset(empty_zero_page, 0, sizeof(empty_zero_page));
-       }
+       /* Switch to the real shared_info page, and clear the
+        * dummy page. */
+       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+       memset(empty_zero_page, 0, sizeof(empty_zero_page));
 
        init_mm.context.pinned = 1;
 
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/Kconfig
--- a/drivers/xen/Kconfig       Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/Kconfig       Thu Jun 08 15:10:05 2006 -0400
@@ -6,7 +6,7 @@ mainmenu "Xen Configuration"
 
 config XEN
        bool
-       default y if X86_XEN || X86_64_XEN || PPC_XEN
+       default y if X86_XEN || X86_64_XEN
        help
          This is the Linux Xen port.
 
@@ -234,24 +234,27 @@ config XEN_UTIL
 
 config XEN_BALLOON
        bool
-       default y if ! PPC_XEN
+       default y
+
+config XEN_DEVMEM
+       bool
+       default y
 
 config XEN_SKBUFF
        bool
+       default y
        depends on NET
-       default y
 
 config XEN_REBOOT
        bool
-       default y if ! PPC_XEN
+       default y
 
 config XEN_SMPBOOT
        bool
+       default y
        depends on SMP
-       default y if ! PPC_XEN
 
 config XEN_XENCOMM
        bool
        default n
-
 endif
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/Makefile
--- a/drivers/xen/Makefile      Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/Makefile      Thu Jun 08 15:10:05 2006 -0400
@@ -1,5 +1,4 @@ obj-y   += core/
 obj-y  += core/
-obj-y  += char/
 obj-y  += console/
 obj-y  += evtchn/
 obj-y  += privcmd/
@@ -7,6 +6,7 @@ obj-y   += xenbus/
 
 obj-$(CONFIG_XEN_UTIL)                 += util.o
 obj-$(CONFIG_XEN_BALLOON)              += balloon/
+obj-$(CONFIG_XEN_DEVMEM)               += char/
 obj-$(CONFIG_XEN_BLKDEV_BACKEND)       += blkback/
 obj-$(CONFIG_XEN_NETDEV_BACKEND)       += netback/
 obj-$(CONFIG_XEN_TPMDEV_BACKEND)       += tpmback/
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/balloon/balloon.c
--- a/drivers/xen/balloon/balloon.c     Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/balloon/balloon.c     Thu Jun 08 15:10:05 2006 -0400
@@ -360,12 +360,6 @@ static void balloon_process(void *unused
 /* Resets the Xen limit, sets new target, and kicks off processing. */
 static void set_new_target(unsigned long target)
 {
-       unsigned long min_target;
-
-       /* Do not allow target to reduce below 2% of maximum memory size. */
-       min_target = max_pfn / 50;
-       target = max(target, min_target);
-
        /* No need for lock. Not read-modify-write updates. */
        hard_limit   = ~0UL;
        target_pages = target;
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/blkfront/blkfront.c
--- a/drivers/xen/blkfront/blkfront.c   Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/blkfront/blkfront.c   Thu Jun 08 15:10:05 2006 -0400
@@ -452,10 +452,6 @@ int blkif_ioctl(struct inode *inode, str
                      command, (long)argument, inode->i_rdev);
 
        switch (command) {
-       case HDIO_GETGEO:
-               /* return ENOSYS to use defaults */
-               return -ENOSYS;
-
        case CDROMMULTISESSION:
                DPRINTK("FIXME: support multisession CDs later\n");
                for (i = 0; i < sizeof(struct cdrom_multisession); i++)
@@ -469,6 +465,23 @@ int blkif_ioctl(struct inode *inode, str
                return -EINVAL; /* same return as native Linux */
        }
 
+       return 0;
+}
+
+
+int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
+{
+       /* We don't have real geometry info, but let's at least return
+          values consistent with the size of the device */
+       sector_t nsect = get_capacity(bd->bd_disk);
+       sector_t cylinders = nsect;
+
+       hg->heads = 0xff;
+       hg->sectors = 0x3f;
+       sector_div(cylinders, hg->heads * hg->sectors);
+       hg->cylinders = cylinders;
+       if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
+               hg->cylinders = 0xffff;
        return 0;
 }
 
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/blkfront/block.h
--- a/drivers/xen/blkfront/block.h      Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/blkfront/block.h      Thu Jun 08 15:10:05 2006 -0400
@@ -140,6 +140,7 @@ extern int blkif_release(struct inode *i
 extern int blkif_release(struct inode *inode, struct file *filep);
 extern int blkif_ioctl(struct inode *inode, struct file *filep,
                        unsigned command, unsigned long argument);
+extern int blkif_getgeo(struct block_device *, struct hd_geometry *);
 extern int blkif_check(dev_t dev);
 extern int blkif_revalidate(dev_t dev);
 extern void do_blkif_request (request_queue_t *rq);
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/blkfront/vbd.c
--- a/drivers/xen/blkfront/vbd.c        Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/blkfront/vbd.c        Thu Jun 08 15:10:05 2006 -0400
@@ -91,6 +91,7 @@ static struct block_device_operations xl
        .open = blkif_open,
        .release = blkif_release,
        .ioctl  = blkif_ioctl,
+       .getgeo = blkif_getgeo
 };
 
 DEFINE_SPINLOCK(blkif_io_lock);
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/core/Makefile
--- a/drivers/xen/core/Makefile Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/core/Makefile Thu Jun 08 15:10:05 2006 -0400
@@ -1,15 +1,17 @@
+#
+# Makefile for the linux kernel.
+#
 #
 # Makefile for the linux kernel.
 #
 
 obj-y := evtchn.o gnttab.o features.o
 
-
 obj-$(CONFIG_PROC_FS)          += xen_proc.o
 obj-$(CONFIG_SYSFS)            += hypervisor_sysfs.o
 obj-$(CONFIG_HOTPLUG_CPU)      += cpu_hotplug.o
 obj-$(CONFIG_XEN_SYSFS)                += xen_sysfs.o
+obj-$(CONFIG_IA64)             += xenia64_init.o
 obj-$(CONFIG_XEN_SKBUFF)       += skbuff.o
 obj-$(CONFIG_XEN_REBOOT)       += reboot.o
 obj-$(CONFIG_XEN_SMPBOOT)      += smpboot.o
-obj-$(CONFIG_XEN_XENCOMM)      += xencomm.o
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/core/cpu_hotplug.c
--- a/drivers/xen/core/cpu_hotplug.c    Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/core/cpu_hotplug.c    Thu Jun 08 15:10:05 2006 -0400
@@ -160,7 +160,7 @@ void smp_resume(void)
                vcpu_hotplug(cpu);
 }
 
-int cpu_up_is_allowed(unsigned int cpu)
+int cpu_up_check(unsigned int cpu)
 {
        int rc = 0;
 
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/core/smpboot.c
--- a/drivers/xen/core/smpboot.c        Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/core/smpboot.c        Thu Jun 08 15:10:05 2006 -0400
@@ -87,9 +87,8 @@ void __init prefill_possible_map(void)
 
        for (i = 0; i < NR_CPUS; i++) {
                rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
-               if (rc == -ENOENT)
-                       break;
-               cpu_set(i, cpu_possible_map);
+               if (rc >= 0)
+                       cpu_set(i, cpu_possible_map);
        }
 }
 
@@ -148,12 +147,17 @@ static void xen_smp_intr_exit(unsigned i
 }
 #endif
 
-static void cpu_bringup(void)
+void cpu_bringup(void)
 {
        cpu_init();
        touch_softlockup_watchdog();
        preempt_disable();
        local_irq_enable();
+}
+
+static void cpu_bringup_and_idle(void)
+{
+       cpu_bringup();
        cpu_idle();
 }
 
@@ -178,7 +182,7 @@ void cpu_initialize_context(unsigned int
        ctxt.user_regs.fs = 0;
        ctxt.user_regs.gs = 0;
        ctxt.user_regs.ss = __KERNEL_DS;
-       ctxt.user_regs.eip = (unsigned long)cpu_bringup;
+       ctxt.user_regs.eip = (unsigned long)cpu_bringup_and_idle;
        ctxt.user_regs.eflags = X86_EFLAGS_IF | 0x1000; /* IOPL_RING1 */
 
        memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
@@ -202,7 +206,7 @@ void cpu_initialize_context(unsigned int
        ctxt.failsafe_callback_cs  = __KERNEL_CS;
        ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
 
-       ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
+       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
 #else /* __x86_64__ */
        ctxt.user_regs.cs = __KERNEL_CS;
        ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs);
@@ -214,7 +218,7 @@ void cpu_initialize_context(unsigned int
        ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
        ctxt.syscall_callback_eip  = (unsigned long)system_call;
 
-       ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
+       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt));
 
        ctxt.gs_base_kernel = (unsigned long)(cpu_pda(cpu));
 #endif
@@ -395,7 +399,7 @@ int __devinit __cpu_up(unsigned int cpu)
 {
        int rc;
 
-       rc = cpu_up_is_allowed(cpu);
+       rc = cpu_up_check(cpu);
        if (rc)
                return rc;
 
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/netback/loopback.c
--- a/drivers/xen/netback/loopback.c    Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/netback/loopback.c    Thu Jun 08 15:10:05 2006 -0400
@@ -146,11 +146,13 @@ static void loopback_construct(struct ne
        dev->hard_start_xmit = loopback_start_xmit;
        dev->get_stats       = loopback_get_stats;
        dev->set_multicast_list = loopback_set_multicast_list;
+       dev->change_mtu      = NULL; /* allow arbitrary mtu */
 
        dev->tx_queue_len    = 0;
 
        dev->features        = (NETIF_F_HIGHDMA |
                                NETIF_F_LLTX |
+                               NETIF_F_SG |
                                NETIF_F_IP_CSUM);
 
        SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c     Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/netback/netback.c     Thu Jun 08 15:10:05 2006 -0400
@@ -458,6 +458,9 @@ inline static void net_tx_action_dealloc
        dc = dealloc_cons;
        dp = dealloc_prod;
 
+       /* Ensure we see all indexes enqueued by netif_idx_release(). */
+       smp_rmb();
+
        /*
         * Free up any grants we have finished using
         */
@@ -487,6 +490,177 @@ inline static void net_tx_action_dealloc
        }
 }
 
+static void netbk_tx_err(netif_t *netif, RING_IDX end)
+{
+       RING_IDX cons = netif->tx.req_cons;
+
+       do {
+               netif_tx_request_t *txp = RING_GET_REQUEST(&netif->tx, cons);
+               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+       } while (++cons < end);
+       netif->tx.req_cons = cons;
+       netif_schedule_work(netif);
+       netif_put(netif);
+}
+
+static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp,
+                               int work_to_do)
+{
+       netif_tx_request_t *first = txp;
+       RING_IDX cons = netif->tx.req_cons;
+       int frags = 1;
+
+       while (txp->flags & NETTXF_more_data) {
+               if (frags >= work_to_do) {
+                       DPRINTK("Need more frags\n");
+                       return -frags;
+               }
+
+               txp = RING_GET_REQUEST(&netif->tx, cons + frags);
+               if (txp->size > first->size) {
+                       DPRINTK("Frags galore\n");
+                       return -frags;
+               }
+
+               first->size -= txp->size;
+               frags++;
+
+               if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
+                       DPRINTK("txp->offset: %x, size: %u\n",
+                               txp->offset, txp->size);
+                       return -frags;
+               }
+       }
+
+       return frags;
+}
+
+static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif,
+                                                 struct sk_buff *skb,
+                                                 gnttab_map_grant_ref_t *mop)
+{
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+       skb_frag_t *frags = shinfo->frags;
+       netif_tx_request_t *txp;
+       unsigned long pending_idx = *((u16 *)skb->data);
+       RING_IDX cons = netif->tx.req_cons + 1;
+       int i, start;
+
+       /* Skip first skb fragment if it is on same page as header fragment. */
+       start = ((unsigned long)shinfo->frags[0].page == pending_idx);
+
+       for (i = start; i < shinfo->nr_frags; i++) {
+               txp = RING_GET_REQUEST(&netif->tx, cons++);
+               pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
+
+               gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx),
+                                 GNTMAP_host_map | GNTMAP_readonly,
+                                 txp->gref, netif->domid);
+
+               memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp));
+               netif_get(netif);
+               pending_tx_info[pending_idx].netif = netif;
+               frags[i].page = (void *)pending_idx;
+       }
+
+       return mop;
+}
+
+static int netbk_tx_check_mop(struct sk_buff *skb,
+                              gnttab_map_grant_ref_t **mopp)
+{
+       gnttab_map_grant_ref_t *mop = *mopp;
+       int pending_idx = *((u16 *)skb->data);
+       netif_t *netif = pending_tx_info[pending_idx].netif;
+       netif_tx_request_t *txp;
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+       int nr_frags = shinfo->nr_frags;
+       int i, err, start;
+
+       /* Check status of header. */
+       err = mop->status;
+       if (unlikely(err)) {
+               txp = &pending_tx_info[pending_idx].req;
+               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+               pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
+               netif_put(netif);
+       } else {
+               set_phys_to_machine(
+                       __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
+                       FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
+               grant_tx_handle[pending_idx] = mop->handle;
+       }
+
+       /* Skip first skb fragment if it is on same page as header fragment. */
+       start = ((unsigned long)shinfo->frags[0].page == pending_idx);
+
+       for (i = start; i < nr_frags; i++) {
+               int j, newerr;
+
+               pending_idx = (unsigned long)shinfo->frags[i].page;
+
+               /* Check error status: if okay then remember grant handle. */
+               newerr = (++mop)->status;
+               if (likely(!newerr)) {
+                       set_phys_to_machine(
+                               __pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT,
+                               FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
+                       grant_tx_handle[pending_idx] = mop->handle;
+                       /* Had a previous error? Invalidate this fragment. */
+                       if (unlikely(err))
+                               netif_idx_release(pending_idx);
+                       continue;
+               }
+
+               /* Error on this fragment: respond to client with an error. */
+               txp = &pending_tx_info[pending_idx].req;
+               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+               pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
+               netif_put(netif);
+
+               /* Not the first error? Preceding frags already invalidated. */
+               if (err)
+                       continue;
+
+               /* First error: invalidate header and preceding fragments. */
+               pending_idx = *((u16 *)skb->data);
+               netif_idx_release(pending_idx);
+               for (j = start; j < i; j++) {
+                       pending_idx = (unsigned long)shinfo->frags[i].page;
+                       netif_idx_release(pending_idx);
+               }
+
+               /* Remember the error: invalidate all subsequent fragments. */
+               err = newerr;
+       }
+
+       *mopp = mop + 1;
+       return err;
+}
+
+static void netbk_fill_frags(struct sk_buff *skb)
+{
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+       int nr_frags = shinfo->nr_frags;
+       int i;
+
+       for (i = 0; i < nr_frags; i++) {
+               skb_frag_t *frag = shinfo->frags + i;
+               netif_tx_request_t *txp;
+               unsigned long pending_idx;
+
+               pending_idx = (unsigned long)frag->page;
+               txp = &pending_tx_info[pending_idx].req;
+               frag->page = virt_to_page(MMAP_VADDR(pending_idx));
+               frag->size = txp->size;
+               frag->page_offset = txp->offset;
+
+               skb->len += txp->size;
+               skb->data_len += txp->size;
+               skb->truesize += txp->size;
+       }
+}
+
 /* Called after netfront has transmitted */
 static void net_tx_action(unsigned long unused)
 {
@@ -504,7 +678,7 @@ static void net_tx_action(unsigned long 
                net_tx_action_dealloc();
 
        mop = tx_map_ops;
-       while ((NR_PENDING_REQS < MAX_PENDING_REQS) &&
+       while (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
                !list_empty(&net_schedule_list)) {
                /* Get a netif from the list with work to do. */
                ent = net_schedule_list.next;
@@ -552,38 +726,44 @@ static void net_tx_action(unsigned long 
                }
                netif->remaining_credit -= txreq.size;
 
-               netif->tx.req_cons++;
-
-               netif_schedule_work(netif);
-
-               if (unlikely(txreq.size < ETH_HLEN) || 
-                   unlikely(txreq.size > ETH_FRAME_LEN)) {
+               ret = netbk_count_requests(netif, &txreq, work_to_do);
+               if (unlikely(ret < 0)) {
+                       netbk_tx_err(netif, i - ret);
+                       continue;
+               }
+               i += ret;
+
+               if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
+                       DPRINTK("Too many frags\n");
+                       netbk_tx_err(netif, i);
+                       continue;
+               }
+
+               if (unlikely(txreq.size < ETH_HLEN)) {
                        DPRINTK("Bad packet size: %d\n", txreq.size);
-                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-                       netif_put(netif);
+                       netbk_tx_err(netif, i);
                        continue; 
                }
 
                /* No crossing a page as the payload mustn't fragment. */
-               if (unlikely((txreq.offset + txreq.size) >= PAGE_SIZE)) {
+               if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) {
                        DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", 
                                txreq.offset, txreq.size, 
                                (txreq.offset &~PAGE_MASK) + txreq.size);
-                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-                       netif_put(netif);
+                       netbk_tx_err(netif, i);
                        continue;
                }
 
                pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
 
-               data_len = (txreq.size > PKT_PROT_LEN) ?
+               data_len = (txreq.size > PKT_PROT_LEN &&
+                           ret < MAX_SKB_FRAGS + 1) ?
                        PKT_PROT_LEN : txreq.size;
 
                skb = alloc_skb(data_len+16, GFP_ATOMIC);
                if (unlikely(skb == NULL)) {
                        DPRINTK("Can't allocate a skb in start_xmit.\n");
-                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-                       netif_put(netif);
+                       netbk_tx_err(netif, i);
                        break;
                }
 
@@ -600,9 +780,23 @@ static void net_tx_action(unsigned long 
                pending_tx_info[pending_idx].netif = netif;
                *((u16 *)skb->data) = pending_idx;
 
+               __skb_put(skb, data_len);
+
+               skb_shinfo(skb)->nr_frags = ret - 1;
+               if (data_len < txreq.size) {
+                       skb_shinfo(skb)->nr_frags++;
+                       skb_shinfo(skb)->frags[0].page =
+                               (void *)(unsigned long)pending_idx;
+               }
+
                __skb_queue_tail(&tx_queue, skb);
 
                pending_cons++;
+
+               mop = netbk_get_requests(netif, skb, mop);
+
+               netif->tx.req_cons = i;
+               netif_schedule_work(netif);
 
                if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops))
                        break;
@@ -617,75 +811,56 @@ static void net_tx_action(unsigned long 
 
        mop = tx_map_ops;
        while ((skb = __skb_dequeue(&tx_queue)) != NULL) {
+               netif_tx_request_t *txp;
+
                pending_idx = *((u16 *)skb->data);
                netif       = pending_tx_info[pending_idx].netif;
-               memcpy(&txreq, &pending_tx_info[pending_idx].req,
-                      sizeof(txreq));
+               txp         = &pending_tx_info[pending_idx].req;
 
                /* Check the remap error code. */
-               if (unlikely(mop->status)) {
+               if (unlikely(netbk_tx_check_mop(skb, &mop))) {
                        printk(KERN_ALERT "#### netback grant fails\n");
-                       make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
-                       netif_put(netif);
+                       skb_shinfo(skb)->nr_frags = 0;
                        kfree_skb(skb);
-                       mop++;
-                       pending_ring[MASK_PEND_IDX(pending_prod++)] =
-                               pending_idx;
                        continue;
                }
-               set_phys_to_machine(
-                       __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
-                       FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
-               grant_tx_handle[pending_idx] = mop->handle;
-
-               data_len = (txreq.size > PKT_PROT_LEN) ?
-                       PKT_PROT_LEN : txreq.size;
-
-               __skb_put(skb, data_len);
+
+               data_len = skb->len;
                memcpy(skb->data, 
-                      (void *)(MMAP_VADDR(pending_idx)|txreq.offset),
+                      (void *)(MMAP_VADDR(pending_idx)|txp->offset),
                       data_len);
-               if (data_len < txreq.size) {
+               if (data_len < txp->size) {
                        /* Append the packet payload as a fragment. */
-                       skb_shinfo(skb)->frags[0].page        = 
-                               virt_to_page(MMAP_VADDR(pending_idx));
-                       skb_shinfo(skb)->frags[0].size        =
-                               txreq.size - data_len;
-                       skb_shinfo(skb)->frags[0].page_offset = 
-                               txreq.offset + data_len;
-                       skb_shinfo(skb)->nr_frags = 1;
+                       txp->offset += data_len;
+                       txp->size -= data_len;
                } else {
                        /* Schedule a response immediately. */
                        netif_idx_release(pending_idx);
                }
-
-               skb->data_len  = txreq.size - data_len;
-               skb->len      += skb->data_len;
-               skb->truesize += skb->data_len;
-
-               skb->dev      = netif->dev;
-               skb->protocol = eth_type_trans(skb, skb->dev);
 
                /*
                 * Old frontends do not assert data_validated but we
                 * can infer it from csum_blank so test both flags.
                 */
-               if (txreq.flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
+               if (txp->flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                        skb->proto_data_valid = 1;
                } else {
                        skb->ip_summed = CHECKSUM_NONE;
                        skb->proto_data_valid = 0;
                }
-               skb->proto_csum_blank = !!(txreq.flags & NETTXF_csum_blank);
-
-               netif->stats.rx_bytes += txreq.size;
+               skb->proto_csum_blank = !!(txp->flags & NETTXF_csum_blank);
+
+               netbk_fill_frags(skb);
+
+               skb->dev      = netif->dev;
+               skb->protocol = eth_type_trans(skb, skb->dev);
+
+               netif->stats.rx_bytes += skb->len;
                netif->stats.rx_packets++;
 
                netif_rx(skb);
                netif->dev->last_rx = jiffies;
-
-               mop++;
        }
 }
 
@@ -695,7 +870,10 @@ static void netif_idx_release(u16 pendin
        unsigned long flags;
 
        spin_lock_irqsave(&_lock, flags);
-       dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
+       dealloc_ring[MASK_PEND_IDX(dealloc_prod)] = pending_idx;
+       /* Sync with net_tx_action_dealloc: insert idx /then/ incr producer. */
+       smp_wmb();
+       dealloc_prod++;
        spin_unlock_irqrestore(&_lock, flags);
 
        tasklet_schedule(&net_tx_tasklet);
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/netback/xenbus.c
--- a/drivers/xen/netback/xenbus.c      Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/netback/xenbus.c      Thu Jun 08 15:10:05 2006 -0400
@@ -69,6 +69,8 @@ static int netback_probe(struct xenbus_d
 static int netback_probe(struct xenbus_device *dev,
                         const struct xenbus_device_id *id)
 {
+       const char *message;
+       xenbus_transaction_t xbt;
        int err;
        struct backend_info *be = kzalloc(sizeof(struct backend_info),
                                          GFP_KERNEL);
@@ -86,6 +88,27 @@ static int netback_probe(struct xenbus_d
        if (err)
                goto fail;
 
+       do {
+               err = xenbus_transaction_start(&xbt);
+               if (err) {
+                       xenbus_dev_fatal(dev, err, "starting transaction");
+                       goto fail;
+               }
+
+               err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
+               if (err) {
+                       message = "writing feature-sg";
+                       goto abort_transaction;
+               }
+
+               err = xenbus_transaction_end(xbt, 0);
+       } while (err == -EAGAIN);
+
+       if (err) {
+               xenbus_dev_fatal(dev, err, "completing transaction");
+               goto fail;
+       }
+
        err = xenbus_switch_state(dev, XenbusStateInitWait);
        if (err) {
                goto fail;
@@ -93,6 +116,9 @@ static int netback_probe(struct xenbus_d
 
        return 0;
 
+abort_transaction:
+       xenbus_transaction_end(xbt, 1);
+       xenbus_dev_fatal(dev, err, "%s", message);
 fail:
        DPRINTK("failed");
        netback_remove(dev);
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/netfront/netfront.c
--- a/drivers/xen/netfront/netfront.c   Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/netfront/netfront.c   Thu Jun 08 15:10:05 2006 -0400
@@ -45,6 +45,7 @@
 #include <linux/bitops.h>
 #include <linux/ethtool.h>
 #include <linux/in.h>
+#include <linux/if_ether.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
@@ -173,6 +174,11 @@ static void xennet_sysfs_delif(struct ne
 #define xennet_sysfs_delif(dev) do { } while(0)
 #endif
 
+static inline int xennet_can_sg(struct net_device *dev)
+{
+       return dev->features & NETIF_F_SG;
+}
+
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
  * structures and the ring buffers for communication with the backend, and
@@ -307,8 +313,6 @@ again:
                goto destroy_ring;
        }
 
-       xenbus_switch_state(dev, XenbusStateConnected);
-
        return 0;
 
  abort_transaction:
@@ -370,12 +374,9 @@ static int setup_device(struct xenbus_de
                goto fail;
 
        memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
-       network_connect(netdev);
        info->irq = bind_evtchn_to_irqhandler(
                info->evtchn, netif_int, SA_SAMPLE_RANDOM, netdev->name,
                netdev);
-       (void)send_fake_arp(netdev);
-       show_device(info);
 
        return 0;
 
@@ -391,15 +392,24 @@ static void backend_changed(struct xenbu
 static void backend_changed(struct xenbus_device *dev,
                            enum xenbus_state backend_state)
 {
+       struct netfront_info *np = dev->data;
+       struct net_device *netdev = np->netdev;
+
        DPRINTK("\n");
 
        switch (backend_state) {
        case XenbusStateInitialising:
-       case XenbusStateInitWait:
        case XenbusStateInitialised:
        case XenbusStateConnected:
        case XenbusStateUnknown:
        case XenbusStateClosed:
+               break;
+
+       case XenbusStateInitWait:
+               network_connect(netdev);
+               xenbus_switch_state(dev, XenbusStateConnected);
+               (void)send_fake_arp(netdev);
+               show_device(np);
                break;
 
        case XenbusStateClosing:
@@ -452,13 +462,17 @@ static int network_open(struct net_devic
        return 0;
 }
 
+static inline int netfront_tx_slot_available(struct netfront_info *np)
+{
+       return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
+}
+
 static inline void network_maybe_wake_tx(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
 
        if (unlikely(netif_queue_stopped(dev)) &&
-           !RING_FULL(&np->tx) &&
-           !gnttab_empty_grant_references(&np->gref_tx_head) &&
+           netfront_tx_slot_available(np) &&
            likely(netif_running(dev)))
                netif_wake_queue(dev);
 }
@@ -485,7 +499,7 @@ static void network_tx_buf_gc(struct net
                                printk(KERN_ALERT "network_tx_buf_gc: warning "
                                       "-- grant still in use by backend "
                                       "domain.\n");
-                               break; /* bail immediately */
+                               BUG();
                        }
                        gnttab_end_foreign_access_ref(
                                np->grant_tx_ref[id], GNTMAP_readonly);
@@ -638,36 +652,95 @@ static void network_alloc_rx_buffers(str
        RING_PUSH_REQUESTS(&np->rx);
 }
 
+static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
+                             struct netif_tx_request *tx)
+{
+       struct netfront_info *np = netdev_priv(dev);
+       char *data = skb->data;
+       unsigned long mfn;
+       RING_IDX prod = np->tx.req_prod_pvt;
+       int frags = skb_shinfo(skb)->nr_frags;
+       unsigned int offset = offset_in_page(data);
+       unsigned int len = skb_headlen(skb);
+       unsigned int id;
+       grant_ref_t ref;
+       int i;
+
+       while (len > PAGE_SIZE - offset) {
+               tx->size = PAGE_SIZE - offset;
+               tx->flags |= NETTXF_more_data;
+               len -= tx->size;
+               data += tx->size;
+               offset = 0;
+
+               id = get_id_from_freelist(np->tx_skbs);
+               np->tx_skbs[id] = skb_get(skb);
+               tx = RING_GET_REQUEST(&np->tx, prod++);
+               tx->id = id;
+               ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+               BUG_ON((signed short)ref < 0);
+
+               mfn = virt_to_mfn(data);
+               gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
+                                               mfn, GNTMAP_readonly);
+
+               tx->gref = np->grant_tx_ref[id] = ref;
+               tx->offset = offset;
+               tx->size = len;
+               tx->flags = 0;
+       }
+
+       for (i = 0; i < frags; i++) {
+               skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+
+               tx->flags |= NETTXF_more_data;
+
+               id = get_id_from_freelist(np->tx_skbs);
+               np->tx_skbs[id] = skb_get(skb);
+               tx = RING_GET_REQUEST(&np->tx, prod++);
+               tx->id = id;
+               ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+               BUG_ON((signed short)ref < 0);
+
+               mfn = pfn_to_mfn(page_to_pfn(frag->page));
+               gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
+                                               mfn, GNTMAP_readonly);
+
+               tx->gref = np->grant_tx_ref[id] = ref;
+               tx->offset = frag->page_offset;
+               tx->size = frag->size;
+               tx->flags = 0;
+       }
+
+       np->tx.req_prod_pvt = prod;
+}
 
 static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned short id;
        struct netfront_info *np = netdev_priv(dev);
        struct netif_tx_request *tx;
+       char *data = skb->data;
        RING_IDX i;
        grant_ref_t ref;
        unsigned long mfn;
        int notify;
-
-       if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >=
-                    PAGE_SIZE)) {
-               struct sk_buff *nskb;
-               nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC|__GFP_NOWARN);
-               if (unlikely(nskb == NULL))
-                       goto drop;
-               skb_put(nskb, skb->len);
-               memcpy(nskb->data, skb->data, skb->len);
-               /* Copy only the header fields we use in this driver. */
-               nskb->dev = skb->dev;
-               nskb->ip_summed = skb->ip_summed;
-               nskb->proto_data_valid = skb->proto_data_valid;
-               dev_kfree_skb(skb);
-               skb = nskb;
+       int frags = skb_shinfo(skb)->nr_frags;
+       unsigned int offset = offset_in_page(data);
+       unsigned int len = skb_headlen(skb);
+
+       frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE;
+       if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
+               printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
+                      frags);
+               dump_stack();
+               goto drop;
        }
 
        spin_lock_irq(&np->tx_lock);
 
-       if (unlikely(!netif_carrier_ok(dev))) {
+       if (unlikely(!netif_carrier_ok(dev) ||
+                    (frags > 1 && !xennet_can_sg(dev)))) {
                spin_unlock_irq(&np->tx_lock);
                goto drop;
        }
@@ -682,12 +755,12 @@ static int network_start_xmit(struct sk_
        tx->id   = id;
        ref = gnttab_claim_grant_reference(&np->gref_tx_head);
        BUG_ON((signed short)ref < 0);
-       mfn = virt_to_mfn(skb->data);
+       mfn = virt_to_mfn(data);
        gnttab_grant_foreign_access_ref(
                ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly);
        tx->gref = np->grant_tx_ref[id] = ref;
-       tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
-       tx->size = skb->len;
+       tx->offset = offset;
+       tx->size = len;
 
        tx->flags = 0;
        if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
@@ -696,14 +769,17 @@ static int network_start_xmit(struct sk_
                tx->flags |= NETTXF_data_validated;
 
        np->tx.req_prod_pvt = i + 1;
+
+       xennet_make_frags(skb, dev, tx);
+       tx->size = skb->len;
+
        RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
        if (notify)
                notify_remote_via_irq(np->irq);
 
        network_tx_buf_gc(dev);
 
-       if (RING_FULL(&np->tx) ||
-           gnttab_empty_grant_references(&np->gref_tx_head))
+       if (!netfront_tx_slot_available(np))
                netif_stop_queue(dev);
 
        spin_unlock_irq(&np->tx_lock);
@@ -963,12 +1039,46 @@ static struct net_device_stats *network_
        return &np->stats;
 }
 
+static int xennet_change_mtu(struct net_device *dev, int mtu)
+{
+       int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
+
+       if (mtu > max)
+               return -EINVAL;
+       dev->mtu = mtu;
+       return 0;
+}
+
+static int xennet_set_sg(struct net_device *dev, u32 data)
+{
+       if (data) {
+               struct netfront_info *np = netdev_priv(dev);
+               int val;
+
+               if (xenbus_scanf(XBT_NULL, np->xbdev->otherend, "feature-sg",
+                                "%d", &val) < 0)
+                       val = 0;
+               if (!val)
+                       return -ENOSYS;
+       } else if (dev->mtu > ETH_DATA_LEN)
+               dev->mtu = ETH_DATA_LEN;
+
+       return ethtool_op_set_sg(dev, data);
+}
+
+static void xennet_set_features(struct net_device *dev)
+{
+       xennet_set_sg(dev, 1);
+}
+
 static void network_connect(struct net_device *dev)
 {
        struct netfront_info *np;
        int i, requeue_idx;
        struct netif_tx_request *tx;
        struct sk_buff *skb;
+
+       xennet_set_features(dev);
 
        np = netdev_priv(dev);
        spin_lock_irq(&np->tx_lock);
@@ -1081,6 +1191,8 @@ static struct ethtool_ops network_ethtoo
 {
        .get_tx_csum = ethtool_op_get_tx_csum,
        .set_tx_csum = ethtool_op_set_tx_csum,
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = xennet_set_sg,
 };
 
 #ifdef CONFIG_SYSFS
@@ -1297,6 +1409,7 @@ static struct net_device * __devinit cre
        netdev->poll            = netif_poll;
        netdev->set_multicast_list = network_set_multicast_list;
        netdev->uninit          = netif_uninit;
+       netdev->change_mtu      = xennet_change_mtu;
        netdev->weight          = 64;
        netdev->features        = NETIF_F_IP_CSUM;
 
diff -r 760669a37a3a -r 5c0c59eb5f73 drivers/xen/privcmd/privcmd.c
--- a/drivers/xen/privcmd/privcmd.c     Wed Jun 07 19:53:53 2006 -0400
+++ b/drivers/xen/privcmd/privcmd.c     Thu Jun 08 15:10:05 2006 -0400
@@ -63,11 +63,11 @@ static int privcmd_ioctl(struct inode *i
                __asm__ __volatile__ (
                        "pushl %%ebx; pushl %%ecx; pushl %%edx; "
                        "pushl %%esi; pushl %%edi; "
-                       "movl  4(%%eax),%%ebx ;"
-                       "movl  8(%%eax),%%ecx ;"
-                       "movl 12(%%eax),%%edx ;"
-                       "movl 16(%%eax),%%esi ;"
-                       "movl 20(%%eax),%%edi ;"
+                       "movl  8(%%eax),%%ebx ;"
+                       "movl 16(%%eax),%%ecx ;"
+                       "movl 24(%%eax),%%edx ;"
+                       "movl 32(%%eax),%%esi ;"
+                       "movl 40(%%eax),%%edi ;"
                        "movl   (%%eax),%%eax ;"
                        "shll $5,%%eax ;"
                        "addl $hypercall_page,%%eax ;"
@@ -214,7 +214,7 @@ static int privcmd_ioctl(struct inode *i
        batch_err:
                printk("batch_err ret=%d vma=%p addr=%lx "
                       "num=%d arr=%p %lx-%lx\n", 
-                      ret, vma, m.addr, m.num, m.arr,
+                      ret, vma, (unsigned long)m.addr, m.num, m.arr,
                       vma ? vma->vm_start : 0, vma ? vma->vm_end : 0);
                break;
        }
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-i386/mach-xen/asm/dma-mapping.h
--- a/include/asm-i386/mach-xen/asm/dma-mapping.h       Wed Jun 07 19:53:53 
2006 -0400
+++ b/include/asm-i386/mach-xen/asm/dma-mapping.h       Thu Jun 08 15:10:05 
2006 -0400
@@ -128,8 +128,6 @@ dma_get_cache_alignment(void)
         * maximum possible, to be safe */
        return (1 << INTERNODE_CACHE_SHIFT);
 }
-#else
-extern int dma_get_cache_alignment(void);
 #endif
 
 #define dma_is_consistent(d)   (1)
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-i386/mach-xen/asm/hypercall.h
--- a/include/asm-i386/mach-xen/asm/hypercall.h Wed Jun 07 19:53:53 2006 -0400
+++ b/include/asm-i386/mach-xen/asm/hypercall.h Thu Jun 08 15:10:05 2006 -0400
@@ -260,6 +260,13 @@ HYPERVISOR_event_channel_op(
 }
 
 static inline int
+HYPERVISOR_acm_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
 HYPERVISOR_xen_version(
        int cmd, void *arg)
 {
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-i386/mach-xen/asm/system.h
--- a/include/asm-i386/mach-xen/asm/system.h    Wed Jun 07 19:53:53 2006 -0400
+++ b/include/asm-i386/mach-xen/asm/system.h    Thu Jun 08 15:10:05 2006 -0400
@@ -115,10 +115,12 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t"
        __asm__ ( \
                "movl %%cr3,%0\n\t" \
                :"=r" (__dummy)); \
-       machine_to_phys(__dummy); \
+       __dummy = xen_cr3_to_pfn(__dummy); \
+       mfn_to_pfn(__dummy) << PAGE_SHIFT; \
 })
 #define write_cr3(x) ({                                                \
-       maddr_t __dummy = phys_to_machine(x);                   \
+       unsigned int __dummy = pfn_to_mfn((x) >> PAGE_SHIFT);   \
+       __dummy = xen_pfn_to_cr3(__dummy);                      \
        __asm__ __volatile__("movl %0,%%cr3": :"r" (__dummy));  \
 })
 
@@ -519,8 +521,8 @@ do {                                                        
                \
                preempt_enable_no_resched();                            \
 } while (0)
 
-#define safe_halt()            ((void)0)
-#define halt()                 ((void)0)
+void safe_halt(void);
+void halt(void);
 
 #define __save_and_cli(x)                                              \
 do {                                                                   \
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-i386/mach-xen/setup_arch_post.h
--- a/include/asm-i386/mach-xen/setup_arch_post.h       Wed Jun 07 19:53:53 
2006 -0400
+++ b/include/asm-i386/mach-xen/setup_arch_post.h       Thu Jun 08 15:10:05 
2006 -0400
@@ -61,13 +61,6 @@ static void __init machine_specific_arch
                .address = { __KERNEL_CS, (unsigned long)nmi },
        };
 
-       if (xen_feature(XENFEAT_auto_translated_physmap) &&
-           xen_start_info->shared_info < xen_start_info->nr_pages) {
-               HYPERVISOR_shared_info =
-                       (shared_info_t *)__va(xen_start_info->shared_info);
-               memset(empty_zero_page, 0, sizeof(empty_zero_page));
-       }
-
        ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
        if (ret == 0)
                ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-ia64/hw_irq.h
--- a/include/asm-ia64/hw_irq.h Wed Jun 07 19:53:53 2006 -0400
+++ b/include/asm-ia64/hw_irq.h Thu Jun 08 15:10:05 2006 -0400
@@ -15,7 +15,11 @@
 #include <asm/ptrace.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_XEN
 typedef u8 ia64_vector;
+#else
+typedef u16 ia64_vector;
+#endif
 
 /*
  * 0 special
@@ -86,11 +90,15 @@ extern void ia64_send_ipi (int cpu, int 
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int 
redirect);
 extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
 
+#ifndef CONFIG_XEN
 static inline void
 hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
 {
        platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
 }
+#else
+extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i);
+#endif /* CONFIG_XEN */
 
 /*
  * Default implementations for the irq-descriptor API:
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-ia64/hypercall.h
--- a/include/asm-ia64/hypercall.h      Wed Jun 07 19:53:53 2006 -0400
+++ b/include/asm-ia64/hypercall.h      Thu Jun 08 15:10:05 2006 -0400
@@ -247,6 +247,13 @@ HYPERVISOR_event_channel_op(
 }
 
 static inline int
+HYPERVISOR_acm_op(
+       unsigned int cmd, void *arg)
+{
+    return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
 HYPERVISOR_xen_version(
     int cmd, void *arg)
 {
@@ -313,9 +320,20 @@ HYPERVISOR_suspend(
        return rc;
 }
 
+static inline int
+HYPERVISOR_callback_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, callback_op, cmd, arg);
+}
+
 extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
 static inline void exit_idle(void) {}
-#define do_IRQ(irq, regs) __do_IRQ((irq), (regs))
+#define do_IRQ(irq, regs) ({                   \
+       irq_enter();                            \
+       __do_IRQ((irq), (regs));                \
+       irq_exit();                             \
+})
 
 #ifdef CONFIG_XEN_IA64_DOM0_VP
 #include <linux/err.h>
@@ -418,12 +436,14 @@ HYPERVISOR_ioremap(unsigned long ioaddr,
 HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
 {
        unsigned long ret = ioaddr;
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_ioremap(ioaddr, size);
-               if (unlikely(IS_ERR_VALUE(ret)))
+               if (unlikely(ret == -ENOSYS))
                        panic("hypercall %s failed with %ld. "
                              "Please check Xen and Linux config mismatch\n",
                              __func__, -ret);
+               else if (unlikely(IS_ERR_VALUE(ret)))
+                       ret = ioaddr;
        }
        return ret;
 }
@@ -439,7 +459,7 @@ HYPERVISOR_phystomach(unsigned long gpfn
 HYPERVISOR_phystomach(unsigned long gpfn)
 {
        unsigned long ret = gpfn;
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_phystomach(gpfn);
        }
        return ret;
@@ -456,7 +476,7 @@ HYPERVISOR_machtophys(unsigned long mfn)
 HYPERVISOR_machtophys(unsigned long mfn)
 {
        unsigned long ret = mfn;
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_machtophys(mfn);
        }
        return ret;
@@ -473,7 +493,7 @@ HYPERVISOR_zap_physmap(unsigned long gpf
 HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
 {
        unsigned long ret = 0;
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_zap_physmap(gpfn, extent_order);
        }
        return ret;
@@ -481,7 +501,7 @@ HYPERVISOR_zap_physmap(unsigned long gpf
 
 static inline unsigned long
 __HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
-                        unsigned int flags, domid_t domid)
+                        unsigned long flags, domid_t domid)
 {
        return _hypercall_imm4(unsigned long, ia64_dom0vp_op,
                               IA64_DOM0VP_add_physmap, gpfn, mfn, flags,
@@ -490,11 +510,11 @@ __HYPERVISOR_add_physmap(unsigned long g
 
 static inline unsigned long
 HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
-                      unsigned int flags, domid_t domid)
+                      unsigned long flags, domid_t domid)
 {
        unsigned long ret = 0;
-       BUG_ON(!running_on_xen);//XXX
-       if (running_on_xen) {
+       BUG_ON(!is_running_on_xen());//XXX
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
        }
        return ret;
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-ia64/hypervisor.h
--- a/include/asm-ia64/hypervisor.h     Wed Jun 07 19:53:53 2006 -0400
+++ b/include/asm-ia64/hypervisor.h     Thu Jun 08 15:10:05 2006 -0400
@@ -46,14 +46,12 @@
 #include <asm/hypercall.h>
 #include <asm/ptrace.h>
 #include <asm/page.h>
-#include <asm/xen/privop.h> // for running_on_xen
+#include <asm/xen/privop.h> // for is_running_on_xen()
 
 extern shared_info_t *HYPERVISOR_shared_info;
 extern start_info_t *xen_start_info;
 
 void force_evtchn_callback(void);
-
-#define is_running_on_xen() running_on_xen
 
 /* Turn jiffies into Xen system time. XXX Implement me. */
 #define jiffies_to_st(j)       0
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-ia64/irq.h
--- a/include/asm-ia64/irq.h    Wed Jun 07 19:53:53 2006 -0400
+++ b/include/asm-ia64/irq.h    Thu Jun 08 15:10:05 2006 -0400
@@ -11,8 +11,39 @@
  * 02/29/00     D.Mosberger    moved most things into hw_irq.h
  */
 
+#ifndef CONFIG_XEN
 #define NR_IRQS                256
 #define NR_IRQ_VECTORS NR_IRQS
+#else
+/*
+ * The flat IRQ space is divided into two regions:
+ *  1. A one-to-one mapping of real physical IRQs. This space is only used
+ *     if we have physical device-access privilege. This region is at the 
+ *     start of the IRQ space so that existing device drivers do not need
+ *     to be modified to translate physical IRQ numbers into our IRQ space.
+ *  3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
+ *     are bound using the provided bind/unbind functions.
+ */
+
+#define PIRQ_BASE              0
+#define NR_PIRQS               256
+
+#define DYNIRQ_BASE            (PIRQ_BASE + NR_PIRQS)
+#define NR_DYNIRQS             256
+
+#define NR_IRQS                        (NR_PIRQS + NR_DYNIRQS)
+#define NR_IRQ_VECTORS         NR_IRQS
+
+#define pirq_to_irq(_x)                ((_x) + PIRQ_BASE)
+#define irq_to_pirq(_x)                ((_x) - PIRQ_BASE)
+
+#define dynirq_to_irq(_x)      ((_x) + DYNIRQ_BASE)
+#define irq_to_dynirq(_x)      ((_x) - DYNIRQ_BASE)
+
+#define RESCHEDULE_VECTOR      0
+#define IPI_VECTOR             1
+#define NR_IPIS                        2
+#endif /* CONFIG_XEN */
 
 /*
  * IRQ line status macro IRQ_PER_CPU is used
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-ia64/xen/privop.h
--- a/include/asm-ia64/xen/privop.h     Wed Jun 07 19:53:53 2006 -0400
+++ b/include/asm-ia64/xen/privop.h     Thu Jun 08 15:10:05 2006 -0400
@@ -43,6 +43,7 @@
 
 #ifndef __ASSEMBLY__
 extern int running_on_xen;
+#define is_running_on_xen() running_on_xen
 
 #define        XEN_HYPER_SSM_I         asm("break %0" : : "i" 
(HYPERPRIVOP_SSM_I))
 #define        XEN_HYPER_GET_IVR       asm("break %0" : : "i" 
(HYPERPRIVOP_GET_IVR))
@@ -122,7 +123,7 @@ extern void xen_set_eflag(unsigned long)
 
 #define xen_ia64_intrin_local_irq_restore(x)                           \
 {                                                                      \
-     if (running_on_xen) {                                             \
+     if (is_running_on_xen()) {                                                
\
        if ((x) & IA64_PSR_I) { xen_ssm_i(); }                          \
        else { xen_rsm_i(); }                                           \
     }                                                                  \
@@ -131,7 +132,7 @@ extern void xen_set_eflag(unsigned long)
 
 #define        xen_get_psr_i()                                                 
\
 (                                                                      \
-       (running_on_xen) ?                                              \
+       (is_running_on_xen()) ?                                         \
                (xen_get_virtual_psr_i() ? IA64_PSR_I : 0)              \
                : __ia64_get_psr_i()                                    \
 )
@@ -139,7 +140,7 @@ extern void xen_set_eflag(unsigned long)
 #define xen_ia64_ssm(mask)                                             \
 {                                                                      \
        if ((mask)==IA64_PSR_I) {                                       \
-               if (running_on_xen) { xen_ssm_i(); }                    \
+               if (is_running_on_xen()) { xen_ssm_i(); }                       
\
                else { __ia64_ssm(mask); }                              \
        }                                                               \
        else { __ia64_ssm(mask); }                                      \
@@ -148,7 +149,7 @@ extern void xen_set_eflag(unsigned long)
 #define xen_ia64_rsm(mask)                                             \
 {                                                                      \
        if ((mask)==IA64_PSR_I) {                                       \
-               if (running_on_xen) { xen_rsm_i(); }                    \
+               if (is_running_on_xen()) { xen_rsm_i(); }                       
\
                else { __ia64_rsm(mask); }                              \
        }                                                               \
        else { __ia64_rsm(mask); }                                      \
@@ -167,10 +168,11 @@ extern void xen_set_rr(unsigned long ind
 extern void xen_set_rr(unsigned long index, unsigned long val);
 extern unsigned long xen_get_rr(unsigned long index);
 extern void xen_set_kr(unsigned long index, unsigned long val);
-
-/* Note: It may look wrong to test for running_on_xen in each case.
+extern void xen_ptcga(unsigned long addr, unsigned long size);
+
+/* Note: It may look wrong to test for is_running_on_xen() in each case.
  * However regnum is always a constant so, as written, the compiler
- * eliminates the switch statement, whereas running_on_xen must be
+ * eliminates the switch statement, whereas is_running_on_xen() must be
  * tested dynamically. */
 #define xen_ia64_getreg(regnum)                                                
\
 ({                                                                     \
@@ -178,17 +180,17 @@ extern void xen_set_kr(unsigned long ind
                                                                        \
        switch(regnum) {                                                \
        case _IA64_REG_CR_IVR:                                          \
-               ia64_intri_res = (running_on_xen) ?                     \
+               ia64_intri_res = (is_running_on_xen()) ?                        
\
                        xen_get_ivr() :                                 \
                        __ia64_getreg(regnum);                          \
                break;                                                  \
        case _IA64_REG_CR_TPR:                                          \
-               ia64_intri_res = (running_on_xen) ?                     \
+               ia64_intri_res = (is_running_on_xen()) ?                        
\
                        xen_get_tpr() :                                 \
                        __ia64_getreg(regnum);                          \
                break;                                                  \
        case _IA64_REG_AR_EFLAG:                                        \
-               ia64_intri_res = (running_on_xen) ?                     \
+               ia64_intri_res = (is_running_on_xen()) ?                        
\
                        xen_get_eflag() :                               \
                        __ia64_getreg(regnum);                          \
                break;                                                  \
@@ -203,27 +205,27 @@ extern void xen_set_kr(unsigned long ind
 ({                                                                     \
        switch(regnum) {                                                \
        case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:                     \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_set_kr((regnum-_IA64_REG_AR_KR0), val) :    \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
        case _IA64_REG_CR_ITM:                                          \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_set_itm(val) :                              \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
        case _IA64_REG_CR_TPR:                                          \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_set_tpr(val) :                              \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
        case _IA64_REG_CR_EOI:                                          \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_eoi() :                                     \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
        case _IA64_REG_AR_EFLAG:                                        \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_set_eflag(val) :                            \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-x86_64/mach-xen/asm/hypercall.h
--- a/include/asm-x86_64/mach-xen/asm/hypercall.h       Wed Jun 07 19:53:53 
2006 -0400
+++ b/include/asm-x86_64/mach-xen/asm/hypercall.h       Thu Jun 08 15:10:05 
2006 -0400
@@ -258,6 +258,13 @@ HYPERVISOR_event_channel_op(
 }
 
 static inline int
+HYPERVISOR_acm_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
 HYPERVISOR_xen_version(
        int cmd, void *arg)
 {
diff -r 760669a37a3a -r 5c0c59eb5f73 include/asm-x86_64/mach-xen/asm/system.h
--- a/include/asm-x86_64/mach-xen/asm/system.h  Wed Jun 07 19:53:53 2006 -0400
+++ b/include/asm-x86_64/mach-xen/asm/system.h  Thu Jun 08 15:10:05 2006 -0400
@@ -418,8 +418,8 @@ do {                                                        
                \
        preempt_enable_no_resched();                                    \
        ___x; })
 
-#define safe_halt()            ((void)0)
-#define halt()                 ((void)0)
+void safe_halt(void);
+void halt(void);
 
 void cpu_idle_wait(void);
 
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/cpu_hotplug.h
--- a/include/xen/cpu_hotplug.h Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/cpu_hotplug.h Thu Jun 08 15:10:05 2006 -0400
@@ -13,14 +13,16 @@ void cpu_initialize_context(unsigned int
 #define cpu_initialize_context(cpu)    ((void)0)
 #endif
 
-int cpu_up_is_allowed(unsigned int cpu);
+int cpu_up_check(unsigned int cpu);
 void init_xenbus_allowed_cpumask(void);
 int smp_suspend(void);
 void smp_resume(void);
 
+void cpu_bringup(void);
+
 #else /* !defined(CONFIG_HOTPLUG_CPU) */
 
-#define cpu_up_is_allowed(cpu)         (1)
+#define cpu_up_check(cpu)              (0)
 #define init_xenbus_allowed_cpumask()  ((void)0)
 
 static inline int smp_suspend(void)
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/arch-ia64.h
--- a/include/xen/interface/arch-ia64.h Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/arch-ia64.h Thu Jun 08 15:10:05 2006 -0400
@@ -26,6 +26,9 @@ DEFINE_XEN_GUEST_HANDLE(int);
 DEFINE_XEN_GUEST_HANDLE(int);
 DEFINE_XEN_GUEST_HANDLE(long);
 DEFINE_XEN_GUEST_HANDLE(void);
+
+typedef unsigned long xen_pfn_t;
+DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #endif
 
 /* Arch specific VIRQs definition */
@@ -320,6 +323,8 @@ struct arch_initrd_info {
 };
 typedef struct arch_initrd_info arch_initrd_info_t;
 
+typedef unsigned long xen_callback_t;
+
 #define IA64_COMMAND_LINE_SIZE 512
 struct vcpu_guest_context {
 #define VGCF_FPU_VALID (1<<0)
@@ -367,6 +372,10 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
 #define IA64_DOM0VP_add_physmap         18      // assigne machine page frane
                                                 // to dom0's pseudo physical
                                                 // address space.
+// flags for page assignement to pseudo physical address space
+#define _ASSIGN_readonly                0
+#define ASSIGN_readonly                 (1UL << _ASSIGN_readonly)
+#define ASSIGN_writable                 (0UL << _ASSIGN_readonly) // dummy flag
 
 #endif /* !__ASSEMBLY__ */
 
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/arch-x86_32.h
--- a/include/xen/interface/arch-x86_32.h       Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/arch-x86_32.h       Thu Jun 08 15:10:05 2006 -0400
@@ -28,6 +28,9 @@ DEFINE_XEN_GUEST_HANDLE(int);
 DEFINE_XEN_GUEST_HANDLE(int);
 DEFINE_XEN_GUEST_HANDLE(long);
 DEFINE_XEN_GUEST_HANDLE(void);
+
+typedef unsigned long xen_pfn_t;
+DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #endif
 
 /*
@@ -138,9 +141,17 @@ struct vcpu_guest_context {
 struct vcpu_guest_context {
     /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
     struct { char x[512]; } fpu_ctxt;       /* User-level FPU registers     */
-#define VGCF_I387_VALID (1<<0)
-#define VGCF_HVM_GUEST  (1<<1)
-#define VGCF_IN_KERNEL  (1<<2)
+#define VGCF_I387_VALID                (1<<0)
+#define VGCF_HVM_GUEST                 (1<<1)
+#define VGCF_IN_KERNEL                 (1<<2)
+#define _VGCF_i387_valid               0
+#define VGCF_i387_valid                (1<<_VGCF_i387_valid)
+#define _VGCF_hvm_guest                1
+#define VGCF_hvm_guest                 (1<<_VGCF_hvm_guest)
+#define _VGCF_in_kernel                2
+#define VGCF_in_kernel                 (1<<_VGCF_in_kernel)
+#define _VGCF_failsafe_disables_events 3
+#define VGCF_failsafe_disables_events  (1<<_VGCF_failsafe_disables_events)
     unsigned long flags;                    /* VGCF_* flags                 */
     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
     struct trap_info trap_ctxt[256];        /* Virtual IDT                  */
@@ -158,10 +169,18 @@ typedef struct vcpu_guest_context vcpu_g
 typedef struct vcpu_guest_context vcpu_guest_context_t;
 DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
 
+/*
+ * Page-directory addresses above 4GB do not fit into architectural %cr3.
+ * When accessing %cr3, or equivalent field in vcpu_guest_context, guests
+ * must use the following accessor macros to pack/unpack valid MFNs.
+ */
+#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
+#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
+
 struct arch_shared_info {
     unsigned long max_pfn;                  /* max pfn that appears in table */
     /* Frame containing list of mfns containing list of mfns containing p2m. */
-    unsigned long pfn_to_mfn_frame_list_list;
+    xen_pfn_t     pfn_to_mfn_frame_list_list;
     unsigned long nmi_reason;
 };
 typedef struct arch_shared_info arch_shared_info_t;
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/arch-x86_64.h
--- a/include/xen/interface/arch-x86_64.h       Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/arch-x86_64.h       Thu Jun 08 15:10:05 2006 -0400
@@ -28,6 +28,9 @@ DEFINE_XEN_GUEST_HANDLE(int);
 DEFINE_XEN_GUEST_HANDLE(int);
 DEFINE_XEN_GUEST_HANDLE(long);
 DEFINE_XEN_GUEST_HANDLE(void);
+
+typedef unsigned long xen_pfn_t;
+DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #endif
 
 /*
@@ -211,9 +214,19 @@ struct vcpu_guest_context {
 struct vcpu_guest_context {
     /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
     struct { char x[512]; } fpu_ctxt;       /* User-level FPU registers     */
-#define VGCF_I387_VALID (1<<0)
-#define VGCF_HVM_GUEST  (1<<1)
-#define VGCF_IN_KERNEL  (1<<2)
+#define VGCF_I387_VALID                (1<<0)
+#define VGCF_HVM_GUEST                 (1<<1)
+#define VGCF_IN_KERNEL                 (1<<2)
+#define _VGCF_i387_valid               0
+#define VGCF_i387_valid                (1<<_VGCF_i387_valid)
+#define _VGCF_hvm_guest                1
+#define VGCF_hvm_guest                 (1<<_VGCF_hvm_guest)
+#define _VGCF_in_kernel                2
+#define VGCF_in_kernel                 (1<<_VGCF_in_kernel)
+#define _VGCF_failsafe_disables_events 3
+#define VGCF_failsafe_disables_events  (1<<_VGCF_failsafe_disables_events)
+#define _VGCF_syscall_disables_events  4
+#define VGCF_syscall_disables_events   (1<<_VGCF_syscall_disables_events)
     unsigned long flags;                    /* VGCF_* flags                 */
     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
     struct trap_info trap_ctxt[256];        /* Virtual IDT                  */
@@ -234,10 +247,13 @@ typedef struct vcpu_guest_context vcpu_g
 typedef struct vcpu_guest_context vcpu_guest_context_t;
 DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
 
+#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
+#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
+
 struct arch_shared_info {
     unsigned long max_pfn;                  /* max pfn that appears in table */
     /* Frame containing list of mfns containing list of mfns containing p2m. */
-    unsigned long pfn_to_mfn_frame_list_list;
+    xen_pfn_t     pfn_to_mfn_frame_list_list;
     unsigned long nmi_reason;
 };
 typedef struct arch_shared_info arch_shared_info_t;
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/callback.h
--- a/include/xen/interface/callback.h  Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/callback.h  Thu Jun 08 15:10:05 2006 -0400
@@ -29,12 +29,20 @@
 #define CALLBACKTYPE_nmi                   4
 
 /*
+ * Disable event deliver during callback? This flag is ignored for event and
+ * NMI callbacks: event delivery is unconditionally disabled.
+ */
+#define _CALLBACKF_mask_events             0
+#define CALLBACKF_mask_events              (1U << _CALLBACKF_mask_events)
+
+/*
  * Register a callback.
  */
 #define CALLBACKOP_register                0
 struct callback_register {
-     int type;
-     xen_callback_t address;
+    uint16_t type;
+    uint16_t flags;
+    xen_callback_t address;
 };
 typedef struct callback_register callback_register_t;
 DEFINE_XEN_GUEST_HANDLE(callback_register_t);
@@ -47,7 +55,8 @@ DEFINE_XEN_GUEST_HANDLE(callback_registe
  */
 #define CALLBACKOP_unregister              1
 struct callback_unregister {
-     int type;
+    uint16_t type;
+    uint16_t _unused;
 };
 typedef struct callback_unregister callback_unregister_t;
 DEFINE_XEN_GUEST_HANDLE(callback_unregister_t);
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/grant_table.h
--- a/include/xen/interface/grant_table.h       Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/grant_table.h       Thu Jun 08 15:10:05 2006 -0400
@@ -244,7 +244,7 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_dump_tabl
 #define GNTTABOP_transfer                4
 struct gnttab_transfer {
     /* IN parameters. */
-    unsigned long mfn;
+    xen_pfn_t     mfn;
     domid_t       domid;
     grant_ref_t   ref;
     /* OUT parameters. */
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/io/netif.h
--- a/include/xen/interface/io/netif.h  Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/io/netif.h  Thu Jun 08 15:10:05 2006 -0400
@@ -26,6 +26,10 @@
 /* Packet data has been validated against protocol checksum. */
 #define _NETTXF_data_validated (1)
 #define  NETTXF_data_validated (1U<<_NETTXF_data_validated)
+
+/* Packet continues in the request. */
+#define _NETTXF_more_data      (2)
+#define  NETTXF_more_data      (1U<<_NETTXF_more_data)
 
 struct netif_tx_request {
     grant_ref_t gref;      /* Reference to buffer page */
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/io/ring.h
--- a/include/xen/interface/io/ring.h   Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/io/ring.h   Thu Jun 08 15:10:05 2006 -0400
@@ -151,19 +151,27 @@ typedef struct __name##_back_ring __name
 #define RING_SIZE(_r)                                                   \
     ((_r)->nr_ents)
 
+/* Number of free requests (for use on front side only). */
+#define RING_FREE_REQUESTS(_r)                                         \
+    (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
+
 /* Test if there is an empty slot available on the front ring.
  * (This is only meaningful from the front. )
  */
 #define RING_FULL(_r)                                                   \
-    (((_r)->req_prod_pvt - (_r)->rsp_cons) == RING_SIZE(_r))
+    (RING_FREE_REQUESTS(_r) == 0)
 
 /* Test if there are outstanding messages to be processed on a ring. */
 #define RING_HAS_UNCONSUMED_RESPONSES(_r)                               \
-    ((_r)->rsp_cons != (_r)->sring->rsp_prod)
+    ((_r)->sring->rsp_prod - (_r)->rsp_cons)
 
 #define RING_HAS_UNCONSUMED_REQUESTS(_r)                                \
-    (((_r)->req_cons != (_r)->sring->req_prod) &&                       \
-     (((_r)->req_cons - (_r)->rsp_prod_pvt) != RING_SIZE(_r)))
+    ({                                                                 \
+       unsigned int req = (_r)->sring->req_prod - (_r)->req_cons;      \
+       unsigned int rsp = RING_SIZE(_r) -                              \
+                          ((_r)->req_cons - (_r)->rsp_prod_pvt);       \
+       req < rsp ? req : rsp;                                          \
+    })
 
 /* Direct access to individual ring elements, by index. */
 #define RING_GET_REQUEST(_r, _idx)                                      \
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/memory.h
--- a/include/xen/interface/memory.h    Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/memory.h    Thu Jun 08 15:10:05 2006 -0400
@@ -29,7 +29,7 @@ struct xen_memory_reservation {
      *   OUT: GMFN bases of extents that were allocated
      *   (NB. This command also updates the mach_to_phys translation table)
      */
-    XEN_GUEST_HANDLE(ulong) extent_start;
+    XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
 
     /* Number of extents, and size/alignment of each (2^extent_order pages). */
     unsigned long  nr_extents;
@@ -87,7 +87,7 @@ struct xen_machphys_mfn_list {
      * any large discontiguities in the machine address space, 2MB gaps in
      * the machphys table will be represented by an MFN base of zero.
      */
-    XEN_GUEST_HANDLE(ulong) extent_start;
+    XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
 
     /*
      * Number of extents written to the above array. This will be smaller
@@ -117,7 +117,7 @@ struct xen_add_to_physmap {
     unsigned long idx;
 
     /* GPFN where the source mapping page should appear. */
-    unsigned long gpfn;
+    xen_pfn_t     gpfn;
 };
 typedef struct xen_add_to_physmap xen_add_to_physmap_t;
 DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);
@@ -135,13 +135,13 @@ struct xen_translate_gpfn_list {
     unsigned long nr_gpfns;
 
     /* List of GPFNs to translate. */
-    XEN_GUEST_HANDLE(ulong) gpfn_list;
+    XEN_GUEST_HANDLE(xen_pfn_t) gpfn_list;
 
     /*
      * Output list to contain MFN translations. May be the same as the input
      * list (in which case each input GPFN is overwritten with the output MFN).
      */
-    XEN_GUEST_HANDLE(ulong) mfn_list;
+    XEN_GUEST_HANDLE(xen_pfn_t) mfn_list;
 };
 typedef struct xen_translate_gpfn_list xen_translate_gpfn_list_t;
 DEFINE_XEN_GUEST_HANDLE(xen_translate_gpfn_list_t);
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/sched_ctl.h
--- a/include/xen/interface/sched_ctl.h Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/sched_ctl.h Thu Jun 08 15:10:05 2006 -0400
@@ -49,7 +49,7 @@ struct sched_adjdom_cmd {
             uint32_t extratime;
             uint32_t weight;
         } sedf;
-        struct csched_domain {
+        struct sched_credit_adjdom {
             uint16_t weight;
             uint16_t cap;
         } credit;
diff -r 760669a37a3a -r 5c0c59eb5f73 include/xen/interface/xen.h
--- a/include/xen/interface/xen.h       Wed Jun 07 19:53:53 2006 -0400
+++ b/include/xen/interface/xen.h       Thu Jun 08 15:10:05 2006 -0400
@@ -199,7 +199,7 @@ struct mmuext_op {
     unsigned int cmd;
     union {
         /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */
-        unsigned long mfn;
+        xen_pfn_t     mfn;
         /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */
         unsigned long linear_addr;
     } arg1;
@@ -236,10 +236,24 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
  */
 #define VMASST_CMD_enable                0
 #define VMASST_CMD_disable               1
+
+/* x86/32 guests: simulate full 4GB segment limits. */
 #define VMASST_TYPE_4gb_segments         0
+
+/* x86/32 guests: trap (vector 15) whenever above vmassist is used. */
 #define VMASST_TYPE_4gb_segments_notify  1
+
+/*
+ * x86 guests: support writes to bottom-level PTEs.
+ * NB1. Page-directory entries cannot be written.
+ * NB2. Guest must continue to remove all writable mappings of PTEs.
+ */
 #define VMASST_TYPE_writable_pagetables  2
-#define MAX_VMASST_TYPE 2
+
+/* x86/PAE guests: support PDPTs above 4GB. */
+#define VMASST_TYPE_pae_extended_cr3     3
+
+#define MAX_VMASST_TYPE                  3
 
 #ifndef __ASSEMBLY__
 
@@ -449,9 +463,9 @@ struct start_info {
     unsigned long nr_pages;     /* Total pages allocated to this domain.  */
     unsigned long shared_info;  /* MACHINE address of shared info struct. */
     uint32_t flags;             /* SIF_xxx flags.                         */
-    unsigned long store_mfn;    /* MACHINE page number of shared page.    */
+    xen_pfn_t store_mfn;        /* MACHINE page number of shared page.    */
     uint32_t store_evtchn;      /* Event channel for store communication. */
-    unsigned long console_mfn;  /* MACHINE address of console page.       */
+    xen_pfn_t console_mfn;      /* MACHINE page number of console page.   */
     uint32_t console_evtchn;    /* Event channel for console messages.    */
     /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME).     */
     unsigned long pt_base;      /* VIRTUAL address of page directory.     */
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/xen/drivers/Makefile
--- a/arch/ia64/xen/drivers/Makefile    Wed Jun 07 19:53:53 2006 -0400
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-
-ifneq ($(CONFIG_XEN_IA64_DOM0_VP),y)
-obj-y   += util.o
-endif
-
-obj-y  += core/
-#obj-y += char/
-obj-y  += console/
-obj-y  += evtchn/
-obj-$(CONFIG_XEN_IA64_DOM0_VP) += balloon/
-obj-y  += privcmd/
-obj-y  += xenbus/
-
-obj-$(CONFIG_XEN_BLKDEV_BACKEND)       += blkback/
-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_BLKDEV_TAP)           += blktap/
-obj-$(CONFIG_XEN_TPMDEV_FRONTEND)      += tpmfront/
-obj-$(CONFIG_XEN_PCIDEV_BACKEND)       += pciback/
-obj-$(CONFIG_XEN_PCIDEV_FRONTEND)      += pcifront/
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/xen/drivers/coreMakefile
--- a/arch/ia64/xen/drivers/coreMakefile        Wed Jun 07 19:53:53 2006 -0400
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-obj-y   := gnttab.o features.o
-obj-$(CONFIG_PROC_FS) += xen_proc.o
-
-ifeq ($(ARCH),ia64)
-obj-y   += evtchn_ia64.o
-obj-y   += xenia64_init.o
-ifeq ($(CONFIG_XEN_IA64_DOM0_VP),y)
-obj-$(CONFIG_NET)     += skbuff.o
-endif
-else
-obj-y   += reboot.o evtchn.o fixup.o 
-obj-$(CONFIG_SMP)     += smp.o         # setup_profiling_timer def'd in ia64
-obj-$(CONFIG_NET)     += skbuff.o      # until networking is up on ia64
-endif
-obj-$(CONFIG_SYSFS)   += hypervisor_sysfs.o
-obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/xen/drivers/evtchn_ia64.c
--- a/arch/ia64/xen/drivers/evtchn_ia64.c       Wed Jun 07 19:53:53 2006 -0400
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,261 +0,0 @@
-/* NOTE: This file split off from evtchn.c because there was
-   some discussion that the mechanism is sufficiently different.
-   It may be possible to merge it back in the future... djm */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <asm/hw_irq.h>
-#include <xen/evtchn.h>
-
-#define MAX_EVTCHN 1024
-
-/* Xen will never allocate port zero for any purpose. */
-#define VALID_EVTCHN(_chn) (((_chn) != 0) && ((_chn) < MAX_EVTCHN))
-
-/* Binding types. Hey, only IRQT_VIRQ and IRQT_EVTCHN are supported now
- * for XEN/IA64 - ktian1
- */
-enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
-
-/* Constructor for packed IRQ information. */
-#define mk_irq_info(type, index, evtchn)                               \
-       (((u32)(type) << 24) | ((u32)(index) << 16) | (u32)(evtchn))
-/* Convenient shorthand for packed representation of an unbound IRQ. */
-#define IRQ_UNBOUND    mk_irq_info(IRQT_UNBOUND, 0, 0)
-/* Accessor macros for packed IRQ information. */
-#define evtchn_from_irq(irq) ((u16)(irq_info[irq]))
-#define index_from_irq(irq)  ((u8)(irq_info[irq] >> 16))
-#define type_from_irq(irq)   ((u8)(irq_info[irq] >> 24))
-
-/* Packed IRQ information: binding type, sub-type index, and event channel. */
-static u32 irq_info[NR_IRQS];
-
-/* One note for XEN/IA64 is that we have all event channels bound to one
- * physical irq vector. So we always mean evtchn vector identical to 'irq'
- * vector in this context. - ktian1
- */
-static struct {
-       irqreturn_t (*handler)(int, void *, struct pt_regs *);
-       void *dev_id;
-       char opened;    /* Whether allocated */
-} evtchns[MAX_EVTCHN];
-
-/*
- * This lock protects updates to the following mapping and reference-count
- * arrays. The lock does not need to be acquired to read the mapping tables.
- */
-static spinlock_t irq_mapping_update_lock;
-
-void mask_evtchn(int port)
-{
-       shared_info_t *s = HYPERVISOR_shared_info;
-       synch_set_bit(port, &s->evtchn_mask[0]);
-}
-EXPORT_SYMBOL(mask_evtchn);
-
-void unmask_evtchn(int port)
-{
-       shared_info_t *s = HYPERVISOR_shared_info;
-       unsigned int cpu = smp_processor_id();
-       vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
-
-#if 0  // FIXME: diverged from x86 evtchn.c
-       /* Slow path (hypercall) if this is a non-local port. */
-       if (unlikely(cpu != cpu_from_evtchn(port))) {
-               struct evtchn_unmask op = { .port = port };
-               (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &op);
-               return;
-       }
-#endif
-
-       synch_clear_bit(port, &s->evtchn_mask[0]);
-
-       /*
-        * The following is basically the equivalent of 'hw_resend_irq'. Just
-        * like a real IO-APIC we 'lose the interrupt edge' if the channel is
-        * masked.
-        */
-       if (synch_test_bit(port, &s->evtchn_pending[0]) && 
-           !synch_test_and_set_bit(port / BITS_PER_LONG,
-                                   &vcpu_info->evtchn_pending_sel)) {
-               vcpu_info->evtchn_upcall_pending = 1;
-               if (!vcpu_info->evtchn_upcall_mask)
-                       force_evtchn_callback();
-       }
-}
-EXPORT_SYMBOL(unmask_evtchn);
-
-
-#define unbound_irq(e) (VALID_EVTCHN(e) && (!evtchns[(e)].opened))
-int bind_virq_to_irqhandler(
-       unsigned int virq,
-       unsigned int cpu,
-       irqreturn_t (*handler)(int, void *, struct pt_regs *),
-       unsigned long irqflags,
-       const char *devname,
-       void *dev_id)
-{
-    struct evtchn_bind_virq bind_virq;
-    int evtchn;
-
-    spin_lock(&irq_mapping_update_lock);
-
-    bind_virq.virq = virq;
-    bind_virq.vcpu = cpu;
-    if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &bind_virq) != 0)
-        BUG();
-    evtchn = bind_virq.port;
-
-    if (!unbound_irq(evtchn)) {
-        evtchn = -EINVAL;
-        goto out;
-    }
-
-    evtchns[evtchn].handler = handler;
-    evtchns[evtchn].dev_id = dev_id;
-    evtchns[evtchn].opened = 1;
-    irq_info[evtchn] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
-
-    unmask_evtchn(evtchn);
-out:
-    spin_unlock(&irq_mapping_update_lock);
-    return evtchn;
-}
-
-int bind_evtchn_to_irqhandler(unsigned int evtchn,
-                   irqreturn_t (*handler)(int, void *, struct pt_regs *),
-                   unsigned long irqflags, const char * devname, void *dev_id)
-{
-    spin_lock(&irq_mapping_update_lock);
-
-    if (!unbound_irq(evtchn)) {
-       evtchn = -EINVAL;
-       goto out;
-    }
-
-    evtchns[evtchn].handler = handler;
-    evtchns[evtchn].dev_id = dev_id;
-    evtchns[evtchn].opened = 1;
-    irq_info[evtchn] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
-
-    unmask_evtchn(evtchn);
-out:
-    spin_unlock(&irq_mapping_update_lock);
-    return evtchn;
-}
-
-int bind_ipi_to_irqhandler(
-       unsigned int ipi,
-       unsigned int cpu,
-       irqreturn_t (*handler)(int, void *, struct pt_regs *),
-       unsigned long irqflags,
-       const char *devname,
-       void *dev_id)
-{
-    printk("%s is called which has not been supported now...?\n", 
__FUNCTION__);
-    while(1);
-}
-
-void unbind_from_irqhandler(unsigned int irq, void *dev_id)
-{
-    struct evtchn_close close;
-    int evtchn = evtchn_from_irq(irq);
-
-    spin_lock(&irq_mapping_update_lock);
-
-    if (unbound_irq(irq))
-        goto out;
-
-    close.port = evtchn;
-    if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
-        BUG();
-
-    switch (type_from_irq(irq)) {
-       case IRQT_VIRQ:
-           /* Add smp stuff later... */
-           break;
-       case IRQT_IPI:
-           /* Add smp stuff later... */
-           break;
-       default:
-           break;
-    }
-
-    mask_evtchn(evtchn);
-    evtchns[evtchn].handler = NULL;
-    evtchns[evtchn].opened = 0;
-
-out:
-    spin_unlock(&irq_mapping_update_lock);
-}
-
-void notify_remote_via_irq(int irq)
-{
-       int evtchn = evtchn_from_irq(irq);
-
-       if (!unbound_irq(evtchn))
-               notify_remote_via_evtchn(evtchn);
-}
-
-irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-    unsigned long  l1, l2;
-    unsigned int   l1i, l2i, port;
-    irqreturn_t (*handler)(int, void *, struct pt_regs *);
-    shared_info_t *s = HYPERVISOR_shared_info;
-    vcpu_info_t   *vcpu_info = &s->vcpu_info[smp_processor_id()];
-
-    vcpu_info->evtchn_upcall_mask = 1;
-    vcpu_info->evtchn_upcall_pending = 0;
-
-    /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
-    l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
-    while ( l1 != 0 )
-    {
-        l1i = __ffs(l1);
-        l1 &= ~(1UL << l1i);
-
-        while ( (l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]) != 0 )
-        {
-            l2i = __ffs(l2);
-            l2 &= ~(1UL << l2i);
-
-            port = (l1i * BITS_PER_LONG) + l2i;
-            if ( (handler = evtchns[port].handler) != NULL )
-           {
-               clear_evtchn(port);
-                handler(port, evtchns[port].dev_id, regs);
-           }
-            else
-           {
-                evtchn_device_upcall(port);
-           }
-        }
-    }
-    vcpu_info->evtchn_upcall_mask = 0;
-    return IRQ_HANDLED;
-}
-
-void force_evtchn_callback(void)
-{
-       //(void)HYPERVISOR_xen_version(0, NULL);
-}
-
-static struct irqaction evtchn_irqaction = {
-       .handler =      evtchn_interrupt,
-       .flags =        SA_INTERRUPT,
-       .name =         "xen-event-channel"
-};
-
-static int evtchn_irq = 0xe9;
-void __init evtchn_init(void)
-{
-    shared_info_t *s = HYPERVISOR_shared_info;
-
-    register_percpu_irq(evtchn_irq, &evtchn_irqaction);
-
-    s->arch.evtchn_vector = evtchn_irq;
-    printk("xen-event-channel using irq %d\n", evtchn_irq);
-
-    spin_lock_init(&irq_mapping_update_lock);
-    memset(evtchns, 0, sizeof(evtchns));
-}
diff -r 760669a37a3a -r 5c0c59eb5f73 arch/ia64/xen/xenconsole.c
--- a/arch/ia64/xen/xenconsole.c        Wed Jun 07 19:53:53 2006 -0400
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#include <linux/config.h>
-#include <linux/console.h>
-
-int
-early_xen_console_setup (char *cmdline)
-{
-#ifdef CONFIG_XEN
-#ifndef CONFIG_IA64_HP_SIM
-       extern int running_on_xen;
-       if (running_on_xen) {
-               extern struct console hpsim_cons;
-               hpsim_cons.flags |= CON_BOOT;
-               register_console(&hpsim_cons);
-               return 0;
-       }
-#endif
-#endif
-       return -1;
-}

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.