WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg (stagi

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg (staging)
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 09 Nov 2007 04:21:31 -0800
Delivery-date: Fri, 09 Nov 2007 05:46:57 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1193780291 21600
# Node ID bac78e892e42cb075d98a52c2c9a81df82f12e10
# Parent  0edeca96e7d7821f8413589e2e1f90bf68b696bd
# Parent  71a5313e13f5d99b1b550b1b5f1c0198fc4c9a70
merge with linux-2.6.18-xen.hg (staging)
---
 arch/i386/kernel/entry-xen.S              |   23 
 arch/i386/kernel/smp-xen.c                |    8 
 arch/i386/kernel/sysenter.c               |   46 +
 arch/i386/kernel/time-xen.c               |   41 -
 arch/i386/mm/fault-xen.c                  |    2 
 arch/i386/mm/hypervisor.c                 |    1 
 arch/um/kernel/physmem.c                  |    4 
 arch/x86_64/ia32/Makefile                 |   17 
 arch/x86_64/ia32/ia32entry-xen.S          |  166 +-----
 arch/x86_64/ia32/syscall32-xen.c          |   49 +
 arch/x86_64/ia32/syscall32_syscall-xen.S  |    2 
 arch/x86_64/kernel/entry-xen.S            |    7 
 arch/x86_64/kernel/smp-xen.c              |    8 
 arch/x86_64/kernel/traps-xen.c            |    2 
 arch/x86_64/mm/fault-xen.c                |    2 
 arch/x86_64/mm/init-xen.c                 |    4 
 arch/x86_64/mm/pageattr-xen.c             |    2 
 buildconfigs/linux-defconfig_xen0_ia64    |    1 
 buildconfigs/linux-defconfig_xen0_x86_32  |    1 
 buildconfigs/linux-defconfig_xen0_x86_64  |    1 
 buildconfigs/linux-defconfig_xenU_ia64    |    1 
 buildconfigs/linux-defconfig_xenU_x86_32  |    1 
 buildconfigs/linux-defconfig_xenU_x86_64  |    1 
 buildconfigs/linux-defconfig_xen_ia64     |    1 
 buildconfigs/linux-defconfig_xen_x86_32   |    1 
 buildconfigs/linux-defconfig_xen_x86_64   |    1 
 drivers/cpufreq/cpufreq_ondemand.c        |   81 ++
 drivers/xen/Kconfig                       |    6 
 drivers/xen/blktap/blktap.c               |    8 
 drivers/xen/core/evtchn.c                 |   10 
 drivers/xen/core/smpboot.c                |    1 
 drivers/xen/netfront/accel.c              |  820 +++++++++++-------------------
 drivers/xen/netfront/netfront.c           |   20 
 drivers/xen/netfront/netfront.h           |   82 ---
 drivers/xen/xenbus/xenbus_probe.c         |    8 
 include/asm-i386/mach-xen/asm/page.h      |    8 
 include/asm-ia64/page.h                   |    9 
 include/asm-powerpc/page.h                |    9 
 include/asm-um/page.h                     |    2 
 include/asm-x86_64/mach-xen/asm/page.h    |    8 
 include/asm-x86_64/mach-xen/asm/pgtable.h |    2 
 include/linux/gfp.h                       |    6 
 include/xen/evtchn.h                      |    1 
 include/xen/interface/callback.h          |   37 +
 include/xen/interface/domctl.h            |   56 +-
 include/xen/interface/platform.h          |   22 
 include/xen/interface/sysctl.h            |   25 
 include/xen/interface/vcpu.h              |    3 
 include/xen/interface/xen-compat.h        |    2 
 mm/page_alloc.c                           |   14 
 50 files changed, 753 insertions(+), 880 deletions(-)

diff -r 0edeca96e7d7 -r bac78e892e42 arch/i386/kernel/entry-xen.S
--- a/arch/i386/kernel/entry-xen.S      Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/i386/kernel/entry-xen.S      Tue Oct 30 15:38:11 2007 -0600
@@ -381,6 +381,29 @@ sysexit_ecrit:     /**** END OF SYSEXIT CRIT
 #endif /* !CONFIG_XEN */
        CFI_ENDPROC
 
+       # pv sysenter call handler stub
+ENTRY(sysenter_entry_pv)
+       RING0_INT_FRAME
+       movl $__USER_DS,16(%esp)
+       movl %ebp,12(%esp)
+       movl $__USER_CS,4(%esp)
+       addl $4,%esp
+       /* +5*4 is SS:ESP,EFLAGS,CS:EIP. +8 is esp0 setting. */
+       pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
+/*
+ * Load the potential sixth argument from user stack.
+ * Careful about security.
+ */
+       cmpl $__PAGE_OFFSET-3,%ebp
+       jae syscall_fault
+1:     movl (%ebp),%ebp
+.section __ex_table,"a"
+       .align 4
+       .long 1b,syscall_fault
+.previous
+       /* fall through */
+       CFI_ENDPROC
+ENDPROC(sysenter_entry_pv)
 
        # system call handler stub
 ENTRY(system_call)
diff -r 0edeca96e7d7 -r bac78e892e42 arch/i386/kernel/smp-xen.c
--- a/arch/i386/kernel/smp-xen.c        Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/i386/kernel/smp-xen.c        Tue Oct 30 15:38:11 2007 -0600
@@ -558,9 +558,7 @@ static void stop_this_cpu (void * dummy)
         */
        cpu_clear(smp_processor_id(), cpu_online_map);
        local_irq_disable();
-#if 0
-       disable_local_APIC();
-#endif
+       disable_all_local_evtchn();
        if (cpu_data[smp_processor_id()].hlt_works_ok)
                for(;;) halt();
        for (;;);
@@ -575,9 +573,7 @@ void smp_send_stop(void)
        smp_call_function(stop_this_cpu, NULL, 1, 0);
 
        local_irq_disable();
-#if 0
-       disable_local_APIC();
-#endif
+       disable_all_local_evtchn();
        local_irq_enable();
 }
 
diff -r 0edeca96e7d7 -r bac78e892e42 arch/i386/kernel/sysenter.c
--- a/arch/i386/kernel/sysenter.c       Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/i386/kernel/sysenter.c       Tue Oct 30 15:38:11 2007 -0600
@@ -48,7 +48,7 @@ extern asmlinkage void sysenter_entry(vo
 
 void enable_sep_cpu(void)
 {
-#ifndef CONFIG_X86_NO_TSS
+#ifndef CONFIG_XEN
        int cpu = get_cpu();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
 
@@ -62,8 +62,36 @@ void enable_sep_cpu(void)
        wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
        wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
        wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
-       put_cpu();      
-#endif
+#else
+       extern asmlinkage void sysenter_entry_pv(void);
+       static struct callback_register sysenter = {
+               .type = CALLBACKTYPE_sysenter,
+               .address = { __KERNEL_CS, (unsigned long)sysenter_entry_pv },
+       };
+
+       if (!boot_cpu_has(X86_FEATURE_SEP))
+               return;
+
+       get_cpu();
+
+       if (xen_feature(XENFEAT_supervisor_mode_kernel))
+               sysenter.address.eip = (unsigned long)sysenter_entry;
+
+       switch (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter)) {
+       case 0:
+               break;
+#if CONFIG_XEN_COMPAT < 0x030200
+       case -ENOSYS:
+               sysenter.type = CALLBACKTYPE_sysenter_deprecated;
+               if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) == 0)
+                       break;
+#endif
+       default:
+               clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability);
+               break;
+       }
+#endif
+       put_cpu();
 }
 
 /*
@@ -77,18 +105,6 @@ int __init sysenter_setup(void)
 int __init sysenter_setup(void)
 {
        syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
-
-#ifdef CONFIG_XEN
-       if (boot_cpu_has(X86_FEATURE_SEP)) {
-               static struct callback_register __initdata sysenter = {
-                       .type = CALLBACKTYPE_sysenter,
-                       .address = { __KERNEL_CS, (unsigned long)sysenter_entry 
},
-               };
-
-               if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0)
-                       clear_bit(X86_FEATURE_SEP, 
boot_cpu_data.x86_capability);
-       }
-#endif
 
 #ifdef CONFIG_COMPAT_VDSO
        __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY);
diff -r 0edeca96e7d7 -r bac78e892e42 arch/i386/kernel/time-xen.c
--- a/arch/i386/kernel/time-xen.c       Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/i386/kernel/time-xen.c       Tue Oct 30 15:38:11 2007 -0600
@@ -833,44 +833,15 @@ void notify_arch_cmos_timer(void)
        mod_timer(&sync_xen_wallclock_timer, jiffies + 1);
 }
 
-static long clock_cmos_diff, sleep_start;
-
-static int timer_suspend(struct sys_device *dev, pm_message_t state)
-{
-       /*
-        * Estimate time zone so that set_time can update the clock
-        */
-       clock_cmos_diff = -get_cmos_time();
-       clock_cmos_diff += get_seconds();
-       sleep_start = get_cmos_time();
+static int timer_resume(struct sys_device *dev)
+{
+       extern void time_resume(void);
+       time_resume();
        return 0;
 }
 
-static int timer_resume(struct sys_device *dev)
-{
-       unsigned long flags;
-       unsigned long sec;
-       unsigned long sleep_length;
-
-#ifdef CONFIG_HPET_TIMER
-       if (is_hpet_enabled())
-               hpet_reenable();
-#endif
-       sec = get_cmos_time() + clock_cmos_diff;
-       sleep_length = (get_cmos_time() - sleep_start) * HZ;
-       write_seqlock_irqsave(&xtime_lock, flags);
-       xtime.tv_sec = sec;
-       xtime.tv_nsec = 0;
-       jiffies_64 += sleep_length;
-       wall_jiffies += sleep_length;
-       write_sequnlock_irqrestore(&xtime_lock, flags);
-       touch_softlockup_watchdog();
-       return 0;
-}
-
-void time_resume(void);
 static struct sysdev_class timer_sysclass = {
-       .resume = time_resume,
+       .resume = timer_resume,
        set_kset_name("timer"),
 };
 
@@ -1121,7 +1092,7 @@ void local_teardown_timer(unsigned int c
 }
 #endif
 
