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

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



# 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


 


Rackspace

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