-#if CONFIG_CPU_FREQ
+#ifdef CONFIG_CPU_FREQ
 static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, 
                                void *data)
 {
diff -r 0edeca96e7d7 -r bac78e892e42 arch/i386/mm/fault-xen.c
--- a/arch/i386/mm/fault-xen.c  Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/i386/mm/fault-xen.c  Tue Oct 30 15:38:11 2007 -0600
@@ -346,7 +346,7 @@ static int spurious_fault(struct pt_regs
        if ((error_code & 0x02) && !pte_write(*pte))
                return 0;
 #ifdef CONFIG_X86_PAE
-       if ((error_code & 0x10) && (pte_val(*pte) & _PAGE_NX))
+       if ((error_code & 0x10) && (__pte_val(*pte) & _PAGE_NX))
                return 0;
 #endif
 
diff -r 0edeca96e7d7 -r bac78e892e42 arch/i386/mm/hypervisor.c
--- a/arch/i386/mm/hypervisor.c Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/i386/mm/hypervisor.c Tue Oct 30 15:38:11 2007 -0600
@@ -56,6 +56,7 @@ void xen_l1_entry_update(pte_t *ptr, pte
        u.val = __pte_val(val);
        BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
 }
+EXPORT_SYMBOL_GPL(xen_l1_entry_update);
 
 void xen_l2_entry_update(pmd_t *ptr, pmd_t val)
 {
diff -r 0edeca96e7d7 -r bac78e892e42 arch/um/kernel/physmem.c
--- a/arch/um/kernel/physmem.c  Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/um/kernel/physmem.c  Tue Oct 30 15:38:11 2007 -0600
@@ -226,7 +226,7 @@ EXPORT_SYMBOL(physmem_remove_mapping);
 EXPORT_SYMBOL(physmem_remove_mapping);
 EXPORT_SYMBOL(physmem_subst_mapping);
 
-int arch_free_page(struct page *page, int order)
+void arch_free_page(struct page *page, int order)
 {
        void *virt;
        int i;
@@ -235,8 +235,6 @@ int arch_free_page(struct page *page, in
                virt = __va(page_to_phys(page + i));
                physmem_remove_mapping(virt);
        }
-
-       return 0;
 }
 
 int is_remapped(void *virt)
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/ia32/Makefile
--- a/arch/x86_64/ia32/Makefile Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/ia32/Makefile Tue Oct 30 15:38:11 2007 -0600
@@ -14,11 +14,14 @@ audit-class-$(CONFIG_AUDIT) := audit.o
 audit-class-$(CONFIG_AUDIT) := audit.o
 obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y)
 
+syscall32-types-y := sysenter syscall
+syscall32-types-$(subst 1,$(CONFIG_XEN),$(shell expr $(CONFIG_XEN_COMPAT)0 '<' 
0x0302000)) += int80
+
 $(obj)/syscall32_syscall.o: \
-       $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so)
+       $(foreach F,$(syscall32-types-y),$(obj)/vsyscall-$F.so)
 
 # Teach kbuild about targets
-targets := $(foreach F,sysenter syscall,vsyscall-$F.o vsyscall-$F.so)
+targets := $(foreach F,$(syscall32-types-y),vsyscall-$F.o vsyscall-$F.so)
 
 # The DSO images are built using a special linker script
 quiet_cmd_syscall = SYSCALL $@
@@ -27,18 +30,10 @@ quiet_cmd_syscall = SYSCALL $@
                           -Wl,-soname=linux-gate.so.1 -o $@ \
                           -Wl,-T,$(filter-out FORCE,$^)
 
-$(obj)/vsyscall-int80.so \
-$(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \
+$(foreach F,$(syscall32-types-y),$(obj)/vsyscall-$F.so): \
 $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
        $(call if_changed,syscall)
 
 AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 -Iarch/i386/kernel
 AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 -Iarch/i386/kernel
-
-ifdef CONFIG_XEN
 AFLAGS_vsyscall-int80.o = -m32 -Wa,-32 -Iarch/i386/kernel
-CFLAGS_syscall32.o += -DUSE_INT80
-AFLAGS_syscall32_syscall.o += -DUSE_INT80
-
-$(obj)/syscall32_syscall.o: $(obj)/vsyscall-int80.so
-endif
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/ia32/ia32entry-xen.S
--- a/arch/x86_64/ia32/ia32entry-xen.S  Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/ia32/ia32entry-xen.S  Tue Oct 30 15:38:11 2007 -0600
@@ -92,7 +92,7 @@
  * %ebp user stack
  * 0(%ebp) Arg6        
  *     
- * Interrupts off.
+ * Interrupts on.
  *     
  * This is purely a fast path. For anything complicated we use the int 0x80
  * path below. Set up a complete hardware stack frame to share code
@@ -100,38 +100,26 @@
  */    
 ENTRY(ia32_sysenter_target)
        CFI_STARTPROC32 simple
-       CFI_DEF_CFA     rsp,0
-       CFI_REGISTER    rsp,rbp
-       __swapgs 
-       movq    %gs:pda_kernelstack, %rsp
-       addq    $(PDA_STACKOFFSET),%rsp
-       /*
-        * No need to follow this irqs on/off section: the syscall
-        * disabled irqs, here we enable it straight after entry:
-        */
-       XEN_UNBLOCK_EVENTS(%r11)        
-       __sti
+       CFI_DEF_CFA     rsp,SS+8-RIP+16
+       /*CFI_REL_OFFSET        ss,SS-RIP+16*/
+       CFI_REL_OFFSET  rsp,RSP-RIP+16
+       /*CFI_REL_OFFSET        rflags,EFLAGS-RIP+16*/
+       /*CFI_REL_OFFSET        cs,CS-RIP+16*/
+       CFI_REL_OFFSET  rip,RIP-RIP+16
+       CFI_REL_OFFSET  r11,8
+       CFI_REL_OFFSET  rcx,0
+       movq    8(%rsp),%r11
+       CFI_RESTORE     r11
+       popq    %rcx
+       CFI_ADJUST_CFA_OFFSET -8
+       CFI_RESTORE     rcx
        movl    %ebp,%ebp               /* zero extension */
-       pushq   $__USER32_DS
-       CFI_ADJUST_CFA_OFFSET 8
-       /*CFI_REL_OFFSET ss,0*/
-       pushq   %rbp
-       CFI_ADJUST_CFA_OFFSET 8
-       CFI_REL_OFFSET rsp,0
-       pushfq
-       CFI_ADJUST_CFA_OFFSET 8
-       /*CFI_REL_OFFSET rflags,0*/
-       movl    $VSYSCALL32_SYSEXIT, %r10d
-       CFI_REGISTER rip,r10
-       pushq   $__USER32_CS
-       CFI_ADJUST_CFA_OFFSET 8
-       /*CFI_REL_OFFSET cs,0*/
-       movl    %eax, %eax
-       pushq   %r10
-       CFI_ADJUST_CFA_OFFSET 8
-       CFI_REL_OFFSET rip,0
-       pushq   %rax
-       CFI_ADJUST_CFA_OFFSET 8
+       movl    %eax,%eax
+       movl    $__USER32_DS,40(%rsp)
+       movq    %rbp,32(%rsp)
+       movl    $__USER32_CS,16(%rsp)
+       movl    $VSYSCALL32_SYSEXIT,8(%rsp)
+       movq    %rax,(%rsp)
        cld
        SAVE_ARGS 0,0,0
        /* no need to do an access_ok check here because rbp has been
@@ -143,7 +131,6 @@ 1:  movl    (%rbp),%r9d
        GET_THREAD_INFO(%r10)
        orl    $TS_COMPAT,threadinfo_status(%r10)
        testl  
$(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
-       CFI_REMEMBER_STATE
        jnz  sysenter_tracesys
 sysenter_do_call:      
        cmpl    $(IA32_NR_syscalls-1),%eax
@@ -151,33 +138,9 @@ sysenter_do_call:
        IA32_ARG_FIXUP 1
        call    *ia32_sys_call_table(,%rax,8)
        movq    %rax,RAX-ARGOFFSET(%rsp)
-       GET_THREAD_INFO(%r10)
-       XEN_BLOCK_EVENTS(%r11)  
-       __cli
-       TRACE_IRQS_OFF
-       testl   $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
-       jnz     int_ret_from_sys_call
-       andl    $~TS_COMPAT,threadinfo_status(%r10)
-       /* clear IF, that popfq doesn't enable interrupts early */
-       andl  $~0x200,EFLAGS-R11(%rsp) 
-       RESTORE_ARGS 1,24,1,1,1,1
-       popfq
-       CFI_ADJUST_CFA_OFFSET -8
-       /*CFI_RESTORE rflags*/
-       popq    %rcx                            /* User %esp */
-       CFI_ADJUST_CFA_OFFSET -8
-       CFI_REGISTER rsp,rcx
-       movl    $VSYSCALL32_SYSEXIT,%edx        /* User %eip */
-       CFI_REGISTER rip,rdx
-       TRACE_IRQS_ON
-       __swapgs
-       XEN_UNBLOCK_EVENTS(%r11)                
-       __sti           /* sti only takes effect after the next instruction */
-       /* sysexit */
-       .byte   0xf, 0x35  /* TBD */
+       jmp int_ret_from_sys_call
 
 sysenter_tracesys:
-       CFI_RESTORE_STATE
        SAVE_REST
        CLEAR_RREGS
        movq    $-ENOSYS,RAX(%rsp)      /* really needed? */
@@ -210,7 +173,7 @@ ENDPROC(ia32_sysenter_target)
  * %esp user stack 
  * 0(%esp) Arg6
  *     
- * Interrupts off.
+ * Interrupts on.
  *     
  * This is purely a fast path. For anything complicated we use the int 0x80
  * path below. Set up a complete hardware stack frame to share code
@@ -218,32 +181,20 @@ ENDPROC(ia32_sysenter_target)
  */    
 ENTRY(ia32_cstar_target)
        CFI_STARTPROC32 simple
-       CFI_DEF_CFA     rsp,PDA_STACKOFFSET
-       CFI_REGISTER    rip,rcx
-       /*CFI_REGISTER  rflags,r11*/
-       __swapgs
-       movl    %esp,%r8d
-       CFI_REGISTER    rsp,r8
-       movq    %gs:pda_kernelstack,%rsp
-       /*
-        * No need to follow this irqs on/off section: the syscall
-        * disabled irqs and here we enable it straight after entry:
-        */
-       XEN_UNBLOCK_EVENTS(%r11)        
-       __sti
-       SAVE_ARGS 8,1,1
+       CFI_DEF_CFA     rsp,SS+8-RIP+16
+       /*CFI_REL_OFFSET        ss,SS-RIP+16*/
+       CFI_REL_OFFSET  rsp,RSP-RIP+16
+       /*CFI_REL_OFFSET        rflags,EFLAGS-RIP+16*/
+       /*CFI_REL_OFFSET        cs,CS-RIP+16*/
+       CFI_REL_OFFSET  rip,RIP-RIP+16
        movl    %eax,%eax       /* zero extension */
+       movl    RSP-RIP+16(%rsp),%r8d
+       SAVE_ARGS -8,1,1
        movq    %rax,ORIG_RAX-ARGOFFSET(%rsp)
-       movq    %rcx,RIP-ARGOFFSET(%rsp)
-       CFI_REL_OFFSET rip,RIP-ARGOFFSET
        movq    %rbp,RCX-ARGOFFSET(%rsp) /* this lies slightly to ptrace */
        movl    %ebp,%ecx
-       movq    $__USER32_CS,CS-ARGOFFSET(%rsp)
-       movq    $__USER32_DS,SS-ARGOFFSET(%rsp)
-       movq    %r11,EFLAGS-ARGOFFSET(%rsp)
-       /*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/
-       movq    %r8,RSP-ARGOFFSET(%rsp) 
-       CFI_REL_OFFSET rsp,RSP-ARGOFFSET
+       movl    $__USER32_CS,CS-ARGOFFSET(%rsp)
+       movl    $__USER32_DS,SS-ARGOFFSET(%rsp)
        /* no need to do an access_ok check here because r8 has been
           32bit zero extended */ 
        /* hardware stack frame is complete now */      
@@ -254,7 +205,6 @@ 1:  movl    (%r8),%r9d
        GET_THREAD_INFO(%r10)
        orl   $TS_COMPAT,threadinfo_status(%r10)
        testl 
$(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
-       CFI_REMEMBER_STATE
        jnz   cstar_tracesys
 cstar_do_call: 
        cmpl $IA32_NR_syscalls-1,%eax
@@ -262,26 +212,9 @@ cstar_do_call:
        IA32_ARG_FIXUP 1
        call *ia32_sys_call_table(,%rax,8)
        movq %rax,RAX-ARGOFFSET(%rsp)
-       GET_THREAD_INFO(%r10)
-       XEN_BLOCK_EVENTS(%r11)          
-       __cli
-       TRACE_IRQS_OFF
-       testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
-       jnz  int_ret_from_sys_call
-       andl $~TS_COMPAT,threadinfo_status(%r10)
-       RESTORE_ARGS 1,-ARG_SKIP,1,1,1
-       movl RIP-ARGOFFSET(%rsp),%ecx
-       CFI_REGISTER rip,rcx
-       movl EFLAGS-ARGOFFSET(%rsp),%r11d       
-       /*CFI_REGISTER rflags,r11*/
-       TRACE_IRQS_ON
-       movl RSP-ARGOFFSET(%rsp),%esp
-       CFI_RESTORE rsp
-       __swapgs
-       sysretl  /* TBD */
+       jmp int_ret_from_sys_call
        
 cstar_tracesys:        
-       CFI_RESTORE_STATE
        SAVE_REST
        CLEAR_RREGS
        movq $-ENOSYS,RAX(%rsp) /* really needed? */
@@ -322,32 +255,27 @@ ia32_badarg:
  * Arguments are zero extended. For system calls that want sign extension and
  * take long arguments a wrapper is needed. Most calls can just be called
  * directly.
- * Assumes it is only called from user space and entered with interrupts off.  
+ * Assumes it is only called from user space and entered with interrupts on.
  */                            
 
 ENTRY(ia32_syscall)
        CFI_STARTPROC   simple
-       CFI_DEF_CFA     rsp,SS+8-RIP
-       /*CFI_REL_OFFSET        ss,SS-RIP*/
-       CFI_REL_OFFSET  rsp,RSP-RIP
-       /*CFI_REL_OFFSET        rflags,EFLAGS-RIP*/
-       /*CFI_REL_OFFSET        cs,CS-RIP*/
-       CFI_REL_OFFSET  rip,RIP-RIP
-       __swapgs
-       /*
-        * No need to follow this irqs on/off section: the syscall
-        * disabled irqs and here we enable it straight after entry:
-        */
-       XEN_UNBLOCK_EVENTS(%r11)
-       __sti
-       movq (%rsp),%rcx
+       CFI_DEF_CFA     rsp,SS+8-RIP+16
+       /*CFI_REL_OFFSET        ss,SS-RIP+16*/
+       CFI_REL_OFFSET  rsp,RSP-RIP+16
+       /*CFI_REL_OFFSET        rflags,EFLAGS-RIP+16*/
+       /*CFI_REL_OFFSET        cs,CS-RIP+16*/
+       CFI_REL_OFFSET  rip,RIP-RIP+16
+       CFI_REL_OFFSET  r11,8
+       CFI_REL_OFFSET  rcx,0
        movq 8(%rsp),%r11
-        addq $0x10,%rsp /* skip rcx and r11 */
+       CFI_RESTORE     r11
+       popq %rcx
+       CFI_ADJUST_CFA_OFFSET -8
+       CFI_RESTORE     rcx
        movl %eax,%eax
-       pushq %rax
-       CFI_ADJUST_CFA_OFFSET 8
+       movq %rax,(%rsp)
        cld
-/* 1:  jmp 1b   */
        /* note the registers are not zero extended to the sf.
           this could be a problem. */
        SAVE_ARGS 0,0,1
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/ia32/syscall32-xen.c
--- a/arch/x86_64/ia32/syscall32-xen.c  Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/ia32/syscall32-xen.c  Tue Oct 30 15:38:11 2007 -0600
@@ -13,17 +13,18 @@
 #include <asm/proto.h>
 #include <asm/tlbflush.h>
 #include <asm/ia32_unistd.h>
+#include <xen/interface/callback.h>
 
-#ifdef USE_INT80
-extern unsigned char syscall32_int80[], syscall32_int80_end[];
-#endif
 extern unsigned char syscall32_syscall[], syscall32_syscall_end[];
 extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
 extern int sysctl_vsyscall32;
 
 char *syscall32_page; 
-#ifndef USE_INT80
 static int use_sysenter = -1;
+
+#if CONFIG_XEN_COMPAT < 0x030200
+extern unsigned char syscall32_int80[], syscall32_int80_end[];
+static int use_int80 = 1;
 #endif
 
 static struct page *
@@ -86,13 +87,12 @@ static int __init init_syscall32(void)
        if (!syscall32_page) 
                panic("Cannot allocate syscall32 page"); 
 
-#ifdef USE_INT80
-       /*
-        * At this point we use int 0x80.
-        */
-       memcpy(syscall32_page, syscall32_int80,
-              syscall32_int80_end - syscall32_int80);
-#else
+#if CONFIG_XEN_COMPAT < 0x030200
+       if (use_int80) {
+               memcpy(syscall32_page, syscall32_int80,
+                      syscall32_int80_end - syscall32_int80);
+       } else
+#endif
        if (use_sysenter > 0) {
                memcpy(syscall32_page, syscall32_sysenter,
                       syscall32_sysenter_end - syscall32_sysenter);
@@ -100,7 +100,6 @@ static int __init init_syscall32(void)
                memcpy(syscall32_page, syscall32_syscall,
                       syscall32_syscall_end - syscall32_syscall);
        }       
-#endif
        return 0;
 } 
 
@@ -113,16 +112,26 @@ core_initcall(init_syscall32);
 /* May not be __init: called during resume */
 void syscall32_cpu_init(void)
 {
-#ifndef USE_INT80
-       if (use_sysenter < 0)
-               use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
+       static struct callback_register cstar = {
+               .type = CALLBACKTYPE_syscall32,
+               .address = (unsigned long)ia32_cstar_target
+       };
+       static struct callback_register sysenter = {
+               .type = CALLBACKTYPE_sysenter,
+               .address = (unsigned long)ia32_sysenter_target
+       };
 
        /* Load these always in case some future AMD CPU supports
           SYSENTER from compat mode too. */
-       checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
-       checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
-       checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
+       if ((HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0) ||
+           (HYPERVISOR_callback_op(CALLBACKOP_register, &cstar) < 0))
+#if CONFIG_XEN_COMPAT < 0x030200
+               return;
+       use_int80 = 0;
+#else
+               BUG();
+#endif
 
-       wrmsrl(MSR_CSTAR, ia32_cstar_target);
-#endif
+       if (use_sysenter < 0)
+               use_sysenter = (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL);
 }
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/ia32/syscall32_syscall-xen.S
--- a/arch/x86_64/ia32/syscall32_syscall-xen.S  Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/ia32/syscall32_syscall-xen.S  Tue Oct 30 15:38:11 2007 -0600
@@ -2,7 +2,7 @@
 
        .section ".init.data","aw"
 
-#ifdef USE_INT80
+#if CONFIG_XEN_COMPAT < 0x030200
 
        .globl syscall32_int80
        .globl syscall32_int80_end
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/kernel/entry-xen.S
--- a/arch/x86_64/kernel/entry-xen.S    Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/kernel/entry-xen.S    Tue Oct 30 15:38:11 2007 -0600
@@ -237,7 +237,7 @@ END(ret_from_fork)
  * r11  eflags for syscall/sysret, temporary for C
  * r12-r15,rbp,rbx saved by C code, not touched.               
  * 
- * Interrupts are off on entry.
+ * Interrupts are enabled on entry.
  * Only called from user space.
  *
  * XXX if we had a free scratch register we could save the RSP into the stack 
frame
@@ -252,11 +252,6 @@ ENTRY(system_call)
        _frame (RIP-0x10)
        SAVE_ARGS -8,0
        movq  %rax,ORIG_RAX-ARGOFFSET(%rsp) 
-       /*
-        * No need to follow this irqs off/on section - it's straight
-        * and short:
-        */
-        XEN_UNBLOCK_EVENTS(%r11)        
        GET_THREAD_INFO(%rcx)
        testl 
$(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
        CFI_REMEMBER_STATE
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/kernel/smp-xen.c
--- a/arch/x86_64/kernel/smp-xen.c      Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/kernel/smp-xen.c      Tue Oct 30 15:38:11 2007 -0600
@@ -482,9 +482,7 @@ void smp_stop_cpu(void)
         */
        cpu_clear(smp_processor_id(), cpu_online_map);
        local_irq_save(flags);
-#ifndef CONFIG_XEN
-       disable_local_APIC();
-#endif
+       disable_all_local_evtchn();
        local_irq_restore(flags); 
 }
 
@@ -512,9 +510,7 @@ void smp_send_stop(void)
                spin_unlock(&call_lock);
 
        local_irq_disable();
-#ifndef CONFIG_XEN
-       disable_local_APIC();
-#endif
+       disable_all_local_evtchn();
        local_irq_enable();
 }
 
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/kernel/traps-xen.c
--- a/arch/x86_64/kernel/traps-xen.c    Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/kernel/traps-xen.c    Tue Oct 30 15:38:11 2007 -0600
@@ -1110,7 +1110,7 @@ static trap_info_t trap_table[] = {
 #endif
         { 19, 0|4, __KERNEL_CS, (unsigned long)simd_coprocessor_error     },
 #ifdef CONFIG_IA32_EMULATION
-       { IA32_SYSCALL_VECTOR, 3|4, __KERNEL_CS, (unsigned long)ia32_syscall},
+       { IA32_SYSCALL_VECTOR, 3, __KERNEL_CS, (unsigned long)ia32_syscall},
 #endif
         {  0, 0,           0, 0                                              }
 };
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/mm/fault-xen.c
--- a/arch/x86_64/mm/fault-xen.c        Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/mm/fault-xen.c        Tue Oct 30 15:38:11 2007 -0600
@@ -380,7 +380,7 @@ static int spurious_fault(struct pt_regs
                return 0;
        if ((error_code & PF_WRITE) && !pte_write(*pte))
                return 0;
-       if ((error_code & PF_INSTR) && (pte_val(*pte) & _PAGE_NX))
+       if ((error_code & PF_INSTR) && (__pte_val(*pte) & _PAGE_NX))
                return 0;
 
        return 1;
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/mm/init-xen.c
--- a/arch/x86_64/mm/init-xen.c Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/mm/init-xen.c Tue Oct 30 15:38:11 2007 -0600
@@ -272,7 +272,7 @@ static __init void set_pte_phys(unsigned
 
        pte = pte_offset_kernel(pmd, vaddr);
        if (!pte_none(*pte) &&
-           pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
+           __pte_val(*pte) != (__pte_val(new_pte) & __supported_pte_mask))
                pte_ERROR(*pte);
        set_pte(pte, new_pte);
 
@@ -868,7 +868,7 @@ void __init clear_kernel_mapping(unsigne
                pmd = pmd_offset(pud, address);
                if (!pmd || pmd_none(*pmd))
                        continue; 
-               if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { 
+               if (0 == (__pmd_val(*pmd) & _PAGE_PSE)) {
                        /* Could handle this, but it should not happen 
currently. */
                        printk(KERN_ERR 
               "clear_kernel_mapping: mapping has been split. will leak 
memory\n"); 
diff -r 0edeca96e7d7 -r bac78e892e42 arch/x86_64/mm/pageattr-xen.c
--- a/arch/x86_64/mm/pageattr-xen.c     Tue Oct 30 13:42:54 2007 -0600
+++ b/arch/x86_64/mm/pageattr-xen.c     Tue Oct 30 15:38:11 2007 -0600
@@ -370,7 +370,7 @@ static void revert_page(unsigned long ad
        pud = pud_offset(pgd,address);
        BUG_ON(pud_none(*pud));
        pmd = pmd_offset(pud, address);
-       BUG_ON(pmd_val(*pmd) & _PAGE_PSE);
+       BUG_ON(__pmd_val(*pmd) & _PAGE_PSE);
        pgprot_val(ref_prot) |= _PAGE_PSE;
        large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot);
        set_pte((pte_t *)pmd, large_pte);
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Tue Oct 30 15:38:11 2007 -0600
@@ -1683,6 +1683,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xen0_x86_32
--- a/buildconfigs/linux-defconfig_xen0_x86_32  Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_32  Tue Oct 30 15:38:11 2007 -0600
@@ -1421,6 +1421,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xen0_x86_64
--- a/buildconfigs/linux-defconfig_xen0_x86_64  Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_64  Tue Oct 30 15:38:11 2007 -0600
@@ -1369,6 +1369,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xenU_ia64
--- a/buildconfigs/linux-defconfig_xenU_ia64    Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xenU_ia64    Tue Oct 30 15:38:11 2007 -0600
@@ -1493,6 +1493,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xenU_x86_32
--- a/buildconfigs/linux-defconfig_xenU_x86_32  Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xenU_x86_32  Tue Oct 30 15:38:11 2007 -0600
@@ -920,6 +920,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xenU_x86_64
--- a/buildconfigs/linux-defconfig_xenU_x86_64  Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xenU_x86_64  Tue Oct 30 15:38:11 2007 -0600
@@ -1217,6 +1217,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64     Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen_ia64     Tue Oct 30 15:38:11 2007 -0600
@@ -1683,6 +1683,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Tue Oct 30 15:38:11 2007 -0600
@@ -3280,6 +3280,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Tue Oct 30 13:42:54 2007 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Tue Oct 30 15:38:11 2007 -0600
@@ -3111,6 +3111,7 @@ CONFIG_XEN_SYSFS=y
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_030004_AND_LATER is not set
+# CONFIG_XEN_COMPAT_030100_AND_LATER is not set
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT=0x030002
 CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/cpufreq/cpufreq_ondemand.c
--- a/drivers/cpufreq/cpufreq_ondemand.c        Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/cpufreq/cpufreq_ondemand.c        Tue Oct 30 15:38:11 2007 -0600
@@ -222,17 +222,14 @@ static struct attribute_group dbs_attr_g
 
 /************************** sysfs end ************************/
 
-static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
-{
-       unsigned int idle_ticks, total_ticks;
-       unsigned int load;
+#ifndef CONFIG_XEN
+static int dbs_calc_load(struct cpu_dbs_info_s *this_dbs_info)
+{
+       struct cpufreq_policy *policy;
        cputime64_t cur_jiffies;
-
-       struct cpufreq_policy *policy;
+       cputime64_t total_ticks, idle_ticks;
        unsigned int j;
-
-       if (!this_dbs_info->enable)
-               return;
+       int load;
 
        policy = this_dbs_info->cur_policy;
        cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
@@ -240,7 +237,7 @@ static void dbs_check_cpu(struct cpu_dbs
                        this_dbs_info->prev_cpu_wall);
        this_dbs_info->prev_cpu_wall = cur_jiffies;
        if (!total_ticks)
-               return;
+               return 200;
        /*
         * Every sampling_rate, we check, if current idle time is less
         * than 20% (default), then we try to increase frequency
@@ -270,6 +267,70 @@ static void dbs_check_cpu(struct cpu_dbs
                        idle_ticks = tmp_idle_ticks;
        }
        load = (100 * (total_ticks - idle_ticks)) / total_ticks;
+       return load;
+}
+#else
+
+#include <xen/interface/platform.h>
+static int dbs_calc_load(struct cpu_dbs_info_s *this_dbs_info)
+{
+       int load = 0;
+       struct xen_platform_op op;
+       uint64_t idletime[NR_CPUS];
+       struct cpufreq_policy *policy;
+       unsigned int j;
+       cpumask_t cpumap;
+
+       op.cmd = XENPF_getidletime;
+       set_xen_guest_handle(op.u.getidletime.cpumap_bitmap, (uint8_t *) 
cpus_addr(cpumap));
+       op.u.getidletime.cpumap_nr_cpus = NR_CPUS;// num_online_cpus();
+       set_xen_guest_handle(op.u.getidletime.idletime, idletime);
+       if (HYPERVISOR_platform_op(&op))
+               return 200;
+
+       policy = this_dbs_info->cur_policy;
+       cpumap = policy->cpus;
+       for_each_cpu_mask(j, cpumap) {
+               cputime64_t total_idle_nsecs, tmp_idle_nsecs;
+               cputime64_t total_wall_nsecs, tmp_wall_nsecs;
+               struct cpu_dbs_info_s *j_dbs_info;
+               unsigned long tmp_load;
+
+               j_dbs_info = &per_cpu(cpu_dbs_info, j);
+               total_idle_nsecs = idletime[j];
+               tmp_idle_nsecs = cputime64_sub(total_idle_nsecs,
+                               j_dbs_info->prev_cpu_idle);
+               total_wall_nsecs = op.u.getidletime.now;
+               tmp_wall_nsecs = cputime64_sub(total_wall_nsecs,
+                               j_dbs_info->prev_cpu_wall);
+
+               if (tmp_wall_nsecs == 0)
+                       return 200;
+
+               j_dbs_info->prev_cpu_wall = total_wall_nsecs;
+               j_dbs_info->prev_cpu_idle = total_idle_nsecs;
+
+               tmp_load = (100 * (tmp_wall_nsecs - tmp_idle_nsecs)) /
+                               tmp_wall_nsecs;
+               load = max(load, min(100, (int) tmp_load));
+       }
+       return load;
+}
+#endif
+
+static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
+{
+       int load;
+
+       struct cpufreq_policy *policy;
+
+       if (!this_dbs_info->enable)
+               return;
+
+       policy = this_dbs_info->cur_policy;
+       load = dbs_calc_load(this_dbs_info);
+       if (load > 100) 
+               return;
 
        /* Check for frequency increase */
        if (load > dbs_tuners_ins.up_threshold) {
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/xen/Kconfig
--- a/drivers/xen/Kconfig       Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/xen/Kconfig       Tue Oct 30 15:38:11 2007 -0600
@@ -13,7 +13,7 @@ if XEN
 if XEN
 config XEN_INTERFACE_VERSION
        hex
-       default 0x00030206
+       default 0x00030207
 
 menu "XEN"
 
@@ -247,6 +247,9 @@ choice
        config XEN_COMPAT_030004_AND_LATER
                bool "3.0.4 and later"
 
+       config XEN_COMPAT_030100_AND_LATER
+               bool "3.1.0 and later"
+
        config XEN_COMPAT_LATEST_ONLY
                bool "no compatibility code"
 
@@ -255,6 +258,7 @@ config XEN_COMPAT
 config XEN_COMPAT
        hex
        default 0xffffff if XEN_COMPAT_LATEST_ONLY
+       default 0x030100 if XEN_COMPAT_030100_AND_LATER
        default 0x030004 if XEN_COMPAT_030004_AND_LATER
        default 0x030002 if XEN_COMPAT_030002_AND_LATER
        default 0
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c       Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/xen/blktap/blktap.c       Tue Oct 30 15:38:11 2007 -0600
@@ -115,13 +115,7 @@ static struct tap_blkif *tapfds[MAX_TAP_
 static struct tap_blkif *tapfds[MAX_TAP_DEV];
 static int blktap_next_minor;
 
-static int __init set_blkif_reqs(char *str)
-{
-       get_option(&str, &blkif_reqs);
-       return 1;
-}
-__setup("blkif_reqs=", set_blkif_reqs);
-
+module_param(blkif_reqs, int, 0);
 /* Run-time switchable: /sys/module/blktap/parameters/ */
 static unsigned int log_stats = 0;
 static unsigned int debug_lvl = 0;
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/xen/core/evtchn.c
--- a/drivers/xen/core/evtchn.c Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/xen/core/evtchn.c Tue Oct 30 15:38:11 2007 -0600
@@ -892,6 +892,16 @@ void unmask_evtchn(int port)
 }
 EXPORT_SYMBOL_GPL(unmask_evtchn);
 
+void disable_all_local_evtchn(void)
+{
+       unsigned i, cpu = smp_processor_id();
+       shared_info_t *s = HYPERVISOR_shared_info;
+
+       for (i = 0; i < NR_EVENT_CHANNELS; ++i)
+               if (cpu_from_evtchn(i) == cpu)
+                       synch_set_bit(i, &s->evtchn_mask[0]);
+}
+
 static void restore_cpu_virqs(int cpu)
 {
        struct evtchn_bind_virq bind_virq;
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/xen/core/smpboot.c
--- a/drivers/xen/core/smpboot.c        Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/xen/core/smpboot.c        Tue Oct 30 15:38:11 2007 -0600
@@ -174,6 +174,7 @@ void cpu_bringup(void)
 void cpu_bringup(void)
 {
        cpu_init();
+       identify_cpu(cpu_data + smp_processor_id());
        touch_softlockup_watchdog();
        preempt_disable();
        local_irq_enable();
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/xen/netfront/accel.c
--- a/drivers/xen/netfront/accel.c      Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/xen/netfront/accel.c      Tue Oct 30 15:38:11 2007 -0600
@@ -31,7 +31,7 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
-#include <linux/kref.h>
+#include <linux/mutex.h>
 
 #include <xen/xenbus.h>
 
@@ -45,34 +45,40 @@
 #define WPRINTK(fmt, args...)                          \
        printk(KERN_WARNING "netfront/accel: " fmt, ##args)
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 5)
-#define kref_init(x,y) kref_init(x,y)
-#define kref_put(x,y)  kref_put(x)
-#else
-#define kref_init(x,y) kref_init(x)
-#define kref_put(x,y)  kref_put(x,y)
-#endif
-
 /*
  * List of all netfront accelerator plugin modules available.  Each
  * list entry is of type struct netfront_accelerator.
  */ 
 static struct list_head accelerators_list;
 
-/*
- * Lock to protect access to accelerators_list
- */
+/* Lock to protect access to accelerators_list */
 static spinlock_t accelerators_lock;
 
-/* Forward declaration of kref cleanup functions */
-static void accel_kref_release(struct kref *ref);
-static void vif_kref_release(struct kref *ref);
-
+/* Mutex to prevent concurrent loads and suspends, etc. */
+DEFINE_MUTEX(accelerator_mutex);
 
 void netif_init_accel(void)
 {
        INIT_LIST_HEAD(&accelerators_list);
        spin_lock_init(&accelerators_lock);
+}
+
+void netif_exit_accel(void)
+{
+       struct netfront_accelerator *accelerator, *tmp;
+       unsigned flags;
+
+       spin_lock_irqsave(&accelerators_lock, flags);
+
+       list_for_each_entry_safe(accelerator, tmp, &accelerators_list, link) {
+               BUG_ON(!list_empty(&accelerator->vif_states));
+
+               list_del(&accelerator->link);
+               kfree(accelerator->frontend);
+               kfree(accelerator);
+       }
+
+       spin_unlock_irqrestore(&accelerators_lock, flags);
 }
 
 
@@ -87,9 +93,6 @@ void init_accelerator_vif(struct netfron
        /* It's assumed that these things don't change */
        np->accel_vif_state.np = np;
        np->accel_vif_state.dev = dev;
-
-       np->accel_vif_state.ready_for_probe = 1;
-       np->accel_vif_state.need_probe = NULL;
 }
 
 
@@ -112,18 +115,25 @@ static void add_accelerator_vif(struct n
 static void add_accelerator_vif(struct netfront_accelerator *accelerator,
                                struct netfront_info *np)
 {
+       unsigned flags;
+
+       /* Need lock to write list */
+       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
+
        if (np->accelerator == NULL) {
                np->accelerator = accelerator;
                
                list_add(&np->accel_vif_state.link, &accelerator->vif_states);
        } else {
                /* 
-                * May get here legitimately if reconnecting to the
-                * same accelerator, eg. after resume, so check that
-                * is the case
+                * May get here legitimately if suspend_cancel is
+                * called, but in that case configuration should not
+                * have changed
                 */
                BUG_ON(np->accelerator != accelerator);
        }
+
+       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
 }
 
 
@@ -131,7 +141,8 @@ static void add_accelerator_vif(struct n
  * Initialise the state to track an accelerator plugin module.
  */ 
 static int init_accelerator(const char *frontend, 
-                           struct netfront_accelerator **result)
+                           struct netfront_accelerator **result,
+                           struct netfront_accel_hooks *hooks)
 {
        struct netfront_accelerator *accelerator = 
                kmalloc(sizeof(struct netfront_accelerator), GFP_KERNEL);
@@ -154,10 +165,7 @@ static int init_accelerator(const char *
        INIT_LIST_HEAD(&accelerator->vif_states);
        spin_lock_init(&accelerator->vif_states_lock);
 
-       accelerator->hooks = NULL;
-
-       accelerator->ready_for_probe = 1;
-       accelerator->need_probe = NULL;
+       accelerator->hooks = hooks;
 
        list_add(&accelerator->link, &accelerators_list);
 
@@ -174,17 +182,9 @@ static void
 static void 
 accelerator_set_vif_state_hooks(struct netfront_accel_vif_state *vif_state)
 {
-       /* This function must be called with the vif_state_lock held */
+       /* This function must be called with the vif_states_lock held */
 
        DPRINTK("%p\n",vif_state);
-
-       /*
-        * Take references to stop hooks disappearing.
-        * This persists until vif_kref gets to zero.
-        */
-       kref_get(&vif_state->np->accelerator->accel_kref);
-       /* This persists until vif_state->hooks are cleared */
-       kref_init(&vif_state->vif_kref, vif_kref_release);
 
        /* Make sure there are no data path operations going on */
        netif_poll_disable(vif_state->np->netdev);
@@ -202,47 +202,22 @@ static void accelerator_probe_new_vif(st
                                      struct netfront_accelerator *accelerator)
 {
        struct netfront_accel_hooks *hooks;
-       unsigned flags;
-       
+
        DPRINTK("\n");
 
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
-       
-       /*
-        * Include this frontend device on the accelerator's list
-        */
+       /* Include this frontend device on the accelerator's list */
        add_accelerator_vif(accelerator, np);
        
        hooks = accelerator->hooks;
        
        if (hooks) {
-               if (np->accel_vif_state.ready_for_probe) {
-                       np->accel_vif_state.ready_for_probe = 0;
-                       
-                       kref_get(&accelerator->accel_kref);
-                       
-                       spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                                              flags);
-                       
-                       hooks->new_device(np->netdev, dev);
-                       
-                       kref_put(&accelerator->accel_kref,
-                                accel_kref_release);
-                       /* 
-                        * Hooks will get linked into vif_state by a
-                        * future call by the accelerator to
-                        * netfront_accelerator_ready()
-                        */
-                       return;
-               } else {
-                       if (np->accel_vif_state.need_probe != NULL)
-                               DPRINTK("Probe request on vif awaiting 
probe\n");
-                       np->accel_vif_state.need_probe = hooks;
-               }
-       }
-               
-       spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                              flags);
+               hooks->new_device(np->netdev, dev);
+               /* 
+                * Hooks will get linked into vif_state by a future
+                * call by the accelerator to netfront_accelerator_ready()
+                */
+       }
+
        return;
 }
 
@@ -256,10 +231,12 @@ int netfront_load_accelerator(struct net
                              const char *frontend)
 {
        struct netfront_accelerator *accelerator;
-       int rc;
+       int rc = 0;
        unsigned flags;
 
        DPRINTK(" %s\n", frontend);
+
+       mutex_lock(&accelerator_mutex);
 
        spin_lock_irqsave(&accelerators_lock, flags);
 
@@ -273,22 +250,24 @@ int netfront_load_accelerator(struct net
 
                        accelerator_probe_new_vif(np, dev, accelerator);
 
+                       mutex_unlock(&accelerator_mutex);
                        return 0;
                }
        }
 
        /* Couldn't find it, so create a new one and load the module */
-       if ((rc = init_accelerator(frontend, &accelerator)) < 0) {
+       if ((rc = init_accelerator(frontend, &accelerator, NULL)) < 0) {
                spin_unlock_irqrestore(&accelerators_lock, flags);
+               mutex_unlock(&accelerator_mutex);
                return rc;
        }
 
        spin_unlock_irqrestore(&accelerators_lock, flags);
 
        /* Include this frontend device on the accelerator's list */
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
        add_accelerator_vif(accelerator, np);
-       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
+
+       mutex_unlock(&accelerator_mutex);
 
        DPRINTK("requesting module %s\n", frontend);
 
@@ -300,7 +279,7 @@ int netfront_load_accelerator(struct net
         * it's up and running, and we can continue from there 
         */
 
-       return 0;
+       return rc;
 }
 
 
@@ -312,21 +291,11 @@ int netfront_load_accelerator(struct net
  */
 static void 
 accelerator_probe_vifs(struct netfront_accelerator *accelerator,
-                      struct netfront_accel_hooks *hooks,
-                      unsigned lock_flags)
+                      struct netfront_accel_hooks *hooks)
 {
        struct netfront_accel_vif_state *vif_state, *tmp;
 
-       /* Calling function must have taken the vif_states_lock */
-
        DPRINTK("%p\n", accelerator);
-
-       /* 
-        * kref_init() takes a single reference to the hooks that will
-        * persist until the accelerator hooks are removed (e.g. by
-        * accelerator module unload)
-        */
-       kref_init(&accelerator->accel_kref, accel_kref_release);
 
        /* 
         * Store the hooks for future calls to probe a new device, and
@@ -335,71 +304,23 @@ accelerator_probe_vifs(struct netfront_a
         */
        BUG_ON(hooks == NULL);
        accelerator->hooks = hooks;
-       
+
+       /* 
+        *  currently hold accelerator_mutex, so don't need
+        *  vif_states_lock to read the list
+        */
        list_for_each_entry_safe(vif_state, tmp, &accelerator->vif_states,
                                 link) {
                struct netfront_info *np = vif_state->np;
-
-               if (vif_state->ready_for_probe) {
-                       vif_state->ready_for_probe = 0;
-                       kref_get(&accelerator->accel_kref);
-
-                       /* 
-                        * drop lock before calling hook.  hooks are
-                        * protected by the kref
-                        */
-                       spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                                              lock_flags);
-                       
-                       hooks->new_device(np->netdev, vif_state->dev);
-                       
-                       kref_put(&accelerator->accel_kref, accel_kref_release);
-
-                       /* Retake lock for next go round the loop */
-                       spin_lock_irqsave(&accelerator->vif_states_lock, 
lock_flags);
-                       
-                       /*
-                        * Hooks will get linked into vif_state by a call to
-                        * netfront_accelerator_ready() once accelerator
-                        * plugin is ready for action
-                        */
-               } else {
-                       if (vif_state->need_probe != NULL)
-                               DPRINTK("Probe request on vif awaiting 
probe\n");
-                       vif_state->need_probe = hooks;
-               }
-       }
-       
-       /* Return with vif_states_lock held, as on entry */
-}
-
-
-/* 
- * Wrapper for accelerator_probe_vifs that checks now is a good time
- * to do the probe, and postpones till previous state cleared up if
- * necessary
- */
-static void 
-accelerator_probe_vifs_on_load(struct netfront_accelerator *accelerator,
-                              struct netfront_accel_hooks *hooks)
-{
-       unsigned flags;
-
-       DPRINTK("\n");
-
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
-       
-       if (accelerator->ready_for_probe) {
-               accelerator->ready_for_probe = 0;
-               accelerator_probe_vifs(accelerator, hooks, flags);
-       } else {
-               if (accelerator->need_probe)
-                       DPRINTK("Probe request on accelerator awaiting 
probe\n");
-               accelerator->need_probe = hooks;
-       }
-
-       spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                              flags);
+               
+               hooks->new_device(np->netdev, vif_state->dev);
+               
+               /*
+                * Hooks will get linked into vif_state by a call to
+                * netfront_accelerator_ready() once accelerator
+                * plugin is ready for action
+                */
+       }
 }
 
 
@@ -427,6 +348,8 @@ int netfront_accelerator_loaded(int vers
                }
        }
 
+       mutex_lock(&accelerator_mutex);
+
        spin_lock_irqsave(&accelerators_lock, flags);
 
        /* 
@@ -437,9 +360,9 @@ int netfront_accelerator_loaded(int vers
                if (match_accelerator(frontend, accelerator)) {
                        spin_unlock_irqrestore(&accelerators_lock, flags);
 
-                       accelerator_probe_vifs_on_load(accelerator, hooks);
-
-                       return 0;
+                       accelerator_probe_vifs(accelerator, hooks);
+
+                       goto out;
                }
        }
 
@@ -450,10 +373,12 @@ int netfront_accelerator_loaded(int vers
        DPRINTK("Couldn't find matching accelerator (%s)\n",
                frontend);
 
-       init_accelerator(frontend, &accelerator);
+       init_accelerator(frontend, &accelerator, hooks);
 
        spin_unlock_irqrestore(&accelerators_lock, flags);
 
+ out:
+       mutex_unlock(&accelerator_mutex);
        return 0;
 }
 EXPORT_SYMBOL_GPL(netfront_accelerator_loaded);
@@ -477,6 +402,10 @@ void netfront_accelerator_ready(const ch
 
        list_for_each_entry(accelerator, &accelerators_list, link) {
                if (match_accelerator(frontend, accelerator)) {
+                       /* 
+                        * Mutex not held so need vif_states_lock for
+                        * list
+                        */
                        spin_lock_irqsave
                                (&accelerator->vif_states_lock, flags1);
 
@@ -489,11 +418,9 @@ void netfront_accelerator_ready(const ch
 
                        spin_unlock_irqrestore
                                (&accelerator->vif_states_lock, flags1);
-                       goto done;
+                       break;
                }
        }
-
- done:
        spin_unlock_irqrestore(&accelerators_lock, flags);
 }
 EXPORT_SYMBOL_GPL(netfront_accelerator_ready);
@@ -526,36 +453,30 @@ accelerator_remove_single_hook(struct ne
 /* 
  * Safely remove the accelerator function hooks from a netfront state.
  */
-static void accelerator_remove_hooks(struct netfront_accelerator *accelerator,
-                                    int remove_master)
-{
+static void accelerator_remove_hooks(struct netfront_accelerator *accelerator)
+{
+       struct netfront_accel_hooks *hooks;
        struct netfront_accel_vif_state *vif_state, *tmp;
        unsigned flags;
 
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
-
+       /* Mutex is held so don't need vif_states_lock to iterate list */
        list_for_each_entry_safe(vif_state, tmp,
                                 &accelerator->vif_states,
                                 link) {
+               spin_lock_irqsave(&accelerator->vif_states_lock, flags);
+
+               BUG_ON(vif_state->hooks == NULL);
+               hooks = vif_state->hooks;
                accelerator_remove_single_hook(accelerator, vif_state);
 
-               /* 
-                * Remove the reference taken when the vif_state hooks
-                * were set, must be called without lock held
-                */
                spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
-               kref_put(&vif_state->vif_kref, vif_kref_release);
-               spin_lock_irqsave(&accelerator->vif_states_lock, flags);
+
+               /* Last chance to get statistics from the accelerator */
+               hooks->get_stats(vif_state->np->netdev, &vif_state->np->stats);
+               hooks->remove(vif_state->dev);
        }
        
-       if(remove_master)
-               accelerator->hooks = NULL;
-
-       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
-
-       if(remove_master)
-               /* Remove the reference taken when module loaded */ 
-               kref_put(&accelerator->accel_kref, accel_kref_release);
+       accelerator->hooks = NULL;
 }
 
 
@@ -564,369 +485,266 @@ static void accelerator_remove_hooks(str
  * removes the hooks into the plugin and blocks until all devices have
  * finished using it, so on return it is safe to unload.
  */
-void netfront_accelerator_stop(const char *frontend, int unloading)
-{
-       struct netfront_accelerator *accelerator;
-       unsigned flags;
-
+void netfront_accelerator_stop(const char *frontend)
+{
+       struct netfront_accelerator *accelerator;
+       unsigned flags;
+
+       mutex_lock(&accelerator_mutex);
        spin_lock_irqsave(&accelerators_lock, flags);
 
        list_for_each_entry(accelerator, &accelerators_list, link) {
                if (match_accelerator(frontend, accelerator)) {
                        spin_unlock_irqrestore(&accelerators_lock, flags);
 
-                       /* 
-                        * Use semaphore to ensure we know when all
-                        * uses of hooks are complete
-                        */
-                       sema_init(&accelerator->exit_semaphore, 0);
-
-                       accelerator_remove_hooks(accelerator, unloading);
-
-                       if (unloading)
-                               /* Wait for hooks to be unused, then return */
-                               down(&accelerator->exit_semaphore);
-                       
-                       return;
+                       accelerator_remove_hooks(accelerator);
+
+                       goto out;
                }
        }
        spin_unlock_irqrestore(&accelerators_lock, flags);
+ out:
+       mutex_unlock(&accelerator_mutex);
 }
 EXPORT_SYMBOL_GPL(netfront_accelerator_stop);
 
 
-
-int netfront_check_accelerator_queue_busy(struct net_device *dev,
-                                         struct netfront_info *np)
-{
-       struct netfront_accel_hooks *hooks;
-       int rc = 1;
-       unsigned flags;
-
-       /*
-        * Call the check busy accelerator hook. The use count for the
-        * accelerator's hooks is incremented for the duration of the
-        * call to prevent the accelerator being able to modify the
-        * hooks in the middle (by, for example, unloading)
-        */ 
+/* Helper for call_remove and do_suspend */
+static int do_remove(struct netfront_info *np, struct xenbus_device *dev,
+                    unsigned *lock_flags)
+{
+       struct netfront_accelerator *accelerator = np->accelerator;
+       struct netfront_accel_hooks *hooks;
+       int rc = 0;
+ 
        if (np->accel_vif_state.hooks) {
-               spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
                hooks = np->accel_vif_state.hooks;
-               if (hooks) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-
-                       rc = np->accel_vif_state.hooks->check_busy(dev);
-                       
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-               }
-       }
-
-       return rc;
-}
-
-
+
+               /* 
+                * Try and do the opposite of accelerator_probe_new_vif
+                * to ensure there's no state pointing back at the 
+                * netdev 
+                */
+               accelerator_remove_single_hook(accelerator, 
+                                              &np->accel_vif_state);
+
+               /* Last chance to get statistics from the accelerator */
+               hooks->get_stats(np->netdev, &np->stats);
+
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, 
+                                      *lock_flags);
+
+               rc = hooks->remove(dev);
+
+               spin_lock_irqsave(&accelerator->vif_states_lock, *lock_flags);
+       }
+
+ 
+       return rc;
+}
+ 
+  
 int netfront_accelerator_call_remove(struct netfront_info *np,
-                                    struct xenbus_device *dev)
-{
-       struct netfront_accelerator *accelerator = np->accelerator;
-       struct netfront_accel_vif_state *tmp_vif_state;
-       struct netfront_accel_hooks *hooks;
-       unsigned flags;
-       int rc = 0;
-
-       /* 
-        * Call the remove accelerator hook. The use count for the
-        * accelerator's hooks is incremented for the duration of the
-        * call to prevent the accelerator being able to modify the
-        * hooks in the middle (by, for example, unloading)
-        */ 
-       spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
-       hooks = np->accel_vif_state.hooks;
-
-       /*
-        * Remove this vif_state from the accelerator's list 
-        */
-       list_for_each_entry(tmp_vif_state, &accelerator->vif_states, link) {
+                                    struct xenbus_device *dev)
+{
+       struct netfront_accelerator *accelerator;
+       struct netfront_accel_vif_state *tmp_vif_state;
+       unsigned flags;
+       int rc = 0; 
+
+       mutex_lock(&accelerator_mutex);
+
+       /* Check that we've got a device that was accelerated */
+       if (np->accelerator == NULL)
+               goto out;
+
+       accelerator = np->accelerator;
+
+       spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
+
+       list_for_each_entry(tmp_vif_state, &accelerator->vif_states,
+                           link) {
                if (tmp_vif_state == &np->accel_vif_state) {
                        list_del(&np->accel_vif_state.link);
                        break;
                }
        }
-          
-       if (hooks) {
-               kref_get(&np->accel_vif_state.vif_kref);
-               spin_unlock_irqrestore
-                       (&np->accelerator->vif_states_lock, flags);
-               
-               rc = np->accel_vif_state.hooks->remove(dev);
-               
-               kref_put(&np->accel_vif_state.vif_kref,
-                        vif_kref_release);
-               
-               spin_lock_irqsave(&np->accelerator->vif_states_lock,
-                                 flags);
-
-               /* 
-                * Try and do the opposite of accelerator_probe_new_vif
-                * to ensure there's no state pointing back at the 
-                * netdev 
-                */
-               accelerator_remove_single_hook(accelerator, 
-                                              &np->accel_vif_state);
-                               
-               /* 
-                * Remove the reference taken when the vif_state hooks
-                * were set, must be called without lock held
-                */
-               spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                                      flags);
-               kref_put(&np->accel_vif_state.vif_kref,
-                        vif_kref_release);
-       } else {
-               spin_unlock_irqrestore(&np->accelerator->vif_states_lock,
-                                      flags); 
-       }
-
+
+       rc = do_remove(np, dev, &flags);
+
+       np->accelerator = NULL;
+
+       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags); 
+ out:
+       mutex_unlock(&accelerator_mutex);
        return rc;
 }
-
-
-int netfront_accelerator_call_suspend(struct netfront_info *np,
-                                     struct xenbus_device *dev)
-{
+  
+  
+int netfront_accelerator_suspend(struct netfront_info *np,
+                                struct xenbus_device *dev)
+{
+       unsigned flags;
+       int rc = 0;
+
+       mutex_lock(&accelerator_mutex);
+
+       /* Check that we've got a device that was accelerated */
+       if (np->accelerator == NULL)
+               goto out;
+
+       /* 
+        * Call the remove accelerator hook, but leave the vif_state
+        * on the accelerator's list in case there is a suspend_cancel.
+        */
+       spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
+       
+       rc = do_remove(np, dev, &flags);
+
+       spin_unlock_irqrestore(&np->accelerator->vif_states_lock, flags); 
+ out:
+       mutex_unlock(&accelerator_mutex);
+       return rc;
+}
+  
+  
+int netfront_accelerator_suspend_cancel(struct netfront_info *np,
+                                       struct xenbus_device *dev)
+{
+       struct netfront_accel_vif_state *accel_vif_state = NULL;
+ 
+       mutex_lock(&accelerator_mutex);
+
+       /* Check that we've got a device that was accelerated */
+       if (np->accelerator == NULL)
+               goto out;
+
+       /* Find the vif_state from the accelerator's list */
+       list_for_each_entry(accel_vif_state, &np->accelerator->vif_states,
+                           link) {
+               if (accel_vif_state->dev == dev) {
+                       BUG_ON(accel_vif_state != &np->accel_vif_state);
+ 
+                       /*
+                        * Kick things off again to restore
+                        * acceleration as it was before suspend 
+                        */
+                       accelerator_probe_new_vif(np, dev, np->accelerator);
+ 
+                       break;
+               }
+       }
+       
+ out:
+       mutex_unlock(&accelerator_mutex);
+       return 0;
+}
+ 
+ 
+void netfront_accelerator_resume(struct netfront_info *np,
+                                struct xenbus_device *dev)
+{
+       struct netfront_accel_vif_state *accel_vif_state = NULL;
+       spinlock_t *vif_states_lock;
+       unsigned flags;
+ 
+       mutex_lock(&accelerator_mutex);
+
+       /* Check that we've got a device that was accelerated */
+       if(np->accelerator == NULL)
+               goto out;
+
+       /* Find the vif_state from the accelerator's list */
+       list_for_each_entry(accel_vif_state, &np->accelerator->vif_states, 
+                           link) {
+               if (accel_vif_state->dev == dev) {
+                       BUG_ON(accel_vif_state != &np->accel_vif_state);
+ 
+                       vif_states_lock = &np->accelerator->vif_states_lock;
+                       spin_lock_irqsave(vif_states_lock, flags); 
+ 
+                       /* 
+                        * Remove it from the accelerator's list so
+                        * state is consistent for probing new vifs
+                        * when they get connected
+                        */
+                       list_del(&accel_vif_state->link);
+                       np->accelerator = NULL;
+ 
+                       spin_unlock_irqrestore(vif_states_lock, flags); 
+                       
+                       break;
+               }
+       }
+
+ out:
+       mutex_unlock(&accelerator_mutex);
+       return;
+}
+
+
+int netfront_check_accelerator_queue_ready(struct net_device *dev,
+                                          struct netfront_info *np)
+{
+       struct netfront_accelerator *accelerator;
        struct netfront_accel_hooks *hooks;
-       unsigned flags;
-       int rc = 0;
-
-       IPRINTK("netfront_accelerator_call_suspend\n");
-
-       /* 
-        *  Call the suspend accelerator hook.  The use count for the
-        *  accelerator's hooks is incremented for the duration of
-        *  the call to prevent the accelerator being able to modify
-        *  the hooks in the middle (by, for example, unloading)
-        */
-       if (np->accel_vif_state.hooks) {
-               spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
+       int rc = 1;
+       unsigned flags;
+
+       accelerator = np->accelerator;
+
+       /* Call the check_ready accelerator hook. */ 
+       if (np->accel_vif_state.hooks && accelerator) {
+               spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
                hooks = np->accel_vif_state.hooks;
-               if (hooks) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-
-                       rc = np->accel_vif_state.hooks->suspend(dev);
-
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-               }
-       }
+               if (hooks && np->accelerator == accelerator)
+                       rc = np->accel_vif_state.hooks->check_ready(dev);
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
+       }
+
        return rc;
-}
-
-
-int netfront_accelerator_call_suspend_cancel(struct netfront_info *np,
-                                            struct xenbus_device *dev)
-{
-       struct netfront_accel_hooks *hooks;
-       unsigned flags;
-       int rc = 0;
-
-       IPRINTK(" netfront_accelerator_call_suspend_cancel\n");
-
-       /* 
-        *  Call the suspend_cancel accelerator hook.  The use count
-        *  for the accelerator's hooks is incremented for the
-        *  duration of the call to prevent the accelerator being able
-        *  to modify the hooks in the middle (by, for example,
-        *  unloading)
-        */
-       if (np->accel_vif_state.hooks) {
-               spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
-               hooks = np->accel_vif_state.hooks;
-               if (hooks) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-
-                       rc = np->accel_vif_state.hooks->suspend_cancel(dev);
-
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-               }
-       }
-       return rc;
-}
-
-
-int netfront_accelerator_call_resume(struct netfront_info *np,
-                                    struct xenbus_device *dev)
-{
-       struct netfront_accel_hooks *hooks;
-       unsigned flags;
-       int rc = 0;
-
-       /* 
-        *  Call the resume accelerator hook.  The use count for the
-        *  accelerator's hooks is incremented for the duration of
-        *  the call to prevent the accelerator being able to modify
-        *  the hooks in the middle (by, for example, unloading)
-        */
-       if (np->accel_vif_state.hooks) {
-               spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
-               hooks = np->accel_vif_state.hooks;
-               if (hooks) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-
-                       rc = np->accel_vif_state.hooks->resume(dev);
-
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-               }
-       }
-       return rc;
-}
-
-
-void netfront_accelerator_call_backend_changed(struct netfront_info *np,
-                                              struct xenbus_device *dev,
-                                              enum xenbus_state backend_state)
-{
-       struct netfront_accel_hooks *hooks;
-       unsigned flags;
-
-       /* 
-        * Call the backend_changed accelerator hook. The use count
-        * for the accelerator's hooks is incremented for the duration
-        * of the call to prevent the accelerator being able to modify
-        * the hooks in the middle (by, for example, unloading)
-        */
-       if (np->accel_vif_state.hooks) {
-               spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
-               hooks = np->accel_vif_state.hooks;
-               if (hooks) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-
-                       np->accel_vif_state.hooks->backend_changed
-                               (dev, backend_state);
-
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-               }
-       }
 }
 
 
 void netfront_accelerator_call_stop_napi_irq(struct netfront_info *np,
                                             struct net_device *dev)
 {
+       struct netfront_accelerator *accelerator;
        struct netfront_accel_hooks *hooks;
        unsigned flags;
 
-       /* 
-        * Call the stop_napi_interrupts accelerator hook.  The use
-        * count for the accelerator's hooks is incremented for the
-        * duration of the call to prevent the accelerator being able
-        * to modify the hooks in the middle (by, for example,
-        * unloading)
-        */
-
-       if (np->accel_vif_state.hooks) {
-               spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
+       accelerator = np->accelerator;
+
+       /* Call the stop_napi_interrupts accelerator hook. */
+       if (np->accel_vif_state.hooks && accelerator != NULL) {
+               spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
                hooks = np->accel_vif_state.hooks;
-               if (hooks) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-
+               if (hooks && np->accelerator == accelerator)
                        np->accel_vif_state.hooks->stop_napi_irq(dev);
-               
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&np->accelerator->vif_states_lock, flags);
-               }
-       }
-}
-
-
-/* 
- * Once all users of hooks have kref_put()'d we can signal that it's
- * safe to unload
- */ 
-static void accel_kref_release(struct kref *ref)
-{
-       struct netfront_accelerator *accelerator =
-               container_of(ref, struct netfront_accelerator, accel_kref);
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
+       }
+}
+
+
+int netfront_accelerator_call_get_stats(struct netfront_info *np,
+                                       struct net_device *dev)
+{
+       struct netfront_accelerator *accelerator;
        struct netfront_accel_hooks *hooks;
        unsigned flags;
-
-       DPRINTK("%p\n", accelerator);
-
-       /* Signal that all users of hooks are done */
-       up(&accelerator->exit_semaphore);
-
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
-       if (accelerator->need_probe) {
-               hooks = accelerator->need_probe;
-               accelerator->need_probe = NULL;
-               accelerator_probe_vifs(accelerator, hooks, flags);
-       } 
-       else
-               accelerator->ready_for_probe = 1;
-
-       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
-}
-
-
-static void vif_kref_release(struct kref *ref)
-{
-       struct netfront_accel_vif_state *vif_state = 
-               container_of(ref, struct netfront_accel_vif_state, vif_kref);
-       struct netfront_accel_hooks *hooks;
-       unsigned flags;
-
-       DPRINTK("%p\n", vif_state);
-
-       /* 
-        * Now that this vif has finished using the hooks, it can
-        * decrement the accelerator's global copy ref count 
-        */
-       kref_put(&vif_state->np->accelerator->accel_kref, accel_kref_release);
-
-       spin_lock_irqsave(&vif_state->np->accelerator->vif_states_lock, flags);
-       if (vif_state->need_probe) {
-               hooks = vif_state->need_probe;
-               vif_state->need_probe = NULL;
-               spin_unlock_irqrestore
-                       (&vif_state->np->accelerator->vif_states_lock, flags);
-               hooks->new_device(vif_state->np->netdev, vif_state->dev);
-       } else {
-               vif_state->ready_for_probe = 1;
-               spin_unlock_irqrestore
-                       (&vif_state->np->accelerator->vif_states_lock, flags);
-       }
-}
-
+       int rc = 0;
+
+       accelerator = np->accelerator;
+
+       /* Call the get_stats accelerator hook. */
+       if (np->accel_vif_state.hooks && accelerator != NULL) {
+               spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
+               hooks = np->accel_vif_state.hooks;
+               if (hooks && np->accelerator == accelerator)
+                       rc = np->accel_vif_state.hooks->get_stats(dev,
+                                                                 &np->stats);
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
+       }
+       return rc;
+}
+
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/xen/netfront/netfront.c
--- a/drivers/xen/netfront/netfront.c   Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/xen/netfront/netfront.c   Tue Oct 30 15:38:11 2007 -0600
@@ -308,14 +308,14 @@ static int netfront_suspend(struct xenbu
 static int netfront_suspend(struct xenbus_device *dev)
 {
        struct netfront_info *info = dev->dev.driver_data;
-       return netfront_accelerator_call_suspend(info, dev);
+       return netfront_accelerator_suspend(info, dev);
 }
 
 
 static int netfront_suspend_cancel(struct xenbus_device *dev)
 {
        struct netfront_info *info = dev->dev.driver_data;
-       return netfront_accelerator_call_suspend_cancel(info, dev);
+       return netfront_accelerator_suspend_cancel(info, dev);
 }
 
 
@@ -331,7 +331,7 @@ static int netfront_resume(struct xenbus
 
        DPRINTK("%s\n", dev->nodename);
 
-       netfront_accelerator_call_resume(info, dev);
+       netfront_accelerator_resume(info, dev);
 
        netif_disconnect_backend(info);
        return 0;
@@ -549,8 +549,6 @@ static void backend_changed(struct xenbu
                xenbus_frontend_closed(dev);
                break;
        }
-
-       netfront_accelerator_call_backend_changed(np, dev, backend_state);
 }
 
 /** Send a packet on a net device to encourage switches to learn the
@@ -595,12 +593,12 @@ static inline void network_maybe_wake_tx
        if (unlikely(netif_queue_stopped(dev)) &&
            netfront_tx_slot_available(np) &&
            likely(netif_running(dev)) &&
-           netfront_check_accelerator_queue_busy(dev, np))
+           netfront_check_accelerator_queue_ready(dev, np))
                netif_wake_queue(dev);
 }
 
 
-int netfront_check_queue_busy(struct net_device *dev)
+int netfront_check_queue_ready(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
 
@@ -608,7 +606,7 @@ int netfront_check_queue_busy(struct net
                netfront_tx_slot_available(np) &&
                likely(netif_running(dev));
 }
-EXPORT_SYMBOL(netfront_check_queue_busy);
+EXPORT_SYMBOL(netfront_check_queue_ready);
 
 
 static int network_open(struct net_device *dev)
@@ -1507,7 +1505,7 @@ err:
                         *  fast path is likewise
                         */
                        accel_more_to_do = 
-                               np->accel_vif_state.hooks->start_napi_irq(dev);
+                               np->accel_vif_state.hooks->start_napi_irq(dev);
                }
 
                if (!more_to_do && !accel_more_to_do)
@@ -1674,6 +1672,8 @@ static struct net_device_stats *network_
 static struct net_device_stats *network_get_stats(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
+
+       netfront_accelerator_call_get_stats(np, dev);
        return &np->stats;
 }
 
@@ -2210,6 +2210,8 @@ static void __exit netif_exit(void)
 
        unregister_inetaddr_notifier(&notifier_inetdev);
 
+       netif_exit_accel();
+
        return xenbus_unregister_driver(&netfront);
 }
 module_exit(netif_exit);
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/xen/netfront/netfront.h
--- a/drivers/xen/netfront/netfront.h   Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/xen/netfront/netfront.h   Tue Oct 30 15:38:11 2007 -0600
@@ -37,7 +37,6 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
-#include <linux/kref.h>
 
 #define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
 #define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)
@@ -60,19 +59,9 @@ struct netfront_accel_hooks {
         */
        int (*new_device)(struct net_device *net_dev, struct xenbus_device 
*dev);
        /*
-        * suspend, suspend_cancel, resume, remove: Equivalent to the
-        * normal xenbus_* callbacks
-        */
-       int (*suspend)(struct xenbus_device *dev);
-       int (*suspend_cancel)(struct xenbus_device *dev);
-       int (*resume)(struct xenbus_device *dev);
+        * remove: Opposite of new_device
+        */
        int (*remove)(struct xenbus_device *dev);
-       /* 
-        * backend_changed: Callback from watch based on backend's
-        * xenbus state changing
-        */
-       void (*backend_changed)(struct xenbus_device *dev,
-                               enum xenbus_state backend_state);
        /*
         * The net_device is being polled, check the accelerated
         * hardware for any pending packets
@@ -95,13 +84,18 @@ struct netfront_accel_hooks {
         * Called before re-enabling the TX queue to check the fast
         * path has slots too
         */
-       int (*check_busy)(struct net_device *dev);
+       int (*check_ready)(struct net_device *dev);
+       /*
+        * Get the fastpath network statistics
+        */
+       int (*get_stats)(struct net_device *dev,
+                        struct net_device_stats *stats);
 };
 
 
 /* Version of API/protocol for communication between netfront and
    acceleration plugin supported */
-#define NETFRONT_ACCEL_VERSION 0x00010000
+#define NETFRONT_ACCEL_VERSION 0x00010002
 
 /* 
  * Per-netfront device state for the accelerator.  This is used to
@@ -114,14 +108,6 @@ struct netfront_accel_vif_state {
        struct xenbus_device *dev;
        struct netfront_info *np;
        struct netfront_accel_hooks *hooks;
-
-       /* 
-        * Protect against removal of hooks while in use.  
-        */
-       struct kref vif_kref;
-
-       unsigned ready_for_probe;
-       struct netfront_accel_hooks *need_probe;
 }; 
 
 /* 
@@ -142,10 +128,7 @@ struct netfront_accelerator {
        char *frontend;
        /* The hooks into the accelerator plugin module */
        struct netfront_accel_hooks *hooks;
-       /* 
-        * Protect against removal of hooks while in use.  
-        */
-       struct kref accel_kref;
+
        /* 
         * List of per-netfront device state (struct
         * netfront_accel_vif_state) for each netfront device that is
@@ -153,14 +136,6 @@ struct netfront_accelerator {
         */
        struct list_head vif_states;
        spinlock_t vif_states_lock;
-       /* 
-        * Semaphore to signal that all users of this accelerator have
-        * finished using it before module is unloaded
-        */
-       struct semaphore exit_semaphore; 
-
-       unsigned ready_for_probe;
-       struct netfront_accel_hooks *need_probe;
 };
 
 struct netfront_info {
@@ -251,18 +226,15 @@ extern void netfront_accelerator_ready(c
  *
  * frontend: the string describing the accelerator.  Must match the
  * one passed to netfront_accelerator_loaded()
- *
- * wait: 1 => wait for all users of module to complete before
- * returning, thus making it safe to unload on return
  */ 
-extern void netfront_accelerator_stop(const char *frontend, int wait);
+extern void netfront_accelerator_stop(const char *frontend);
 
 /* 
  * Called by an accelerator before waking the net device's TX queue to
  * ensure the slow path has available slots.  Returns true if OK to
  * wake, false if still busy 
  */
-extern int netfront_check_queue_busy(struct net_device *net_dev);
+extern int netfront_check_queue_ready(struct net_device *net_dev);
 
 
 
@@ -274,28 +246,26 @@ extern int netfront_check_queue_busy(str
  * if still busy
  */ 
 extern 
-int netfront_check_accelerator_queue_busy(struct net_device *dev,
-                                         struct netfront_info *np);
+int netfront_check_accelerator_queue_ready(struct net_device *dev,
+                                          struct netfront_info *np);
 extern
 int netfront_accelerator_call_remove(struct netfront_info *np,
                                     struct xenbus_device *dev);
 extern
-int netfront_accelerator_call_suspend(struct netfront_info *np,
-                                     struct xenbus_device *dev);
-extern
-int netfront_accelerator_call_suspend_cancel(struct netfront_info *np,
-                                            struct xenbus_device *dev);
-extern
-int netfront_accelerator_call_resume(struct netfront_info *np,
-                                    struct xenbus_device *dev);
-extern
-void netfront_accelerator_call_backend_changed(struct netfront_info *np,
-                                              struct xenbus_device *dev,
-                                              enum xenbus_state backend_state);
+int netfront_accelerator_suspend(struct netfront_info *np,
+                                struct xenbus_device *dev);
+extern
+int netfront_accelerator_suspend_cancel(struct netfront_info *np,
+                                       struct xenbus_device *dev);
+extern
+void netfront_accelerator_resume(struct netfront_info *np,
+                                struct xenbus_device *dev);
 extern
 void netfront_accelerator_call_stop_napi_irq(struct netfront_info *np,
                                             struct net_device *dev);
-
+extern
+int netfront_accelerator_call_get_stats(struct netfront_info *np,
+                                       struct net_device *dev);
 extern
 int netfront_load_accelerator(struct netfront_info *np, 
                              struct xenbus_device *dev, 
@@ -303,6 +273,8 @@ int netfront_load_accelerator(struct net
 
 extern
 void netif_init_accel(void);
+extern
+void netif_exit_accel(void);
 
 extern
 void init_accelerator_vif(struct netfront_info *np,
diff -r 0edeca96e7d7 -r bac78e892e42 drivers/xen/xenbus/xenbus_probe.c
--- a/drivers/xen/xenbus/xenbus_probe.c Tue Oct 30 13:42:54 2007 -0600
+++ b/drivers/xen/xenbus/xenbus_probe.c Tue Oct 30 15:38:11 2007 -0600
@@ -69,7 +69,7 @@ static unsigned long xen_store_mfn;
 
 extern struct mutex xenwatch_mutex;
 
-static ATOMIC_NOTIFIER_HEAD(xenstore_chain);
+static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
 
 static void wait_for_devices(struct xenbus_driver *xendrv);
 
@@ -825,7 +825,7 @@ int register_xenstore_notifier(struct no
        if (xenstored_ready > 0)
                ret = nb->notifier_call(nb, 0, NULL);
        else
-               atomic_notifier_chain_register(&xenstore_chain, nb);
+               blocking_notifier_chain_register(&xenstore_chain, nb);
 
        return ret;
 }
@@ -833,7 +833,7 @@ EXPORT_SYMBOL_GPL(register_xenstore_noti
 
 void unregister_xenstore_notifier(struct notifier_block *nb)
 {
-       atomic_notifier_chain_unregister(&xenstore_chain, nb);
+       blocking_notifier_chain_unregister(&xenstore_chain, nb);
 }
 EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
 
@@ -848,7 +848,7 @@ void xenbus_probe(void *unused)
        xenbus_backend_probe_and_watch();
 
        /* Notify others that xenstore is up */
-       atomic_notifier_call_chain(&xenstore_chain, 0, NULL);
+       blocking_notifier_call_chain(&xenstore_chain, 0, NULL);
 }
 
 
diff -r 0edeca96e7d7 -r bac78e892e42 include/asm-i386/mach-xen/asm/page.h
--- a/include/asm-i386/mach-xen/asm/page.h      Tue Oct 30 13:42:54 2007 -0600
+++ b/include/asm-i386/mach-xen/asm/page.h      Tue Oct 30 15:38:11 2007 -0600
@@ -36,14 +36,6 @@
 #include <asm/bug.h>
 #include <xen/interface/xen.h>
 #include <xen/features.h>
-
-#define arch_free_page(_page,_order)           \
-({     int foreign = PageForeign(_page);       \
-       if (foreign)                            \
-               PageForeignDestructor(_page);   \
-       foreign;                                \
-})
-#define HAVE_ARCH_FREE_PAGE
 
 #ifdef CONFIG_X86_USE_3DNOW
 
diff -r 0edeca96e7d7 -r bac78e892e42 include/asm-ia64/page.h
--- a/include/asm-ia64/page.h   Tue Oct 30 13:42:54 2007 -0600
+++ b/include/asm-ia64/page.h   Tue Oct 30 15:38:11 2007 -0600
@@ -239,15 +239,6 @@ get_order (unsigned long size)
 
 #include <asm/maddr.h>
 
-#define arch_free_page(_page, _order)          \
-({                                             \
-       int foreign = PageForeign(_page);       \
-       if (foreign)                            \
-               PageForeignDestructor(_page);   \
-       foreign;                                \
-})
-#define HAVE_ARCH_FREE_PAGE
-
 #endif /* CONFIG_XEN */
 #endif /* __ASSEMBLY__ */
 
diff -r 0edeca96e7d7 -r bac78e892e42 include/asm-powerpc/page.h
--- a/include/asm-powerpc/page.h        Tue Oct 30 13:42:54 2007 -0600
+++ b/include/asm-powerpc/page.h        Tue Oct 30 15:38:11 2007 -0600
@@ -194,15 +194,6 @@ struct vm_area_struct;
 struct vm_area_struct;
 extern const char *arch_vma_name(struct vm_area_struct *vma);
 
-#define arch_free_page(_page, _order)       \
-({                      \
-       int foreign = PageForeign(_page);   \
-       if (foreign) \
-               PageForeignDestructor(_page);   \
-       foreign; \
-})
-#define HAVE_ARCH_FREE_PAGE
-
 #include <asm-generic/memory_model.h>
 #endif /* __ASSEMBLY__ */
 
diff -r 0edeca96e7d7 -r bac78e892e42 include/asm-um/page.h
--- a/include/asm-um/page.h     Tue Oct 30 13:42:54 2007 -0600
+++ b/include/asm-um/page.h     Tue Oct 30 15:38:11 2007 -0600
@@ -114,7 +114,7 @@ extern struct page *arch_validate(struct
 extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
 #define HAVE_ARCH_VALIDATE
 
-extern int arch_free_page(struct page *page, int order);
+extern void arch_free_page(struct page *page, int order);
 #define HAVE_ARCH_FREE_PAGE
 
 #include <asm-generic/memory_model.h>
diff -r 0edeca96e7d7 -r bac78e892e42 include/asm-x86_64/mach-xen/asm/page.h
--- a/include/asm-x86_64/mach-xen/asm/page.h    Tue Oct 30 13:42:54 2007 -0600
+++ b/include/asm-x86_64/mach-xen/asm/page.h    Tue Oct 30 15:38:11 2007 -0600
@@ -15,14 +15,6 @@
  * below. The preprocessor will warn if the two definitions aren't identical.
  */
 #define _PAGE_PRESENT  0x001
-
-#define arch_free_page(_page,_order)           \
-({     int foreign = PageForeign(_page);       \
-       if (foreign)                            \
-               PageForeignDestructor(_page);   \
-       foreign;                                \
-})
-#define HAVE_ARCH_FREE_PAGE
 
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT     12
diff -r 0edeca96e7d7 -r bac78e892e42 include/asm-x86_64/mach-xen/asm/pgtable.h
--- a/include/asm-x86_64/mach-xen/asm/pgtable.h Tue Oct 30 13:42:54 2007 -0600
+++ b/include/asm-x86_64/mach-xen/asm/pgtable.h Tue Oct 30 15:38:11 2007 -0600
@@ -505,7 +505,7 @@ static inline pte_t pte_modify(pte_t pte
 #define __swp_type(x)                  (((x).val >> 1) & 0x3f)
 #define __swp_offset(x)                        ((x).val >> 8)
 #define __swp_entry(type, offset)      ((swp_entry_t) { ((type) << 1) | 
((offset) << 8) })
-#define __pte_to_swp_entry(pte)                ((swp_entry_t) { pte_val(pte) })
+#define __pte_to_swp_entry(pte)                ((swp_entry_t) { __pte_val(pte) 
})
 #define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
 
 extern spinlock_t pgd_lock;
diff -r 0edeca96e7d7 -r bac78e892e42 include/linux/gfp.h
--- a/include/linux/gfp.h       Tue Oct 30 13:42:54 2007 -0600
+++ b/include/linux/gfp.h       Tue Oct 30 15:38:11 2007 -0600
@@ -99,11 +99,7 @@ static inline int gfp_zone(gfp_t gfp)
  */
 
 #ifndef HAVE_ARCH_FREE_PAGE
-/*
- * If arch_free_page returns non-zero then the generic free_page code can
- * immediately bail: the arch-specific function has done all the work.
- */
-static inline int arch_free_page(struct page *page, int order) { return 0; }
+static inline void arch_free_page(struct page *page, int order) { }
 #endif
 
 extern struct page *
diff -r 0edeca96e7d7 -r bac78e892e42 include/xen/evtchn.h
--- a/include/xen/evtchn.h      Tue Oct 30 13:42:54 2007 -0600
+++ b/include/xen/evtchn.h      Tue Oct 30 15:38:11 2007 -0600
@@ -102,6 +102,7 @@ void evtchn_device_upcall(int port);
 void evtchn_device_upcall(int port);
 
 void mask_evtchn(int port);
+void disable_all_local_evtchn(void);
 void unmask_evtchn(int port);
 
 #ifdef CONFIG_SMP
diff -r 0edeca96e7d7 -r bac78e892e42 include/xen/interface/callback.h
--- a/include/xen/interface/callback.h  Tue Oct 30 13:42:54 2007 -0600
+++ b/include/xen/interface/callback.h  Tue Oct 30 15:38:11 2007 -0600
@@ -36,15 +36,39 @@
  * @extra_args == Operation-specific extra arguments (NULL if none).
  */
 
+/* ia64, x86: Callback for event delivery. */
 #define CALLBACKTYPE_event                 0
+
+/* x86: Failsafe callback when guest state cannot be restored by Xen. */
 #define CALLBACKTYPE_failsafe              1
-#define CALLBACKTYPE_syscall               2 /* x86_64 only */
+
+/* x86/64 hypervisor: Syscall by 64-bit guest app ('64-on-64-on-64'). */
+#define CALLBACKTYPE_syscall               2
+
 /*
- * sysenter is only available on x86_32 with the
- * supervisor_mode_kernel option enabled.
+ * x86/32 hypervisor: Only available on x86/32 when supervisor_mode_kernel
+ *     feature is enabled. Do not use this callback type in new code.
  */
-#define CALLBACKTYPE_sysenter              3
+#define CALLBACKTYPE_sysenter_deprecated   3
+
+/* x86: Callback for NMI delivery. */
 #define CALLBACKTYPE_nmi                   4
+
+/*
+ * x86: sysenter is only available as follows:
+ * - 32-bit hypervisor: with the supervisor_mode_kernel feature enabled
+ * - 64-bit hypervisor: 32-bit guest applications on Intel CPUs
+ *                      ('32-on-32-on-64', '32-on-64-on-64')
+ *                      [nb. also 64-bit guest applications on Intel CPUs
+ *                           ('64-on-64-on-64'), but syscall is preferred]
+ */
+#define CALLBACKTYPE_sysenter              5
+
+/*
+ * x86/64 hypervisor: Syscall by 32-bit guest app on AMD CPUs
+ *                    ('32-on-32-on-64', '32-on-64-on-64')
+ */
+#define CALLBACKTYPE_syscall32             7
 
 /*
  * Disable event deliver during callback? This flag is ignored for event and
@@ -79,6 +103,11 @@ typedef struct callback_unregister callb
 typedef struct callback_unregister callback_unregister_t;
 DEFINE_XEN_GUEST_HANDLE(callback_unregister_t);
 
+#if __XEN_INTERFACE_VERSION__ < 0x00030207
+#undef CALLBACKTYPE_sysenter
+#define CALLBACKTYPE_sysenter CALLBACKTYPE_sysenter_deprecated
+#endif
+
 #endif /* __XEN_PUBLIC_CALLBACK_H__ */
 
 /*
diff -r 0edeca96e7d7 -r bac78e892e42 include/xen/interface/domctl.h
--- a/include/xen/interface/domctl.h    Tue Oct 30 13:42:54 2007 -0600
+++ b/include/xen/interface/domctl.h    Tue Oct 30 15:38:11 2007 -0600
@@ -474,11 +474,11 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_
 /* Bind machine I/O address range -> HVM address range. */
 #define XEN_DOMCTL_memory_mapping    39
 struct xen_domctl_memory_mapping {
-    uint64_t first_gfn;       /* first page (hvm guest phys page) in range */
-    uint64_t first_mfn;       /* first page (machine page) in range */
-    uint64_t nr_mfns;         /* number of pages in range (>0) */
-    uint32_t add_mapping;     /* add or remove mapping */
-    uint32_t padding;         /* padding for 64-bit aligned structure */
+    uint64_aligned_t first_gfn; /* first page (hvm guest phys page) in range */
+    uint64_aligned_t first_mfn; /* first page (machine page) in range */
+    uint64_aligned_t nr_mfns;   /* number of pages in range (>0) */
+    uint32_t add_mapping;       /* add or remove mapping */
+    uint32_t padding;           /* padding for 64-bit aligned structure */
 };
 typedef struct xen_domctl_memory_mapping xen_domctl_memory_mapping_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_memory_mapping_t);
@@ -494,6 +494,50 @@ struct xen_domctl_ioport_mapping {
 };
 typedef struct xen_domctl_ioport_mapping xen_domctl_ioport_mapping_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_mapping_t);
+
+
+/*
+ * Pin caching type of RAM space for x86 HVM domU.
+ */
+#define XEN_DOMCTL_pin_mem_cacheattr 41
+/* Caching types: these happen to be the same as x86 MTRR/PAT type codes. */
+#define XEN_DOMCTL_MEM_CACHEATTR_UC  0
+#define XEN_DOMCTL_MEM_CACHEATTR_WC  1
+#define XEN_DOMCTL_MEM_CACHEATTR_WT  4
+#define XEN_DOMCTL_MEM_CACHEATTR_WP  5
+#define XEN_DOMCTL_MEM_CACHEATTR_WB  6
+#define XEN_DOMCTL_MEM_CACHEATTR_UCM 7
+struct xen_domctl_pin_mem_cacheattr {
+    uint64_aligned_t start, end;
+    unsigned int type; /* XEN_DOMCTL_MEM_CACHEATTR_* */
+};
+typedef struct xen_domctl_pin_mem_cacheattr xen_domctl_pin_mem_cacheattr_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_pin_mem_cacheattr_t);
+
+
+#define XEN_DOMCTL_set_ext_vcpucontext 42
+#define XEN_DOMCTL_get_ext_vcpucontext 43
+struct xen_domctl_ext_vcpucontext {
+    /* IN: VCPU that this call applies to. */
+    uint32_t         vcpu;
+    /*
+     * SET: Size of struct (IN)
+     * GET: Size of struct (OUT)
+     */
+    uint32_t         size;
+#if defined(__i386__) || defined(__x86_64__)
+    /* SYSCALL from 32-bit mode and SYSENTER callback information. */
+    /* NB. SYSCALL from 64-bit mode is contained in vcpu_guest_context_t */
+    uint64_aligned_t syscall32_callback_eip;
+    uint64_aligned_t sysenter_callback_eip;
+    uint16_t         syscall32_callback_cs;
+    uint16_t         sysenter_callback_cs;
+    uint8_t          syscall32_disables_events;
+    uint8_t          sysenter_disables_events;
+#endif
+};
+typedef struct xen_domctl_ext_vcpucontext xen_domctl_ext_vcpucontext_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_ext_vcpucontext_t);
 
 
 struct xen_domctl {
@@ -529,6 +573,8 @@ struct xen_domctl {
         struct xen_domctl_bind_pt_irq       bind_pt_irq;
         struct xen_domctl_memory_mapping    memory_mapping;
         struct xen_domctl_ioport_mapping    ioport_mapping;
+        struct xen_domctl_pin_mem_cacheattr pin_mem_cacheattr;
+        struct xen_domctl_ext_vcpucontext   ext_vcpucontext;
         uint8_t                             pad[128];
     } u;
 };
diff -r 0edeca96e7d7 -r bac78e892e42 include/xen/interface/platform.h
--- a/include/xen/interface/platform.h  Tue Oct 30 13:42:54 2007 -0600
+++ b/include/xen/interface/platform.h  Tue Oct 30 15:38:11 2007 -0600
@@ -174,13 +174,27 @@ typedef struct xenpf_change_freq xenpf_c
 typedef struct xenpf_change_freq xenpf_change_freq_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_change_freq_t);
 
+/*
+ * Get idle times (nanoseconds since boot) for physical CPUs specified in the
+ * @cpumap_bitmap with range [0..@cpumap_nr_cpus-1]. The @idletime array is
+ * indexed by CPU number; only entries with the corresponding @cpumap_bitmap
+ * bit set are written to. On return, @cpumap_bitmap is modified so that any
+ * non-existent CPUs are cleared. Such CPUs have their @idletime array entry
+ * cleared.
+ */
 #define XENPF_getidletime         53
 struct xenpf_getidletime {
-    /* IN variables. */
-    uint32_t max_cpus;
+    /* IN/OUT variables */
+    /* IN: CPUs to interrogate; OUT: subset of IN which are present */
+    XEN_GUEST_HANDLE(uint8_t) cpumap_bitmap;
+    /* IN variables */
+    /* Size of cpumap bitmap. */
+    uint32_t cpumap_nr_cpus;
+    /* Must be indexable for every cpu in cpumap_bitmap. */
     XEN_GUEST_HANDLE(uint64_t) idletime;
-    /* OUT variables. */
-    uint32_t nr_cpus;
+    /* OUT variables */
+    /* System time when the idletime snapshots were taken. */
+    uint64_t now;
 };
 typedef struct xenpf_getidletime xenpf_getidletime_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
diff -r 0edeca96e7d7 -r bac78e892e42 include/xen/interface/sysctl.h
--- a/include/xen/interface/sysctl.h    Tue Oct 30 13:42:54 2007 -0600
+++ b/include/xen/interface/sysctl.h    Tue Oct 30 15:38:11 2007 -0600
@@ -34,18 +34,27 @@
 #include "xen.h"
 #include "domctl.h"
 
-#define XEN_SYSCTL_INTERFACE_VERSION 0x00000005
+#define XEN_SYSCTL_INTERFACE_VERSION 0x00000006
 
 /*
  * Read console content from Xen buffer ring.
  */
 #define XEN_SYSCTL_readconsole       1
 struct xen_sysctl_readconsole {
-    /* IN variables. */
-    uint32_t clear;                /* Non-zero -> clear after reading. */
-    XEN_GUEST_HANDLE_64(char) buffer; /* Buffer start */
-    /* IN/OUT variables. */
-    uint32_t count;            /* In: Buffer size;  Out: Used buffer size  */
+    /* IN: Non-zero -> clear after reading. */
+    uint8_t clear;
+    /* IN: Non-zero -> start index specified by @index field. */
+    uint8_t incremental;
+    uint8_t pad0, pad1;
+    /*
+     * IN:  Start index for consuming from ring buffer (if @incremental);
+     * OUT: End index after consuming from ring buffer.
+     */
+    uint32_t index; 
+    /* IN: Virtual address to write console data. */
+    XEN_GUEST_HANDLE_64(char) buffer;
+    /* IN: Size of buffer; OUT: Bytes written to buffer. */
+    uint32_t count;
 };
 typedef struct xen_sysctl_readconsole xen_sysctl_readconsole_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_readconsole_t);
@@ -171,7 +180,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_debug
 /* Get physical CPU information. */
 #define XEN_SYSCTL_getcpuinfo        8
 struct xen_sysctl_cpuinfo {
-    uint64_t idletime;
+    uint64_aligned_t idletime;
 };
 typedef struct xen_sysctl_cpuinfo xen_sysctl_cpuinfo_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpuinfo_t); 
@@ -192,7 +201,7 @@ struct xen_sysctl_availheap {
     uint32_t max_bitwidth;  /* Largest address width (zero if don't care). */
     int32_t  node;          /* NUMA node of interest (-1 for all nodes). */
     /* OUT variables. */
-    uint64_t avail_bytes;   /* Bytes available in the specified region. */
+    uint64_aligned_t avail_bytes;/* Bytes available in the specified region. */
 };
 typedef struct xen_sysctl_availheap xen_sysctl_availheap_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_availheap_t);
diff -r 0edeca96e7d7 -r bac78e892e42 include/xen/interface/vcpu.h
--- a/include/xen/interface/vcpu.h      Tue Oct 30 13:42:54 2007 -0600
+++ b/include/xen/interface/vcpu.h      Tue Oct 30 15:38:11 2007 -0600
@@ -179,6 +179,9 @@ typedef struct vcpu_register_vcpu_info v
 typedef struct vcpu_register_vcpu_info vcpu_register_vcpu_info_t;
 DEFINE_XEN_GUEST_HANDLE(vcpu_register_vcpu_info_t);
 
+/* Send an NMI to the specified VCPU. @extra_arg == NULL. */
+#define VCPUOP_send_nmi             11
+
 #endif /* __XEN_PUBLIC_VCPU_H__ */
 
 /*
diff -r 0edeca96e7d7 -r bac78e892e42 include/xen/interface/xen-compat.h
--- a/include/xen/interface/xen-compat.h        Tue Oct 30 13:42:54 2007 -0600
+++ b/include/xen/interface/xen-compat.h        Tue Oct 30 15:38:11 2007 -0600
@@ -27,7 +27,7 @@
 #ifndef __XEN_PUBLIC_XEN_COMPAT_H__
 #define __XEN_PUBLIC_XEN_COMPAT_H__
 
-#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030206
+#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030207
 
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 /* Xen is built with matching headers and implements the latest interface. */
diff -r 0edeca96e7d7 -r bac78e892e42 mm/page_alloc.c
--- a/mm/page_alloc.c   Tue Oct 30 13:42:54 2007 -0600
+++ b/mm/page_alloc.c   Tue Oct 30 15:38:11 2007 -0600
@@ -451,8 +451,13 @@ static void __free_pages_ok(struct page 
        int i;
        int reserved = 0;
 
-       if (arch_free_page(page, order))
+#ifdef CONFIG_XEN
+       if (PageForeign(page)) {
+               PageForeignDestructor(page);
                return;
+       }
+#endif
+       arch_free_page(page, order);
        if (!PageHighMem(page))
                debug_check_no_locks_freed(page_address(page),
                                           PAGE_SIZE<<order);
@@ -730,8 +735,13 @@ static void fastcall free_hot_cold_page(
        struct per_cpu_pages *pcp;
        unsigned long flags;
 
-       if (arch_free_page(page, 0))
+#ifdef CONFIG_XEN
+       if (PageForeign(page)) {
+               PageForeignDestructor(page);
                return;
+       }
+#endif
+       arch_free_page(page, 0);
 
        if (PageAnon(page))
                page->mapping = NULL;

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

<Prev in Thread] Current Thread [Next in Thread>