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

[Xen-changelog] Merged.



# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID a38c292e8390370ec9473a6444bd63be7e437afe
# Parent  40bb46f599d93a8605740bc5800d5e61d8cc1198
# Parent  1f87f39aa0e19527976780a9aab473d9fe191b8a
Merged.

diff -r 40bb46f599d9 -r a38c292e8390 .hgignore
--- a/.hgignore Tue Jan 10 15:21:00 2006
+++ b/.hgignore Tue Jan 24 16:54:34 2006
@@ -163,6 +163,7 @@
 ^tools/xenstore/xenstore-read$
 ^tools/xenstore/xenstore-rm$
 ^tools/xenstore/xenstore-write$
+^tools/xenstore/xenstore-ls$
 ^tools/xenstore/xenstored$
 ^tools/xenstore/xenstored_test$
 ^tools/xenstore/xs_crashme$
@@ -171,7 +172,6 @@
 ^tools/xenstore/xs_tdb_dump$
 ^tools/xenstore/xs_test$
 ^tools/xenstore/xs_watch_stress$
-^tools/xenstore/xsls$
 ^tools/xentrace/setsize$
 ^tools/xentrace/tbctl$
 ^tools/xentrace/xenctx$
diff -r 40bb46f599d9 -r a38c292e8390 docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Tue Jan 10 15:21:00 2006
+++ b/docs/man/xm.pod.1 Tue Jan 24 16:54:34 2006
@@ -374,7 +374,7 @@
 configured VCPU count is an error.  Trying to set-vcpus to < 1 will be
 quietly ignored.
 
-=item B<vpcu-list> I<[domain-id]>
+=item B<vcpu-list> I<[domain-id]>
 
 Lists VCPU information for a specific domain.  If no domain is
 specified, VCPU information for all domains will be provided.
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_ia64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_ia64 Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_ia64 Tue Jan 24 
16:54:34 2006
@@ -91,8 +91,7 @@
 # CONFIG_IA64_PAGE_SIZE_64KB is not set
 CONFIG_IA64_L1_CACHE_SHIFT=7
 # CONFIG_NUMA is not set
-CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
+CONFIG_VIRTUAL_MEM_MAP=n
 CONFIG_IA64_CYCLONE=y
 CONFIG_IOSAPIC=y
 CONFIG_FORCE_MAX_ZONEORDER=18
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Tue Jan 24 16:54:34 2006
@@ -76,7 +76,9 @@
 DF_MASK                = 0x00000400 
 NT_MASK                = 0x00004000
 VM_MASK                = 0x00020000
-
+/* Pseudo-eflags. */
+NMI_MASK       = 0x80000000
+       
 /* Offsets into shared_info_t. */
 #define evtchn_upcall_pending          /* 0 */
 #define evtchn_upcall_mask             1
@@ -305,8 +307,8 @@
        je ldt_ss                       # returning to user-space with LDT SS
 #endif /* XEN */
 restore_nocheck:
-       testl $VM_MASK, EFLAGS(%esp)
-       jnz resume_vm86
+       testl $(VM_MASK|NMI_MASK), EFLAGS(%esp)
+       jnz hypervisor_iret
        movb EVENT_MASK(%esp), %al
        notb %al                        # %al == ~saved_mask
        XEN_GET_VCPU_INFO(%esi)
@@ -328,11 +330,11 @@
        .long 1b,iret_exc
 .previous
 
-resume_vm86:
-       XEN_UNBLOCK_EVENTS(%esi)
+hypervisor_iret:
+       andl $~NMI_MASK, EFLAGS(%esp)
        RESTORE_REGS
        movl %eax,(%esp)
-       movl $__HYPERVISOR_switch_vm86,%eax
+       movl $__HYPERVISOR_iret,%eax
        int $0x82
        ud2
 
@@ -691,6 +693,15 @@
        call do_debug
        jmp ret_from_exception
 
+ENTRY(nmi)
+       pushl %eax
+       SAVE_ALL
+       xorl %edx,%edx          # zero error code
+       movl %esp,%eax          # pt_regs pointer
+       call do_nmi
+       orl  $NMI_MASK, EFLAGS(%esp)
+       jmp restore_all
+
 #if 0 /* XEN */
 /*
  * NMI is doubly nasty. It can happen _while_ we're handling
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c       Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/io_apic.c       Tue Jan 24 
16:54:34 2006
@@ -622,9 +622,11 @@
                try_to_freeze(PF_FREEZE);
                if (time_after(jiffies,
                                prev_balance_time+balanced_irq_interval)) {
+                       preempt_disable();
                        do_irq_balance();
                        prev_balance_time = jiffies;
                        time_remaining = balanced_irq_interval;
+                       preempt_enable();
                }
        }
        return 0;
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Tue Jan 24 16:54:34 2006
@@ -506,18 +506,11 @@
 
 static void io_check_error(unsigned char reason, struct pt_regs * regs)
 {
-       unsigned long i;
-
        printk("NMI: IOCK error (debug interrupt?)\n");
        show_registers(regs);
 
        /* Re-enable the IOCK line, wait for a few seconds */
-       reason = (reason & 0xf) | 8;
-       outb(reason, 0x61);
-       i = 2000;
-       while (--i) udelay(1000);
-       reason &= ~8;
-       outb(reason, 0x61);
+       clear_io_check_error(reason);
 }
 
 static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
@@ -647,12 +640,6 @@
        do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
 }
 #endif
-
-static inline void conditional_sti(struct pt_regs *regs)
-{
-       if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
-               local_irq_enable();
-}
 
 /*
  * Our handling of the processor debug registers is non-trivial.
@@ -686,9 +673,9 @@
        if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
                                        SIGTRAP) == NOTIFY_STOP)
                return;
-
        /* It's safe to allow irq's after DR6 has been saved */
-       conditional_sti(regs);
+       if (regs->eflags & X86_EFLAGS_IF)
+               local_irq_enable();
 
        /* Mask out spurious debug traps due to lazy DR7 setting */
        if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/i386/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c      Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/init.c      Tue Jan 24 16:54:34 2006
@@ -65,7 +65,7 @@
 {
        pud_t *pud;
        pmd_t *pmd_table;
-
+               
 #ifdef CONFIG_X86_PAE
        pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
        make_lowmem_page_readonly(pmd_table);
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c     Tue Jan 24 16:54:34 2006
@@ -290,15 +290,15 @@
                             const char **vec, unsigned int len)
 {
        char *str;
-       struct xenbus_transaction *xbt;
+       xenbus_transaction_t xbt;
        int err;
 
        if (shutting_down != SHUTDOWN_INVALID)
                return;
 
  again:
-       xbt = xenbus_transaction_start();
-       if (IS_ERR(xbt))
+       err = xenbus_transaction_start(&xbt);
+       if (err)
                return;
        str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
        /* Ignore read errors and empty reads. */
@@ -339,12 +339,12 @@
                          unsigned int len)
 {
        char sysrq_key = '\0';
-       struct xenbus_transaction *xbt;
+       xenbus_transaction_t xbt;
        int err;
 
  again:
-       xbt  = xenbus_transaction_start();
-       if (IS_ERR(xbt))
+       err = xenbus_transaction_start(&xbt);
+       if (err)
                return;
        if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
                printk(KERN_ERR "Unable to read sysrq code in "
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c        Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c        Tue Jan 24 
16:54:34 2006
@@ -526,7 +526,7 @@
 
 unsigned long __init e820_end_of_ram(void)
 {
-        unsigned long max_end_pfn;
+       unsigned long max_end_pfn;
 
        if (xen_override_max_pfn == 0) {
                max_end_pfn = xen_start_info->nr_pages;
@@ -612,7 +612,7 @@
 { 
        end_user_pfn = memparse(p, from);
        end_user_pfn >>= PAGE_SHIFT;    
-        xen_override_max_pfn = (unsigned long) end_user_pfn;
+       xen_override_max_pfn = (unsigned long) end_user_pfn;
 } 
 
 /*
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S       Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S       Tue Jan 24 
16:54:34 2006
@@ -57,7 +57,7 @@
 #ifndef CONFIG_PREEMPT
 #define retint_kernel retint_restore_args
 #endif 
-
+       
 /*
  * C code is not supposed to know about undefined top of stack. Every time 
  * a C function with an pt_regs argument is called from the SYSCALL based 
@@ -65,7 +65,7 @@
  * RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs
  * manipulation.
  */            
-
+               
        /* %rsp:at FRAMEEND */ 
        .macro FIXUP_TOP_OF_STACK tmp
        movq    $__USER_CS,CS(%rsp)
@@ -121,19 +121,19 @@
        .endm
 
         /*
-         * Must be consistent with the definition in arch_x86_64.h:    
-         *     struct switch_to_user {
+         * Must be consistent with the definition in arch-x86_64.h:    
+         *     struct iret_context {
          *        u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
          *     };
          * #define VGCF_IN_SYSCALL (1<<8) 
          */
-        .macro SWITCH_TO_USER flag
+        .macro HYPERVISOR_IRET flag
         subq $8*4,%rsp                   # reuse rip, cs, rflags, rsp, ss in 
the stack
         movq %rax,(%rsp)
         movq %r11,1*8(%rsp)
         movq %rcx,2*8(%rsp)              # we saved %rcx upon exceptions
         movq $\flag,3*8(%rsp)
-        movq $__HYPERVISOR_switch_to_user,%rax
+        movq $__HYPERVISOR_iret,%rax
         syscall
         .endm
 
@@ -225,7 +225,7 @@
        jnz  sysret_careful 
         XEN_UNBLOCK_EVENTS(%rsi)                
        RESTORE_ARGS 0,8,0
-        SWITCH_TO_USER VGCF_IN_SYSCALL
+        HYPERVISOR_IRET VGCF_IN_SYSCALL
 
        /* Handle reschedules */
        /* edx: work, edi: workmask */  
@@ -417,7 +417,6 @@
        RESTORE_REST
        jmp int_ret_from_sys_call
        CFI_ENDPROC
-
 
 /* 
  * Interrupt entry/exit.
@@ -479,7 +478,7 @@
         orb   $3,1*8(%rsp)
        iretq
 user_mode:
-       SWITCH_TO_USER 0                        
+       HYPERVISOR_IRET 0
        
        /* edi: workmask, edx: work */  
 retint_careful:
@@ -720,6 +719,18 @@
        call evtchn_do_upcall
         jmp  error_exit
 
+#ifdef CONFIG_X86_LOCAL_APIC
+ENTRY(nmi)
+       zeroentry do_nmi_callback
+ENTRY(do_nmi_callback)
+        addq $8, %rsp
+        call do_nmi
+        RESTORE_REST
+        XEN_BLOCK_EVENTS(%rsi)
+        GET_THREAD_INFO(%rcx)
+        jmp  retint_restore_args
+#endif
+
         ALIGN
 restore_all_enable_events:  
        XEN_UNBLOCK_EVENTS(%rsi)        # %rsi is already set up...
@@ -734,7 +745,7 @@
         orb   $3,1*8(%rsp)
         iretq
 crit_user_mode:
-        SWITCH_TO_USER 0
+        HYPERVISOR_IRET 0
         
 14:    XEN_LOCKED_BLOCK_EVENTS(%rsi)
        XEN_PUT_VCPU_INFO(%rsi)
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c      Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c      Tue Jan 24 
16:54:34 2006
@@ -68,13 +68,13 @@
 
 static void __init setup_boot_cpu_data(void)
 {
-       int dummy, eax;
+       unsigned int dummy, eax;
 
        /* get vendor info */
-       cpuid(0, &boot_cpu_data.cpuid_level,
-             (int *)&boot_cpu_data.x86_vendor_id[0],
-             (int *)&boot_cpu_data.x86_vendor_id[8],
-             (int *)&boot_cpu_data.x86_vendor_id[4]);
+       cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level,
+             (unsigned int *)&boot_cpu_data.x86_vendor_id[0],
+             (unsigned int *)&boot_cpu_data.x86_vendor_id[8],
+             (unsigned int *)&boot_cpu_data.x86_vendor_id[4]);
 
        /* get cpu type */
        cpuid(1, &eax, &dummy, &dummy,
@@ -109,7 +109,6 @@
        if (s != NULL)
                setup_early_printk(s);
 #endif
-
 #ifdef CONFIG_DISCONTIGMEM
        s = strstr(saved_command_line, "numa=");
        if (s != NULL)
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c     Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/io_apic.c     Tue Jan 24 
16:54:34 2006
@@ -255,10 +255,8 @@
        return 1;
 }
 
-
 __setup("noapic", disable_ioapic_setup);
 __setup("apic", enable_ioapic_setup);
-
 
 #include <asm/pci-direct.h>
 #include <linux/pci_ids.h>
@@ -1146,6 +1144,7 @@
        v = inb(0x4d1) << 8 | inb(0x4d0);
        printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
 }
+
 #endif  /*  0  */
 
 #else
@@ -1191,6 +1190,7 @@
         * Clear the IO-APIC before rebooting:
         */
        clear_IO_APIC();
+
 #ifndef CONFIG_XEN
        disconnect_bsp_APIC();
 #endif
@@ -1202,6 +1202,7 @@
  *
  * by Matt Domsch <Matt_Domsch@xxxxxxxx>  Tue Dec 21 12:25:05 CST 1999
  */
+
 #ifndef CONFIG_XEN
 static void __init setup_ioapic_ids_from_mpc (void)
 {
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/irq.c Tue Jan 24 16:54:34 2006
@@ -9,18 +9,15 @@
  * x86_64-specific irq controller code. (e.g. i8259.c and
  * io_apic.c.)
  */
+
+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
 #include <asm/uaccess.h>
-#include <linux/module.h>
-#include <linux/seq_file.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-
-/*
- * Interrupt statistics:
- */
+#include <asm/io_apic.h>
 
 atomic_t irq_err_count;
-
 #ifdef CONFIG_X86_IO_APIC
 #ifdef APIC_MISMATCH_DEBUG
 atomic_t irq_mis_count;
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ldt.c Tue Jan 24 16:54:34 2006
@@ -62,6 +62,7 @@
        if (reload) {
 #ifdef CONFIG_SMP
                cpumask_t mask;
+
                preempt_disable();
 #endif
                make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
@@ -201,6 +202,7 @@
        struct user_desc ldt_info;
 
        error = -EINVAL;
+
        if (bytecount != sizeof(ldt_info))
                goto out;
        error = -EFAULT;        
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c       Tue Jan 24 
16:54:34 2006
@@ -62,6 +62,7 @@
 #include <asm-xen/xen-public/physdev.h>
 #include "setup_arch_pre.h"
 #include <asm/hypervisor.h>
+#include <asm-xen/xen-public/nmi.h>
 #define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 #define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
 #define end_pfn_map end_pfn
@@ -304,7 +305,6 @@
 }
 #endif
 
-
 static __init void parse_cmdline_early (char ** cmdline_p)
 {
        char c = ' ', *to = command_line, *from = COMMAND_LINE;
@@ -379,6 +379,7 @@
                        acpi_skip_timer_override = 1;
 #endif
 #endif
+
 #ifndef CONFIG_XEN
                if (!memcmp(from, "nolapic", 7) ||
                    !memcmp(from, "disableapic", 11))
@@ -391,7 +392,8 @@
                        skip_ioapic_setup = 0;
                        ioapic_force = 1;
                }
-#endif                 
+#endif
+                       
                if (!memcmp(from, "mem=", 4))
                        parse_memopt(from+4, &from); 
 
@@ -588,7 +590,7 @@
        HYPERVISOR_vm_assist(VMASST_CMD_enable,
                             VMASST_TYPE_writable_pagetables);
 
-        ARCH_SETUP
+       ARCH_SETUP
 #else
        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
        drive_info = DRIVE_INFO;
@@ -612,7 +614,7 @@
        init_mm.end_code = (unsigned long) &_etext;
        init_mm.end_data = (unsigned long) &_edata;
 #ifdef CONFIG_XEN
-        init_mm.brk = start_pfn << PAGE_SHIFT;
+       init_mm.brk = start_pfn << PAGE_SHIFT;
 #else
        init_mm.brk = (unsigned long) &_end;    
 
@@ -667,7 +669,6 @@
        /* reserve ebda region */
        reserve_ebda_region();
 #endif
-
 
 #ifdef CONFIG_SMP
        /*
@@ -790,8 +791,6 @@
 
        }
 
-
-
        if ( ! (xen_start_info->flags & SIF_INITDOMAIN))
        {
                acpi_disabled = 1;
@@ -835,7 +834,7 @@
         * and also for regions reported as reserved by the e820.
         */
        probe_roms();
-       e820_reserve_resources();
+       e820_reserve_resources(); 
 #endif
 
        request_resource(&iomem_resource, &video_ram_resource);
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c     Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c     Tue Jan 24 
16:54:34 2006
@@ -33,6 +33,7 @@
 #ifdef CONFIG_XEN
 #include <asm/hypervisor.h>
 #endif
+
 char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
 
 cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
@@ -165,7 +166,6 @@
 }
 #endif
 
-
 void pda_init(int cpu)
 { 
        struct x8664_pda *pda = &cpu_pda[cpu];
@@ -175,9 +175,10 @@
 #ifndef CONFIG_XEN
        wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
 #else
-        HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL, 
-                                    (unsigned long)(cpu_pda + cpu));
-#endif
+       HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL, 
+                                   (unsigned long)(cpu_pda + cpu));
+#endif
+
        pda->me = pda;
        pda->cpunumber = cpu; 
        pda->irqcount = -1;
@@ -201,6 +202,7 @@
        }
 
        switch_pt();
+
        pda->irqstackptr += IRQSTACKSIZE-64;
 } 
 
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smp.c Tue Jan 24 16:54:34 2006
@@ -30,8 +30,9 @@
 #include <asm/apicdef.h>
 #ifdef CONFIG_XEN
 #include <asm-xen/evtchn.h>
-
-#else
+#endif
+
+#ifndef CONFIG_XEN
 /*
  *     Smarter SMP flushing macros. 
  *             c/o Linus Torvalds.
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c       Tue Jan 24 
16:54:34 2006
@@ -559,9 +559,11 @@
        printk("Uhhuh. NMI received. Dazed and confused, but trying to 
continue\n");
        printk("You probably have a hardware problem with your RAM chips\n");
 
+#if 0 /* XEN */
        /* Clear and disable the memory parity error line. */
        reason = (reason & 0xf) | 4;
        outb(reason, 0x61);
+#endif /* XEN */
 }
 
 static void io_check_error(unsigned char reason, struct pt_regs * regs)
@@ -569,12 +571,14 @@
        printk("NMI: IOCK error (debug interrupt?)\n");
        show_registers(regs);
 
+#if 0 /* XEN */
        /* Re-enable the IOCK line, wait for a few seconds */
        reason = (reason & 0xf) | 8;
        outb(reason, 0x61);
        mdelay(2000);
        reason &= ~8;
        outb(reason, 0x61);
+#endif /* XEN */
 }
 
 static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
@@ -890,7 +894,6 @@
 asmlinkage void math_state_restore(void)
 {
        struct task_struct *me = current;
-        
         /* clts(); */ /* 'clts' is done for us by Xen during virtual trap. */
 
        if (!used_math())
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c   Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c   Tue Jan 24 16:54:34 2006
@@ -153,7 +153,6 @@
        pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
        preempt_enable();
        pgd += pgd_index(address);
-
        printk("PGD %lx ", pgd_val(*pgd));
        if (bad_address(pgd)) goto bad;
        if (!pgd_present(*pgd)) goto ret; 
@@ -258,7 +257,6 @@
        pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
        preempt_enable();
        pgd += pgd_index(address);
-
        pgd_ref = pgd_offset_k(address);
        if (pgd_none(*pgd_ref))
                return -1;
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c    Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c    Tue Jan 24 16:54:34 2006
@@ -40,14 +40,14 @@
 #include <asm/proto.h>
 #include <asm/smp.h>
 
+#ifndef Dprintk
+#define Dprintk(x...)
+#endif
+
 extern unsigned long *contiguous_bitmap;
 
 #if defined(CONFIG_SWIOTLB)
 extern void swiotlb_init(void);
-#endif
-
-#ifndef Dprintk
-#define Dprintk(x...)
 #endif
 
 extern char _stext[];
@@ -200,9 +200,9 @@
 
 static inline pud_t *pud_offset_u(unsigned long address)
 {
-        pud_t *pud = level3_user_pgt;
-
-        return pud + pud_index(address);
+       pud_t *pud = level3_user_pgt;
+
+       return pud + pud_index(address);
 }
 
 static void set_pte_phys(unsigned long vaddr,
@@ -215,34 +215,27 @@
 
        Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
 
-        pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
-
+       pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
        if (pgd_none(*pgd)) {
                printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
                return;
        }
-        
-        pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
-
+       pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
        if (pud_none(*pud)) {
                pmd = (pmd_t *) spp_getpage(); 
-
-                make_page_readonly(pmd);
-                xen_pmd_pin(__pa(pmd));
+               make_page_readonly(pmd);
+               xen_pmd_pin(__pa(pmd));
                set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
                if (pmd != pmd_offset(pud, 0)) {
                        printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, 
pmd_offset(pud,0));
                        return;
                }
        }
-
        pmd = pmd_offset(pud, vaddr);
-
        if (pmd_none(*pmd)) {
                pte = (pte_t *) spp_getpage();
-                make_page_readonly(pte);
-
-                xen_pte_pin(__pa(pte));
+               make_page_readonly(pte);
+               xen_pte_pin(__pa(pte));
                set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
                if (pte != pte_offset_kernel(pmd, 0)) {
                        printk("PAGETABLE BUG #02!\n");
@@ -252,11 +245,10 @@
        new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
 
        pte = pte_offset_kernel(pmd, vaddr);
-
        if (!pte_none(*pte) &&
            pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
                pte_ERROR(*pte);
-        set_pte(pte, new_pte);
+       set_pte(pte, new_pte);
 
        /*
         * It's enough to flush this one mapping.
@@ -284,11 +276,11 @@
        if (pud_none(*pud)) {
 
                pmd = (pmd_t *) spp_getpage(); 
-                make_page_readonly(pmd);
-                xen_pmd_pin(__pa(pmd));
+               make_page_readonly(pmd);
+               xen_pmd_pin(__pa(pmd));
 
                set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
-         
+
                if (pmd != pmd_offset(pud, 0)) {
                        printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, 
pmd_offset(pud,0));
                        return;
@@ -298,8 +290,8 @@
 
        if (pmd_none(*pmd)) {
                pte = (pte_t *) spp_getpage();
-                make_page_readonly(pte);  
-                xen_pte_pin(__pa(pte));
+               make_page_readonly(pte);  
+               xen_pte_pin(__pa(pte));
 
                set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
                if (pte != pte_offset_kernel(pmd, 0)) {
@@ -311,12 +303,12 @@
        new_pte = pfn_pte_ma(phys >> PAGE_SHIFT, prot);
        pte = pte_offset_kernel(pmd, vaddr);
 
-        /* 
-         * Note that the pte page is already RO, thus we want to use
-         * xen_l1_entry_update(), not set_pte().
-         */
-        xen_l1_entry_update(pte, 
-                            pfn_pte_ma(phys >> PAGE_SHIFT, prot));
+       /* 
+        * Note that the pte page is already RO, thus we want to use
+        * xen_l1_entry_update(), not set_pte().
+        */
+       xen_l1_entry_update(pte, 
+                           pfn_pte_ma(phys >> PAGE_SHIFT, prot));
 
        /*
         * It's enough to flush this one mapping.
@@ -347,7 +339,6 @@
        }
 }
 
-
 /*
  * At this point it only supports vsyscall area.
  */
@@ -360,18 +351,18 @@
                return;
        }
 
-        set_pte_phys(address, phys, prot, SET_FIXMAP_USER); 
+       set_pte_phys(address, phys, prot, SET_FIXMAP_USER); 
 }
 
 unsigned long __initdata table_start, tables_space; 
 
 unsigned long get_machine_pfn(unsigned long addr)
 {
-        pud_t* pud = pud_offset_k(addr);
-        pmd_t* pmd = pmd_offset(pud, addr);
-        pte_t *pte = pte_offset_kernel(pmd, addr);
-        
-        return pte_mfn(*pte);
+       pud_t* pud = pud_offset_k(addr);
+       pmd_t* pmd = pmd_offset(pud, addr);
+       pte_t *pte = pte_offset_kernel(pmd, addr);
+
+       return pte_mfn(*pte);
 } 
 
 static __init void *alloc_static_page(unsigned long *phys)
@@ -411,12 +402,11 @@
 
 static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned 
long end)
 { 
-        long i, j, k; 
-        unsigned long paddr;
+       long i, j, k; 
+       unsigned long paddr;
 
        i = pud_index(address);
        pud = pud + i;
-
        for (; i < PTRS_PER_PUD; pud++, i++) {
                unsigned long pmd_phys;
                pmd_t *pmd;
@@ -429,38 +419,37 @@
                } 
 
                pmd = alloc_static_page(&pmd_phys);
-                early_make_page_readonly(pmd);
-                xen_pmd_pin(pmd_phys);
+               early_make_page_readonly(pmd);
+               xen_pmd_pin(pmd_phys);
                set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
-
                for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
-                        unsigned long pte_phys;
-                        pte_t *pte, *pte_save;
+                       unsigned long pte_phys;
+                       pte_t *pte, *pte_save;
 
                        if (paddr >= end) { 
                                for (; j < PTRS_PER_PMD; j++, pmd++)
                                        set_pmd(pmd,  __pmd(0)); 
                                break;
                        }
-                        pte = alloc_static_page(&pte_phys);
-                        pte_save = pte;
-                        for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += 
PTE_SIZE) {
-                                if ((paddr >= end) ||
-                                    ((paddr >> PAGE_SHIFT) >=
-                                     xen_start_info->nr_pages)) { 
-                                        __set_pte(pte, __pte(0)); 
-                                        continue;
-                                }
-                                if (make_readonly(paddr)) {
-                                        __set_pte(pte, 
-                                                __pte(paddr | (_KERNPG_TABLE & 
~_PAGE_RW)));
-                                        continue;
-                                }
-                                __set_pte(pte, __pte(paddr | _KERNPG_TABLE));
-                        }
-                        pte = pte_save;
-                        early_make_page_readonly(pte);  
-                        xen_pte_pin(pte_phys);
+                       pte = alloc_static_page(&pte_phys);
+                       pte_save = pte;
+                       for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += 
PTE_SIZE) {
+                               if ((paddr >= end) ||
+                                   ((paddr >> PAGE_SHIFT) >=
+                                    xen_start_info->nr_pages)) { 
+                                       __set_pte(pte, __pte(0)); 
+                                       continue;
+                               }
+                               if (make_readonly(paddr)) {
+                                       __set_pte(pte, 
+                                               __pte(paddr | (_KERNPG_TABLE & 
~_PAGE_RW)));
+                                       continue;
+                               }
+                               __set_pte(pte, __pte(paddr | _KERNPG_TABLE));
+                       }
+                       pte = pte_save;
+                       early_make_page_readonly(pte);  
+                       xen_pte_pin(pte_phys);
                        set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE));
                }
        }
@@ -506,7 +495,7 @@
        level3_kernel_pgt[pud_index(__START_KERNEL_map)] = 
                __pud(__pa_symbol(level2_kernel_pgt) |
                      _KERNPG_TABLE | _PAGE_USER);
-        memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
+       memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
 
        early_make_page_readonly(init_level4_pgt);
        early_make_page_readonly(init_level4_user_pgt);
@@ -618,7 +607,7 @@
 
 void zap_low_mappings(void)
 {
-        /* this is not required for Xen */
+       /* this is not required for Xen */
 #if 0
        swap_low_mappings();
 #endif
@@ -629,11 +618,11 @@
 {
        {
                unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-                /*     unsigned int max_dma; */
-                /* max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> 
PAGE_SHIFT; */
-                /* if (end_pfn < max_dma) */
+               /*      unsigned int max_dma; */
+               /* max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> 
PAGE_SHIFT; */
+               /* if (end_pfn < max_dma) */
                        zones_size[ZONE_DMA] = end_pfn;
-#if 0                
+#if 0
                else {
                        zones_size[ZONE_DMA] = max_dma;
                        zones_size[ZONE_NORMAL] = end_pfn - max_dma;
@@ -642,16 +631,16 @@
                free_area_init(zones_size);
        }
 
-        set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
-        HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
-
-        memset(empty_zero_page, 0, sizeof(empty_zero_page));
+       set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
+       HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+
+       memset(empty_zero_page, 0, sizeof(empty_zero_page));
        init_mm.context.pinned = 1;
 
 #ifdef CONFIG_XEN_PHYSDEV_ACCESS
        {
                int i;
-        /* Setup mapping of lower 1st MB */
+               /* Setup mapping of lower 1st MB */
                for (i = 0; i < NR_FIX_ISAMAPS; i++)
                        if (xen_start_info->flags & SIF_PRIVILEGED)
                                set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
@@ -701,7 +690,7 @@
 
 static inline int page_is_ram (unsigned long pagenr)
 {
-        return 1;
+       return 1;
 }
 
 static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
@@ -790,10 +779,10 @@
 void free_initmem(void)
 {
 #ifdef __DO_LATER__
-        /*
-         * Some pages can be pinned, but some are not. Unpinning such pages 
-         * triggers BUG(). 
-         */
+       /*
+        * Some pages can be pinned, but some are not. Unpinning such pages 
+        * triggers BUG(). 
+        */
        unsigned long addr;
 
        addr = (unsigned long)(&__init_begin);
@@ -801,12 +790,12 @@
                ClearPageReserved(virt_to_page(addr));
                set_page_count(virt_to_page(addr), 1);
                memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); 
-                xen_pte_unpin(__pa(addr));
-                make_page_writable(__va(__pa(addr)));
-                /*
-                 * Make pages from __PAGE_OFFSET address as well
-                 */
-                make_page_writable((void *)addr);
+               xen_pte_unpin(__pa(addr));
+               make_page_writable(__va(__pa(addr)));
+               /*
+                * Make pages from __PAGE_OFFSET address as well
+                */
+               make_page_writable((void *)addr);
                free_page(addr);
                totalram_pages++;
        }
@@ -856,7 +845,7 @@
        if (pgd_none(*pgd))
                return 0;
 
-        pud = pud_offset_k(addr);
+       pud = pud_offset_k(addr);
        if (pud_none(*pud))
                return 0; 
 
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Tue Jan 24 
16:54:34 2006
@@ -544,7 +544,7 @@
                kfree(pending_grant_handles);
                kfree(pending_vaddrs);
                printk("%s: out of memory\n", __FUNCTION__);
-               return -1;
+               return -ENOMEM;
        }
 
        blkif_interface_init();
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Jan 24 16:54:34 2006
@@ -19,16 +19,8 @@
 #include <asm-xen/gnttab.h>
 #include <asm-xen/driver_util.h>
 
-#if 0
-#define ASSERT(_p) \
-    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
-    __LINE__, __FILE__); *(int*)0=0; }
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
-                           __FILE__ , __LINE__ , ## _a )
-#else
-#define ASSERT(_p) ((void)0)
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
+                                    __FILE__ , __LINE__ , ## _a )
 
 struct vbd {
        blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Tue Jan 24 16:54:34 2006
@@ -11,7 +11,6 @@
 
 #define vbd_sz(_v)   ((_v)->bdev->bd_part ?                            \
        (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
-#define bdev_put(_b) blkdev_put(_b)
 
 unsigned long vbd_size(struct vbd *vbd)
 {
@@ -69,7 +68,7 @@
 void vbd_free(struct vbd *vbd)
 {
        if (vbd->bdev)
-               bdev_put(vbd->bdev);
+               blkdev_put(vbd->bdev);
        vbd->bdev = NULL;
 }
 
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Jan 24 16:54:34 2006
@@ -24,12 +24,9 @@
 #include <asm-xen/xenbus.h>
 #include "common.h"
 
-
-#if 0
 #undef DPRINTK
 #define DPRINTK(fmt, args...) \
-    printk("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#endif
+    pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, 
##args)
 
 
 struct backend_info
@@ -302,7 +299,7 @@
  */
 static void connect(struct backend_info *be)
 {
-       struct xenbus_transaction *xbt;
+       xenbus_transaction_t xbt;
        int err;
        struct xenbus_device *dev = be->dev;
 
@@ -310,10 +307,9 @@
 
        /* Supply the information about the device the frontend needs */
 again:
-       xbt = xenbus_transaction_start();
-
-       if (IS_ERR(xbt)) {
-               err = PTR_ERR(xbt);
+       err = xenbus_transaction_start(&xbt);
+
+       if (err) {
                xenbus_dev_fatal(dev, err, "starting transaction");
                return;
        }
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Jan 24 
16:54:34 2006
@@ -35,14 +35,6 @@
  * IN THE SOFTWARE.
  */
 
-#if 1
-#define ASSERT(p)                                                         \
-       if (!(p)) { printk("Assertion '%s' failed, line %d, file %s", #p , \
-       __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p)
-#endif
-
 #include <linux/version.h>
 #include "block.h"
 #include <linux/cdrom.h>
@@ -161,7 +153,7 @@
                           struct blkfront_info *info)
 {
        const char *message = NULL;
-       struct xenbus_transaction *xbt;
+       xenbus_transaction_t xbt;
        int err;
 
        /* Create shared ring, alloc event channel. */
@@ -170,8 +162,8 @@
                goto out;
 
 again:
-       xbt = xenbus_transaction_start();
-       if (IS_ERR(xbt)) {
+       err = xenbus_transaction_start(&xbt);
+       if (err) {
                xenbus_dev_fatal(dev, err, "starting transaction");
                goto destroy_blkring;
        }
@@ -551,7 +543,7 @@
                        lsect = fsect + (bvec->bv_len >> 9) - 1;
                        /* install a grant reference. */
                        ref = gnttab_claim_grant_reference(&gref_head);
-                       ASSERT(ref != -ENOSPC);
+                       BUG_ON(ref == -ENOSPC);
 
                        gnttab_grant_foreign_access_ref(
                                ref,
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue Jan 24 16:54:34 2006
@@ -69,11 +69,7 @@
 #define WPRINTK(fmt, args...) ((void)0)
 #endif
  
-#if 0
-#define DPRINTK(_f, _a...) printk ( KERN_ALERT _f , ## _a )
-#else
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug ( _f , ## _a )
 
 #if 0
 #define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h  Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h  Tue Jan 24 16:54:34 2006
@@ -19,16 +19,8 @@
 #include <asm-xen/gnttab.h>
 #include <asm-xen/driver_util.h>
 
-#if 0
-#define ASSERT(_p) \
-    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
-    __LINE__, __FILE__); *(int*)0=0; }
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
-                           __FILE__ , __LINE__ , ## _a )
-#else
-#define ASSERT(_p) ((void)0)
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
+                                    __FILE__ , __LINE__ , ## _a )
 
 #define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
 
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Tue Jan 24 16:54:34 2006
@@ -22,16 +22,8 @@
 #include <asm-xen/gnttab.h>
 #include <asm-xen/driver_util.h>
 
-#if 0
-#define ASSERT(_p) \
-    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
-    __LINE__, __FILE__); *(int*)0=0; }
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
-                           __FILE__ , __LINE__ , ## _a )
-#else
-#define ASSERT(_p) ((void)0)
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
+                                    __FILE__ , __LINE__ , ## _a )
 #define IPRINTK(fmt, args...) \
     printk(KERN_INFO "xen_net: " fmt, ##args)
 #define WPRINTK(fmt, args...) \
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Tue Jan 24 
16:54:34 2006
@@ -27,6 +27,7 @@
 #include <linux/inetdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/ethtool.h>
 #include <net/dst.h>
 
 static int nloopbacks = 8;
@@ -122,6 +123,12 @@
        /*dev->mtu             = 16*1024;*/
 }
 
+static struct ethtool_ops network_ethtool_ops =
+{
+       .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = ethtool_op_set_tx_csum,
+};
+
 static int __init make_loopback(int i)
 {
        struct net_device *dev1, *dev2;
@@ -140,6 +147,8 @@
 
        dev1->features |= NETIF_F_NO_CSUM;
        dev2->features |= NETIF_F_IP_CSUM;
+
+       SET_ETHTOOL_OPS(dev2, &network_ethtool_ops);
 
        /*
         * Initialise a dummy MAC address for the 'dummy backend' interface. We
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Tue Jan 24 
16:54:34 2006
@@ -120,7 +120,7 @@
 {
        netif_t *netif = netdev_priv(dev);
 
-       ASSERT(skb->dev == dev);
+       BUG_ON(skb->dev != dev);
 
        /* Drop the packet if the target domain has no receive buffers. */
        if (!netif->active || 
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Jan 24 
16:54:34 2006
@@ -154,13 +154,8 @@
 };
 #endif
 
-#ifdef DEBUG
-#define DPRINTK(fmt, args...)                                          \
-       printk(KERN_ALERT "netfront (%s:%d) " fmt, __FUNCTION__,        \
-              __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
+#define DPRINTK(fmt, args...) pr_debug("netfront (%s:%d) " fmt, \
+                                       __FUNCTION__, __LINE__, ##args)
 #define IPRINTK(fmt, args...)                          \
        printk(KERN_INFO "netfront: " fmt, ##args)
 #define WPRINTK(fmt, args...)                          \
@@ -260,7 +255,7 @@
                           struct netfront_info *info)
 {
        const char *message;
-       struct xenbus_transaction *xbt;
+       xenbus_transaction_t xbt;
        int err;
 
        err = xen_net_read_mac(dev, info->mac);
@@ -275,8 +270,8 @@
                goto out;
 
 again:
-       xbt = xenbus_transaction_start();
-       if (IS_ERR(xbt)) {
+       err = xenbus_transaction_start(&xbt);
+       if (err) {
                xenbus_dev_fatal(dev, err, "starting transaction");
                goto destroy_ring;
        }
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Tue Jan 24 16:54:34 2006
@@ -17,16 +17,8 @@
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
-#if 0
-#define ASSERT(_p) \
-    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
-    __LINE__, __FILE__); *(int*)0=0; }
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
-                           __FILE__ , __LINE__ , ## _a )
-#else
-#define ASSERT(_p) ((void)0)
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
+#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
+                                    __FILE__ , __LINE__ , ## _a )
 
 typedef struct tpmif_st {
        struct list_head tpmif_list;
@@ -84,11 +76,6 @@
 
 #define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE))
 
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
 #endif /* __TPMIF__BACKEND__COMMON_H__ */
 
 /*
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Jan 24 16:54:34 2006
@@ -78,7 +78,7 @@
 
        memset(be, 0, sizeof(*be));
 
-       be->is_instance_set = FALSE;
+       be->is_instance_set = 0;
        be->dev = dev;
        dev->data = be;
 
@@ -89,7 +89,7 @@
                goto fail;
        }
 
-       err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
+       err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
        if (err) {
                goto fail;
        }
@@ -109,7 +109,7 @@
                = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
 
-       err = xenbus_scanf(NULL, dev->nodename,
+       err = xenbus_scanf(XBT_NULL, dev->nodename,
                           "instance","%li", &instance);
        if (XENBUS_EXIST_ERR(err)) {
                return;
@@ -120,7 +120,7 @@
                return;
        }
 
-       if (be->is_instance_set != FALSE && be->instance != instance) {
+       if (be->is_instance_set != 0 && be->instance != instance) {
                printk(KERN_WARNING
                       "tpmback: changing instance (from %ld to %ld) "
                       "not allowed.\n",
@@ -128,7 +128,7 @@
                return;
        }
 
-       if (be->is_instance_set == FALSE) {
+       if (be->is_instance_set == 0) {
                be->tpmif = tpmif_find(dev->otherend_id,
                                       instance);
                if (IS_ERR(be->tpmif)) {
@@ -138,7 +138,7 @@
                        return;
                }
                be->instance = instance;
-               be->is_instance_set = TRUE;
+               be->is_instance_set = 1;
 
                /*
                 * There's an unfortunate problem:
@@ -177,7 +177,7 @@
                break;
 
        case XenbusStateClosing:
-               xenbus_switch_state(dev, NULL, XenbusStateClosing);
+               xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
                break;
 
        case XenbusStateClosed:
@@ -230,15 +230,14 @@
 
 static void connect(struct backend_info *be)
 {
-       struct xenbus_transaction *xbt;
+       xenbus_transaction_t xbt;
        int err;
        struct xenbus_device *dev = be->dev;
        unsigned long ready = 1;
 
 again:
-       xbt = xenbus_transaction_start();
-       if (IS_ERR(xbt)) {
-               err = PTR_ERR(xbt);
+       err = xenbus_transaction_start(&xbt);
+       if (err) {
                xenbus_dev_fatal(be->dev, err, "starting transaction");
                return;
        }
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Tue Jan 24 
16:54:34 2006
@@ -54,14 +54,6 @@
 
 #undef DEBUG
 
-#if 1
-#define ASSERT(_p) \
-    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
-        __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p)
-#endif
-
 /* locally visible variables */
 static grant_ref_t gref_head;
 static struct tpm_private my_private;
@@ -80,12 +72,8 @@
                     const u8 * buf, size_t count, int userbuffer,
                     void *remember);
 
-#if DEBUG
 #define DPRINTK(fmt, args...) \
-    printk(KERN_ALERT "xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, 
##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
+    pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
 #define IPRINTK(fmt, args...) \
     printk(KERN_INFO "xen_tpm_fr: " fmt, ##args)
 #define WPRINTK(fmt, args...) \
@@ -102,11 +90,8 @@
                copied = txb->size;
        }
        if (isuserbuffer) {
-               if (copy_from_user(txb->data,
-                                  src,
-                                  copied)) {
+               if (copy_from_user(txb->data, src, copied))
                        return -EFAULT;
-               }
        } else {
                memcpy(txb->data, src, copied);
        }
@@ -196,15 +181,12 @@
 static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
                                   const void *ptr)
 {
-       int rc;
+       int rc = 0;
 
        down(&upperlayer_lock);
 
-       if (upperlayer_tpmfe && upperlayer_tpmfe->receive) {
+       if (upperlayer_tpmfe && upperlayer_tpmfe->receive)
                rc = upperlayer_tpmfe->receive(buf, count, ptr);
-       } else {
-               rc = 0;
-       }
 
        up(&upperlayer_lock);
        return rc;
@@ -253,8 +235,8 @@
 
 static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
 {
-       tpmif_set_connected_state(tp, FALSE);
-       if ( tp->tx != NULL ) {
+       tpmif_set_connected_state(tp, 0);
+       if (tp->tx != NULL) {
                gnttab_end_foreign_access(info->ring_ref, 0,
                                          (unsigned long)tp->tx);
                tp->tx = NULL;
@@ -271,7 +253,7 @@
 {
        const char *message = NULL;
        int err;
-       struct xenbus_transaction *xbt;
+       xenbus_transaction_t xbt;
 
        err = setup_tpmring(dev, info);
        if (err) {
@@ -280,8 +262,8 @@
        }
 
 again:
-       xbt = xenbus_transaction_start();
-       if (IS_ERR(xbt)) {
+       err = xenbus_transaction_start(&xbt);
+       if (err) {
                xenbus_dev_fatal(dev, err, "starting transaction");
                goto destroy_tpmring;
        }
@@ -341,15 +323,15 @@
                break;
 
        case XenbusStateConnected:
-               tpmif_set_connected_state(tp, TRUE);
+               tpmif_set_connected_state(tp, 1);
                break;
 
        case XenbusStateClosing:
-               tpmif_set_connected_state(tp, FALSE);
+               tpmif_set_connected_state(tp, 0);
                break;
 
        case XenbusStateClosed:
-               if (tp->is_suspended == FALSE) {
+               if (tp->is_suspended == 0) {
                        device_unregister(&dev->dev);
                }
                break;
@@ -364,7 +346,7 @@
        struct tpmfront_info *info;
        int handle;
 
-       err = xenbus_scanf(NULL, dev->nodename,
+       err = xenbus_scanf(XBT_NULL, dev->nodename,
                           "handle", "%i", &handle);
        if (XENBUS_EXIST_ERR(err))
                return err;
@@ -409,20 +391,19 @@
 tpmfront_suspend(struct xenbus_device *dev)
 {
        struct tpm_private *tp = &my_private;
-       u32 ctr = 0;
+       u32 ctr;
 
        /* lock, so no app can send */
        down(&suspend_lock);
-       tp->is_suspended = TRUE;
-
-       while (atomic_read(&tp->tx_busy) && ctr <= 25) {
+       tp->is_suspended = 1;
+
+       for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 25; ctr++) {
                if ((ctr % 10) == 0)
                        printk("TPM-FE [INFO]: Waiting for outstanding 
request.\n");
                /*
                 * Wait for a request to be responded to.
                 */
                interruptible_sleep_on_timeout(&tp->wait_q, 100);
-               ctr++;
        }
 
        if (atomic_read(&tp->tx_busy)) {
@@ -440,16 +421,13 @@
 tpmfront_resume(struct xenbus_device *dev)
 {
        struct tpmfront_info *info = dev->data;
-       int err = talk_to_backend(dev, info);
-
-
-       return err;
+       return talk_to_backend(dev, info);
 }
 
 static void
 tpmif_connect(u16 evtchn, domid_t domid)
 {
-       int err = 0;
+       int err;
        struct tpm_private *tp = &my_private;
 
        tp->evtchn = evtchn;
@@ -493,12 +471,8 @@
 {
        unsigned int i;
 
-       i = 0;
-       while (i < TPMIF_TX_RING_SIZE) {
+       for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
                tp->tx_buffers[i] = tx_buffer_alloc();
-               i++;
-       }
-
        return 1;
 }
 
@@ -521,9 +495,7 @@
                goto exit;
        }
 
-       i = 0;
-       while (i < TPMIF_TX_RING_SIZE &&
-              offset < received) {
+       for (i = 0; i < TPMIF_TX_RING_SIZE && offset < received; i++) {
                struct tx_buffer *txb = tp->tx_buffers[i];
                tpmif_tx_request_t *tx;
                unsigned int tocopy;
@@ -539,7 +511,6 @@
                gnttab_release_grant_reference(&gref_head, tx->ref);
 
                offset += tocopy;
-               i++;
        }
 
        tpm_fe_send_upperlayer(buffer, received, tp->tx_remember);
@@ -583,19 +554,18 @@
                return -EBUSY;
        }
 
-       if (tp->is_connected != TRUE) {
+       if (tp->is_connected != 1) {
                spin_unlock_irq(&tp->tx_lock);
                return -EIO;
        }
 
-       i = 0;
-       while (count > 0 && i < TPMIF_TX_RING_SIZE) {
+       for (i = 0; count > 0 && i < TPMIF_TX_RING_SIZE; i++) {
                struct tx_buffer *txb = tp->tx_buffers[i];
                int copied;
 
                if (NULL == txb) {
-                       DPRINTK("txb (i=%d) is NULL. buffers initilized?\n", i);
-                       DPRINTK("Not transmitting anything!\n");
+                       DPRINTK("txb (i=%d) is NULL. buffers initilized?\n"
+                               "Not transmitting anything!\n", i);
                        spin_unlock_irq(&tp->tx_lock);
                        return -EFAULT;
                }
@@ -603,6 +573,7 @@
                                        isuserbuffer);
                if (copied < 0) {
                        /* An error occurred */
+                       spin_unlock_irq(&tp->tx_lock);
                        return copied;
                }
                count -= copied;
@@ -618,9 +589,10 @@
                        txb->data[0],txb->data[1],txb->data[2],txb->data[3]);
 
                /* get the granttable reference for this page */
-               tx->ref = gnttab_claim_grant_reference( &gref_head );
-
-               if(-ENOSPC == tx->ref ) {
+               tx->ref = gnttab_claim_grant_reference(&gref_head);
+
+               if (-ENOSPC == tx->ref) {
+                       spin_unlock_irq(&tp->tx_lock);
                        DPRINTK(" Grant table claim reference failed in func:%s 
line:%d file:%s\n", __FUNCTION__, __LINE__, __FILE__);
                        return -ENOSPC;
                }
@@ -628,7 +600,6 @@
                                                 tp->backend_id,
                                                 (tx->addr >> PAGE_SHIFT),
                                                 0 /*RW*/);
-               i++;
                wmb();
        }
 
@@ -672,7 +643,7 @@
         * should disconnect - assumption is that we will resume
         * The semaphore keeps apps from sending.
         */
-       if (is_connected == FALSE && tp->is_suspended == TRUE) {
+       if (is_connected == 0 && tp->is_suspended == 1) {
                return;
        }
 
@@ -681,8 +652,8 @@
         * after being suspended - now resuming.
         * This also removes the suspend state.
         */
-       if (is_connected == TRUE && tp->is_suspended == TRUE) {
-               tp->is_suspended = FALSE;
+       if (is_connected == 1 && tp->is_suspended == 1) {
+               tp->is_suspended = 0;
                /* unlock, so apps can resume sending */
                up(&suspend_lock);
        }
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h      Tue Jan 24 
16:54:34 2006
@@ -1,10 +1,5 @@
 #ifndef TPM_FRONT_H
 #define TPM_FRONT_H
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
 
 struct tpm_private {
        tpmif_tx_interface_t *tx;
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c   Tue Jan 24 
16:54:34 2006
@@ -34,13 +34,8 @@
 /* xenbus_probe.c */
 extern char *kasprintf(const char *fmt, ...);
 
-#if 0
 #define DPRINTK(fmt, args...) \
-    printk("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
-
+    pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, 
##args)
 
 int xenbus_watch_path(struct xenbus_device *dev, const char *path,
                      struct xenbus_watch *watch, 
@@ -87,7 +82,7 @@
 
 
 int xenbus_switch_state(struct xenbus_device *dev,
-                       struct xenbus_transaction *xbt,
+                       xenbus_transaction_t xbt,
                        XenbusState state)
 {
        /* We check whether the state is currently set to the given value, and
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Tue Jan 24 
16:54:34 2006
@@ -47,7 +47,7 @@
 
 struct xenbus_dev_transaction {
        struct list_head list;
-       struct xenbus_transaction *handle;
+       xenbus_transaction_t handle;
 };
 
 struct xenbus_dev_data {
@@ -147,13 +147,11 @@
                }
 
                if (u->u.msg.type == XS_TRANSACTION_START) {
-                       trans->handle = (struct xenbus_transaction *)
-                               simple_strtoul(reply, NULL, 0);
+                       trans->handle = simple_strtoul(reply, NULL, 0);
                        list_add(&trans->list, &u->transactions);
                } else if (u->u.msg.type == XS_TRANSACTION_END) {
                        list_for_each_entry(trans, &u->transactions, list)
-                               if ((unsigned long)trans->handle ==
-                                   (unsigned long)u->u.msg.tx_id)
+                               if (trans->handle == u->u.msg.tx_id)
                                        break;
                        BUG_ON(&trans->list == &u->transactions);
                        list_del(&trans->list);
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Jan 24 
16:54:34 2006
@@ -27,12 +27,8 @@
  * IN THE SOFTWARE.
  */
 
-#if 0
 #define DPRINTK(fmt, args...) \
-    printk("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
+    pr_debug("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
 
 #include <linux/kernel.h>
 #include <linux/err.h>
@@ -470,12 +466,17 @@
 
        DPRINTK("%s", info->nodename);
 
-       if (!strncmp(xendev->nodename, info->nodename, len)) {
-               info->dev = xendev;
-               get_device(dev);
-               return 1;
-       }
-       return 0;
+       /* Match the info->nodename path, or any subdirectory of that path. */
+       if (strncmp(xendev->nodename, info->nodename, len))
+               return 0;
+
+       /* If the node name is longer, ensure it really is a subdirectory. */
+       if ((strlen(xendev->nodename) > len) && (xendev->nodename[len] != '/'))
+               return 0;
+
+       info->dev = xendev;
+       get_device(dev);
+       return 1;
 }
 
 static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Tue Jan 24 
16:54:34 2006
@@ -190,7 +190,7 @@
 }
 
 /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
-static void *xs_talkv(struct xenbus_transaction *t,
+static void *xs_talkv(xenbus_transaction_t t,
                      enum xsd_sockmsg_type type,
                      const struct kvec *iovec,
                      unsigned int num_vecs,
@@ -201,7 +201,7 @@
        unsigned int i;
        int err;
 
-       msg.tx_id = (u32)(unsigned long)t;
+       msg.tx_id = t;
        msg.req_id = 0;
        msg.type = type;
        msg.len = 0;
@@ -242,7 +242,7 @@
 }
 
 /* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xenbus_transaction *t,
+static void *xs_single(xenbus_transaction_t t,
                       enum xsd_sockmsg_type type,
                       const char *string,
                       unsigned int *len)
@@ -309,7 +309,7 @@
        return ret;
 }
 
-char **xenbus_directory(struct xenbus_transaction *t,
+char **xenbus_directory(xenbus_transaction_t t,
                        const char *dir, const char *node, unsigned int *num)
 {
        char *strings, *path;
@@ -329,7 +329,7 @@
 EXPORT_SYMBOL(xenbus_directory);
 
 /* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(struct xenbus_transaction *t,
+int xenbus_exists(xenbus_transaction_t t,
                  const char *dir, const char *node)
 {
        char **d;
@@ -347,7 +347,7 @@
  * Returns a kmalloced value: call free() on it after use.
  * len indicates length in bytes.
  */
-void *xenbus_read(struct xenbus_transaction *t,
+void *xenbus_read(xenbus_transaction_t t,
                  const char *dir, const char *node, unsigned int *len)
 {
        char *path;
@@ -366,7 +366,7 @@
 /* Write the value of a single file.
  * Returns -err on failure.
  */
-int xenbus_write(struct xenbus_transaction *t,
+int xenbus_write(xenbus_transaction_t t,
                 const char *dir, const char *node, const char *string)
 {
        const char *path;
@@ -389,7 +389,7 @@
 EXPORT_SYMBOL(xenbus_write);
 
 /* Create a new directory. */
-int xenbus_mkdir(struct xenbus_transaction *t,
+int xenbus_mkdir(xenbus_transaction_t t,
                 const char *dir, const char *node)
 {
        char *path;
@@ -406,7 +406,7 @@
 EXPORT_SYMBOL(xenbus_mkdir);
 
 /* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
+int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node)
 {
        char *path;
        int ret;
@@ -424,30 +424,28 @@
 /* Start a transaction: changes by others will not be seen during this
  * transaction, and changes will not be visible to others until end.
  */
-struct xenbus_transaction *xenbus_transaction_start(void)
+int xenbus_transaction_start(xenbus_transaction_t *t)
 {
        char *id_str;
-       unsigned long id;
 
        down_read(&xs_state.suspend_mutex);
 
        id_str = xs_single(XBT_NULL, XS_TRANSACTION_START, "", NULL);
        if (IS_ERR(id_str)) {
                up_read(&xs_state.suspend_mutex);
-               return (struct xenbus_transaction *)id_str;
-       }
-
-       id = simple_strtoul(id_str, NULL, 0);
+               return PTR_ERR(id_str);
+       }
+
+       *t = simple_strtoul(id_str, NULL, 0);
        kfree(id_str);
-
-       return (struct xenbus_transaction *)id;
+       return 0;
 }
 EXPORT_SYMBOL(xenbus_transaction_start);
 
 /* End a transaction.
  * If abandon is true, transaction is discarded instead of committed.
  */
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
+int xenbus_transaction_end(xenbus_transaction_t t, int abort)
 {
        char abortstr[2];
        int err;
@@ -466,7 +464,7 @@
 EXPORT_SYMBOL(xenbus_transaction_end);
 
 /* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(struct xenbus_transaction *t,
+int xenbus_scanf(xenbus_transaction_t t,
                 const char *dir, const char *node, const char *fmt, ...)
 {
        va_list ap;
@@ -489,7 +487,7 @@
 EXPORT_SYMBOL(xenbus_scanf);
 
 /* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
+int xenbus_printf(xenbus_transaction_t t,
                  const char *dir, const char *node, const char *fmt, ...)
 {
        va_list ap;
@@ -515,7 +513,7 @@
 EXPORT_SYMBOL(xenbus_printf);
 
 /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
+int xenbus_gather(xenbus_transaction_t t, const char *dir, ...)
 {
        va_list ap;
        const char *name;
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Jan 24 
16:54:34 2006
@@ -32,6 +32,7 @@
 
 #include <asm-xen/xen-public/xen.h>
 #include <asm-xen/xen-public/sched.h>
+#include <asm-xen/xen-public/nmi.h>
 
 #define _hypercall0(type, name)                        \
 ({                                             \
@@ -300,6 +301,14 @@
                           SHUTDOWN_suspend, srec);
 }
 
+static inline int
+HYPERVISOR_nmi_op(
+       unsigned long op,
+       unsigned long arg)
+{
+       return _hypercall2(int, nmi_op, op, arg);
+}
+
 #endif /* __HYPERCALL_H__ */
 
 /*
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h  
Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h  
Tue Jan 24 16:54:34 2006
@@ -29,6 +29,7 @@
 
 extern void hypervisor_callback(void);
 extern void failsafe_callback(void);
+extern void nmi(void);
 
 static void __init machine_specific_arch_setup(void)
 {
@@ -36,5 +37,7 @@
            __KERNEL_CS, (unsigned long)hypervisor_callback,
            __KERNEL_CS, (unsigned long)failsafe_callback);
 
+       HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
+
        machine_specific_modify_cpu_capabilities(&boot_cpu_data);
 }
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Tue Jan 
10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Tue Jan 
24 16:54:34 2006
@@ -287,9 +287,9 @@
 }
 
 static inline int
-HYPERVISOR_switch_to_user(void)
-{
-       return _hypercall0(int, switch_to_user);
+HYPERVISOR_iret(void)
+{
+       return _hypercall0(int, iret);
 }
 
 static inline int
@@ -305,6 +305,14 @@
 {
        return _hypercall3(int, sched_op, SCHEDOP_shutdown,
                           SHUTDOWN_suspend, srec);
+}
+
+static inline int
+HYPERVISOR_nmi_op(
+       unsigned long op,
+       unsigned long arg)
+{
+       return _hypercall2(int, nmi_op, op, arg);
 }
 
 #endif /* __HYPERCALL_H__ */
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_post.h
--- 
a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_post.h    
    Tue Jan 10 15:21:00 2006
+++ 
b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/setup_arch_post.h    
    Tue Jan 24 16:54:34 2006
@@ -35,6 +35,7 @@
 
 extern void hypervisor_callback(void);
 extern void failsafe_callback(void);
+extern void nmi(void);
 
 static void __init machine_specific_arch_setup(void)
 {
@@ -43,5 +44,9 @@
                 (unsigned long) failsafe_callback,
                 (unsigned long) system_call);
 
+#ifdef CONFIG_X86_LOCAL_APIC
+       HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
+#endif
+
        machine_specific_modify_cpu_capabilities(&boot_cpu_data);
 }
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h Tue Jan 10 
15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h Tue Jan 24 
16:54:34 2006
@@ -417,12 +417,7 @@
    Other CPUs get synced lazily via the page fault handler. */
 static inline pud_t *pud_offset_k(unsigned long address)
 {
-       unsigned long addr;
-
-       addr = pgd_val(init_level4_pgt[pud_index(address)]);
-       addr &= PHYSICAL_PAGE_MASK; /* machine physical */
-        addr = machine_to_phys(addr);
-       return __pud_offset_k((pud_t *)__va(addr), address);
+       return pud_offset(pgd_offset_k(address), address);
 }
 
 /* PMD  - Level 2 access */
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/include/asm-xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h     Tue Jan 24 16:54:34 2006
@@ -37,7 +37,7 @@
 #include <asm-xen/xen-public/io/xenbus.h>
 #include <asm-xen/xen-public/io/xs_wire.h>
 
-#define XBT_NULL NULL
+#define XBT_NULL 0
 
 /* Register callback to watch this node. */
 struct xenbus_watch
@@ -102,35 +102,35 @@
 int xenbus_register_backend(struct xenbus_driver *drv);
 void xenbus_unregister_driver(struct xenbus_driver *drv);
 
-struct xenbus_transaction;
-
-char **xenbus_directory(struct xenbus_transaction *t,
+typedef u32 xenbus_transaction_t;
+
+char **xenbus_directory(xenbus_transaction_t t,
                        const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(struct xenbus_transaction *t,
+void *xenbus_read(xenbus_transaction_t t,
                  const char *dir, const char *node, unsigned int *len);
-int xenbus_write(struct xenbus_transaction *t,
+int xenbus_write(xenbus_transaction_t t,
                 const char *dir, const char *node, const char *string);
-int xenbus_mkdir(struct xenbus_transaction *t,
+int xenbus_mkdir(xenbus_transaction_t t,
                 const char *dir, const char *node);
-int xenbus_exists(struct xenbus_transaction *t,
+int xenbus_exists(xenbus_transaction_t t,
                  const char *dir, const char *node);
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
-struct xenbus_transaction *xenbus_transaction_start(void);
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
+int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node);
+int xenbus_transaction_start(xenbus_transaction_t *t);
+int xenbus_transaction_end(xenbus_transaction_t t, int abort);
 
 /* Single read and scanf: returns -errno or num scanned if > 0. */
-int xenbus_scanf(struct xenbus_transaction *t,
+int xenbus_scanf(xenbus_transaction_t t,
                 const char *dir, const char *node, const char *fmt, ...)
        __attribute__((format(scanf, 4, 5)));
 
 /* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
+int xenbus_printf(xenbus_transaction_t t,
                  const char *dir, const char *node, const char *fmt, ...)
        __attribute__((format(printf, 4, 5)));
 
 /* Generic read function: NULL-terminated triples of name,
  * sprintf-style type string, and pointer. Returns 0 or errno.*/
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
+int xenbus_gather(xenbus_transaction_t t, const char *dir, ...);
 
 /* notifer routines for when the xenstore comes up */
 int register_xenstore_notifier(struct notifier_block *nb);
@@ -196,7 +196,7 @@
  * XenbusStateClosing, and the error will be saved in the store.
  */
 int xenbus_switch_state(struct xenbus_device *dev,
-                       struct xenbus_transaction *xbt,
+                       xenbus_transaction_t xbt,
                        XenbusState new_state);
 
 
diff -r 40bb46f599d9 -r a38c292e8390 tools/examples/xmexample.vti
--- a/tools/examples/xmexample.vti      Tue Jan 10 15:21:00 2006
+++ b/tools/examples/xmexample.vti      Tue Jan 24 16:54:34 2006
@@ -21,7 +21,7 @@
 memory = 256
 
 # A name for your domain. All domains must have different names.
-name = "ExampleVMXDomain"
+name = "ExampleVTIDomain"
 
 # List of which CPUS this domain is allowed to use, default Xen picks
 #cpus = ""         # leave to Xen to pick
@@ -30,7 +30,11 @@
 
 # Optionally define mac and/or bridge for the network interfaces.
 # Random MACs are assigned if not given.
-#vif = [ 'mac=00:16:3e:00:00:11, bridge=xen-br0' ]
+#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
+# type=ioemu specify the NIC is an ioemu device not netfront
+vif = [ 'type=ioemu, bridge=xenbr0' ]
+# for multiple NICs in device model, 3 in this example
+#vif = [ 'type=ioemu, bridge=xenbr0', 'type=ioemu', 'type=ioemu']
 
 #----------------------------------------------------------------------------
 # Define the disk devices you want the domain to have access to, and
@@ -53,7 +57,7 @@
 #============================================================================
 
 # New stuff
-device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm.debug'
+device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
 
 # Advanced users only. Don't touch if you don't know what you're doing
 memmap = '/usr/lib/xen/boot/mem-map.sxp'
diff -r 40bb46f599d9 -r a38c292e8390 tools/firmware/vmxassist/acpi_madt.c
--- a/tools/firmware/vmxassist/acpi_madt.c      Tue Jan 10 15:21:00 2006
+++ b/tools/firmware/vmxassist/acpi_madt.c      Tue Jan 24 16:54:34 2006
@@ -55,7 +55,6 @@
 get_hvm_info_table(void)
 {
        struct hvm_info_table *t;
-       int i;
 
        if (table != NULL)
                return table;
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/audio/audio.c
--- a/tools/ioemu/audio/audio.c Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/audio/audio.c Tue Jan 24 16:54:34 2006
@@ -257,11 +257,11 @@
     switch (hw->fmt) {
     case AUD_FMT_S16:
     case AUD_FMT_S8:
-        memset (buf, len << hw->shift, 0x00);
+        memset (buf, 0x00, len << hw->shift);
         break;
 
     case AUD_FMT_U8:
-        memset (buf, len << hw->shift, 0x80);
+        memset (buf, 0x80, len << hw->shift);
         break;
 
     case AUD_FMT_U16:
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/audio/noaudio.c
--- a/tools/ioemu/audio/noaudio.c       Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/audio/noaudio.c       Tue Jan 24 16:54:34 2006
@@ -41,7 +41,6 @@
 {
     NoVoice *no = (NoVoice *) hw;
     int rpos, live, decr, samples;
-    uint8_t *dst;
     st_sample_t *src;
     int64_t now = qemu_get_clock (vm_clock);
     int64_t ticks = now - no->old_ticks;
@@ -82,7 +81,6 @@
 
 static int no_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
 {
-    NoVoice *no = (NoVoice *) hw;
     hw->freq = freq;
     hw->nchannels = nchannels;
     hw->fmt = fmt;
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/cpu.h
--- a/tools/ioemu/cpu.h Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/cpu.h Tue Jan 24 16:54:34 2006
@@ -63,6 +63,9 @@
 /* MSDOS compatibility mode FPU exception support */
 void cpu_set_ferr(CPUX86State *s);
 
+/* helper2.c */
+void cpu_x86_set_a20(CPUX86State *env, int a20_state);
+
 #if defined(__i386__) || defined(__x86_64__)
 #define TARGET_PAGE_BITS 12
 #elif defined(__ia64__)
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/hw/pc.c       Tue Jan 24 16:54:34 2006
@@ -382,8 +382,6 @@
 {
     char buf[1024];
     int ret, linux_boot, initrd_size, i, nb_nics1;
-    unsigned long bios_offset, vga_bios_offset;
-    int bios_size, isa_bios_size;
     PCIBus *pci_bus;
     extern void * shared_vram;
     
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/vl.c  Tue Jan 24 16:54:34 2006
@@ -1204,7 +1204,7 @@
         return -1;
     }
     strcat(path, "/console/tty");
-    if (!xs_write(xs, NULL, path, pts, strlen(pts))) {
+    if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
         fprintf(logfile, "xs_write for console fail");
         return -1;
     }
diff -r 40bb46f599d9 -r a38c292e8390 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue Jan 10 15:21:00 2006
+++ b/tools/ioemu/vl.h  Tue Jan 24 16:54:34 2006
@@ -354,6 +354,9 @@
 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
 
+/* port-e9.c */
+void port_e9_init(void);
+
 /* block.c */
 typedef struct BlockDriverState BlockDriverState;
 typedef struct BlockDriver BlockDriver;
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xc_ia64_stubs.c
--- a/tools/libxc/xc_ia64_stubs.c       Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xc_ia64_stubs.c       Tue Jan 24 16:54:34 2006
@@ -23,7 +23,8 @@
 }
 
 int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, 
-                  uint32_t max_factor, uint32_t flags, int (*suspend)(void))
+                  uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
+                  int (*suspend)(int domid))
 {
     PERROR("xc_linux_save not implemented\n");
     return -1;
@@ -664,15 +665,7 @@
         goto error_out;
     }
 
-    if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) ){
-        PERROR("Could not get vcpu context");
-        goto error_out;
-    }
-
-    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) {
-        ERROR("Domain is already constructed");
-        goto error_out;
-    }
+    memset(ctxt, 0, sizeof(*ctxt));
 
     if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image, 
image_size, 
                        control_evtchn, store_evtchn, store_mfn ) < 0 ){
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xc_linux_build.c      Tue Jan 24 16:54:34 2006
@@ -33,10 +33,8 @@
 #endif
 
 #ifdef __ia64__
-#define already_built(ctxt) (0)
 #define get_tot_pages xc_get_max_pages
 #else
-#define already_built(ctxt) ((ctxt)->ctrlreg[3] != 0)
 #define get_tot_pages xc_get_tot_pages
 #endif
 
@@ -800,17 +798,7 @@
         goto error_out;
     }
 
-    if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
-    {
-        PERROR("Could not get vcpu context");
-        goto error_out;
-    }
-
-    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) || already_built(ctxt) )
-    {
-        ERROR("Domain is already constructed");
-        goto error_out;
-    }
+    memset(ctxt, 0, sizeof(*ctxt));
 
     if ( setup_guest(xc_handle, domid, image, image_size, 
                      initrd_gfd, initrd_size, nr_pages, 
@@ -865,6 +853,8 @@
     ctxt->user_regs.esi = vstartinfo_start;
     ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
 
+    ctxt->flags = VGCF_IN_KERNEL;
+
     /* FPU is set up to default initial state. */
     memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
 
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xc_linux_restore.c    Tue Jan 24 16:54:34 2006
@@ -170,13 +170,6 @@
     }
 
 
-    /* Only have to worry about vcpu 0 even for SMP */
-    if (xc_vcpu_getcontext( xc_handle, dom, 0, &ctxt)) {
-        ERR("Could not get vcpu context");
-        goto out;
-    }
-
-    
     /* Read the saved P2M frame list */
     if(!(p2m_frame_list = malloc(P2M_FL_SIZE))) { 
         ERR("Couldn't allocate p2m_frame_list array");
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c        Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xc_vmx_build.c        Tue Jan 24 16:54:34 2006
@@ -651,18 +651,7 @@
         goto error_out;
     }
 
-    if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
-    {
-        PERROR("Could not get vcpu context");
-        goto error_out;
-    }
-
-    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
-         (ctxt->ctrlreg[3] != 0) )
-    {
-        ERROR("Domain is already constructed");
-        goto error_out;
-    }
+    memset(ctxt, 0, sizeof(*ctxt));
 
     if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
                      ctxt, op.u.getdomaininfo.shared_info_frame, 
control_evtchn,
diff -r 40bb46f599d9 -r a38c292e8390 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Tue Jan 10 15:21:00 2006
+++ b/tools/libxc/xenguest.h    Tue Jan 24 16:54:34 2006
@@ -21,9 +21,9 @@
  * @parm dom the id of the domain
  * @return 0 on success, -1 on failure
  */
-int xc_linux_save(int xc_handle, int fd, uint32_t dom, uint32_t max_iters, 
+int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, 
                   uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
-                  int (*suspend)(int));
+                  int (*suspend)(int domid));
 
 
 /**
diff -r 40bb46f599d9 -r a38c292e8390 tools/python/xen/lowlevel/xs/xs.c
--- a/tools/python/xen/lowlevel/xs/xs.c Tue Jan 10 15:21:00 2006
+++ b/tools/python/xen/lowlevel/xs/xs.c Tue Jan 24 16:54:34 2006
@@ -66,7 +66,7 @@
 
 static int parse_transaction_path(XsHandle *self, PyObject *args,
                                   struct xs_handle **xh,
-                                  struct xs_transaction_handle **th,
+                                  xs_transaction_t *th,
                                   char **path);
 
 
@@ -83,7 +83,7 @@
 static PyObject *xspy_read(XsHandle *self, PyObject *args)
 {
     struct xs_handle *xh;
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char *path;
 
     char *xsval;
@@ -120,7 +120,7 @@
 {
     static char *arg_spec = "sss#";
     struct xs_handle *xh = xshandle(self);
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char *thstr;
     char *path;
     char *data;
@@ -132,7 +132,7 @@
     if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path, &data, &data_n))
         return NULL;
 
-    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+    th = strtoul(thstr, NULL, 16);
 
     Py_BEGIN_ALLOW_THREADS
     result = xs_write(xh, th, path, data, data_n);
@@ -155,7 +155,7 @@
 static PyObject *xspy_ls(XsHandle *self, PyObject *args)
 {
     struct xs_handle *xh;
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char *path;
 
     char **xsval;
@@ -193,7 +193,7 @@
 static PyObject *xspy_mkdir(XsHandle *self, PyObject *args)
 {
     struct xs_handle *xh;
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char *path;
 
     bool result;
@@ -221,7 +221,7 @@
 static PyObject *xspy_rm(XsHandle *self, PyObject *args)
 {
     struct xs_handle *xh;
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char *path;
 
     bool result;
@@ -256,7 +256,7 @@
     unsigned int perms_n = 0;
     int i;
 
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char *thstr;
 
     if (!xh)
@@ -264,7 +264,7 @@
     if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path))
         return NULL;
 
-    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+    th = strtoul(thstr, NULL, 16);
 
     Py_BEGIN_ALLOW_THREADS
     perms = xs_get_permissions(xh, th, path, &perms_n);
@@ -312,7 +312,7 @@
     int xsperms_n;
     PyObject *tuple0 = NULL;
 
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char *thstr;
 
     if (!xh)
@@ -320,7 +320,7 @@
     if (!PyArg_ParseTuple(args, "ssO", &thstr, &path, &perms))
         goto exit;
 
-    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+    th = strtoul(thstr, NULL, 16);
 
     if (!PyList_Check(perms)) {
         PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
@@ -509,7 +509,7 @@
 static PyObject *xspy_transaction_start(XsHandle *self)
 {
     struct xs_handle *xh = xshandle(self);
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char thstr[MAX_STRLEN(unsigned long) + 1];
 
     if (!xh)
@@ -519,7 +519,7 @@
     th = xs_transaction_start(xh);
     Py_END_ALLOW_THREADS
 
-    if (th == NULL) {
+    if (th == XBT_NULL) {
         PyErr_SetFromErrno(PyExc_RuntimeError);
         return NULL;
     }
@@ -547,7 +547,7 @@
     struct xs_handle *xh = xshandle(self);
     bool result;
 
-    struct xs_transaction_handle *th;
+    xs_transaction_t th;
     char *thstr;
 
     if (!xh)
@@ -556,7 +556,7 @@
                                      &thstr, &abort))
         return NULL;
 
-    th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+    th = strtoul(thstr, NULL, 16);
 
     Py_BEGIN_ALLOW_THREADS
     result = xs_transaction_end(xh, th, abort);
@@ -727,7 +727,7 @@
  */
 static int parse_transaction_path(XsHandle *self, PyObject *args,
                                   struct xs_handle **xh,
-                                  struct xs_transaction_handle **th,
+                                  xs_transaction_t *th,
                                   char **path)
 {
     char *thstr;
@@ -740,7 +740,7 @@
     if (!PyArg_ParseTuple(args, "ss", &thstr, path))
         return 0;
 
-    *th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
+    *th = strtoul(thstr, NULL, 16);
 
     return 1;
 }
diff -r 40bb46f599d9 -r a38c292e8390 tools/vtpm/Makefile
--- a/tools/vtpm/Makefile       Tue Jan 10 15:21:00 2006
+++ b/tools/vtpm/Makefile       Tue Jan 24 16:54:34 2006
@@ -10,6 +10,8 @@
 
 # Emulator tarball name
 TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
+
+GMP_HEADER = /usr/include/gmp.h
 
 all: build
 
@@ -55,5 +57,12 @@
        patch -p1 <../vtpm.patch
 
 build_sub:
-       $(MAKE) -C $(TPM_EMULATOR_DIR)
-       $(MAKE) -C $(VTPM_DIR)
+       if [ -e $(GMP_HEADER) ]; then \
+               $(MAKE) -C $(VTPM_DIR); \
+               if [ "$(BUILD_EMULATOR)" = "y" ]; then \
+                       $(MAKE) -C $(TPM_EMULATOR_DIR); \
+               fi \
+       else \
+               echo "*** Unable to build VTPMs. libgmp could not be found."; \
+       fi
+
diff -r 40bb46f599d9 -r a38c292e8390 tools/vtpm/Rules.mk
--- a/tools/vtpm/Rules.mk       Tue Jan 10 15:21:00 2006
+++ b/tools/vtpm/Rules.mk       Tue Jan 24 16:54:34 2006
@@ -33,5 +33,7 @@
 
 -include $(DEP_FILES)
 
+BUILD_EMULATOR = n
+
 # Make sure these are just rules
 .PHONY : all build install clean
diff -r 40bb46f599d9 -r a38c292e8390 tools/vtpm_manager/Makefile
--- a/tools/vtpm_manager/Makefile       Tue Jan 10 15:21:00 2006
+++ b/tools/vtpm_manager/Makefile       Tue Jan 24 16:54:34 2006
@@ -4,13 +4,18 @@
 include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
 
 SUBDIRS                = crypto tcs util manager
+OPENSSL_HEADER = /usr/include/openssl/crypto.h
 
 all: build
 
 build:
-       @set -e; for subdir in $(SUBDIRS); do \
-               $(MAKE) -C $$subdir $@; \
-       done
+       if [ -e $(OPENSSL_HEADER) ]; then \
+               @set -e; for subdir in $(SUBDIRS); do \
+                       $(MAKE) -C $$subdir $@; \
+               done; \
+       else \
+               echo "*** Cannot build vtpm_manager: OpenSSL developement files 
missing."; \
+       fi
 
 install: build
        @set -e; for subdir in $(SUBDIRS); do \
diff -r 40bb46f599d9 -r a38c292e8390 tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Tue Jan 10 15:21:00 2006
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Tue Jan 24 16:54:34 2006
@@ -151,9 +151,6 @@
                                    &osap) );
   
   // Generate boot key's auth
-  Crypto_GetRandom(  &vtpm_globals->storage_key_usage_auth, 
-                    sizeof(TPM_AUTHDATA) );
-  
   TPM_AUTHDATA bootKeyWrapAuth;
   memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
   
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenmon/Makefile
--- a/tools/xenmon/Makefile     Tue Jan 10 15:21:00 2006
+++ b/tools/xenmon/Makefile     Tue Jan 24 16:54:34 2006
@@ -13,12 +13,9 @@
 INSTALL         = install
 INSTALL_PROG    = $(INSTALL) -m0755
 INSTALL_DIR     = $(INSTALL) -d -m0755
-INSTALL_DATA    = $(INSTALL) -m064
+INSTALL_DATA    = $(INSTALL) -m0644
 
-prefix=/usr/local
-mandir=$(prefix)/share/man
-man1dir=$(mandir)/man1
-sbindir=$(prefix)/sbin
+sbindir=/usr/sbin
 
 XEN_ROOT=../..
 include $(XEN_ROOT)/tools/Rules.mk
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstat/libxenstat/src/xenstat.c
--- a/tools/xenstat/libxenstat/src/xenstat.c    Tue Jan 10 15:21:00 2006
+++ b/tools/xenstat/libxenstat/src/xenstat.c    Tue Jan 24 16:54:34 2006
@@ -705,7 +705,7 @@
 
        snprintf(path, sizeof(path),"/local/domain/%i/name", domain_id);
        
-       name = xs_read(handle->xshandle, NULL, path, NULL);
+       name = xs_read(handle->xshandle, XBT_NULL, path, NULL);
        if (name == NULL)
                name = strdup(" ");
 
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/Makefile
--- a/tools/xenstore/Makefile   Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/Makefile   Tue Jan 24 16:54:34 2006
@@ -27,7 +27,7 @@
 CLIENTS += xenstore-write
 CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS))
 
-all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xsls
+all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xenstore-ls
 
 testcode: xs_test xenstored_test xs_random
 
@@ -40,7 +40,7 @@
 $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c
        $(COMPILE.c) -DCLIENT_$(*F) -o $@ $<
 
-xsls: xsls.o libxenstore.so
+xenstore-ls: xsls.o libxenstore.so
        $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@
 
 xenstored_test: xenstored_core_test.o xenstored_watch_test.o 
xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o 
fake_libxc.o utils.o tdb.o
@@ -77,7 +77,7 @@
 clean: testsuite-clean
        rm -f *.o *.opic *.so
        rm -f xenstored xs_random xs_stress xs_crashme
-       rm -f xs_test xenstored_test xs_tdb_dump xsls $(CLIENTS)
+       rm -f xs_test xenstored_test xs_tdb_dump xenstore-ls $(CLIENTS)
        $(RM) $(PROG_DEP)
 
 print-dir:
@@ -129,7 +129,7 @@
 tarball: clean
        cd .. && tar -c -j -v -h -f xenstore.tar.bz2 xenstore/
 
-install: libxenstore.so xenstored xsls $(CLIENTS)
+install: libxenstore.so xenstored xenstore-ls $(CLIENTS)
        $(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored
        $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored
        $(INSTALL_DIR) -p $(DESTDIR)/usr/bin
@@ -137,7 +137,7 @@
        $(INSTALL_DIR) -p $(DESTDIR)/usr/include
        $(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin
        $(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/bin
-       $(INSTALL_PROG) xsls $(DESTDIR)/usr/bin
+       $(INSTALL_PROG) xenstore-ls $(DESTDIR)/usr/bin
        $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
        $(INSTALL_DATA) libxenstore.so $(DESTDIR)/usr/$(LIBDIR)
        $(INSTALL_DATA) xs.h $(DESTDIR)/usr/include
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/utils.c
--- a/tools/xenstore/utils.c    Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/utils.c    Tue Jan 24 16:54:34 2006
@@ -92,23 +92,33 @@
        else
                fd = open(filename, O_RDONLY, 0);
 
-       if (fd < 0)
+       if (fd == -1)
                return NULL;
 
        buffer = malloc(max+1);
+       if (!buffer)
+               goto error;
        *size = 0;
        while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
                *size += ret;
-               if (*size == max)
-                       buffer = realloc(buffer, max *= 2 + 1);
+               if (*size == max) {
+                       void *nbuffer;
+                       max *= 2;
+                       nbuffer = realloc(buffer, max + 1);
+                       if (!nbuffer)
+                               goto error;
+                       buffer = nbuffer;
+               }
        }
-       if (ret < 0) {
-               free(buffer);
-               buffer = NULL;
-       } else
-               ((char *)buffer)[*size] = '\0';
+       if (ret < 0)
+               goto error;
+       ((char *)buffer)[*size] = '\0';
        close(fd);
        return buffer;
+error:
+       free(buffer);
+       close(fd);
+       return NULL;
 }
 
 void release_file(void *data, unsigned long size __attribute__((unused)))
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xenstore_client.c
--- a/tools/xenstore/xenstore_client.c  Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xenstore_client.c  Tue Jan 24 16:54:34 2006
@@ -66,7 +66,7 @@
 
 #if defined(CLIENT_rm)
 static int
-do_rm(char *path, struct xs_handle *xsh, struct xs_transaction_handle *xth)
+do_rm(char *path, struct xs_handle *xsh, xs_transaction_t xth)
 {
     if (xs_rm(xsh, xth, path)) {
         return 0;
@@ -81,7 +81,7 @@
 
 static int
 perform(int optind, int argc, char **argv, struct xs_handle *xsh,
-        struct xs_transaction_handle *xth, int prefix, int tidy)
+        xs_transaction_t xth, int prefix, int tidy)
 {
     while (optind < argc) {
 #if defined(CLIENT_read)
@@ -179,7 +179,7 @@
 main(int argc, char **argv)
 {
     struct xs_handle *xsh;
-    struct xs_transaction_handle *xth;
+    xs_transaction_t xth;
     int ret = 0, socket = 0;
     int prefix = 0;
     int tidy = 0;
@@ -243,7 +243,7 @@
 
   again:
     xth = xs_transaction_start(xsh);
-    if (xth == NULL)
+    if (xth == XBT_NULL)
        errx(1, "couldn't start transaction");
 
     ret = perform(optind, argc, argv, xsh, xth, prefix, tidy);
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xenstored_core.c   Tue Jan 24 16:54:34 2006
@@ -174,69 +174,27 @@
        }
 }
 
-static void trace_io(const struct connection *conn,
-                    const char *prefix,
-                    const struct buffered_data *data)
-{
-       char string[64];
-       unsigned int i;
-       time_t now;
-       struct tm *tm;
+void trace(const char *fmt, ...)
+{
+       va_list arglist;
+       char *str;
+       char sbuf[1024];
+       int ret;
 
        if (tracefd < 0)
                return;
 
-       now = time(NULL);
-       tm = localtime(&now);
-
-       write(tracefd, prefix, strlen(prefix));
-       sprintf(string, " %p %02d:%02d:%02d ", conn, tm->tm_hour, tm->tm_min,
-               tm->tm_sec);
-       write(tracefd, string, strlen(string));
-       write(tracefd, sockmsg_string(data->hdr.msg.type),
-             strlen(sockmsg_string(data->hdr.msg.type)));
-       write(tracefd, " (", 2);
-       for (i = 0; i < data->hdr.msg.len; i++) {
-               if (data->buffer[i] == '\0')
-                       write(tracefd, " ", 1);
-               else
-                       write(tracefd, data->buffer + i, 1);
-       }
-       write(tracefd, ")\n", 2);
-}
-
-void trace_create(const void *data, const char *type)
-{
-       char string[64];
-       if (tracefd < 0)
+       /* try to use a static buffer */
+       va_start(arglist, fmt);
+       ret = vsnprintf(sbuf, 1024, fmt, arglist);
+       va_end(arglist);
+
+       if (ret <= 1024) {
+               write(tracefd, sbuf, ret);
                return;
-
-       write(tracefd, "CREATE ", strlen("CREATE "));
-       write(tracefd, type, strlen(type));
-       sprintf(string, " %p\n", data);
-       write(tracefd, string, strlen(string));
-}
-
-void trace_destroy(const void *data, const char *type)
-{
-       char string[64];
-       if (tracefd < 0)
-               return;
-
-       write(tracefd, "DESTROY ", strlen("DESTROY "));
-       write(tracefd, type, strlen(type));
-       sprintf(string, " %p\n", data);
-       write(tracefd, string, strlen(string));
-}
-
-void trace(const char *fmt, ...)
-{
-       va_list arglist;
-       char *str;
-
-       if (tracefd < 0)
-               return;
-
+       }
+
+       /* fail back to dynamic allocation */
        va_start(arglist, fmt);
        str = talloc_vasprintf(NULL, fmt, arglist);
        va_end(arglist);
@@ -244,6 +202,38 @@
        talloc_free(str);
 }
 
+static void trace_io(const struct connection *conn,
+                    const char *prefix,
+                    const struct buffered_data *data)
+{
+       unsigned int i;
+       time_t now;
+       struct tm *tm;
+
+       if (tracefd < 0)
+               return;
+
+       now = time(NULL);
+       tm = localtime(&now);
+
+       trace("%s %p %02d:%02d:%02d %s (", prefix, conn,
+             tm->tm_hour, tm->tm_min, tm->tm_sec,
+             sockmsg_string(data->hdr.msg.type));
+       
+       for (i = 0; i < data->hdr.msg.len; i++)
+               trace("%c", (data->buffer[i] != '\0') ? data->buffer[i] : ' ');
+       trace(")\n");
+}
+
+void trace_create(const void *data, const char *type)
+{
+       trace("CREATE %s %p\n", type, data);
+}
+
+void trace_destroy(const void *data, const char *type)
+{
+       trace("DESTROY %s %p\n", type, data);
+}
 
 /**
  * Signal handler for SIGHUP, which requests that the trace log is reopened
@@ -268,7 +258,7 @@
                if (tracefd < 0)
                        perror("Could not open tracefile");
                else
-                       write(tracefd, "\n***\n", strlen("\n***\n"));
+                       trace("\n***\n");
        }
 }
 
@@ -1311,11 +1301,10 @@
 {
        struct connection *new;
 
-       new = talloc(talloc_autofree_context(), struct connection);
+       new = talloc_zero(talloc_autofree_context(), struct connection);
        if (!new)
                return NULL;
 
-       memset(new, 0, sizeof(*new));
        new->fd = -1;
        new->write = write;
        new->read = read;
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xenstored_domain.c Tue Jan 24 16:54:34 2006
@@ -278,12 +278,12 @@
        talloc_set_destructor(domain, destroy_domain);
 
        /* Tell kernel we're interested in this event. */
-        bind.remote_domain = domid;
-        bind.remote_port   = port;
-        rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
-        if (rc == -1)
-            return NULL;
-        domain->port = rc;
+       bind.remote_domain = domid;
+       bind.remote_port   = port;
+       rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+       if (rc == -1)
+           return NULL;
+       domain->port = rc;
 
        domain->conn = new_connection(writechn, readchn);
        domain->conn->domain = domain;
@@ -426,10 +426,10 @@
        int result;
        unsigned int domid;
 
-        if (!domid_str) {
-                send_error(conn, EINVAL);
-                return;
-        }
+       if (!domid_str) {
+               send_error(conn, EINVAL);
+               return;
+       }
 
        domid = atoi(domid_str);
        if (domid == DOMID_SELF)
@@ -461,35 +461,45 @@
 
 static int dom0_init(void) 
 { 
-        int rc, fd;
+       int rc, fd;
        evtchn_port_t port; 
-        unsigned long mfn; 
-        char str[20]; 
-        struct domain *dom0; 
-        
-        fd = open(XENSTORED_PROC_MFN, O_RDONLY); 
-        
-        rc = read(fd, str, sizeof(str)); 
-        str[rc] = '\0'; 
-        mfn = strtoul(str, NULL, 0); 
-        
-        close(fd); 
-        
-        fd = open(XENSTORED_PROC_PORT, O_RDONLY); 
-        
-        rc = read(fd, str, sizeof(str)); 
-        str[rc] = '\0'; 
-        port = strtoul(str, NULL, 0); 
-        
-        close(fd); 
-        
-        
-        dom0 = new_domain(NULL, 0, mfn, port); 
-        talloc_steal(dom0->conn, dom0); 
-
-        evtchn_notify(dom0->port); 
-
-        return 0; 
+       unsigned long mfn; 
+       char str[20]; 
+       struct domain *dom0; 
+
+       fd = open(XENSTORED_PROC_MFN, O_RDONLY); 
+       if (fd == -1)
+               return -1;
+
+       rc = read(fd, str, sizeof(str)); 
+       if (rc == -1)
+               goto outfd;
+       str[rc] = '\0'; 
+       mfn = strtoul(str, NULL, 0); 
+
+       close(fd); 
+
+       fd = open(XENSTORED_PROC_PORT, O_RDONLY); 
+       if (fd == -1)
+               return -1;
+
+       rc = read(fd, str, sizeof(str)); 
+       if (rc == -1)
+               goto outfd;
+       str[rc] = '\0'; 
+       port = strtoul(str, NULL, 0); 
+
+       close(fd); 
+
+       dom0 = new_domain(NULL, 0, mfn, port); 
+       talloc_steal(dom0->conn, dom0); 
+
+       evtchn_notify(dom0->port); 
+
+       return 0; 
+outfd:
+       close(fd);
+       return -1;
 }
 
 
@@ -539,9 +549,9 @@
        if (eventchn_fd < 0)
                barf_perror("Failed to open evtchn device");
 
-        if (dom0_init() != 0) 
-                barf_perror("Failed to initialize dom0 state"); 
-     
+       if (dom0_init() != 0) 
+               barf_perror("Failed to initialize dom0 state"); 
+
        bind.virq = VIRQ_DOM_EXC;
        rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
        if (rc == -1)
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xs.c
--- a/tools/xenstore/xs.c       Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xs.c       Tue Jan 24 16:54:34 2006
@@ -292,7 +292,7 @@
 }
 
 /* Send message to xs, get malloc'ed reply.  NULL and set errno on error. */
-static void *xs_talkv(struct xs_handle *h, struct xs_transaction_handle *t,
+static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
                      enum xsd_sockmsg_type type,
                      const struct iovec *iovec,
                      unsigned int num_vecs,
@@ -304,7 +304,7 @@
        unsigned int i;
        struct sigaction ignorepipe, oldact;
 
-       msg.tx_id = (uint32_t)(unsigned long)t;
+       msg.tx_id = t;
        msg.req_id = 0;
        msg.type = type;
        msg.len = 0;
@@ -368,7 +368,7 @@
 }
 
 /* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xs_handle *h, struct xs_transaction_handle *t,
+static void *xs_single(struct xs_handle *h, xs_transaction_t t,
                       enum xsd_sockmsg_type type,
                       const char *string,
                       unsigned int *len)
@@ -388,7 +388,7 @@
        return true;
 }
 
-char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
+char **xs_directory(struct xs_handle *h, xs_transaction_t t,
                    const char *path, unsigned int *num)
 {
        char *strings, *p, **ret;
@@ -420,7 +420,7 @@
  * Returns a malloced value: call free() on it after use.
  * len indicates length in bytes, not including the nul.
  */
-void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
+void *xs_read(struct xs_handle *h, xs_transaction_t t,
              const char *path, unsigned int *len)
 {
        return xs_single(h, t, XS_READ, path, len);
@@ -429,7 +429,7 @@
 /* Write the value of a single file.
  * Returns false on failure.
  */
-bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_write(struct xs_handle *h, xs_transaction_t t,
              const char *path, const void *data, unsigned int len)
 {
        struct iovec iovec[2];
@@ -446,7 +446,7 @@
 /* Create a new directory.
  * Returns false on failure, or success if it already exists.
  */
-bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
              const char *path)
 {
        return xs_bool(xs_single(h, t, XS_MKDIR, path, NULL));
@@ -455,7 +455,7 @@
 /* Destroy a file or directory (directories must be empty).
  * Returns false on failure, or success if it doesn't exist.
  */
-bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_rm(struct xs_handle *h, xs_transaction_t t,
           const char *path)
 {
        return xs_bool(xs_single(h, t, XS_RM, path, NULL));
@@ -465,7 +465,7 @@
  * Returns malloced array, or NULL: call free() after use.
  */
 struct xs_permissions *xs_get_permissions(struct xs_handle *h,
-                                         struct xs_transaction_handle *t,
+                                         xs_transaction_t t,
                                          const char *path, unsigned int *num)
 {
        char *strings;
@@ -499,7 +499,7 @@
  * Returns false on failure.
  */
 bool xs_set_permissions(struct xs_handle *h,
-                       struct xs_transaction_handle *t,
+                       xs_transaction_t t,
                        const char *path,
                        struct xs_permissions *perms,
                        unsigned int num_perms)
@@ -634,21 +634,21 @@
 /* Start a transaction: changes by others will not be seen during this
  * transaction, and changes will not be visible to others until end.
  * You can only have one transaction at any time.
- * Returns NULL on failure.
- */
-struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h)
+ * Returns XBT_NULL on failure.
+ */
+xs_transaction_t xs_transaction_start(struct xs_handle *h)
 {
        char *id_str;
-       unsigned long id;
+       xs_transaction_t id;
 
        id_str = xs_single(h, XBT_NULL, XS_TRANSACTION_START, "", NULL);
        if (id_str == NULL)
-               return NULL;
+               return XBT_NULL;
 
        id = strtoul(id_str, NULL, 0);
        free(id_str);
 
-       return (struct xs_transaction_handle *)id;
+       return id;
 }
 
 /* End a transaction.
@@ -656,7 +656,7 @@
  * Returns false on failure, which indicates an error: transactions will
  * not fail spuriously.
  */
-bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
                        bool abort)
 {
        char abortstr[2];
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xs.h
--- a/tools/xenstore/xs.h       Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xs.h       Tue Jan 24 16:54:34 2006
@@ -22,10 +22,10 @@
 
 #include <xs_lib.h>
 
-#define XBT_NULL NULL
+#define XBT_NULL 0
 
 struct xs_handle;
-struct xs_transaction_handle;
+typedef uint32_t xs_transaction_t;
 
 /* On failure, these routines set errno. */
 
@@ -47,45 +47,45 @@
  * Returns a malloced array: call free() on it after use.
  * Num indicates size.
  */
-char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
+char **xs_directory(struct xs_handle *h, xs_transaction_t t,
                    const char *path, unsigned int *num);
 
 /* Get the value of a single file, nul terminated.
  * Returns a malloced value: call free() on it after use.
  * len indicates length in bytes, not including terminator.
  */
-void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
+void *xs_read(struct xs_handle *h, xs_transaction_t t,
              const char *path, unsigned int *len);
 
 /* Write the value of a single file.
  * Returns false on failure.
  */
-bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_write(struct xs_handle *h, xs_transaction_t t,
              const char *path, const void *data, unsigned int len);
 
 /* Create a new directory.
  * Returns false on failure, or success if it already exists.
  */
-bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
              const char *path);
 
 /* Destroy a file or directory (and children).
  * Returns false on failure, or if it doesn't exist.
  */
-bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_rm(struct xs_handle *h, xs_transaction_t t,
           const char *path);
 
 /* Get permissions of node (first element is owner, first perms is "other").
  * Returns malloced array, or NULL: call free() after use.
  */
 struct xs_permissions *xs_get_permissions(struct xs_handle *h,
-                                         struct xs_transaction_handle *t,
+                                         xs_transaction_t t,
                                          const char *path, unsigned int *num);
 
 /* Set permissions of node (must be owner).
  * Returns false on failure.
  */
-bool xs_set_permissions(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_set_permissions(struct xs_handle *h, xs_transaction_t t,
                        const char *path, struct xs_permissions *perms,
                        unsigned int num_perms);
 
@@ -115,14 +115,14 @@
  * You can only have one transaction at any time.
  * Returns NULL on failure.
  */
-struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h);
+xs_transaction_t xs_transaction_start(struct xs_handle *h);
 
 /* End a transaction.
  * If abandon is true, transaction is discarded instead of committed.
  * Returns false on failure: if errno == EAGAIN, you have to restart
  * transaction.
  */
-bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
+bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
                        bool abort);
 
 /* Introduce a new domain.
diff -r 40bb46f599d9 -r a38c292e8390 tools/xenstore/xs_test.c
--- a/tools/xenstore/xs_test.c  Tue Jan 10 15:21:00 2006
+++ b/tools/xenstore/xs_test.c  Tue Jan 24 16:54:34 2006
@@ -43,7 +43,7 @@
 #define XSTEST
 
 static struct xs_handle *handles[10] = { NULL };
-static struct xs_transaction_handle *txh[10] = { XBT_NULL };
+static xs_transaction_t txh[10] = { XBT_NULL };
 
 static unsigned int timeout_ms = 500;
 static bool timeout_suppressed = true;
@@ -535,7 +535,7 @@
        *(uint16_t *)((void *)interface + 36) = atoi(eventchn);
 
        if (!xs_introduce_domain(handles[handle], atoi(domid),
-                                atol(mfn), atoi(eventchn), path)) {
+                                atol(mfn), atoi(eventchn))) {
                failed(handle);
                munmap(interface, getpagesize());
                return;
diff -r 40bb46f599d9 -r a38c292e8390 tools/xentrace/Makefile
--- a/tools/xentrace/Makefile   Tue Jan 10 15:21:00 2006
+++ b/tools/xentrace/Makefile   Tue Jan 24 16:54:34 2006
@@ -33,14 +33,14 @@
 
 install: build
        [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
-       [ -z "$(LIBBIN)"] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
+       [ -z "$(LIBBIN)" ] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
                $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
        [ -d $(DESTDIR)/usr/share/man/man1 ] || \
                $(INSTALL_DIR) $(DESTDIR)/usr/share/man/man1
        [ -d $(DESTDIR)/usr/share/man/man8 ] || \
                $(INSTALL_DIR) $(DESTDIR)/usr/share/man/man8
        $(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin
-       [ -z "$(LIBBIN)"] || $(INSTALL_PROG) $(LIBBIN) 
$(DESTDIR)/usr/$(LIBDIR)/xen/bin
+       [ -z "$(LIBBIN)" ] || $(INSTALL_PROG) $(LIBBIN) 
$(DESTDIR)/usr/$(LIBDIR)/xen/bin
        $(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/share/man/man1
        $(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/share/man/man8
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile    Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/Makefile    Tue Jan 24 16:54:34 2006
@@ -22,6 +22,10 @@
        memset.o strlen.o memcpy_mck.o                                  \
        __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o                   \
        __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
+
+ifeq ($(crash_debug),y)
+OBJS += gdbstub.o
+endif
 
 # xen stack unwinder
 # unwind_decoder.c is included in unwind.c
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/Rules.mk
--- a/xen/arch/ia64/Rules.mk    Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/Rules.mk    Tue Jan 24 16:54:34 2006
@@ -23,10 +23,10 @@
            -I$(BASEDIR)/include/asm-ia64/linux-xen                     \
           -I$(BASEDIR)/include/asm-ia64/linux-null                     \
            -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
-CFLAGS  += -Wno-pointer-arith -Wredundant-decls
+#CFLAGS  += -Wno-pointer-arith -Wredundant-decls
 CFLAGS  += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY
 CFLAGS += -ffixed-r13 -mfixed-range=f12-f15,f32-f127
-CFLAGS += -w -g
+CFLAGS += -g
 #CFLAGS  += -DVTI_DEBUG
 ifeq ($(VALIDATE_VT),y)
 CFLAGS  += -DVALIDATE_VT
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/asm-offsets.c       Tue Jan 24 16:54:34 2006
@@ -15,7 +15,7 @@
 #define task_struct vcpu
 
 #define DEFINE(sym, val) \
-        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+        asm volatile("\n->" #sym " (%0) " #val : : "i" (val))
 
 #define BLANK() asm volatile("\n->" : : )
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/asm-xsi-offsets.c
--- a/xen/arch/ia64/asm-xsi-offsets.c   Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/asm-xsi-offsets.c   Tue Jan 24 16:54:34 2006
@@ -38,7 +38,7 @@
 #define task_struct vcpu
 
 #define DEFINE(sym, val) \
-        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+        asm volatile("\n->" #sym " (%0) " #val : : "i" (val))
 
 #define BLANK() asm volatile("\n->" : : )
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/linux-xen/sal.c
--- a/xen/arch/ia64/linux-xen/sal.c     Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/linux-xen/sal.c     Tue Jan 24 16:54:34 2006
@@ -16,6 +16,7 @@
 
 #ifdef XEN
 #include <linux/smp.h>
+#include <xen/lib.h>
 #endif
 #include <asm/page.h>
 #include <asm/sal.h>
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c     Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/linux-xen/smp.c     Tue Jan 24 16:54:34 2006
@@ -57,8 +57,21 @@
 void flush_tlb_mask(cpumask_t mask)
 {
 #ifdef CONFIG_SMP
-    printf("flush_tlb_mask called, not implemented for SMP\n");
-       dummy();
+    int cpu;
+
+    cpu = smp_processor_id();
+    if (cpu_isset (cpu, mask)) {
+        cpu_clear(cpu, mask);
+       local_flush_tlb_all ();
+    }
+
+    if (cpus_empty(mask))
+        return;
+
+    for (cpu = 0; cpu < NR_CPUS; ++cpu)
+        if (cpu_isset(cpu, mask))
+          smp_call_function_single
+            (cpu, (void (*)(void *))local_flush_tlb_all, NULL, 1, 1);
 #endif
 }
 //#if CONFIG_SMP || IA64
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/linux-xen/smpboot.c
--- a/xen/arch/ia64/linux-xen/smpboot.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/linux-xen/smpboot.c Tue Jan 24 16:54:34 2006
@@ -64,6 +64,10 @@
 #ifdef XEN
 #include <asm/hw_irq.h>
 int ht_per_core = 1;
+#ifndef CONFIG_SMP
+cpumask_t cpu_online_map = CPU_MASK_CPU0;
+EXPORT_SYMBOL(cpu_online_map);
+#endif
 #endif
 
 #ifdef CONFIG_SMP /* ifdef XEN */
@@ -482,9 +486,8 @@
        struct vcpu *v;
        void *stack;
 
-       if ( (idle = do_createdomain(IDLE_DOMAIN_ID, cpu)) == NULL )
-               panic("failed 'createdomain' for CPU %d", cpu);
-       v = idle->vcpu[0];
+       v = idle_vcpu[cpu] = alloc_vcpu(idle_vcpu[0]->domain, cpu, cpu);
+       BUG_ON(v == NULL);
 
        printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v);
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/vmx/vlsapic.c       Tue Jan 24 16:54:34 2006
@@ -119,7 +119,7 @@
     itc_freq = local_cpu_data->itc_freq;
     vtm->cfg_max_jump=itc_freq*MAX_JUMP_STEP/1000;
     vtm->cfg_min_grun=itc_freq*MIN_GUEST_RUNNING_TIME/1000;
-    init_ac_timer(&vtm->vtm_timer, vtm_timer_fn, vcpu, 0);
+    init_timer(&vtm->vtm_timer, vtm_timer_fn, vcpu, 0);
     vtm_reset(vcpu);
 }
 
@@ -163,20 +163,20 @@
     local_irq_save(spsr);
     itv = VCPU(vcpu, itv);
     if ( ITV_IRQ_MASK(itv) )
-        rem_ac_timer(&vtm->vtm_timer);
+        stop_timer(&vtm->vtm_timer);
     vtm_interruption_update(vcpu, vtm);
     local_irq_restore(spsr);
 }
 
 
 /*
- * Update interrupt or hook the vtm ac_timer for fire 
+ * Update interrupt or hook the vtm timer for fire 
  * At this point vtm_timer should be removed if itv is masked.
  */
 /* Interrupt must be disabled at this point */
 
 extern u64 cycle_to_ns(u64 cyle);
-#define TIMER_SLOP (50*1000) /* ns */  /* copy from ac_timer.c */
+#define TIMER_SLOP (50*1000) /* ns */  /* copy from timer.c */
 void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm)
 {
     uint64_t    cur_itc,vitm,vitv;
@@ -198,7 +198,7 @@
     
     if ( diff_last >= 0 ) {
         // interrupt already fired.
-        rem_ac_timer(&vtm->vtm_timer);
+        stop_timer(&vtm->vtm_timer);
     }
     else if ( diff_now >= 0 ) {
         // ITV is fired.
@@ -207,24 +207,24 @@
     /* Both last_itc & cur_itc < itm, wait for fire condition */
     else {
         expires = NOW() + cycle_to_ns(0-diff_now) + TIMER_SLOP;
-        set_ac_timer(&vtm->vtm_timer, expires);
+        set_timer(&vtm->vtm_timer, expires);
     }
     local_irq_restore(spsr);
 }
 
 /*
  * Action for vtm when the domain is scheduled out.
- * Remove the ac_timer for vtm.
+ * Remove the timer for vtm.
  */
 void vtm_domain_out(VCPU *vcpu)
 {
     if(!is_idle_domain(vcpu->domain))
-       rem_ac_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
+       stop_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
 }
 
 /*
  * Action for vtm when the domain is scheduled in.
- * Fire vtm IRQ or add the ac_timer for vtm.
+ * Fire vtm IRQ or add the timer for vtm.
  */
 void vtm_domain_in(VCPU *vcpu)
 {
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/vmx/vmx_process.c   Tue Jan 24 16:54:34 2006
@@ -41,6 +41,7 @@
 #include <asm/regionreg.h>
 #include <asm/privop.h>
 #include <asm/ia64_int.h>
+#include <asm/debugger.h>
 //#include <asm/hpsim_ssc.h>
 #include <asm/dom_fw.h>
 #include <asm/vmx_vcpu.h>
@@ -107,6 +108,14 @@
                if (running_on_sim) do_ssc(vcpu_get_gr_nat(current,36), regs);
                else do_ssc(vcpu_get_gr_nat(current,36), regs);
        }
+#endif
+#ifdef CRASH_DEBUG
+       if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
+        IS_VMM_ADDRESS(regs->cr_iip)) {
+               if (iim == 0)
+                       show_registers(regs);
+               debugger_trap_fatal(0 /* don't care */, regs);
+       } else
 #endif
        if (iim == d->arch.breakimm) {
                struct ia64_pal_retval y;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/domain.c        Tue Jan 24 16:54:34 2006
@@ -65,12 +65,14 @@
 
 unsigned long map_domain_page0(struct domain *);
 extern unsigned long dom_fw_setup(struct domain *, char *, int);
+static void init_switch_stack(struct vcpu *v);
 
 /* this belongs in include/asm, but there doesn't seem to be a suitable place 
*/
-void free_perdomain_pt(struct domain *d)
-{
-       printf("free_perdomain_pt: not implemented\n");
+void arch_domain_destroy(struct domain *d)
+{
+       printf("arch_domain_destroy: not implemented\n");
        //free_page((unsigned long)d->mm.perdomain_pt);
+       free_xenheap_page(d->shared_info);
 }
 
 static void default_idle(void)
@@ -87,7 +89,6 @@
        int cpu = smp_processor_id();
        for ( ; ; )
        {
-       printf ("idle%dD\n", cpu);
 #ifdef IA64
 //        __IRQ_STAT(cpu, idle_timestamp) = jiffies
 #else
@@ -145,16 +146,45 @@
 struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
 {
        struct vcpu *v;
-
-       if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
+       struct thread_info *ti;
+
+       /* Still keep idle vcpu0 static allocated at compilation, due
+        * to some code from Linux still requires it in early phase.
+        */
+       if (is_idle_domain(d) && !vcpu_id)
+           v = idle_vcpu[0];
+       else {
+           if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL)
                return NULL;
-
-       memset(v, 0, sizeof(*v)); 
-        memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch));
-       v->arch.privregs = 
+           memset(v, 0, sizeof(*v)); 
+       }
+
+       ti = alloc_thread_info(v);
+       /* Clear thread_info to clear some important fields, like
+        * preempt_count
+        */
+       memset(ti, 0, sizeof(struct thread_info));
+       init_switch_stack(v);
+
+       if (!is_idle_domain(d)) {
+           v->arch.privregs = 
                alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
-       printf("arch_vcpu_info=%p\n", v->arch.privregs);
-       memset(v->arch.privregs, 0, PAGE_SIZE);
+           BUG_ON(v->arch.privregs == NULL);
+           memset(v->arch.privregs, 0, PAGE_SIZE);
+
+           if (!vcpu_id)
+               memset(&d->shared_info->evtchn_mask[0], 0xff,
+                   sizeof(d->shared_info->evtchn_mask));
+
+           v->vcpu_info = &(d->shared_info->vcpu_info[0]);
+           v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
+           v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4;
+           v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0;
+           v->arch.metaphysical_saved_rr4 = d->arch.metaphysical_rr4;
+           v->arch.starting_rid = d->arch.starting_rid;
+           v->arch.ending_rid = d->arch.ending_rid;
+           v->arch.breakimm = d->arch.breakimm;
+       }
 
        return v;
 }
@@ -182,34 +212,21 @@
        memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
 }
 
-int arch_do_createdomain(struct vcpu *v)
-{
-       struct domain *d = v->domain;
-       struct thread_info *ti = alloc_thread_info(v);
-
-       /* Clear thread_info to clear some important fields, like preempt_count 
*/
-       memset(ti, 0, sizeof(struct thread_info));
-       init_switch_stack(v);
-
-       d->shared_info = (void *)alloc_xenheap_page();
-       if (!d->shared_info) {
-               printk("ERROR/HALTING: CAN'T ALLOC PAGE\n");
-               while (1);
-       }
+int arch_domain_create(struct domain *d)
+{
+       // the following will eventually need to be negotiated dynamically
+       d->xen_vastart = XEN_START_ADDR;
+       d->xen_vaend = XEN_END_ADDR;
+       d->shared_info_va = SHAREDINFO_ADDR;
+
+       if (is_idle_domain(d))
+           return 0;
+
+       if ((d->shared_info = (void *)alloc_xenheap_page()) == NULL)
+           goto fail_nomem;
        memset(d->shared_info, 0, PAGE_SIZE);
-       if (v == d->vcpu[0])
-           memset(&d->shared_info->evtchn_mask[0], 0xff,
-               sizeof(d->shared_info->evtchn_mask));
-#if 0
-       d->vcpu[0].arch.privregs = 
-                       alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
-       printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs);
-       memset(d->vcpu.arch.privregs, 0, PAGE_SIZE);
-#endif
-       v->vcpu_info = &(d->shared_info->vcpu_info[0]);
 
        d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
-
        /* We may also need emulation rid for region4, though it's unlikely
         * to see guest issue uncacheable access in metaphysical mode. But
         * keep such info here may be more sane.
@@ -217,41 +234,27 @@
        if (((d->arch.metaphysical_rr0 = allocate_metaphysical_rr()) == -1UL)
         || ((d->arch.metaphysical_rr4 = allocate_metaphysical_rr()) == -1UL))
                BUG();
-//     VCPU(v, metaphysical_mode) = 1;
-       v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
-       v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4;
-       v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0;
-       v->arch.metaphysical_saved_rr4 = d->arch.metaphysical_rr4;
 #define DOMAIN_RID_BITS_DEFAULT 18
        if (!allocate_rid_range(d,DOMAIN_RID_BITS_DEFAULT)) // FIXME
                BUG();
-       v->arch.starting_rid = d->arch.starting_rid;
-       v->arch.ending_rid = d->arch.ending_rid;
-       // the following will eventually need to be negotiated dynamically
-       d->xen_vastart = XEN_START_ADDR;
-       d->xen_vaend = XEN_END_ADDR;
-       d->shared_info_va = SHAREDINFO_ADDR;
        d->arch.breakimm = 0x1000;
-       v->arch.breakimm = d->arch.breakimm;
-
        d->arch.sys_pgnr = 0;
-       if (d->domain_id != IDLE_DOMAIN_ID) {
-               d->arch.mm = xmalloc(struct mm_struct);
-               if (unlikely(!d->arch.mm)) {
-                       printk("Can't allocate mm_struct for domain 
%d\n",d->domain_id);
-                       return -ENOMEM;
-               }
-               memset(d->arch.mm, 0, sizeof(*d->arch.mm));
-               d->arch.mm->pgd = pgd_alloc(d->arch.mm);
-               if (unlikely(!d->arch.mm->pgd)) {
-                       printk("Can't allocate pgd for domain 
%d\n",d->domain_id);
-                       return -ENOMEM;
-               }
-       } else
-               d->arch.mm = NULL;
-       printf ("arch_do_create_domain: domain=%p\n", d);
-
+
+       if ((d->arch.mm = xmalloc(struct mm_struct)) == NULL)
+           goto fail_nomem;
+       memset(d->arch.mm, 0, sizeof(*d->arch.mm));
+
+       if ((d->arch.mm->pgd = pgd_alloc(d->arch.mm)) == NULL)
+           goto fail_nomem;
+
+       printf ("arch_domain_create: domain=%p\n", d);
        return 0;
+
+fail_nomem:
+       free_xenheap_page(d->shared_info);
+       xfree(d->arch.mm);
+       pgd_free(d->arch.mm->pgd);
+       return -ENOMEM;
 }
 
 void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/hyperprivop.S
--- a/xen/arch/ia64/xen/hyperprivop.S   Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/hyperprivop.S   Tue Jan 24 16:54:34 2006
@@ -12,6 +12,7 @@
 #include <asm/offsets.h>
 #include <asm/processor.h>
 #include <asm/system.h>
+#include <asm/debugger.h>
 #include <public/arch-ia64.h>
 
 
@@ -549,7 +550,12 @@
 (p7)    br.spnt.many 1f ;;
         cmp.eq p7,p0=r17,r0
 (p7)    br.spnt.few dispatch_break_fault ;;
-1:
+#ifdef CRASH_DEBUG
+       movl r21=CDB_BREAK_NUM ;;
+       cmp.eq p7,p0=r17,r21
+(p7)   br.spnt.few dispatch_break_fault ;;
+#endif 
+1:     
 #if 1 /* special handling in case running on simulator */
        movl r20=first_break;;
        ld4 r23=[r20];;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/idle0_task.c
--- a/xen/arch/ia64/xen/idle0_task.c    Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/idle0_task.c    Tue Jan 24 16:54:34 2006
@@ -11,29 +11,14 @@
        .mmlist         = LIST_HEAD_INIT(name.mmlist),          \
 }
 
-#define IDLE0_EXEC_DOMAIN(_ed,_d)    \
+#define IDLE_VCPU(_v)               \
 {                                    \
     processor:   0,                  \
-    mm:          0,                  \
-    thread:      INIT_THREAD,        \
-    domain:      (_d)                \
-}
-
-#define IDLE0_DOMAIN(_t)             \
-{                                    \
-    domain_id:   IDLE_DOMAIN_ID,     \
-    refcnt:      ATOMIC_INIT(1)      \
+    domain:      0                   \
 }
 
 struct mm_struct init_mm = INIT_MM(init_mm);
 EXPORT_SYMBOL(init_mm);
-
-struct domain idle0_domain = IDLE0_DOMAIN(idle0_domain);
-#if 0
-struct vcpu idle0_vcpu = IDLE0_EXEC_DOMAIN(idle0_vcpu,
-                                                         &idle0_domain);
-#endif
-
 
 /*
  * Initial task structure.
@@ -43,15 +28,12 @@
  */
 union {
        struct {
-               struct domain task;
+               struct vcpu task;
        } s;
        unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
-} init_task_mem asm ("init_task") __attribute__((section(".data.init_task")));
-// = {{
-       ;
-//.task =              IDLE0_EXEC_DOMAIN(init_task_mem.s.task,&idle0_domain),
-//};
-//};
+} init_task_mem asm ("init_task") __attribute__((section(".data.init_task"))) 
= {{
+       .task = IDLE_VCPU(init_task_mem.s.task)
+}};
 
 EXPORT_SYMBOL(init_task);
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/ivt.S
--- a/xen/arch/ia64/xen/ivt.S   Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/ivt.S   Tue Jan 24 16:54:34 2006
@@ -15,6 +15,7 @@
 #define sys_call_table 0
 #define sys_ni_syscall 0
 #include <asm/vhpt.h>
+#include <asm/debugger.h>
 #endif
 /*
  * arch/ia64/kernel/ivt.S
@@ -841,6 +842,13 @@
        ;;
        cmp.eq p7,p0=r17,r0
 (p7)   br.spnt.few dispatch_break_fault ;;
+#ifdef CRASH_DEBUG
+        // panic can occur before domain0 is created.
+        // in such case referencing XSI_PSR_IC causes nested_dtlb_miss
+        movl r18=CDB_BREAK_NUM ;;
+        cmp.eq p7,p0=r17,r18 ;; 
+(p7)    br.spnt.few dispatch_break_fault ;;
+#endif
        movl r18=XSI_PSR_IC
        ;;
        ld8 r19=[r18]
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/mm_init.c
--- a/xen/arch/ia64/xen/mm_init.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/mm_init.c       Tue Jan 24 16:54:34 2006
@@ -502,6 +502,7 @@
 }
 #endif /* CONFIG_VIRTUAL_MEM_MAP */
 
+#ifndef XEN
 static int
 count_reserved_pages (u64 start, u64 end, void *arg)
 {
@@ -514,6 +515,7 @@
        *count += num_reserved;
        return 0;
 }
+#endif
 
 /*
  * Boot command-line option "nolwsys" can be used to disable the use of any 
light-weight
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/process.c       Tue Jan 24 16:54:34 2006
@@ -31,6 +31,7 @@
 #include <asm/dom_fw.h>
 #include "hpsim_ssc.h"
 #include <xen/multicall.h>
+#include <asm/debugger.h>
 
 extern unsigned long vcpu_get_itir_on_fault(struct vcpu *, UINT64);
 extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
@@ -652,7 +653,7 @@
 ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, 
unsigned long iim)
 {
        struct domain *d = (struct domain *) current->domain;
-       struct vcpu *v = (struct domain *) current;
+       struct vcpu *v = current;
        extern unsigned long running_on_sim;
 
        if (first_break) {
@@ -663,7 +664,14 @@
        if (iim == 0x80001 || iim == 0x80002) { //FIXME: don't hardcode constant
                if (running_on_sim) do_ssc(vcpu_get_gr(current,36), regs);
                else do_ssc(vcpu_get_gr(current,36), regs);
-       }
+       } 
+#ifdef CRASH_DEBUG
+       else if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs)) {
+               if (iim == 0)
+                       show_registers(regs);
+               debugger_trap_fatal(0 /* don't care */, regs);
+       } 
+#endif
        else if (iim == d->arch.breakimm) {
                /* by default, do not continue */
                v->arch.hypercall_continuation = 0;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/sn_console.c
--- a/xen/arch/ia64/xen/sn_console.c    Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/sn_console.c    Tue Jan 24 16:54:34 2006
@@ -4,6 +4,7 @@
  * Copyright (c) 2005 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
+#include <xen/lib.h>
 #include <asm/acpi.h>
 #include <asm/sn/sn_sal.h>
 #include <xen/serial.h>
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/xenmisc.c
--- a/xen/arch/ia64/xen/xenmisc.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/xenmisc.c       Tue Jan 24 16:54:34 2006
@@ -18,6 +18,7 @@
 #include <xen/softirq.h>
 #include <public/sched.h>
 #include <asm/vhpt.h>
+#include <asm/debugger.h>
 
 efi_memory_desc_t ia64_efi_io_md;
 EXPORT_SYMBOL(ia64_efi_io_md);
@@ -75,7 +76,7 @@
 
 void raise_actimer_softirq(void)
 {
-       raise_softirq(AC_TIMER_SOFTIRQ);
+       raise_softirq(TIMER_SOFTIRQ);
 }
 
 unsigned long
@@ -202,6 +203,8 @@
 {
        printk("dump_pageframe_info not implemented\n");
 }
+
+int nmi_count(int x) { return x; }
 
 ///////////////////////////////
 // called from arch/ia64/head.S
@@ -354,6 +357,11 @@
        va_end(args);
        printf(buf);
        if (regs) show_registers(regs);
+       if (regs) {
+               debugger_trap_fatal(0 /* don't care */, regs);
+       } else {
+               debugger_trap_immediate();
+       }
        domain_pause_by_systemcontroller(current->domain);
        v->domain->shutdown_code = SHUTDOWN_crash;
        set_bit(_DOMF_shutdown, v->domain->domain_flags);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/xensetup.c      Tue Jan 24 16:54:34 2006
@@ -21,12 +21,13 @@
 #include <asm/page.h>
 #include <asm/setup.h>
 #include <xen/string.h>
+#include <asm/vmx.h>
 
 unsigned long xenheap_phys_end;
 
 char saved_command_line[COMMAND_LINE_SIZE];
 
-struct vcpu *idle_vcpu[NR_CPUS] = { &idle0_vcpu };
+struct vcpu *idle_vcpu[NR_CPUS];
 
 cpumask_t cpu_present_map;
 
@@ -156,15 +157,11 @@
     unsigned long dom0_memory_start, dom0_memory_size;
     unsigned long dom0_initrd_start, dom0_initrd_size;
     unsigned long initial_images_start, initial_images_end;
+    struct domain *idle_domain;
 
     running_on_sim = is_platform_hp_ski();
     /* Kernel may be relocated by EFI loader */
     xen_pstart = ia64_tpa(KERNEL_START);
-
-    /* Must do this early -- e.g., spinlocks rely on get_current(). */
-    //set_current(&idle0_vcpu);
-    ia64_r13 = (void *)&idle0_vcpu;
-    idle0_vcpu.domain = &idle0_domain;
 
     early_setup_arch(&cmdline);
 
@@ -281,18 +278,22 @@
        (xenheap_phys_end-__pa(heap_start)) >> 20,
        (xenheap_phys_end-__pa(heap_start)) >> 10);
 
+printk("About to call scheduler_init()\n");
+    scheduler_init();
+    idle_vcpu[0] = (struct vcpu*) ia64_r13;
+    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
+    BUG_ON(idle_domain == NULL);
+
     late_setup_arch(&cmdline);
     setup_per_cpu_areas();
     mem_init();
 
-printk("About to call scheduler_init()\n");
-    scheduler_init();
     local_irq_disable();
     init_IRQ ();
 printk("About to call init_xen_time()\n");
     init_xen_time(); /* initialise the time */
-printk("About to call ac_timer_init()\n");
-    ac_timer_init();
+printk("About to call timer_init()\n");
+    timer_init();
 
 #ifdef CONFIG_XEN_CONSOLE_INPUT        /* CONFIG_SERIAL_8250_CONSOLE=n in 
dom0! */
     initialize_keytable();
@@ -308,13 +309,9 @@
     }
 
     smp_prepare_cpus(max_cpus);
-
     /* We aren't hotplug-capable yet. */
-    //BUG_ON(!cpus_empty(cpu_present_map));
     for_each_cpu ( i )
         cpu_set(i, cpu_present_map);
-
-    //BUG_ON(!local_irq_is_enabled());
 
     /*  Enable IRQ to receive IPI (needed for ITC sync).  */
     local_irq_enable();
@@ -342,19 +339,14 @@
 
 
     /* Create initial domain 0. */
-printk("About to call do_createdomain()\n");
-    dom0 = do_createdomain(0, 0);
-    init_task.domain = &idle0_domain;
-    init_task.processor = 0;
-//    init_task.mm = &init_mm;
-    init_task.domain->arch.mm = &init_mm;
-//    init_task.thread = INIT_THREAD;
-    //arch_do_createdomain(current);
+printk("About to call domain_create()\n");
+    dom0 = domain_create(0, 0);
+
 #ifdef CLONE_DOMAIN0
     {
     int i;
     for (i = 0; i < CLONE_DOMAIN0; i++) {
-       clones[i] = do_createdomain(i+1, 0);
+       clones[i] = domain_create(i+1, 0);
         if ( clones[i] == NULL )
             panic("Error creating domain0 clone %d\n",i);
     }
@@ -431,8 +423,8 @@
 
     local_irq_enable();
 
-    printf("About to call schedulers_start dom0=%p, idle0_dom=%p\n",
-          dom0, &idle0_domain);
+    printf("About to call schedulers_start dom0=%p, idle_dom=%p\n",
+          dom0, &idle_domain);
     schedulers_start();
 
     domain_unpause_by_systemcontroller(dom0);
@@ -445,9 +437,10 @@
 {
     char *p=info;
 
-    *p=0;
-
-    p+=sprintf(p,"xen_%d.%d_ia64 ",XEN_VERSION,XEN_SUBVERSION);
+    p += sprintf(p,"xen-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
+
+    if (vmx_enabled)
+        p += sprintf(p,"hvm-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
 
     *(p-1) = 0;
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/xentime.c
--- a/xen/arch/ia64/xen/xentime.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/xentime.c       Tue Jan 24 16:54:34 2006
@@ -196,7 +196,7 @@
 //#endif
                /* double check, in case we got hit by a (slow) PMI: */
        } while (time_after_eq(ia64_get_itc(), new_itm));
-       raise_softirq(AC_TIMER_SOFTIRQ);
+       raise_softirq(TIMER_SOFTIRQ);
 
        return IRQ_HANDLED;
 }
@@ -235,7 +235,7 @@
     return 0;
 }
 
-int reprogram_ac_timer(s_time_t timeout)
+int reprogram_timer(s_time_t timeout)
 {
        struct vcpu *v = current;
        s_time_t expire;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/Makefile     Tue Jan 24 16:54:34 2006
@@ -32,7 +32,7 @@
 OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS))
 
 ifneq ($(crash_debug),y)
-OBJS := $(patsubst cdb%.o,,$(OBJS))
+OBJS := $(patsubst gdbstub%.o,,$(OBJS))
 endif
 
 default: $(TARGET)
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/apic.c       Tue Jan 24 16:54:34 2006
@@ -870,7 +870,7 @@
  * returns 1 on success
  * returns 0 if the timeout value is too small or in the past.
  */
-int reprogram_ac_timer(s_time_t timeout)
+int reprogram_timer(s_time_t timeout)
 {
     s_time_t    now;
     s_time_t    expire;
@@ -931,7 +931,7 @@
 {
     ack_APIC_irq();
     perfc_incrc(apic_timer);
-    raise_softirq(AC_TIMER_SOFTIRQ);
+    raise_softirq(TIMER_SOFTIRQ);
 }
 
 /*
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/domain.c     Tue Jan 24 16:54:34 2006
@@ -110,6 +110,20 @@
             break;
 }
 
+void __attribute__((noreturn)) __machine_halt(void *unused)
+{
+    for ( ; ; )
+        safe_halt();
+}
+
+void machine_halt(void)
+{
+    watchdog_disable();
+    console_start_sync();
+    smp_call_function(__machine_halt, NULL, 1, 0);
+    __machine_halt(NULL);
+}
+
 void machine_restart(char * __unused)
 {
     int i;
@@ -117,8 +131,7 @@
     if ( opt_noreboot )
     {
         printk("Reboot disabled on cmdline: require manual reset\n");
-        for ( ; ; )
-            safe_halt();
+        machine_halt();
     }
 
     watchdog_disable();
@@ -164,20 +177,6 @@
 }
 
 
-void __attribute__((noreturn)) __machine_halt(void *unused)
-{
-    for ( ; ; )
-        safe_halt();
-}
-
-void machine_halt(void)
-{
-    watchdog_disable();
-    console_start_sync();
-    smp_call_function(__machine_halt, NULL, 1, 0);
-    __machine_halt(NULL);
-}
-
 void dump_pageframe_info(struct domain *d)
 {
     struct pfn_info *page;
@@ -215,7 +214,6 @@
 
     memset(v, 0, sizeof(*v));
 
-    memcpy(&v->arch, &idle_vcpu[0]->arch, sizeof(v->arch));
     v->arch.flags = TF_kernel_mode;
 
     if ( is_idle_domain(d) )
@@ -223,40 +221,31 @@
         percpu_ctxt[vcpu_id].curr_vcpu = v;
         v->arch.schedule_tail = continue_idle_domain;
     }
-
-    if ( (v->vcpu_id = vcpu_id) != 0 )
-    {
-        v->arch.schedule_tail  = d->vcpu[0]->arch.schedule_tail;
-        v->arch.perdomain_ptes =
-            d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
-    }
+    else
+    {
+        v->arch.schedule_tail = continue_nonidle_domain;
+    }
+
+    v->arch.perdomain_ptes =
+        d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
+
+    v->arch.guest_vtable  = __linear_l2_table;
+    v->arch.shadow_vtable = __shadow_linear_l2_table;
+#if defined(__x86_64__)
+    v->arch.guest_vl3table = __linear_l3_table;
+    v->arch.guest_vl4table = __linear_l4_table;
+#endif
 
     return v;
 }
 
 void free_vcpu_struct(struct vcpu *v)
 {
-    BUG_ON(v->next_in_list != NULL);
-    if ( v->vcpu_id != 0 )
-        v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL;
     xfree(v);
 }
 
-void free_perdomain_pt(struct domain *d)
-{
-    free_xenheap_pages(
-        d->arch.mm_perdomain_pt,
-        get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
-
-#ifdef __x86_64__
-    free_xenheap_page(d->arch.mm_perdomain_l2);
-    free_xenheap_page(d->arch.mm_perdomain_l3);
-#endif
-}
-
-int arch_do_createdomain(struct vcpu *v)
-{
-    struct domain *d = v->domain;
+int arch_domain_create(struct domain *d)
+{
     l1_pgentry_t gdt_l1e;
     int vcpuid, pdpt_order, rc;
 #ifdef __x86_64__
@@ -267,9 +256,7 @@
     d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order);
     if ( d->arch.mm_perdomain_pt == NULL )
         goto fail_nomem;
-
     memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order);
-    v->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
 
     /*
      * Map Xen segments into every VCPU's GDT, irrespective of whether every
@@ -283,19 +270,11 @@
         d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
                                  FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
 
-    v->arch.guest_vtable  = __linear_l2_table;
-    v->arch.shadow_vtable = __shadow_linear_l2_table;
-
 #if defined(__i386__)
 
-    d->arch.mapcache.l1tab = d->arch.mm_perdomain_pt +
-        (GDT_LDT_MBYTES << (20 - PAGE_SHIFT));
-    spin_lock_init(&d->arch.mapcache.lock);
+    mapcache_init(d);
 
 #else /* __x86_64__ */
-
-    v->arch.guest_vl3table = __linear_l3_table;
-    v->arch.guest_vl4table = __linear_l4_table;
 
     d->arch.mm_perdomain_l2 = alloc_xenheap_page();
     d->arch.mm_perdomain_l3 = alloc_xenheap_page();
@@ -333,10 +312,7 @@
             goto fail_nomem;
 
         memset(d->shared_info, 0, PAGE_SIZE);
-        v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
         SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
-
-        v->arch.schedule_tail = continue_nonidle_domain;
     }
 
     return 0;
@@ -349,6 +325,20 @@
 #endif
     free_xenheap_pages(d->arch.mm_perdomain_pt, pdpt_order);
     return -ENOMEM;
+}
+
+void arch_domain_destroy(struct domain *d)
+{
+    free_xenheap_pages(
+        d->arch.mm_perdomain_pt,
+        get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
+
+#ifdef __x86_64__
+    free_xenheap_page(d->arch.mm_perdomain_l2);
+    free_xenheap_page(d->arch.mm_perdomain_l3);
+#endif
+
+    free_xenheap_page(d->shared_info);
 }
 
 /* This is called by arch_final_setup_guest and do_boot_vcpu */
@@ -481,14 +471,6 @@
 
 
 #ifdef __x86_64__
-
-void toggle_guest_mode(struct vcpu *v)
-{
-    v->arch.flags ^= TF_kernel_mode;
-    __asm__ __volatile__ ( "swapgs" );
-    update_pagetables(v);
-    write_ptbase(v);
-}
 
 #define loadsegment(seg,value) ({               \
     int __r = 1;                                \
@@ -659,35 +641,6 @@
     percpu_ctxt[smp_processor_id()].dirty_segment_mask = dirty_segment_mask;
 }
 
-long do_switch_to_user(void)
-{
-    struct cpu_user_regs  *regs = guest_cpu_user_regs();
-    struct switch_to_user  stu;
-    struct vcpu    *v = current;
-
-    if ( unlikely(copy_from_user(&stu, (void *)regs->rsp, sizeof(stu))) ||
-         unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
-        return -EFAULT;
-
-    toggle_guest_mode(v);
-
-    regs->rip    = stu.rip;
-    regs->cs     = stu.cs | 3; /* force guest privilege */
-    regs->rflags = (stu.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;
-    regs->rsp    = stu.rsp;
-    regs->ss     = stu.ss | 3; /* force guest privilege */
-
-    if ( !(stu.flags & VGCF_IN_SYSCALL) )
-    {
-        regs->entry_vector = 0;
-        regs->r11 = stu.r11;
-        regs->rcx = stu.rcx;
-    }
-
-    /* Saved %rax gets written back to regs->rax in entry.S. */
-    return stu.rax;
-}
-
 #define switch_kernel_stack(_n,_c) ((void)0)
 
 #elif defined(__i386__)
@@ -785,7 +738,8 @@
     if ( unlikely(!cpu_isset(cpu, dirty_mask) && !cpus_empty(dirty_mask)) )
     {
         /* Other cpus call __sync_lazy_execstate from flush ipi handler. */
-        flush_tlb_mask(dirty_mask);
+        if ( !cpus_empty(next->vcpu_dirty_cpumask) )
+            flush_tlb_mask(next->vcpu_dirty_cpumask);
     }
 
     local_irq_disable();
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/mm.c Tue Jan 24 16:54:34 2006
@@ -297,7 +297,6 @@
 
 #if defined(__x86_64__)
     /* If in user mode, switch to kernel mode just to read LDT mapping. */
-    extern void toggle_guest_mode(struct vcpu *);
     int user_mode = !(v->arch.flags & TF_kernel_mode);
 #define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
 #elif defined(__i386__)
@@ -2971,7 +2970,6 @@
 
 #ifdef CONFIG_X86_64
     struct vcpu *v = current;
-    extern void toggle_guest_mode(struct vcpu *);
     int user_mode = !(v->arch.flags & TF_kernel_mode);
 #endif
 
@@ -3001,7 +2999,7 @@
         BUG();
     }
     PTWR_PRINTK("[%c] disconnected_l1va at %p is %"PRIpte"\n",
-                PTWR_PRINT_WHICH, ptep, pte.l1);
+                PTWR_PRINT_WHICH, ptep, l1e_get_intpte(pte));
     l1e_remove_flags(pte, _PAGE_RW);
 
     /* Write-protect the p.t. page in the guest page table. */
@@ -3019,18 +3017,31 @@
     /* NB. INVLPG is a serialising instruction: flushes pending updates. */
     flush_tlb_one_mask(d->domain_dirty_cpumask, l1va);
     PTWR_PRINTK("[%c] disconnected_l1va at %p now %"PRIpte"\n",
-                PTWR_PRINT_WHICH, ptep, pte.l1);
+                PTWR_PRINT_WHICH, ptep, l1e_get_intpte(pte));
 
     /*
      * STEP 2. Validate any modified PTEs.
      */
 
-    pl1e = d->arch.ptwr[which].pl1e;
-    modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
-    unmap_domain_page(pl1e);
-    perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
-    ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
-    d->arch.ptwr[which].prev_nr_updates = modified;
+    if ( likely(d == current->domain) )
+    {
+        pl1e = map_domain_page(l1e_get_pfn(pte));
+        modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
+        unmap_domain_page(pl1e);
+        perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
+        ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified);
+        d->arch.ptwr[which].prev_nr_updates = modified;
+    }
+    else
+    {
+        /*
+         * Must make a temporary global mapping, since we are running in the
+         * wrong address space, so no access to our own mapcache.
+         */
+        pl1e = map_domain_page_global(l1e_get_pfn(pte));
+        modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page);
+        unmap_domain_page_global(pl1e);
+    }
 
     /*
      * STEP 3. Reattach the L1 p.t. page into the current address space.
@@ -3208,7 +3219,7 @@
 {
     unsigned long    pfn;
     struct pfn_info *page;
-    l1_pgentry_t     pte;
+    l1_pgentry_t    *pl1e, pte;
     l2_pgentry_t    *pl2e, l2e;
     int              which, flags;
     unsigned long    l2_idx;
@@ -3345,11 +3356,10 @@
     }
     
     /* Temporarily map the L1 page, and make a copy of it. */
-    d->arch.ptwr[which].pl1e = map_domain_page(pfn);
-    memcpy(d->arch.ptwr[which].page,
-           d->arch.ptwr[which].pl1e,
-           L1_PAGETABLE_ENTRIES * sizeof(l1_pgentry_t));
-    
+    pl1e = map_domain_page(pfn);
+    memcpy(d->arch.ptwr[which].page, pl1e, PAGE_SIZE);
+    unmap_domain_page(pl1e);
+
     /* Finally, make the p.t. page writable by the guest OS. */
     l1e_add_flags(pte, _PAGE_RW);
     if ( unlikely(__put_user(pte.l1,
@@ -3358,7 +3368,6 @@
         MEM_LOG("ptwr: Could not update pte at %p", (unsigned long *)
                 &linear_pg_table[l1_linear_offset(addr)]);
         /* Toss the writable pagetable state and crash. */
-        unmap_domain_page(d->arch.ptwr[which].pl1e);
         d->arch.ptwr[which].l1va = 0;
         domain_crash(d);
         return 0;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/nmi.c
--- a/xen/arch/x86/nmi.c        Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/nmi.c        Tue Jan 24 16:54:34 2006
@@ -23,18 +23,20 @@
 #include <xen/sched.h>
 #include <xen/console.h>
 #include <xen/smp.h>
+#include <xen/keyhandler.h>
 #include <asm/current.h>
 #include <asm/mc146818rtc.h>
 #include <asm/msr.h>
 #include <asm/mpspec.h>
 #include <asm/debugger.h>
 #include <asm/div64.h>
+#include <asm/apic.h>
 
 unsigned int nmi_watchdog = NMI_NONE;
 static unsigned int nmi_hz = HZ;
 static unsigned int nmi_perfctr_msr;   /* the MSR to reset in NMI handler */
 static unsigned int nmi_p4_cccr_val;
-static struct ac_timer nmi_timer[NR_CPUS];
+static struct timer nmi_timer[NR_CPUS];
 static unsigned int nmi_timer_ticks[NR_CPUS];
 
 /*
@@ -132,7 +134,7 @@
 {
     int cpu = smp_processor_id();
     nmi_timer_ticks[cpu]++;
-    set_ac_timer(&nmi_timer[cpu], NOW() + MILLISECS(1000));
+    set_timer(&nmi_timer[cpu], NOW() + MILLISECS(1000));
 }
 
 static void disable_lapic_nmi_watchdog(void)
@@ -308,8 +310,6 @@
 
 void __pminit setup_apic_nmi_watchdog(void)
 {
-    int cpu = smp_processor_id();
-
     if (!nmi_watchdog)
         return;
 
@@ -344,49 +344,37 @@
 
     lapic_nmi_owner = LAPIC_NMI_WATCHDOG;
     nmi_active = 1;
-
-    init_ac_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu);
 }
 
 static unsigned int
 last_irq_sums [NR_CPUS],
     alert_counter [NR_CPUS];
 
-static spinlock_t   watchdog_lock = SPIN_LOCK_UNLOCKED;
-static unsigned int watchdog_disable_count = 1;
-static unsigned int watchdog_on;
+static atomic_t watchdog_disable_count = ATOMIC_INIT(1);
 
 void watchdog_disable(void)
 {
-    unsigned long flags;
-
-    spin_lock_irqsave(&watchdog_lock, flags);
-
-    if ( watchdog_disable_count++ == 0 )
-        watchdog_on = 0;
-
-    spin_unlock_irqrestore(&watchdog_lock, flags);
+    atomic_inc(&watchdog_disable_count);
 }
 
 void watchdog_enable(void)
 {
-    unsigned int  cpu;
-    unsigned long flags;
-
-    spin_lock_irqsave(&watchdog_lock, flags);
-
-    if ( --watchdog_disable_count == 0 )
+    static unsigned long heartbeat_initialised;
+    unsigned int cpu;
+
+    if ( !atomic_dec_and_test(&watchdog_disable_count) ||
+         test_and_set_bit(0, &heartbeat_initialised) )
+        return;
+
+    /*
+     * Activate periodic heartbeats. We cannot do this earlier during 
+     * setup because the timer infrastructure is not available.
+     */
+    for_each_online_cpu ( cpu )
     {
-        watchdog_on = 1;
-        /*
-         * Ensure periodic heartbeats are active. We cannot do this earlier
-         * during setup because the timer infrastructure is not available. 
-         */
-        for_each_online_cpu ( cpu )
-            set_ac_timer(&nmi_timer[cpu], NOW());
-    }
-
-    spin_unlock_irqrestore(&watchdog_lock, flags);
+        init_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu);
+        set_timer(&nmi_timer[cpu], NOW());
+    }
 }
 
 void nmi_watchdog_tick(struct cpu_user_regs * regs)
@@ -395,7 +383,7 @@
 
     sum = nmi_timer_ticks[cpu];
 
-    if ( (last_irq_sums[cpu] == sum) && watchdog_on )
+    if ( (last_irq_sums[cpu] == sum) && !atomic_read(&watchdog_disable_count) )
     {
         /*
          * Ayiee, looks like this CPU is stuck ... wait a few IRQs (5 seconds) 
@@ -440,3 +428,51 @@
         write_watchdog_counter(NULL);
     }
 }
+
+/*
+ * For some reason the destination shorthand for self is not valid
+ * when used with the NMI delivery mode. This is documented in Tables
+ * 8-3 and 8-4 in IA32 Reference Manual Volume 3. We send the IPI to
+ * our own APIC ID explicitly which is valid.
+ */
+static void do_nmi_trigger(unsigned char key)
+{
+    u32 id = apic_read(APIC_ID);
+
+    printk("Triggering NMI on APIC ID %x\n", id);
+
+    local_irq_disable();
+    apic_wait_icr_idle();
+    apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(id));
+    apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_INT_ASSERT);
+    local_irq_enable();
+}
+
+static void do_nmi_stats(unsigned char key)
+{
+    int i;
+    struct domain *d;
+    struct vcpu *v;
+    printk("CPU\tNMI\n");
+    for_each_cpu(i)
+        printk("%3d\t%3d\n", i, nmi_count(i));
+
+    if ((d = dom0) == NULL)
+        return;
+    if ((v = d->vcpu[0]) == NULL)
+        return;
+    if (v->vcpu_flags & (VCPUF_nmi_pending|VCPUF_nmi_masked))
+        printk("dom0 vpu0: NMI %s%s\n",
+               v->vcpu_flags & VCPUF_nmi_pending ? "pending " : "",
+               v->vcpu_flags & VCPUF_nmi_masked ? "masked " : "");
+    else
+        printk("dom0 vcpu0: NMI neither pending nor masked\n");
+}
+
+static __init int register_nmi_trigger(void)
+{
+    register_keyhandler('n', do_nmi_trigger, "trigger an NMI");
+    register_keyhandler('N', do_nmi_stats,   "NMI statistics");
+    return 0;
+}
+__initcall(register_nmi_trigger);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/setup.c      Tue Jan 24 16:54:34 2006
@@ -385,7 +385,7 @@
 
     scheduler_init();
 
-    idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
+    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     BUG_ON(idle_domain == NULL);
 
     set_current(idle_domain->vcpu[0]);
@@ -423,7 +423,7 @@
 
     trap_init();
 
-    ac_timer_init();
+    timer_init();
 
     early_time_init();
 
@@ -478,7 +478,8 @@
 
     schedulers_start();
 
-    watchdog_enable();
+    if ( opt_watchdog ) 
+        watchdog_enable();
 
     shadow_mode_init();
 
@@ -486,7 +487,7 @@
     acm_init(&initrdidx, mbi, initial_images_start);
 
     /* Create initial domain 0. */
-    dom0 = do_createdomain(0, 0);
+    dom0 = domain_create(0, 0);
     if ( dom0 == NULL )
         panic("Error creating domain 0\n");
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/shadow.c     Tue Jan 24 16:54:34 2006
@@ -469,6 +469,7 @@
 {
     unsigned long smfn;
     l2_pgentry_t *spl2e;
+    int i;
 
     SH_VVLOG("shadow_l2_table(gpfn=%lx, gmfn=%lx)", gpfn, gmfn);
 
@@ -503,9 +504,11 @@
         spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
             l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
 
-        spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-            
l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
-                            __PAGE_HYPERVISOR);
+        for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+            spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
+                l2e_from_page(virt_to_page(page_get_owner(pfn_to_page(gmfn))->
+                                           arch.mm_perdomain_pt) + i,
+                              __PAGE_HYPERVISOR);
 
         if ( shadow_mode_translate(d) ) // NB: not external
         {
@@ -2135,6 +2138,7 @@
 #if CONFIG_PAGING_LEVELS == 2
     unsigned long hl2mfn;
 #endif
+    int need_sync = 0;
 
     int max_mode = ( shadow_mode_external(d) ? SHM_external
                      : shadow_mode_translate(d) ? SHM_translate
@@ -2150,8 +2154,8 @@
     if ( max_mode & (SHM_enable | SHM_external) )
     {
         if ( likely(v->arch.guest_vtable != NULL) )
-            unmap_domain_page(v->arch.guest_vtable);
-        v->arch.guest_vtable = map_domain_page(gmfn);
+            unmap_domain_page_global(v->arch.guest_vtable);
+        v->arch.guest_vtable = map_domain_page_global(gmfn);
     }
 
     /*
@@ -2166,8 +2170,17 @@
 #elif CONFIG_PAGING_LEVELS == 4
         smfn = shadow_l4_table(d, gpfn, gmfn);
 #endif
-    }else
-        shadow_sync_all(d);
+    }
+    else
+    {
+        /*
+         *  move sync later in order to avoid this smfn been 
+         *  unshadowed occasionally
+         */
+        need_sync = 1;
+    }
+
+
     if ( !get_shadow_ref(smfn) )
         BUG();
     old_smfn = pagetable_get_pfn(v->arch.shadow_table);
@@ -2187,8 +2200,8 @@
         )
     {
         if ( v->arch.shadow_vtable )
-            unmap_domain_page(v->arch.shadow_vtable);
-        v->arch.shadow_vtable = map_domain_page(smfn);
+            unmap_domain_page_global(v->arch.shadow_vtable);
+        v->arch.shadow_vtable = map_domain_page_global(smfn);
     }
 
 #if CONFIG_PAGING_LEVELS == 2
@@ -2204,8 +2217,8 @@
         if ( unlikely(!(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow))) )
             hl2mfn = shadow_hl2_table(d, gpfn, gmfn, smfn);
         if ( v->arch.hl2_vtable )
-            unmap_domain_page(v->arch.hl2_vtable);
-        v->arch.hl2_vtable = map_domain_page(hl2mfn);
+            unmap_domain_page_global(v->arch.hl2_vtable);
+        v->arch.hl2_vtable = map_domain_page_global(hl2mfn);
     }
 
     /*
@@ -2237,6 +2250,9 @@
         local_flush_tlb();
     }
 #endif /* CONFIG_PAGING_LEVELS == 2 */
+
+    if(likely(need_sync))
+        shadow_sync_all(d);
 
 #if CONFIG_PAGING_LEVELS == 3
     /* FIXME: PAE code to be written */
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/shadow32.c   Tue Jan 24 16:54:34 2006
@@ -726,6 +726,7 @@
     l2_pgentry_t *mpl2e;
     struct pfn_info *mmfn_info;
     struct domain *d = v->domain;
+    int i;
 
     ASSERT(pagetable_get_paddr(v->arch.monitor_table) == 0);
 
@@ -733,16 +734,17 @@
     ASSERT(mmfn_info != NULL);
 
     mmfn = page_to_pfn(mmfn_info);
-    mpl2e = (l2_pgentry_t *)map_domain_page(mmfn);
+    mpl2e = (l2_pgentry_t *)map_domain_page_global(mmfn);
     memset(mpl2e, 0, PAGE_SIZE);
 
     memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
            &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
            HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
 
-    mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-        l2e_from_paddr(__pa(d->arch.mm_perdomain_pt),
-                        __PAGE_HYPERVISOR);
+    for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+        mpl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
+            l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
+                          __PAGE_HYPERVISOR);
 
     // map the phys_to_machine map into the Read-Only MPT space for this domain
     mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
@@ -794,7 +796,7 @@
      * Then free monitor_table.
      */
     mfn = pagetable_get_pfn(v->arch.monitor_table);
-    unmap_domain_page(v->arch.monitor_vtable);
+    unmap_domain_page_global(v->arch.monitor_vtable);
     free_domheap_page(pfn_to_page(mfn));
 
     v->arch.monitor_table = mk_pagetable(0);
@@ -929,7 +931,7 @@
         if ( v->arch.guest_vtable &&
              (v->arch.guest_vtable != __linear_l2_table) )
         {
-            unmap_domain_page(v->arch.guest_vtable);
+            unmap_domain_page_global(v->arch.guest_vtable);
         }
         if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
             v->arch.guest_vtable = __linear_l2_table;
@@ -942,7 +944,7 @@
         if ( v->arch.shadow_vtable &&
              (v->arch.shadow_vtable != __shadow_linear_l2_table) )
         {
-            unmap_domain_page(v->arch.shadow_vtable);
+            unmap_domain_page_global(v->arch.shadow_vtable);
         }
         if ( !(mode & SHM_external) )
             v->arch.shadow_vtable = __shadow_linear_l2_table;
@@ -955,7 +957,7 @@
         if ( v->arch.hl2_vtable &&
              (v->arch.hl2_vtable != __linear_hl2_table) )
         {
-            unmap_domain_page(v->arch.hl2_vtable);
+            unmap_domain_page_global(v->arch.hl2_vtable);
         }
         if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
             v->arch.hl2_vtable = __linear_hl2_table;
@@ -1508,6 +1510,7 @@
 {
     unsigned long smfn;
     l2_pgentry_t *spl2e;
+    int i;
 
     SH_VVLOG("shadow_l2_table(gpfn=%lx, gmfn=%lx)", gpfn, gmfn);
 
@@ -1542,9 +1545,11 @@
         spl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] =
             l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
 
-        spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-            
l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
-                            __PAGE_HYPERVISOR);
+        for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+            spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
+            l2e_from_page(virt_to_page(page_get_owner(pfn_to_page(gmfn))->
+                                       arch.mm_perdomain_pt) + i,
+                          __PAGE_HYPERVISOR);
 
         if ( shadow_mode_translate(d) ) // NB: not external
         {
@@ -2891,6 +2896,7 @@
     unsigned long gmfn = pagetable_get_pfn(v->arch.guest_table);
     unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
     unsigned long smfn, hl2mfn, old_smfn;
+    int need_sync = 0;
 
     int max_mode = ( shadow_mode_external(d) ? SHM_external
                      : shadow_mode_translate(d) ? SHM_translate
@@ -2906,8 +2912,8 @@
     if ( max_mode & (SHM_enable | SHM_external) )
     {
         if ( likely(v->arch.guest_vtable != NULL) )
-            unmap_domain_page(v->arch.guest_vtable);
-        v->arch.guest_vtable = map_domain_page(gmfn);
+            unmap_domain_page_global(v->arch.guest_vtable);
+        v->arch.guest_vtable = map_domain_page_global(gmfn);
     }
 
     /*
@@ -2916,7 +2922,13 @@
     if ( unlikely(!(smfn = __shadow_status(d, gpfn, PGT_base_page_table))) )
         smfn = shadow_l2_table(d, gpfn, gmfn);
     else
-        shadow_sync_all(d);
+    {
+        /*
+         *  move sync later in order to avoid this smfn been 
+         *  unshadowed occasionally
+         */
+        need_sync = 1;
+    }
     if ( !get_shadow_ref(smfn) )
         BUG();
     old_smfn = pagetable_get_pfn(v->arch.shadow_table);
@@ -2932,8 +2944,8 @@
     if ( max_mode == SHM_external )
     {
         if ( v->arch.shadow_vtable )
-            unmap_domain_page(v->arch.shadow_vtable);
-        v->arch.shadow_vtable = map_domain_page(smfn);
+            unmap_domain_page_global(v->arch.shadow_vtable);
+        v->arch.shadow_vtable = map_domain_page_global(smfn);
     }
 
     /*
@@ -2948,8 +2960,8 @@
         if ( unlikely(!(hl2mfn = __shadow_status(d, gpfn, PGT_hl2_shadow))) )
             hl2mfn = shadow_hl2_table(d, gpfn, gmfn, smfn);
         if ( v->arch.hl2_vtable )
-            unmap_domain_page(v->arch.hl2_vtable);
-        v->arch.hl2_vtable = map_domain_page(hl2mfn);
+            unmap_domain_page_global(v->arch.hl2_vtable);
+        v->arch.hl2_vtable = map_domain_page_global(hl2mfn);
     }
 
     /*
@@ -2980,6 +2992,9 @@
         // XXX - maybe this can be optimized somewhat??
         local_flush_tlb();
     }
+
+    if(likely(need_sync))
+        shadow_sync_all(d);
 }
 
 void clear_all_shadow_status(struct domain *d)
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/shadow_public.c      Tue Jan 24 16:54:34 2006
@@ -151,6 +151,8 @@
 
     for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
         put_page_from_l1e(pl1e[i], d);
+
+    unmap_domain_page(pl1e);
 }
 
 /*
@@ -254,6 +256,7 @@
     pae_l3 = map_domain_page(pagetable_get_pfn(d->arch.phys_table));
     for (i = 0; i < PDP_ENTRIES; i++)
         l3[i] = l3e_from_pfn(l3e_get_pfn(pae_l3[i]), __PAGE_HYPERVISOR);
+    unmap_domain_page(pae_l3);
 
     unmap_domain_page(l4);
     unmap_domain_page(l3);
@@ -275,7 +278,7 @@
     ASSERT( mmfn_info );
 
     mmfn = page_to_pfn(mmfn_info);
-    mpl4e = (l4_pgentry_t *) map_domain_page(mmfn);
+    mpl4e = (l4_pgentry_t *) map_domain_page_global(mmfn);
     memcpy(mpl4e, &idle_pg_table[0], PAGE_SIZE);
     mpl4e[l4_table_offset(PERDOMAIN_VIRT_START)] =
         l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR);
@@ -298,7 +301,7 @@
      * free monitor_table.
      */
     mfn = pagetable_get_pfn(v->arch.monitor_table);
-    unmap_domain_page(v->arch.monitor_vtable);
+    unmap_domain_page_global(v->arch.monitor_vtable);
     free_domheap_page(pfn_to_page(mfn));
 
     v->arch.monitor_table = mk_pagetable(0);
@@ -325,6 +328,7 @@
     l2_pgentry_t *mpl2e;
     struct pfn_info *mmfn_info;
     struct domain *d = v->domain;
+    int i;
 
     ASSERT(pagetable_get_paddr(v->arch.monitor_table) == 0);
 
@@ -332,16 +336,17 @@
     ASSERT(mmfn_info != NULL);
 
     mmfn = page_to_pfn(mmfn_info);
-    mpl2e = (l2_pgentry_t *)map_domain_page(mmfn);
+    mpl2e = (l2_pgentry_t *)map_domain_page_global(mmfn);
     memset(mpl2e, 0, PAGE_SIZE);
 
     memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
            &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
            HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
 
-    mpl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
-        l2e_from_paddr(__pa(d->arch.mm_perdomain_pt),
-                       __PAGE_HYPERVISOR);
+    for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
+        mpl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
+            l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
+                          __PAGE_HYPERVISOR);
 
     // map the phys_to_machine map into the Read-Only MPT space for this domain
     mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
@@ -393,7 +398,7 @@
      * Then free monitor_table.
      */
     mfn = pagetable_get_pfn(v->arch.monitor_table);
-    unmap_domain_page(v->arch.monitor_vtable);
+    unmap_domain_page_global(v->arch.monitor_vtable);
     free_domheap_page(pfn_to_page(mfn));
 
     v->arch.monitor_table = mk_pagetable(0);
@@ -977,7 +982,7 @@
         if ( v->arch.guest_vtable &&
              (v->arch.guest_vtable != __linear_l2_table) )
         {
-            unmap_domain_page(v->arch.guest_vtable);
+            unmap_domain_page_global(v->arch.guest_vtable);
         }
         if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
             v->arch.guest_vtable = __linear_l2_table;
@@ -990,7 +995,7 @@
         if ( v->arch.shadow_vtable &&
              (v->arch.shadow_vtable != __shadow_linear_l2_table) )
         {
-            unmap_domain_page(v->arch.shadow_vtable);
+            unmap_domain_page_global(v->arch.shadow_vtable);
         }
         if ( !(mode & SHM_external) && d->arch.ops->guest_paging_levels == 2)
             v->arch.shadow_vtable = __shadow_linear_l2_table;
@@ -1004,7 +1009,7 @@
         if ( v->arch.hl2_vtable &&
              (v->arch.hl2_vtable != __linear_hl2_table) )
         {
-            unmap_domain_page(v->arch.hl2_vtable);
+            unmap_domain_page_global(v->arch.hl2_vtable);
         }
         if ( (mode & (SHM_translate | SHM_external)) == SHM_translate )
             v->arch.hl2_vtable = __linear_hl2_table;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/time.c       Tue Jan 24 16:54:34 2006
@@ -17,7 +17,7 @@
 #include <xen/config.h>
 #include <xen/init.h>
 #include <xen/time.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
 #include <xen/smp.h>
 #include <xen/irq.h>
 #include <xen/softirq.h>
@@ -56,7 +56,7 @@
     s_time_t stime_local_stamp;
     s_time_t stime_master_stamp;
     struct time_scale tsc_scale;
-    struct ac_timer calibration_timer;
+    struct timer calibration_timer;
 } __cacheline_aligned;
 
 static struct cpu_time cpu_time[NR_CPUS];
@@ -163,7 +163,7 @@
 
     /* Rough hack to allow accurate timers to sort-of-work with no APIC. */
     if ( !cpu_has_apic )
-        raise_softirq(AC_TIMER_SOFTIRQ);
+        raise_softirq(TIMER_SOFTIRQ);
 
     if ( using_pit )
         pit_overflow();
@@ -342,7 +342,7 @@
 /* Protected by platform_timer_lock. */
 static u64 hpet_counter64, hpet_overflow_period;
 static u32 hpet_stamp;
-static struct ac_timer hpet_overflow_timer;
+static struct timer hpet_overflow_timer;
 
 static void hpet_overflow(void *unused)
 {
@@ -354,7 +354,7 @@
     hpet_stamp = counter;
     spin_unlock_irq(&platform_timer_lock);
 
-    set_ac_timer(&hpet_overflow_timer, NOW() + hpet_overflow_period);
+    set_timer(&hpet_overflow_timer, NOW() + hpet_overflow_period);
 }
 
 static u64 read_hpet_count(void)
@@ -430,7 +430,7 @@
         (void)do_div(hpet_overflow_period, (u32)hpet_rate);
     }
 
-    init_ac_timer(&hpet_overflow_timer, hpet_overflow, NULL, 0);
+    init_timer(&hpet_overflow_timer, hpet_overflow, NULL, 0);
     hpet_overflow(NULL);
     platform_timer_stamp = hpet_counter64;
 
@@ -459,7 +459,7 @@
 /* Protected by platform_timer_lock. */
 static u64 cyclone_counter64;
 static u32 cyclone_stamp;
-static struct ac_timer cyclone_overflow_timer;
+static struct timer cyclone_overflow_timer;
 static volatile u32 *cyclone_timer; /* Cyclone MPMC0 register */
 
 static void cyclone_overflow(void *unused)
@@ -472,7 +472,7 @@
     cyclone_stamp = counter;
     spin_unlock_irq(&platform_timer_lock);
 
-    set_ac_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000));
+    set_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000));
 }
 
 static u64 read_cyclone_count(void)
@@ -510,7 +510,7 @@
 
     read_platform_count = read_cyclone_count;
 
-    init_ac_timer(&cyclone_overflow_timer, cyclone_overflow, NULL, 0);
+    init_timer(&cyclone_overflow_timer, cyclone_overflow, NULL, 0);
     cyclone_overflow(NULL);
     platform_timer_stamp = cyclone_counter64;
     set_time_scale(&platform_timer_scale, CYCLONE_TIMER_FREQ);
@@ -876,7 +876,7 @@
     cpu_time[cpu].stime_master_stamp = curr_master_stime;
 
  out:
-    set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
+    set_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
 
     if ( cpu == 0 )
         platform_time_calibration();
@@ -896,9 +896,9 @@
     cpu_time[cpu].stime_master_stamp = now;
     cpu_time[cpu].stime_local_stamp  = now;
 
-    init_ac_timer(&cpu_time[cpu].calibration_timer,
+    init_timer(&cpu_time[cpu].calibration_timer,
                   local_time_calibration, NULL, cpu);
-    set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
+    set_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH);
 }
 
 /* Late init function (after all CPUs are booted). */
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/traps.c      Tue Jan 24 16:54:34 2006
@@ -130,9 +130,19 @@
 static void show_guest_stack(struct cpu_user_regs *regs)
 {
     int i;
-    unsigned long *stack = (unsigned long *)regs->esp, addr;
-
-    printk("Guest stack trace from "__OP"sp=%p:\n   ", stack);
+    unsigned long *stack, addr;
+
+    if ( VM86_MODE(regs) )
+    {
+        stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff));
+        printk("Guest stack trace from ss:sp = %04x:%04x (VM86)\n   ",
+               regs->ss, (uint16_t)(regs->esp & 0xffff));
+    }
+    else
+    {
+        stack = (unsigned long *)regs->esp;
+        printk("Guest stack trace from "__OP"sp=%p:\n   ", stack);
+    }
 
     for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
     {
@@ -596,7 +606,6 @@
     u16 x;
 #if defined(__x86_64__)
     /* If in user mode, switch to kernel mode just to read I/O bitmap. */
-    extern void toggle_guest_mode(struct vcpu *);
     int user_mode = !(v->arch.flags & TF_kernel_mode);
 #define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v)
 #elif defined(__i386__)
@@ -964,16 +973,26 @@
     case 0x30: /* WRMSR */
         /* Ignore the instruction if unprivileged. */
         if ( !IS_PRIV(v->domain) )
-            DPRINTK("Non-priv domain attempted WRMSR(%p,%08lx,%08lx).\n",
-                    _p(regs->ecx), (long)regs->eax, (long)regs->edx);
+        {
+            u32 l, h;
+            if ( (rdmsr_user(regs->ecx, l, h) != 0) ||
+                 (regs->ecx != MSR_EFER) ||
+                 (regs->eax != l) || (regs->edx != h) )
+                DPRINTK("Non-priv domain attempted WRMSR %p from "
+                        "%08x:%08x to %08lx:%08lx.\n",
+                        _p(regs->ecx), h, l, (long)regs->edx, (long)regs->eax);
+        }
         else if ( wrmsr_user(regs->ecx, regs->eax, regs->edx) )
             goto fail;
         break;
 
     case 0x32: /* RDMSR */
         if ( !IS_PRIV(v->domain) )
-            DPRINTK("Non-priv domain attempted RDMSR(%p,%08lx,%08lx).\n",
-                    _p(regs->ecx), (long)regs->eax, (long)regs->edx);
+        {
+            if ( regs->ecx != MSR_EFER )
+                DPRINTK("Non-priv domain attempted RDMSR %p.\n",
+                        _p(regs->ecx));
+        }
         /* Everyone can read the MSR space. */
         if ( rdmsr_user(regs->ecx, regs->eax, regs->edx) )
             goto fail;
@@ -1080,26 +1099,23 @@
     return 0;
 }
 
-
-/* Defer dom0 notification to softirq context (unsafe in NMI context). */
-static unsigned long nmi_dom0_softirq_reason;
-#define NMI_DOM0_PARITY_ERR 0
-#define NMI_DOM0_IO_ERR     1
-#define NMI_DOM0_UNKNOWN    2
-
-static void nmi_dom0_softirq(void)
-{
-    if ( dom0 == NULL )
+static void nmi_softirq(void)
+{
+    /* Only used to defer wakeup of dom0,vcpu0 to a safe (non-NMI) context. */
+    evtchn_notify(dom0->vcpu[0]);
+}
+
+static void nmi_dom0_report(unsigned int reason_idx)
+{
+    struct domain *d;
+
+    if ( (d = dom0) == NULL )
         return;
 
-    if ( test_and_clear_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason) )
-        send_guest_virq(dom0->vcpu[0], VIRQ_PARITY_ERR);
-
-    if ( test_and_clear_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason) )
-        send_guest_virq(dom0->vcpu[0], VIRQ_IO_ERR);
-
-    if ( test_and_clear_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason) )
-        send_guest_virq(dom0->vcpu[0], VIRQ_NMI);
+    set_bit(reason_idx, &d->shared_info->arch.nmi_reason);
+
+    if ( test_and_set_bit(_VCPUF_nmi_pending, &d->vcpu[0]->vcpu_flags) )
+        raise_softirq(NMI_SOFTIRQ); /* not safe to wake up a vcpu here */
 }
 
 asmlinkage void mem_parity_error(struct cpu_user_regs *regs)
@@ -1107,8 +1123,7 @@
     switch ( opt_nmi[0] )
     {
     case 'd': /* 'dom0' */
-        set_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason);
-        raise_softirq(NMI_DOM0_SOFTIRQ);
+        nmi_dom0_report(_XEN_NMIREASON_parity_error);
     case 'i': /* 'ignore' */
         break;
     default:  /* 'fatal' */
@@ -1127,8 +1142,7 @@
     switch ( opt_nmi[0] )
     {
     case 'd': /* 'dom0' */
-        set_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason);
-        raise_softirq(NMI_DOM0_SOFTIRQ);
+        nmi_dom0_report(_XEN_NMIREASON_io_error);
     case 'i': /* 'ignore' */
         break;
     default:  /* 'fatal' */
@@ -1147,8 +1161,7 @@
     switch ( opt_nmi[0] )
     {
     case 'd': /* 'dom0' */
-        set_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason);
-        raise_softirq(NMI_DOM0_SOFTIRQ);
+        nmi_dom0_report(_XEN_NMIREASON_unknown);
     case 'i': /* 'ignore' */
         break;
     default:  /* 'fatal' */
@@ -1347,7 +1360,7 @@
 
     cpu_init();
 
-    open_softirq(NMI_DOM0_SOFTIRQ, nmi_dom0_softirq);
+    open_softirq(NMI_SOFTIRQ, nmi_softirq);
 }
 
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx.c        Tue Jan 24 16:54:34 2006
@@ -98,19 +98,18 @@
         /* unmap IO shared page */
         struct domain *d = v->domain;
         if ( d->arch.vmx_platform.shared_page_va )
-            unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
+            unmap_domain_page_global(
+                (void *)d->arch.vmx_platform.shared_page_va);
     }
 
     destroy_vmcs(&v->arch.arch_vmx);
     free_monitor_pagetable(v);
     vpit = &v->domain->arch.vmx_platform.vmx_pit;
-    if ( active_ac_timer(&(vpit->pit_timer)) )
-        rem_ac_timer(&vpit->pit_timer);
-    if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) )
-        rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
+    kill_timer(&vpit->pit_timer);
+    kill_timer(&v->arch.arch_vmx.hlt_timer);
     if ( vmx_apic_support(v->domain) && (VLAPIC(v) != NULL) )
     {
-        rem_ac_timer(&VLAPIC(v)->vlapic_timer);
+        kill_timer(&VLAPIC(v)->vlapic_timer);
         xfree(VLAPIC(v));
     }
 }
@@ -1599,7 +1598,7 @@
         next_wakeup = next_pit;
     }
     if ( next_wakeup != - 1 ) 
-        set_ac_timer(&current->arch.arch_vmx.hlt_timer, next_wakeup);
+        set_timer(&current->arch.arch_vmx.hlt_timer, next_wakeup);
     do_block();
 }
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c      Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx_intercept.c      Tue Jan 24 16:54:34 2006
@@ -356,19 +356,19 @@
     vpit->pending_intr_nr++;
     if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) {
         vpit->scheduled += vpit->period;
-        set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+        set_timer(&vpit->pit_timer, vpit->scheduled);
     }
 }
 
 void pickup_deactive_ticks(struct vmx_virpit *vpit)
 {
 
-    if ( !active_ac_timer(&(vpit->pit_timer)) ) {
+    if ( !active_timer(&(vpit->pit_timer)) ) {
         /* pick up missed timer tick */
         missed_ticks(vpit);
     
         vpit->scheduled += vpit->period;
-        set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+        set_timer(&vpit->pit_timer, vpit->scheduled);
     }
 }
 
@@ -385,14 +385,14 @@
     /* load init count*/
     if (p->state == STATE_IORESP_HOOK) {
         /* set up actimer, handle re-init */
-        if ( active_ac_timer(&(vpit->pit_timer)) ) {
+        if ( active_timer(&(vpit->pit_timer)) ) {
             VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT: guest reset PIT with channel 
%lx!\n", (unsigned long) ((p->u.data >> 24) & 0x3) );
-            rem_ac_timer(&(vpit->pit_timer));
+            stop_timer(&(vpit->pit_timer));
             reinit = 1;
  
         }
         else {
-            init_ac_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
+            init_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor);
         }
 
         /* init count for this channel */
@@ -431,7 +431,7 @@
         }
 
         vpit->scheduled = NOW() + vpit->period;
-        set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+        set_timer(&vpit->pit_timer, vpit->scheduled);
 
         /*restore the state*/
         p->state = STATE_IORESP_READY;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c     Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx_io.c     Tue Jan 24 16:54:34 2006
@@ -819,7 +819,7 @@
         if ( !vpit->first_injected ) {
             vpit->pending_intr_nr = 0;
             vpit->scheduled = NOW() + vpit->period;
-            set_ac_timer(&vpit->pit_timer, vpit->scheduled);
+            set_timer(&vpit->pit_timer, vpit->scheduled);
             vpit->first_injected = 1;
         } else {
             vpit->pending_intr_nr--;
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx_vlapic.c
--- a/xen/arch/x86/vmx_vlapic.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx_vlapic.c Tue Jan 24 16:54:34 2006
@@ -391,7 +391,7 @@
       (262144 / get_apic_bus_scale()) * vlapic->timer_divide_counter;
     vlapic->vlapic_timer.expires = cur + offset;
 
-    set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires );
+    set_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires );
 
     VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_begin_timer: "
                 "bus_scale %x now %08x%08x expire %08x%08x "
@@ -739,7 +739,7 @@
 
     case APIC_TMICT:
         if (vlapic_timer_active(vlapic))
-            rem_ac_timer(&(vlapic->vlapic_timer));
+            stop_timer(&(vlapic->vlapic_timer));
 
         vlapic->timer_initial = val;
         vlapic->timer_current = val;
@@ -846,7 +846,7 @@
         vlapic->timer_current = vlapic->timer_initial;
         offset = vlapic->timer_current * (262144/get_apic_bus_scale()) * 
vlapic->timer_divide_counter;
         vlapic->vlapic_timer.expires = NOW() + offset;
-        set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires);
+        set_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires);
     }else {
         vlapic->timer_current = 0;
     }
@@ -986,7 +986,7 @@
 
     vmx_vioapic_add_lapic(vlapic, v);
 
-    init_ac_timer(&vlapic->vlapic_timer,
+    init_timer(&vlapic->vlapic_timer,
                   vlapic_timer_fn, vlapic, v->processor);
 
 #ifdef VLAPIC_NO_BIOS
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c   Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/vmx_vmcs.c   Tue Jan 24 16:54:34 2006
@@ -193,7 +193,7 @@
         domain_crash_synchronous();
     }
 
-    p = map_domain_page(mpfn);
+    p = map_domain_page_global(mpfn);
     if (p == NULL) {
         printk("Can not map io request shared page for VMX domain.\n");
         domain_crash_synchronous();
@@ -341,7 +341,7 @@
         vlapic_init(v);
 
     vmx_set_host_env(v);
-    init_ac_timer(&v->arch.arch_vmx.hlt_timer, hlt_timer_fn, v, v->processor);
+    init_timer(&v->arch.arch_vmx.hlt_timer, hlt_timer_fn, v, v->processor);
 
     error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
     error |= __vmwrite(GUEST_LDTR_BASE, 0);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_32/asm-offsets.c
--- a/xen/arch/x86/x86_32/asm-offsets.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_32/asm-offsets.c Tue Jan 24 16:54:34 2006
@@ -65,6 +65,10 @@
            arch.guest_context.kernel_ss);
     OFFSET(VCPU_kernel_sp, struct vcpu,
            arch.guest_context.kernel_sp);
+    OFFSET(VCPU_flags, struct vcpu, vcpu_flags);
+    OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr);
+    DEFINE(_VCPUF_nmi_pending, _VCPUF_nmi_pending);
+    DEFINE(_VCPUF_nmi_masked, _VCPUF_nmi_masked);
     BLANK();
 
     OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_32/domain_page.c
--- a/xen/arch/x86/x86_32/domain_page.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_32/domain_page.c Tue Jan 24 16:54:34 2006
@@ -1,14 +1,9 @@
 /******************************************************************************
  * domain_page.h
  * 
- * Allow temporary mapping of domain pages. Based on ideas from the
- * Linux PKMAP code -- the copyrights and credits are retained below.
- */
-
-/*
- * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@xxxxxxx
- *          Gerhard Wichert, Siemens AG, Gerhard.Wichert@xxxxxxxxxxxxxx *
- * Copyright (C) 1999 Ingo Molnar <mingo@xxxxxxxxxx>
+ * Allow temporary mapping of domain pages.
+ * 
+ * Copyright (c) 2003-2006, Keir Fraser <keir@xxxxxxxxxxxxx>
  */
 
 #include <xen/config.h>
@@ -20,84 +15,203 @@
 #include <asm/flushtlb.h>
 #include <asm/hardirq.h>
 
-#define MAPCACHE_ORDER    10
-#define MAPCACHE_ENTRIES  (1 << MAPCACHE_ORDER)
-
-/* Use a spare PTE bit to mark entries ready for recycling. */
-#define READY_FOR_TLB_FLUSH (1<<10)
-
-static void flush_all_ready_maps(void)
-{
-    struct mapcache *cache = &current->domain->arch.mapcache;
-    unsigned int i;
-
-    for ( i = 0; i < MAPCACHE_ENTRIES; i++ )
-        if ( (l1e_get_flags(cache->l1tab[i]) & READY_FOR_TLB_FLUSH) )
-            cache->l1tab[i] = l1e_empty();
-}
-
-void *map_domain_pages(unsigned long pfn, unsigned int order)
+void *map_domain_page(unsigned long pfn)
 {
     unsigned long va;
-    unsigned int idx, i, flags, vcpu = current->vcpu_id;
-    struct mapcache *cache = &current->domain->arch.mapcache;
-#ifndef NDEBUG
-    unsigned int flush_count = 0;
-#endif
+    unsigned int idx, i, vcpu = current->vcpu_id;
+    struct domain *d;
+    struct mapcache *cache;
+    struct vcpu_maphash_entry *hashent;
 
     ASSERT(!in_irq());
+
     perfc_incrc(map_domain_page_count);
 
     /* If we are the idle domain, ensure that we run on our own page tables. */
-    if ( unlikely(is_idle_vcpu(current)) )
+    d = current->domain;
+    if ( unlikely(is_idle_domain(d)) )
         __sync_lazy_execstate();
 
+    cache = &d->arch.mapcache;
+
+    hashent = &cache->vcpu_maphash[vcpu].hash[MAPHASH_HASHFN(pfn)];
+    if ( hashent->pfn == pfn )
+    {
+        idx = hashent->idx;
+        hashent->refcnt++;
+        ASSERT(hashent->refcnt != 0);
+        ASSERT(l1e_get_pfn(cache->l1tab[idx]) == pfn);
+        goto out;
+    }
+
     spin_lock(&cache->lock);
 
     /* Has some other CPU caused a wrap? We must flush if so. */
-    if ( cache->epoch != cache->shadow_epoch[vcpu] )
-    {
+    if ( unlikely(cache->epoch != cache->shadow_epoch[vcpu]) )
+    {
+        cache->shadow_epoch[vcpu] = cache->epoch;
+        if ( NEED_FLUSH(tlbflush_time[smp_processor_id()],
+                        cache->tlbflush_timestamp) )
+        {
+            perfc_incrc(domain_page_tlb_flush);
+            local_flush_tlb();
+        }
+    }
+
+    idx = find_next_zero_bit(cache->inuse, MAPCACHE_ENTRIES, cache->cursor);
+    if ( unlikely(idx >= MAPCACHE_ENTRIES) )
+    {
+        /* /First/, clean the garbage map and update the inuse list. */
+        for ( i = 0; i < ARRAY_SIZE(cache->garbage); i++ )
+        {
+            unsigned long x = xchg(&cache->garbage[i], 0);
+            cache->inuse[i] &= ~x;
+        }
+
+        /* /Second/, flush TLBs. */
         perfc_incrc(domain_page_tlb_flush);
         local_flush_tlb();
-        cache->shadow_epoch[vcpu] = cache->epoch;
-    }
-
-    do {
-        idx = cache->cursor = (cache->cursor + 1) & (MAPCACHE_ENTRIES - 1);
-        if ( unlikely(idx == 0) )
-        {
-            ASSERT(flush_count++ == 0);
-            flush_all_ready_maps();
-            perfc_incrc(domain_page_tlb_flush);
-            local_flush_tlb();
-            cache->shadow_epoch[vcpu] = ++cache->epoch;
-        }
-
-        flags = 0;
-        for ( i = 0; i < (1U << order); i++ )
-            flags |= l1e_get_flags(cache->l1tab[idx+i]);
-    }
-    while ( flags & _PAGE_PRESENT );
-
-    for ( i = 0; i < (1U << order); i++ )
-        cache->l1tab[idx+i] = l1e_from_pfn(pfn+i, __PAGE_HYPERVISOR);
+        cache->shadow_epoch[vcpu] = ++cache->epoch;
+        cache->tlbflush_timestamp = tlbflush_current_time();
+
+        idx = find_first_zero_bit(cache->inuse, MAPCACHE_ENTRIES);
+        ASSERT(idx < MAPCACHE_ENTRIES);
+    }
+
+    set_bit(idx, cache->inuse);
+    cache->cursor = idx + 1;
 
     spin_unlock(&cache->lock);
 
+    cache->l1tab[idx] = l1e_from_pfn(pfn, __PAGE_HYPERVISOR);
+
+ out:
     va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT);
     return (void *)va;
 }
 
-void unmap_domain_pages(void *va, unsigned int order)
-{
-    unsigned int idx, i;
+void unmap_domain_page(void *va)
+{
+    unsigned int idx;
     struct mapcache *cache = &current->domain->arch.mapcache;
+    unsigned long pfn;
+    struct vcpu_maphash_entry *hashent;
+
+    ASSERT(!in_irq());
 
     ASSERT((void *)MAPCACHE_VIRT_START <= va);
     ASSERT(va < (void *)MAPCACHE_VIRT_END);
 
     idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT;
-
-    for ( i = 0; i < (1U << order); i++ )
-        l1e_add_flags(cache->l1tab[idx+i], READY_FOR_TLB_FLUSH);
-}
+    pfn = l1e_get_pfn(cache->l1tab[idx]);
+    hashent = &cache->vcpu_maphash[current->vcpu_id].hash[MAPHASH_HASHFN(pfn)];
+
+    if ( hashent->idx == idx )
+    {
+        ASSERT(hashent->pfn == pfn);
+        ASSERT(hashent->refcnt != 0);
+        hashent->refcnt--;
+    }
+    else if ( hashent->refcnt == 0 )
+    {
+        if ( hashent->idx != MAPHASHENT_NOTINUSE )
+        {
+            /* /First/, zap the PTE. */
+            ASSERT(l1e_get_pfn(cache->l1tab[hashent->idx]) == hashent->pfn);
+            cache->l1tab[hashent->idx] = l1e_empty();
+            /* /Second/, mark as garbage. */
+            set_bit(hashent->idx, cache->garbage);
+        }
+
+        /* Add newly-freed mapping to the maphash. */
+        hashent->pfn = pfn;
+        hashent->idx = idx;
+    }
+    else
+    {
+        /* /First/, zap the PTE. */
+        cache->l1tab[idx] = l1e_empty();
+        /* /Second/, mark as garbage. */
+        set_bit(idx, cache->garbage);
+    }
+}
+
+void mapcache_init(struct domain *d)
+{
+    unsigned int i, j;
+
+    d->arch.mapcache.l1tab = d->arch.mm_perdomain_pt +
+        (GDT_LDT_MBYTES << (20 - PAGE_SHIFT));
+    spin_lock_init(&d->arch.mapcache.lock);
+
+    /* Mark all maphash entries as not in use. */
+    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
+        for ( j = 0; j < MAPHASH_ENTRIES; j++ )
+            d->arch.mapcache.vcpu_maphash[i].hash[j].idx =
+                MAPHASHENT_NOTINUSE;
+}
+
+#define GLOBALMAP_BITS (IOREMAP_MBYTES << (20 - PAGE_SHIFT))
+static unsigned long inuse[BITS_TO_LONGS(GLOBALMAP_BITS)];
+static unsigned long garbage[BITS_TO_LONGS(GLOBALMAP_BITS)];
+static unsigned int inuse_cursor;
+static spinlock_t globalmap_lock = SPIN_LOCK_UNLOCKED;
+
+void *map_domain_page_global(unsigned long pfn)
+{
+    l2_pgentry_t *pl2e;
+    l1_pgentry_t *pl1e;
+    unsigned int idx, i;
+    unsigned long va;
+
+    ASSERT(!in_irq() && local_irq_is_enabled());
+
+    spin_lock(&globalmap_lock);
+
+    idx = find_next_zero_bit(inuse, GLOBALMAP_BITS, inuse_cursor);
+    va = IOREMAP_VIRT_START + (idx << PAGE_SHIFT);
+    if ( unlikely(va >= FIXADDR_START) )
+    {
+        /* /First/, clean the garbage map and update the inuse list. */
+        for ( i = 0; i < ARRAY_SIZE(garbage); i++ )
+        {
+            unsigned long x = xchg(&garbage[i], 0);
+            inuse[i] &= ~x;
+        }
+
+        /* /Second/, flush all TLBs to get rid of stale garbage mappings. */
+        flush_tlb_all();
+
+        idx = find_first_zero_bit(inuse, GLOBALMAP_BITS);
+        va = IOREMAP_VIRT_START + (idx << PAGE_SHIFT);
+        ASSERT(va < FIXADDR_START);
+    }
+
+    set_bit(idx, inuse);
+    inuse_cursor = idx + 1;
+
+    spin_unlock(&globalmap_lock);
+
+    pl2e = virt_to_xen_l2e(va);
+    pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(va);
+    *pl1e = l1e_from_pfn(pfn, __PAGE_HYPERVISOR);
+
+    return (void *)va;
+}
+
+void unmap_domain_page_global(void *va)
+{
+    unsigned long __va = (unsigned long)va;
+    l2_pgentry_t *pl2e;
+    l1_pgentry_t *pl1e;
+    unsigned int idx;
+
+    /* /First/, we zap the PTE. */
+    pl2e = virt_to_xen_l2e(__va);
+    pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(__va);
+    *pl1e = l1e_empty();
+
+    /* /Second/, we add to the garbage map. */
+    idx = (__va - IOREMAP_VIRT_START) >> PAGE_SHIFT;
+    set_bit(idx, garbage);
+}
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_32/entry.S       Tue Jan 24 16:54:34 2006
@@ -326,7 +326,9 @@
         shl  $IRQSTAT_shift,%eax
         test %ecx,irq_stat(%eax,1)
         jnz  process_softirqs
-/*test_guest_events:*/
+        btr  $_VCPUF_nmi_pending,VCPU_flags(%ebx)
+        jc   process_nmi
+test_guest_events:
         movl VCPU_vcpu_info(%ebx),%eax
         testb $0xFF,VCPUINFO_upcall_mask(%eax)
         jnz  restore_all_guest
@@ -348,7 +350,24 @@
         sti       
         call do_softirq
         jmp  test_all_events
-                
+       
+       ALIGN
+process_nmi:
+        movl VCPU_nmi_addr(%ebx),%eax
+        test %eax,%eax
+        jz   test_all_events
+        bts  $_VCPUF_nmi_masked,VCPU_flags(%ebx)
+        jc   1f
+        sti
+        leal VCPU_trap_bounce(%ebx),%edx
+        movl %eax,TRAPBOUNCE_eip(%edx)
+        movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx)
+        movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
+        call create_bounce_frame
+        jmp  test_all_events
+1:      bts  $_VCPUF_nmi_pending,VCPU_flags(%ebx)
+        jmp  test_guest_events
+
 /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
 /*   {EIP, CS, EFLAGS, [ESP, SS]}                                        */
 /* %edx == trap_bounce, %ebx == struct vcpu                       */
@@ -620,9 +639,7 @@
         jne   defer_nmi
 
 continue_nmi:
-        movl  $(__HYPERVISOR_DS),%edx
-        movl  %edx,%ds
-        movl  %edx,%es
+        SET_XEN_SEGMENTS(d)
         movl  %esp,%edx
         pushl %edx
         call  do_nmi
@@ -659,42 +676,6 @@
         GET_GUEST_REGS(%ecx)
         movl %eax,UREGS_eax(%ecx)
         jmp  do_sched_op
-
-do_switch_vm86:
-        # Reset the stack pointer
-        GET_GUEST_REGS(%ecx)
-        movl %ecx,%esp
-
-        # GS:ESI == Ring-1 stack activation
-        movl UREGS_esp(%esp),%esi
-VFLT1:  mov  UREGS_ss(%esp),%gs
-
-        # ES:EDI == Ring-0 stack activation
-        leal UREGS_eip(%esp),%edi
-
-        # Restore the hypercall-number-clobbered EAX on our stack frame
-VFLT2:  movl %gs:(%esi),%eax
-        movl %eax,UREGS_eax(%esp)
-        addl $4,%esi
-               
-       # Copy the VM86 activation from the ring-1 stack to the ring-0 stack
-        movl $(UREGS_user_sizeof-UREGS_eip)/4,%ecx
-VFLT3:  movl %gs:(%esi),%eax
-        stosl
-        addl $4,%esi
-        loop VFLT3
-
-        # Fix up EFLAGS: IOPL=0, IF=1, VM=1
-        andl $~X86_EFLAGS_IOPL,UREGS_eflags(%esp)
-        orl  $X86_EFLAGS_IF|X86_EFLAGS_VM,UREGS_eflags(%esp)
-        
-        jmp test_all_events
-
-.section __ex_table,"a"
-        .long VFLT1,domain_crash_synchronous
-        .long VFLT2,domain_crash_synchronous
-        .long VFLT3,domain_crash_synchronous
-.previous
 
 .data
 
@@ -744,11 +725,12 @@
         .long do_grant_table_op     /* 20 */
         .long do_vm_assist
         .long do_update_va_mapping_otherdomain
-        .long do_switch_vm86
+        .long do_iret
         .long do_vcpu_op
         .long do_ni_hypercall       /* 25 */
         .long do_mmuext_op
-        .long do_acm_op             /* 27 */
+        .long do_acm_op
+        .long do_nmi_op
         .rept NR_hypercalls-((.-hypercall_table)/4)
         .long do_ni_hypercall
         .endr
@@ -777,11 +759,12 @@
         .byte 3 /* do_grant_table_op    */  /* 20 */
         .byte 2 /* do_vm_assist         */
         .byte 5 /* do_update_va_mapping_otherdomain */
-        .byte 0 /* do_switch_vm86       */
+        .byte 0 /* do_iret              */
         .byte 3 /* do_vcpu_op           */
         .byte 0 /* do_ni_hypercall      */  /* 25 */
         .byte 4 /* do_mmuext_op         */
         .byte 1 /* do_acm_op            */
+        .byte 2 /* do_nmi_op            */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_32/traps.c       Tue Jan 24 16:54:34 2006
@@ -157,6 +157,64 @@
         __asm__ __volatile__ ( "hlt" );
 }
 
+asmlinkage unsigned long do_iret(void)
+{
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
+    u32 eflags;
+
+    /* Check worst-case stack frame for overlap with Xen protected area. */
+    if ( unlikely(!access_ok(regs->esp, 40)) )
+        domain_crash_synchronous();
+
+    /* Pop and restore EAX (clobbered by hypercall). */
+    if ( unlikely(__copy_from_user(&regs->eax, (void __user *)regs->esp, 4)) )
+        domain_crash_synchronous();
+    regs->esp += 4;
+
+    /* Pop and restore CS and EIP. */
+    if ( unlikely(__copy_from_user(&regs->eip, (void __user *)regs->esp, 8)) )
+        domain_crash_synchronous();
+    regs->esp += 8;
+
+    /*
+     * Pop, fix up and restore EFLAGS. We fix up in a local staging area
+     * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
+     */
+    if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) )
+        domain_crash_synchronous();
+    regs->esp += 4;
+    regs->eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;
+
+    if ( VM86_MODE(regs) )
+    {
+        /* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */
+        if ( __copy_from_user(&regs->esp, (void __user *)regs->esp, 24) )
+            domain_crash_synchronous();
+    }
+    else if ( unlikely(RING_0(regs)) )
+    {
+        domain_crash_synchronous();
+    }
+    else if ( !RING_1(regs) )
+    {
+        /* Return to ring 2/3: pop and restore ESP and SS. */
+        if ( __copy_from_user(&regs->esp, (void __user *)regs->esp, 8) )
+            domain_crash_synchronous();
+    }
+
+    /* No longer in NMI context. */
+    clear_bit(_VCPUF_nmi_masked, &current->vcpu_flags);
+
+    /* Restore upcall mask from saved value. */
+    current->vcpu_info->evtchn_upcall_mask = regs->saved_upcall_mask;
+
+    /*
+     * The hypercall exit path will overwrite EAX with this return
+     * value.
+     */
+    return regs->eax;
+}
+
 BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi)
 asmlinkage void smp_deferred_nmi(struct cpu_user_regs regs)
 {
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_64/asm-offsets.c
--- a/xen/arch/x86/x86_64/asm-offsets.c Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_64/asm-offsets.c Tue Jan 24 16:54:34 2006
@@ -65,6 +65,10 @@
            arch.guest_context.syscall_callback_eip);
     OFFSET(VCPU_kernel_sp, struct vcpu,
            arch.guest_context.kernel_sp);
+    OFFSET(VCPU_flags, struct vcpu, vcpu_flags);
+    OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr);
+    DEFINE(_VCPUF_nmi_pending, _VCPUF_nmi_pending);
+    DEFINE(_VCPUF_nmi_masked, _VCPUF_nmi_masked);
     BLANK();
 
     OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_64/entry.S       Tue Jan 24 16:54:34 2006
@@ -171,7 +171,9 @@
         leaq  irq_stat(%rip),%rcx
         testl $~0,(%rcx,%rax,1)
         jnz   process_softirqs
-/*test_guest_events:*/
+        btr   $_VCPUF_nmi_pending,VCPU_flags(%rbx)
+        jc    process_nmi
+test_guest_events:
         movq  VCPU_vcpu_info(%rbx),%rax
         testb $0xFF,VCPUINFO_upcall_mask(%rax)
         jnz   restore_all_guest
@@ -322,6 +324,23 @@
         call do_softirq
         jmp  test_all_events
 
+       ALIGN
+/* %rbx: struct vcpu */
+process_nmi:
+        movq VCPU_nmi_addr(%rbx),%rax
+        test %rax,%rax
+        jz   test_all_events
+        bts  $_VCPUF_nmi_masked,VCPU_flags(%rbx)
+        jc   1f
+        sti
+        leaq VCPU_trap_bounce(%rbx),%rdx
+        movq %rax,TRAPBOUNCE_eip(%rdx)
+        movw $(TBF_INTERRUPT|TBF_SLOW_IRET),TRAPBOUNCE_flags(%rdx)
+        call create_bounce_frame
+        jmp  test_all_events
+1:      bts  $_VCPUF_nmi_pending,VCPU_flags(%rbx)
+        jmp  test_guest_events
+       
 /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK:                     */
 /*   { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS }   */
 /* %rdx: trap_bounce, %rbx: struct vcpu                           */
@@ -339,6 +358,9 @@
 1:      /* In kernel context already: push new frame at existing %rsp. */
         movq  UREGS_rsp+8(%rsp),%rsi
         andb  $0xfc,UREGS_cs+8(%rsp)    # Indicate kernel context to guest.
+       testw $(TBF_SLOW_IRET),TRAPBOUNCE_flags(%rdx)
+       jz    2f
+       orb   $0x01,UREGS_cs+8(%rsp)
 2:      andq  $~0xf,%rsi                # Stack frames are 16-byte aligned.
         movq  $HYPERVISOR_VIRT_START,%rax
         cmpq  %rax,%rsi
@@ -569,7 +591,7 @@
         SAVE_ALL
         movq  %rsp,%rdi
         call  do_nmi
-       jmp   restore_all_xen
+        jmp   ret_from_intr
 
 do_arch_sched_op:
         # Ensure we return success even if we return via schedule_tail()
@@ -626,11 +648,12 @@
         .quad do_grant_table_op     /* 20 */
         .quad do_vm_assist
         .quad do_update_va_mapping_otherdomain
-        .quad do_switch_to_user
+        .quad do_iret
         .quad do_vcpu_op
         .quad do_set_segment_base   /* 25 */
         .quad do_mmuext_op
         .quad do_acm_op
+        .quad do_nmi_op
         .rept NR_hypercalls-((.-hypercall_table)/4)
         .quad do_ni_hypercall
         .endr
@@ -659,11 +682,12 @@
         .byte 3 /* do_grant_table_op    */  /* 20 */
         .byte 2 /* do_vm_assist         */
         .byte 4 /* do_update_va_mapping_otherdomain */
-        .byte 0 /* do_switch_to_user    */
+        .byte 0 /* do_iret              */
         .byte 3 /* do_vcpu_op           */
         .byte 2 /* do_set_segment_base  */  /* 25 */
         .byte 4 /* do_mmuext_op         */
         .byte 1 /* do_acm_op            */
+        .byte 2 /* do_nmi_op            */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/x86_64/traps.c       Tue Jan 24 16:54:34 2006
@@ -12,6 +12,7 @@
 #include <asm/current.h>
 #include <asm/flushtlb.h>
 #include <asm/msr.h>
+#include <asm/shadow.h>
 #include <asm/vmx.h>
 
 void show_registers(struct cpu_user_regs *regs)
@@ -113,6 +114,52 @@
         __asm__ __volatile__ ( "hlt" );
 }
 
+void toggle_guest_mode(struct vcpu *v)
+{
+    v->arch.flags ^= TF_kernel_mode;
+    __asm__ __volatile__ ( "swapgs" );
+    update_pagetables(v);
+    write_ptbase(v);
+}
+
+long do_iret(void)
+{
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
+    struct iret_context iret_saved;
+    struct vcpu *v = current;
+
+    if ( unlikely(copy_from_user(&iret_saved, (void *)regs->rsp,
+                                 sizeof(iret_saved))) )
+        domain_crash_synchronous();
+
+    /* Returning to user mode? */
+    if ( (iret_saved.cs & 3) == 3 )
+    {
+        if ( unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
+            return -EFAULT;
+        toggle_guest_mode(v);
+    }
+
+    regs->rip    = iret_saved.rip;
+    regs->cs     = iret_saved.cs | 3; /* force guest privilege */
+    regs->rflags = (iret_saved.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;
+    regs->rsp    = iret_saved.rsp;
+    regs->ss     = iret_saved.ss | 3; /* force guest privilege */
+
+    if ( !(iret_saved.flags & VGCF_IN_SYSCALL) )
+    {
+        regs->entry_vector = 0;
+        regs->r11 = iret_saved.r11;
+        regs->rcx = iret_saved.rcx;
+    }
+
+    /* No longer in NMI context. */
+    clear_bit(_VCPUF_nmi_masked, &current->vcpu_flags);
+
+    /* Saved %rax gets written back to regs->rax in entry.S. */
+    return iret_saved.rax;
+}
+
 asmlinkage void syscall_enter(void);
 void __init percpu_traps_init(void)
 {
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/Makefile
--- a/xen/common/Makefile       Tue Jan 10 15:21:00 2006
+++ b/xen/common/Makefile       Tue Jan 24 16:54:34 2006
@@ -3,6 +3,9 @@
 
 ifneq ($(perfc),y)
 OBJS := $(subst perfc.o,,$(OBJS))
+endif
+ifneq ($(crash_debug),y)
+OBJS := $(patsubst gdbstub.o,,$(OBJS))
 endif
 
 default: common.o
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     Tue Jan 10 15:21:00 2006
+++ b/xen/common/dom0_ops.c     Tue Jan 24 16:54:34 2006
@@ -208,7 +208,7 @@
                 pro = i;
 
         ret = -ENOMEM;
-        if ( (d = do_createdomain(dom, pro)) == NULL )
+        if ( (d = domain_create(dom, pro)) == NULL )
             break;
 
         memcpy(d->handle, op->u.createdomain.handle,
@@ -323,7 +323,7 @@
         new_affinity = v->cpu_affinity;
         memcpy(cpus_addr(new_affinity),
                &op->u.setvcpuaffinity.cpumap,
-               min((int)BITS_TO_LONGS(NR_CPUS),
+               min((int)(BITS_TO_LONGS(NR_CPUS) * sizeof(long)),
                    (int)sizeof(op->u.setvcpuaffinity.cpumap)));
 
         ret = vcpu_set_affinity(v, &new_affinity);
@@ -450,6 +450,10 @@
         if ( (v = d->vcpu[op->u.getvcpucontext.vcpu]) == NULL )
             goto getvcpucontext_out;
 
+        ret = -ENODATA;
+        if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+            goto getvcpucontext_out;
+
         ret = -ENOMEM;
         if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
             goto getvcpucontext_out;
@@ -501,7 +505,7 @@
         op->u.getvcpuinfo.cpumap   = 0;
         memcpy(&op->u.getvcpuinfo.cpumap,
                cpus_addr(v->cpu_affinity),
-               min((int)BITS_TO_LONGS(NR_CPUS),
+               min((int)(BITS_TO_LONGS(NR_CPUS) * sizeof(long)),
                    (int)sizeof(op->u.getvcpuinfo.cpumap)));
         ret = 0;
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/domain.c
--- a/xen/common/domain.c       Tue Jan 10 15:21:00 2006
+++ b/xen/common/domain.c       Tue Jan 24 16:54:34 2006
@@ -29,7 +29,7 @@
 
 struct domain *dom0;
 
-struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
+struct domain *domain_create(domid_t dom_id, unsigned int cpu)
 {
     struct domain *d, **pd;
     struct vcpu *v;
@@ -46,25 +46,27 @@
     INIT_LIST_HEAD(&d->page_list);
     INIT_LIST_HEAD(&d->xenpage_list);
 
+    rangeset_domain_initialise(d);
+
     if ( !is_idle_domain(d) )
+    {
         set_bit(_DOMF_ctrl_pause, &d->domain_flags);
-
-    if ( !is_idle_domain(d) &&
-         ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
-        goto fail1;
-    
+        if ( evtchn_init(d) != 0 )
+            goto fail1;
+        if ( grant_table_create(d) != 0 )
+            goto fail2;
+    }
+
+    if ( arch_domain_create(d) != 0 )
+        goto fail3;
+
     if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
-        goto fail2;
-
-    rangeset_domain_initialise(d);
+        goto fail4;
 
     d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
     d->irq_caps   = rangeset_new(d, "Interrupts", 0);
-
-    if ( (d->iomem_caps == NULL) ||
-         (d->irq_caps == NULL) ||
-         (arch_do_createdomain(v) != 0) )
-        goto fail3;
+    if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
+        goto fail4; /* NB. alloc_vcpu() is undone in free_domain() */
 
     if ( !is_idle_domain(d) )
     {
@@ -82,12 +84,16 @@
 
     return d;
 
+ fail4:
+    arch_domain_destroy(d);
  fail3:
+    if ( !is_idle_domain(d) )
+        grant_table_destroy(d);
+ fail2:
+    if ( !is_idle_domain(d) )
+        evtchn_destroy(d);
+ fail1:
     rangeset_domain_destroy(d);
- fail2:
-    grant_table_destroy(d);
- fail1:
-    evtchn_destroy(d);
     free_domain(d);
     return NULL;
 }
@@ -256,16 +262,16 @@
 
 
 /* Release resources belonging to task @p. */
-void domain_destruct(struct domain *d)
+void domain_destroy(struct domain *d)
 {
     struct domain **pd;
     atomic_t      old, new;
 
     BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
 
-    /* May be already destructed, or get_domain() can race us. */
+    /* May be already destroyed, or get_domain() can race us. */
     _atomic_set(old, 0);
-    _atomic_set(new, DOMAIN_DESTRUCTED);
+    _atomic_set(new, DOMAIN_DESTROYED);
     old = atomic_compareandswap(old, new, &d->refcnt);
     if ( _atomic_read(old) != 0 )
         return;
@@ -287,8 +293,7 @@
     evtchn_destroy(d);
     grant_table_destroy(d);
 
-    free_perdomain_pt(d);
-    free_xenheap_page(d->shared_info);
+    arch_domain_destroy(d);
 
     free_domain(d);
 
@@ -369,15 +374,16 @@
     if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
         return -EINVAL;
     
-    if ( !test_bit(_DOMF_ctrl_pause, &d->domain_flags) )
-        return -EINVAL;
-
     if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
         return -ENOMEM;
+
+    domain_pause(d);
 
     rc = -EFAULT;
     if ( copy_from_user(c, setvcpucontext->ctxt, sizeof(*c)) == 0 )
         rc = arch_set_info_guest(v, c);
+
+    domain_unpause(d);
 
     xfree(c);
     return rc;
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/kernel.c
--- a/xen/common/kernel.c       Tue Jan 10 15:21:00 2006
+++ b/xen/common/kernel.c       Tue Jan 24 16:54:34 2006
@@ -11,6 +11,7 @@
 #include <xen/compile.h>
 #include <xen/sched.h>
 #include <asm/current.h>
+#include <public/nmi.h>
 #include <public/version.h>
 
 void cmdline_parse(char *cmdline)
@@ -146,6 +147,43 @@
     }
 
     return -ENOSYS;
+}
+
+long do_nmi_op(unsigned int cmd, void *arg)
+{
+    struct vcpu *v = current;
+    struct domain *d = current->domain;
+    long rc = 0;
+
+    switch ( cmd )
+    {
+    case XENNMI_register_callback:
+        if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
+        { 
+           rc = -EINVAL;
+        }
+        else
+        {
+            v->nmi_addr = (unsigned long)arg;
+#ifdef CONFIG_X86
+            /*
+             * If no handler was registered we can 'lose the NMI edge'.
+             * Re-assert it now.
+             */
+            if ( d->shared_info->arch.nmi_reason != 0 )
+                set_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
+#endif
+        }
+        break;
+    case XENNMI_unregister_callback:
+        v->nmi_addr = 0;
+        break;
+    default:
+        rc = -ENOSYS;
+        break;
+    }
+
+    return rc;
 }
 
 long do_vm_assist(unsigned int cmd, unsigned int type)
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/memory.c
--- a/xen/common/memory.c       Tue Jan 10 15:21:00 2006
+++ b/xen/common/memory.c       Tue Jan 24 16:54:34 2006
@@ -38,10 +38,7 @@
 
     if ( (extent_order != 0) &&
          !multipage_allocation_permitted(current->domain) )
-    {
-        DPRINTK("Only I/O-capable domains may allocate multi-page extents.\n");
         return 0;
-    }
 
     for ( i = 0; i < nr_extents; i++ )
     {
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/sched_bvt.c
--- a/xen/common/sched_bvt.c    Tue Jan 10 15:21:00 2006
+++ b/xen/common/sched_bvt.c    Tue Jan 24 16:54:34 2006
@@ -20,7 +20,7 @@
 #include <xen/delay.h>
 #include <xen/event.h>
 #include <xen/time.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
 #include <xen/perfc.h>
 #include <xen/sched-if.h>
 #include <xen/softirq.h>
@@ -45,9 +45,9 @@
                                              limits*/
     s32                 warp_value;       /* virtual time warp */
     s_time_t            warpl;            /* warp limit */
-    struct ac_timer     warp_timer;       /* deals with warpl */
+    struct timer        warp_timer;       /* deals with warpl */
     s_time_t            warpu;            /* unwarp time requirement */
-    struct ac_timer     unwarp_timer;     /* deals with warpu */
+    struct timer        unwarp_timer;     /* deals with warpu */
 
     struct bvt_vcpu_info vcpu_inf[MAX_VIRT_CPUS];
 };
@@ -98,9 +98,9 @@
 static void warp_timer_fn(void *data)
 {
     struct bvt_dom_info *inf = data;
-    unsigned int cpu = inf->domain->vcpu[0]->processor;
-    
-    spin_lock_irq(&schedule_data[cpu].schedule_lock);
+    struct vcpu *v = inf->domain->vcpu[0];
+
+    vcpu_schedule_lock_irq(v);
 
     inf->warp = 0;
 
@@ -108,28 +108,28 @@
     if ( inf->warpu == 0 )
     {
         inf->warpback = 0;
-        cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);   
-    }
-    
-    set_ac_timer(&inf->unwarp_timer, NOW() + inf->warpu);
-
-    spin_unlock_irq(&schedule_data[cpu].schedule_lock);
+        cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);   
+    }
+    
+    set_timer(&inf->unwarp_timer, NOW() + inf->warpu);
+
+    vcpu_schedule_unlock_irq(v);
 }
 
 static void unwarp_timer_fn(void *data)
 {
     struct bvt_dom_info *inf = data;
-    unsigned int cpu = inf->domain->vcpu[0]->processor;
-
-    spin_lock_irq(&schedule_data[cpu].schedule_lock);
+    struct vcpu *v = inf->domain->vcpu[0];
+
+    vcpu_schedule_lock_irq(v);
 
     if ( inf->warpback )
     {
         inf->warp = 1;
-        cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);   
+        cpu_raise_softirq(v->processor, SCHEDULE_SOFTIRQ);   
     }
      
-    spin_unlock_irq(&schedule_data[cpu].schedule_lock);
+    vcpu_schedule_unlock_irq(v);
 }
 
 static inline u32 calc_avt(struct vcpu *d, s_time_t now)
@@ -168,6 +168,7 @@
 static int bvt_alloc_task(struct vcpu *v)
 {
     struct domain *d = v->domain;
+    struct bvt_dom_info *inf;
 
     if ( (d->sched_priv == NULL) )
     {
@@ -176,32 +177,12 @@
         memset(d->sched_priv, 0, sizeof(struct bvt_dom_info));
     }
 
-    v->sched_priv = &BVT_INFO(d)->vcpu_inf[v->vcpu_id];
-
-    BVT_INFO(d)->vcpu_inf[v->vcpu_id].inf = BVT_INFO(d);
-    BVT_INFO(d)->vcpu_inf[v->vcpu_id].vcpu = v;
-
-    return 0;
-}
-
-/*
- * Add and remove a domain
- */
-static void bvt_add_task(struct vcpu *v) 
-{
-    struct bvt_dom_info *inf = BVT_INFO(v->domain);
-    struct bvt_vcpu_info *einf = EBVT_INFO(v);
-    ASSERT(inf != NULL);
-    ASSERT(v   != NULL);
-
-    /* Allocate per-CPU context if this is the first domain to be added. */
-    if ( CPU_INFO(v->processor) == NULL )
-    {
-        schedule_data[v->processor].sched_priv = xmalloc(struct bvt_cpu_info);
-        BUG_ON(CPU_INFO(v->processor) == NULL);
-        INIT_LIST_HEAD(RUNQUEUE(v->processor));
-        CPU_SVT(v->processor) = 0;
-    }
+    inf = BVT_INFO(d);
+
+    v->sched_priv = &inf->vcpu_inf[v->vcpu_id];
+
+    inf->vcpu_inf[v->vcpu_id].inf  = BVT_INFO(d);
+    inf->vcpu_inf[v->vcpu_id].vcpu = v;
 
     if ( v->vcpu_id == 0 )
     {
@@ -214,11 +195,28 @@
         inf->warpl       = MILLISECS(2000);
         inf->warpu       = MILLISECS(1000);
         /* Initialise the warp timers. */
-        init_ac_timer(&inf->warp_timer, warp_timer_fn, inf, v->processor);
-        init_ac_timer(&inf->unwarp_timer, unwarp_timer_fn, inf, v->processor);
-    }
-
-    einf->vcpu = v;
+        init_timer(&inf->warp_timer, warp_timer_fn, inf, v->processor);
+        init_timer(&inf->unwarp_timer, unwarp_timer_fn, inf, v->processor);
+    }
+
+    return 0;
+}
+
+/*
+ * Add and remove a domain
+ */
+static void bvt_add_task(struct vcpu *v) 
+{
+    struct bvt_vcpu_info *einf = EBVT_INFO(v);
+
+    /* Allocate per-CPU context if this is the first domain to be added. */
+    if ( CPU_INFO(v->processor) == NULL )
+    {
+        schedule_data[v->processor].sched_priv = xmalloc(struct bvt_cpu_info);
+        BUG_ON(CPU_INFO(v->processor) == NULL);
+        INIT_LIST_HEAD(RUNQUEUE(v->processor));
+        CPU_SVT(v->processor) = 0;
+    }
 
     if ( is_idle_vcpu(v) )
     {
@@ -271,7 +269,7 @@
     if ( is_idle_vcpu(curr) || (einf->evt <= curr_evt) )
         cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
     else if ( schedule_data[cpu].s_timer.expires > r_time )
-        set_ac_timer(&schedule_data[cpu].s_timer, r_time);
+        set_timer(&schedule_data[cpu].s_timer, r_time);
 }
 
 
@@ -305,8 +303,14 @@
  */
 static void bvt_free_task(struct domain *d)
 {
-    ASSERT(d->sched_priv != NULL);
-    xfree(d->sched_priv);
+    struct bvt_dom_info *inf = BVT_INFO(d);
+
+    ASSERT(inf != NULL);
+
+    kill_timer(&inf->warp_timer);
+    kill_timer(&inf->unwarp_timer);
+
+    xfree(inf);
 }
 
 /* Control the scheduler. */
@@ -355,10 +359,10 @@
         inf->warpu = MILLISECS(warpu);
         
         /* If the unwarp timer set up it needs to be removed */
-        rem_ac_timer(&inf->unwarp_timer);
+        stop_timer(&inf->unwarp_timer);
         /* If we stop warping the warp timer needs to be removed */
         if ( !warpback )
-            rem_ac_timer(&inf->warp_timer);
+            stop_timer(&inf->warp_timer);
     }
     else if ( cmd->direction == SCHED_INFO_GET )
     {
@@ -405,7 +409,7 @@
         prev_einf->evt = calc_evt(prev, prev_einf->avt);
        
         if(prev_inf->warpback && prev_inf->warpl > 0)
-            rem_ac_timer(&prev_inf->warp_timer);
+            stop_timer(&prev_inf->warp_timer);
         
         __del_from_runqueue(prev);
         
@@ -455,7 +459,7 @@
     }
     
     if ( next_einf->inf->warp && next_einf->inf->warpl > 0 )
-        set_ac_timer(&next_einf->inf->warp_timer, now + next_einf->inf->warpl);
+        set_timer(&next_einf->inf->warp_timer, now + next_einf->inf->warpl);
    
     /* Extract the domain pointers from the dom infos */
     next        = next_einf->vcpu;
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   Tue Jan 10 15:21:00 2006
+++ b/xen/common/sched_sedf.c   Tue Jan 24 16:54:34 2006
@@ -9,7 +9,7 @@
 #include <xen/sched.h>
 #include <xen/sched-if.h>
 #include <public/sched_ctl.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
 #include <xen/softirq.h>
 #include <xen/time.h>
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/schedule.c
--- a/xen/common/schedule.c     Tue Jan 10 15:21:00 2006
+++ b/xen/common/schedule.c     Tue Jan 24 16:54:34 2006
@@ -21,7 +21,7 @@
 #include <xen/delay.h>
 #include <xen/event.h>
 #include <xen/time.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
 #include <xen/perfc.h>
 #include <xen/sched-if.h>
 #include <xen/softirq.h>
@@ -71,17 +71,31 @@
           : (typeof(ops.fn(__VA_ARGS__)))0 )
 
 /* Per-CPU periodic timer sends an event to the currently-executing domain. */
-static struct ac_timer t_timer[NR_CPUS]; 
+static struct timer t_timer[NR_CPUS]; 
+
+struct domain *alloc_domain(void)
+{
+    struct domain *d;
+
+    if ( (d = xmalloc(struct domain)) != NULL )
+        memset(d, 0, sizeof(*d));
+
+    return d;
+}
 
 void free_domain(struct domain *d)
 {
+    struct vcpu *v;
     int i;
 
+    for_each_vcpu ( d, v )
+        sched_rem_domain(v);
+
     SCHED_OP(free_task, d);
 
     for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- )
-        if ( d->vcpu[i] != NULL )
-            free_vcpu_struct(d->vcpu[i]);
+        if ( (v = d->vcpu[i]) != NULL )
+            free_vcpu_struct(v);
 
     xfree(d);
 }
@@ -100,48 +114,33 @@
     v->vcpu_id = vcpu_id;
     v->processor = cpu_id;
     atomic_set(&v->pausecnt, 0);
+    v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
 
     v->cpu_affinity = is_idle_domain(d) ?
         cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
 
-    d->vcpu[vcpu_id] = v;
+    if ( (vcpu_id != 0) && !is_idle_domain(d) )
+        set_bit(_VCPUF_down, &v->vcpu_flags);
 
     if ( SCHED_OP(alloc_task, v) < 0 )
     {
-        d->vcpu[vcpu_id] = NULL;
         free_vcpu_struct(v);
         return NULL;
     }
 
+    d->vcpu[vcpu_id] = v;
+    if ( vcpu_id != 0 )
+        d->vcpu[v->vcpu_id-1]->next_in_list = v;
+
     sched_add_domain(v);
 
-    if ( vcpu_id != 0 )
-    {
-        v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
-        d->vcpu[v->vcpu_id-1]->next_in_list = v;
-        set_bit(_VCPUF_down, &v->vcpu_flags);
-    }
-
     return v;
 }
 
-struct domain *alloc_domain(void)
-{
-    struct domain *d;
-
-    if ( (d = xmalloc(struct domain)) != NULL )
-        memset(d, 0, sizeof(*d));
-
-    return d;
-}
-
-/*
- * Add and remove a domain
- */
 void sched_add_domain(struct vcpu *v) 
 {
     /* Initialise the per-domain timer. */
-    init_ac_timer(&v->timer, dom_timer_fn, v, v->processor);
+    init_timer(&v->timer, dom_timer_fn, v, v->processor);
 
     if ( is_idle_vcpu(v) )
     {
@@ -156,7 +155,7 @@
 
 void sched_rem_domain(struct vcpu *v) 
 {
-    rem_ac_timer(&v->timer);
+    kill_timer(&v->timer);
     SCHED_OP(rem_task, v);
     TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id);
 }
@@ -165,26 +164,19 @@
 {
     unsigned long flags;
 
-    spin_lock_irqsave(&schedule_data[v->processor].schedule_lock, flags);
+    vcpu_schedule_lock_irqsave(v, flags);
     if ( likely(!vcpu_runnable(v)) )
         SCHED_OP(sleep, v);
-    spin_unlock_irqrestore(&schedule_data[v->processor].schedule_lock, flags);
+    vcpu_schedule_unlock_irqrestore(v, flags);
 
     TRACE_2D(TRC_SCHED_SLEEP, v->domain->domain_id, v->vcpu_id);
-} 
+}
 
 void vcpu_sleep_sync(struct vcpu *v)
 {
     vcpu_sleep_nosync(v);
 
-    /*
-     * We can be sure that the VCPU is finally descheduled after the running
-     * flag is cleared and the scheduler lock is released. We also check that
-     * the domain continues to be unrunnable, in case someone else wakes it.
-     */
-    while ( !vcpu_runnable(v) &&
-            (test_bit(_VCPUF_running, &v->vcpu_flags) ||
-             spin_is_locked(&schedule_data[v->processor].schedule_lock)) )
+    while ( !vcpu_runnable(v) && test_bit(_VCPUF_running, &v->vcpu_flags) )
         cpu_relax();
 
     sync_vcpu_execstate(v);
@@ -194,20 +186,23 @@
 {
     unsigned long flags;
 
-    spin_lock_irqsave(&schedule_data[v->processor].schedule_lock, flags);
+    vcpu_schedule_lock_irqsave(v, flags);
     if ( likely(vcpu_runnable(v)) )
     {
         SCHED_OP(wake, v);
         v->wokenup = NOW();
     }
-    spin_unlock_irqrestore(&schedule_data[v->processor].schedule_lock, flags);
+    vcpu_schedule_unlock_irqrestore(v, flags);
 
     TRACE_2D(TRC_SCHED_WAKE, v->domain->domain_id, v->vcpu_id);
 }
 
 int vcpu_set_affinity(struct vcpu *v, cpumask_t *affinity)
 {
-    if ( cpus_empty(*affinity) )
+    cpumask_t online_affinity;
+
+    cpus_and(online_affinity, *affinity, cpu_online_map);
+    if ( cpus_empty(online_affinity) )
         return -EINVAL;
 
     return SCHED_OP(set_affinity, v, affinity);
@@ -282,9 +277,9 @@
     struct vcpu *v = current;
 
     if ( timeout == 0 )
-        rem_ac_timer(&v->timer);
+        stop_timer(&v->timer);
     else
-        set_ac_timer(&v->timer, timeout);
+        set_timer(&v->timer, timeout);
 
     return 0;
 }
@@ -311,68 +306,42 @@
 {
     struct domain *d;
     struct vcpu *v;
-    int cpu;
-#if NR_CPUS <=32
-    unsigned long have_lock;
- #else
-    unsigned long long have_lock;
-#endif
-    int succ;
-
-    #define __set_cpu_bit(cpu, data) data |= ((typeof(data))1)<<cpu
-    #define __get_cpu_bit(cpu, data) (data & ((typeof(data))1)<<cpu)
-    #define __clear_cpu_bits(data) data = ((typeof(data))0)
     
-    if ( cmd->sched_id != ops.sched_id )
-        return -EINVAL;
-    
-    if ( cmd->direction != SCHED_INFO_PUT && cmd->direction != SCHED_INFO_GET )
+    if ( (cmd->sched_id != ops.sched_id) ||
+         ((cmd->direction != SCHED_INFO_PUT) &&
+          (cmd->direction != SCHED_INFO_GET)) )
         return -EINVAL;
 
     d = find_domain_by_id(cmd->domain);
     if ( d == NULL )
         return -ESRCH;
 
-    /* acquire locks on all CPUs on which vcpus of this domain run */
-    do {
-        succ = 0;
-        __clear_cpu_bits(have_lock);
-        for_each_vcpu ( d, v )
-        {
-            cpu = v->processor;
-            if ( !__get_cpu_bit(cpu, have_lock) )
-            {
-                /* if we don't have a lock on this CPU: acquire it*/
-                if ( spin_trylock(&schedule_data[cpu].schedule_lock) )
-                {
-                    /*we have this lock!*/
-                    __set_cpu_bit(cpu, have_lock);
-                    succ = 1;
-                }
-                else
-                {
-                    /*we didn,t get this lock -> free all other locks too!*/
-                    for ( cpu = 0; cpu < NR_CPUS; cpu++ )
-                        if ( __get_cpu_bit(cpu, have_lock) )
-                            spin_unlock(&schedule_data[cpu].schedule_lock);
-                    /* and start from the beginning! */
-                    succ = 0;
-                    /* leave the "for_each_domain_loop" */
-                    break;
-                }
-            }
-        }
-    } while ( !succ );
+    /*
+     * Most VCPUs we can simply pause. If we are adjusting this VCPU then
+     * we acquire the local schedule_lock to guard against concurrent updates.
+     */
+    for_each_vcpu ( d, v )
+    {
+        if ( v == current )
+            vcpu_schedule_lock_irq(v);
+        else
+            vcpu_pause(v);
+    }
 
     SCHED_OP(adjdom, d, cmd);
 
-    for ( cpu = 0; cpu < NR_CPUS; cpu++ )
-        if ( __get_cpu_bit(cpu, have_lock) )
-            spin_unlock(&schedule_data[cpu].schedule_lock);
-    __clear_cpu_bits(have_lock);
-
     TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
+
+    for_each_vcpu ( d, v )
+    {
+        if ( v == current )
+            vcpu_schedule_unlock_irq(v);
+        else
+            vcpu_unpause(v);
+    }
+
     put_domain(d);
+
     return 0;
 }
 
@@ -395,7 +364,7 @@
 
     spin_lock_irq(&schedule_data[cpu].schedule_lock);
 
-    rem_ac_timer(&schedule_data[cpu].s_timer);
+    stop_timer(&schedule_data[cpu].s_timer);
     
     prev->cpu_time += now - prev->lastschd;
 
@@ -409,7 +378,7 @@
     
     next->lastschd = now;
 
-    set_ac_timer(&schedule_data[cpu].s_timer, now + r_time);
+    set_timer(&schedule_data[cpu].s_timer, now + r_time);
 
     if ( unlikely(prev == next) )
     {
@@ -451,6 +420,7 @@
     }
 #endif
 
+    ASSERT(!test_bit(_VCPUF_running, &next->vcpu_flags));
     set_bit(_VCPUF_running, &next->vcpu_flags);
 
     spin_unlock_irq(&schedule_data[cpu].schedule_lock);
@@ -492,7 +462,7 @@
 /* Periodic tick timer: send timer event to current domain */
 static void t_timer_fn(void *unused)
 {
-    struct vcpu  *v  = current;
+    struct vcpu  *v   = current;
     unsigned int  cpu = smp_processor_id();
 
     schedule_data[cpu].tick++;
@@ -505,7 +475,7 @@
 
     page_scrub_schedule_work();
 
-    set_ac_timer(&t_timer[cpu], NOW() + MILLISECS(10));
+    set_timer(&t_timer[cpu], NOW() + MILLISECS(10));
 }
 
 /* Domain timer function, sends a virtual timer interrupt to domain */
@@ -527,8 +497,8 @@
     for ( i = 0; i < NR_CPUS; i++ )
     {
         spin_lock_init(&schedule_data[i].schedule_lock);
-        init_ac_timer(&schedule_data[i].s_timer, s_timer_fn, NULL, i);
-        init_ac_timer(&t_timer[i], t_timer_fn, NULL, i);
+        init_timer(&schedule_data[i].s_timer, s_timer_fn, NULL, i);
+        init_timer(&t_timer[i], t_timer_fn, NULL, i);
     }
 
     for ( i = 0; schedulers[i] != NULL; i++ )
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/xmalloc.c
--- a/xen/common/xmalloc.c      Tue Jan 10 15:21:00 2006
+++ b/xen/common/xmalloc.c      Tue Jan 24 16:54:34 2006
@@ -30,7 +30,7 @@
 #include <xen/config.h>
 #include <xen/mm.h>
 #include <xen/spinlock.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
 #include <xen/cache.h>
 #include <xen/prefetch.h>
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Tue Jan 10 15:21:00 2006
+++ b/xen/drivers/char/ns16550.c        Tue Jan 24 16:54:34 2006
@@ -33,7 +33,7 @@
     /* UART with IRQ line: interrupt-driven I/O. */
     struct irqaction irqaction;
     /* UART with no IRQ line: periodically-polled I/O. */
-    struct ac_timer timer;
+    struct timer timer;
     unsigned int timeout_ms;
 } ns16550_com[2] = { { 0 } };
 
@@ -138,7 +138,7 @@
     if ( ns_read_reg(uart, LSR) & LSR_THRE )
         serial_tx_interrupt(port, regs);
 
-    set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+    set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
 }
 
 static int ns16550_tx_empty(struct serial_port *port)
@@ -214,8 +214,8 @@
         bits = uart->data_bits + uart->stop_bits + !!uart->parity;
         uart->timeout_ms = max_t(
             unsigned int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);
-        init_ac_timer(&uart->timer, ns16550_poll, port, 0);
-        set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+        init_timer(&uart->timer, ns16550_poll, port, 0);
+        set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
     }
     else
     {
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h     Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/config.h     Tue Jan 24 16:54:34 2006
@@ -92,7 +92,7 @@
 //#define __acquire(x) (void)0
 //#define __release(x) (void)0
 //#define __cond_lock(x) (x)
-#define __must_check
+//#define __must_check
 #define __deprecated
 #ifndef RELOC_HIDE
 # define RELOC_HIDE(ptr, off)                                  \
@@ -121,7 +121,7 @@
 
 // from include/asm-ia64/smp.h
 #ifdef CONFIG_SMP
-#warning "Lots of things to fix to enable CONFIG_SMP!"
+//#warning "Lots of things to fix to enable CONFIG_SMP!"
 #endif
 #define        get_cpu()       smp_processor_id()
 #define put_cpu()      do {} while(0)
@@ -140,10 +140,6 @@
 #undef free_task_struct
 #undef alloc_task_struct
 #define get_thread_info(v) alloc_thread_info(v)
-
-// initial task has a different name in Xen
-//#define      idle0_task      init_task
-#define        idle0_vcpu      init_task
 
 // avoid redefining task_t in asm/thread_info.h
 #define task_t struct domain
@@ -160,7 +156,7 @@
 #define platform_outl  __ia64_outl
 
 // FIXME: This just overrides a use in a typedef (not allowed in ia64,
-//  or maybe just in older gcc's?) used in ac_timer.c but should be OK
+//  or maybe just in older gcc's?) used in timer.c but should be OK
 //  (and indeed is probably required!) elsewhere
 #undef __cacheline_aligned
 #undef ____cacheline_aligned
@@ -187,7 +183,9 @@
                  struct exception_table_entry *finish);
 void sort_main_extable(void);
 
+#if 0 /* Already defined in xen/lib.h */
 #define printk printf
+#endif
 
 #undef  __ARCH_IRQ_STAT
 
@@ -205,7 +203,6 @@
 #define        OPT_CONSOLE_STR "com2"
 #endif
 
-#define __attribute_used__     __attribute__ ((unused))
 #define __nocast
 
 // see include/asm-x86/atomic.h (different from standard linux)
@@ -255,9 +252,6 @@
 #define seq_printf(a,b...) printf(b)
 #define CONFIG_BLK_DEV_INITRD // needed to reserve memory for domain0
 
-// needed for newer ACPI code
-#define asmlinkage
-
 #define FORCE_CRASH()  asm("break 0;;");
 
 void dummy_called(char *function);
@@ -306,13 +300,8 @@
 #endif
 
 
-// FOLLOWING ADDED FOR XEN POST-NGIO and/or LINUX 2.6.7
-
-// following derived from linux/include/linux/compiler-gcc3.h
-// problem because xen (over?)simplifies include/xen/compiler.h
-#if __GNUC_MAJOR < 3 || __GNUC_MINOR__ >= 3
-# define __attribute_used__    __attribute__((__used__))
-#else
-# define __attribute_used__    __attribute__((__unused__))
-#endif
+#ifndef __ASSEMBLY__
+#include <linux/linkage.h>
+#endif
+
 #endif /* _IA64_CONFIG_H_ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/debugger.h
--- a/xen/include/asm-ia64/debugger.h   Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/debugger.h   Tue Jan 24 16:54:34 2006
@@ -24,6 +24,54 @@
 
 #include <xen/softirq.h>
 
+// this number is an arbitary number which is not used for any other purpose
+// __builtin_trap(), FORCE_CRASH() 0x0
+// ski  0x80001, 0x80002
+// kdb  0x80100, 0x80101
+// kprobe 0x80200, jprobe 0x80300
+// kgdb 0x6665
+// gdb 0x99998 (#define IA64_BREAKPOINT 0x00003333300LL)
+
+// cdb should handle 0 and CDB_BREAK_NUM.
+#define CDB_BREAK_NUM  0x80800
+
+
+#ifndef __ASSEMBLY__
+
+#include <xen/gdbstub.h>
+
+// NOTE: on xen struct pt_regs = struct cpu_user_regs
+//       see include/asm-ia64/linux-xen/asm/ptrace.h
+#ifdef CRASH_DEBUG
+// crash_debug=y
+
+/* The main trap handlers use these helper macros which include early bail. */
+static inline int debugger_trap_entry(
+    unsigned int vector, struct cpu_user_regs *regs)
+{
+    return 0;
+}
+
+extern int __trap_to_cdb(struct cpu_user_regs *r);
+static inline int debugger_trap_fatal(
+    unsigned int vector, struct cpu_user_regs *regs)
+{
+       (void)__trap_to_gdb(regs, vector);
+    return 0;
+}
+
+#define ____debugger_trap_immediate(b) __asm__ __volatile__ ("break.m "#b"\n")
+#define __debugger_trap_immediate(b) ____debugger_trap_immediate(b)
+#define debugger_trap_immediate() __debugger_trap_immediate(CDB_BREAK_NUM)
+
+//XXX temporal work around
+#ifndef CONFIG_SMP
+#define smp_send_stop()        /* nothing */
+#endif
+
+#elif defined DOMU_DEBUG
+// domu_debug=y
+#warning "domu_debug is not implemented yet."
 /* The main trap handlers use these helper macros which include early bail. */
 static inline int debugger_trap_entry(
     unsigned int vector, struct cpu_user_regs *regs)
@@ -37,6 +85,23 @@
     return 0;
 }
 
-#define debugger_trap_immediate() do {} while(0)
+#define debugger_trap_immediate()              ((void)0)
+#else
+/* The main trap handlers use these helper macros which include early bail. */
+static inline int debugger_trap_entry(
+    unsigned int vector, struct cpu_user_regs *regs)
+{
+    return 0;
+}
+
+static inline int debugger_trap_fatal(
+    unsigned int vector, struct cpu_user_regs *regs)
+{
+    return 0;
+}
+
+#define debugger_trap_immediate()              ((void)0)
+#endif
+#endif // __ASSEMBLLY__
 
 #endif /* __ASM_DEBUGGER_H__ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h     Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/domain.h     Tue Jan 24 16:54:34 2006
@@ -9,8 +9,6 @@
 #include <public/arch-ia64.h>
 #include <asm/vmx_platform.h>
 #include <xen/list.h>
-
-extern int arch_do_createdomain(struct vcpu *);
 
 extern void domain_relinquish_resources(struct domain *);
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/linux-xen/asm/ptrace.h
--- a/xen/include/asm-ia64/linux-xen/asm/ptrace.h       Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/linux-xen/asm/ptrace.h       Tue Jan 24 16:54:34 2006
@@ -110,6 +110,7 @@
   return (struct cpu_user_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1;
 }
 
+struct pt_regs *guest_cpu_user_regs(void);
 
 #else
 struct pt_regs {
diff -r 40bb46f599d9 -r a38c292e8390 
xen/include/asm-ia64/linux-xen/linux/interrupt.h
--- a/xen/include/asm-ia64/linux-xen/linux/interrupt.h  Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/linux-xen/linux/interrupt.h  Tue Jan 24 16:54:34 2006
@@ -104,6 +104,7 @@
    al. should be converted to tasklets, not to softirqs.
  */
 
+#ifndef XEN
 enum
 {
        HI_SOFTIRQ=0,
@@ -113,6 +114,7 @@
        SCSI_SOFTIRQ,
        TASKLET_SOFTIRQ
 };
+#endif
 
 /* softirq mask and active fields moved to irq_cpustat_t in
  * asm/hardirq.h to get better cache usage.  KAO
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/mm.h Tue Jan 24 16:54:34 2006
@@ -67,10 +67,12 @@
         } free;
 
     } u;
+#if 0
 // following added for Linux compiling
     page_flags_t flags;
     atomic_t _count;
     struct list_head lru;      // is this the same as above "list"?
+#endif
 };
 
 #define set_page_count(p,v)    atomic_set(&(p)->_count, v - 1)
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h       Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/vmmu.h       Tue Jan 24 16:54:34 2006
@@ -151,8 +151,8 @@
 typedef u64 *(THASH_FN)(PTA pta, u64 va);
 typedef u64 *(TTAG_FN)(PTA pta, u64 va);
 typedef u64 *(GET_MFN_FN)(domid_t d, u64 gpfn, u64 pages);
-typedef void *(REM_NOTIFIER_FN)(struct hash_cb *hcb, thash_data_t *entry);
-typedef void (RECYCLE_FN)(struct hash_cb *hc, u64 para);
+typedef void *(REM_NOTIFIER_FN)(struct thash_cb *hcb, thash_data_t *entry);
+typedef void (RECYCLE_FN)(struct thash_cb *hc, u64 para);
 typedef ia64_rr (GET_RR_FN)(struct vcpu *vcpu, u64 reg);
 typedef thash_data_t *(FIND_OVERLAP_FN)(struct thash_cb *hcb, 
         u64 va, u64 ps, int rid, char cl, search_section_t s_sect);
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-ia64/vtm.h
--- a/xen/include/asm-ia64/vtm.h        Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-ia64/vtm.h        Tue Jan 24 16:54:34 2006
@@ -23,7 +23,7 @@
 #ifndef _VTM_H_
 #define _VTM_H_
 
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
 #include <xen/types.h>
 
 #define MAX_JUMP_STEP       (5000)   /* 500ms, max jump step */
@@ -46,7 +46,7 @@
        uint64_t    cfg_max_jump;   // max jump within one time suspendsion
        uint64_t    cfg_min_grun;   // min guest running time since last jump
 //     uint64_t    latest_read_itc;    // latest guest read ITC
-       struct ac_timer vtm_timer;
+       struct timer    vtm_timer;
 //     int        triggered;
        
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/debugger.h
--- a/xen/include/asm-x86/debugger.h    Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/debugger.h    Tue Jan 24 16:54:34 2006
@@ -42,19 +42,19 @@
 
 #if defined(CRASH_DEBUG)
 
-extern int __trap_to_cdb(struct cpu_user_regs *r);
+#include <xen/gdbstub.h>
 
 #define __debugger_trap_entry(_v, _r) (0)
 
 static inline int __debugger_trap_fatal(
     unsigned int vector, struct cpu_user_regs *regs)
 {
-    (void)__trap_to_cdb(regs);
+    (void)__trap_to_gdb(regs, vector);
     return (vector == TRAP_int3); /* int3 is harmless */
 }
 
 /* Int3 is a trivial way to gather cpu_user_regs context. */
-#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
+#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
 
 #elif 0
 
@@ -73,7 +73,7 @@
 }
 
 /* Int3 is a trivial way to gather cpu_user_regs context. */
-#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
+#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
 
 #else
 
@@ -100,6 +100,8 @@
 }
 
 #define debugger_trap_fatal(v, r) (__debugger_trap_fatal(v, r))
+#ifndef debugger_trap_immediate
 #define debugger_trap_immediate() (__debugger_trap_immediate())
+#endif
 
 #endif /* __X86_DEBUGGER_H__ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/domain.h      Tue Jan 24 16:54:34 2006
@@ -13,12 +13,43 @@
     unsigned long  eip;
 };
 
+#define MAPHASH_ENTRIES 8
+#define MAPHASH_HASHFN(pfn) ((pfn) & (MAPHASH_ENTRIES-1))
+#define MAPHASHENT_NOTINUSE ((u16)~0U)
+struct vcpu_maphash {
+    struct vcpu_maphash_entry {
+        unsigned long pfn;
+        uint16_t      idx;
+        uint16_t      refcnt;
+    } hash[MAPHASH_ENTRIES];
+} __cacheline_aligned;
+
+#define MAPCACHE_ORDER   10
+#define MAPCACHE_ENTRIES (1 << MAPCACHE_ORDER)
 struct mapcache {
+    /* The PTEs that provide the mappings, and a cursor into the array. */
     l1_pgentry_t *l1tab;
     unsigned int cursor;
+
+    /* Protects map_domain_page(). */
+    spinlock_t lock;
+
+    /* Garbage mappings are flushed from TLBs in batches called 'epochs'. */
     unsigned int epoch, shadow_epoch[MAX_VIRT_CPUS];
-    spinlock_t lock;
+    u32 tlbflush_timestamp;
+
+    /* Which mappings are in use, and which are garbage to reap next epoch? */
+    unsigned long inuse[BITS_TO_LONGS(MAPCACHE_ENTRIES)];
+    unsigned long garbage[BITS_TO_LONGS(MAPCACHE_ENTRIES)];
+
+    /* Lock-free per-VCPU hash of recently-used mappings. */
+    struct vcpu_maphash vcpu_maphash[MAX_VIRT_CPUS];
 };
+
+extern void mapcache_init(struct domain *);
+
+/* x86/64: toggle guest between kernel and user modes. */
+extern void toggle_guest_mode(struct vcpu *);
 
 struct arch_domain
 {
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/mm.h  Tue Jan 24 16:54:34 2006
@@ -309,16 +309,13 @@
     unsigned long l1va;
     /* Copy of the p.t. page, taken before guest is given write access. */
     l1_pgentry_t *page;
-    /* A temporary Xen mapping of the actual p.t. page. */
-    l1_pgentry_t *pl1e;
     /* Index in L2 page table where this L1 p.t. is always hooked. */
     unsigned int l2_idx; /* NB. Only used for PTWR_PT_ACTIVE. */
     /* Info about last ptwr update batch. */
     unsigned int prev_nr_updates;
-    /* Exec domain which created writable mapping. */
+    /* VCPU which created writable mapping. */
     struct vcpu *vcpu;
-    /* EIP of the address which took the original write fault
-       used for stats collection only */
+    /* EIP of the original write fault (stats collection only). */
     unsigned long eip;
 };
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/nmi.h
--- a/xen/include/asm-x86/nmi.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/nmi.h Tue Jan 24 16:54:34 2006
@@ -1,6 +1,8 @@
 
 #ifndef ASM_NMI_H
 #define ASM_NMI_H
+
+#include <public/nmi.h>
 
 struct cpu_user_regs;
  
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/processor.h   Tue Jan 24 16:54:34 2006
@@ -123,6 +123,7 @@
 #define TBF_EXCEPTION_ERRCODE  2
 #define TBF_INTERRUPT          8
 #define TBF_FAILSAFE          16
+#define TBF_SLOW_IRET         32
 
 /* 'arch_vcpu' flags values */
 #define _TF_kernel_mode        0
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/vmx_vlapic.h
--- a/xen/include/asm-x86/vmx_vlapic.h  Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/vmx_vlapic.h  Tue Jan 24 16:54:34 2006
@@ -187,7 +187,7 @@
     uint32_t           timer_current;
     uint32_t           timer_divconf;
     uint32_t           timer_divide_counter;
-    struct ac_timer    vlapic_timer;
+    struct timer    vlapic_timer;
     int                intr_pending_count[MAX_VECTOR];
     s_time_t           timer_current_update;
     uint32_t           icr_high;
@@ -216,7 +216,7 @@
 
 static inline int  vlapic_timer_active(struct vlapic *vlapic)
 {
-    return  active_ac_timer(&(vlapic->vlapic_timer));
+    return  active_timer(&(vlapic->vlapic_timer));
 }
 
 int vlapic_find_highest_irr(struct vlapic *vlapic);
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/vmx_vmcs.h
--- a/xen/include/asm-x86/vmx_vmcs.h    Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/vmx_vmcs.h    Tue Jan 24 16:54:34 2006
@@ -100,7 +100,7 @@
     void                    *io_bitmap_a, *io_bitmap_b;
     struct vlapic           *vlapic;
     u64                     tsc_offset;
-    struct ac_timer         hlt_timer;  /* hlt ins emulation wakeup timer */
+    struct timer         hlt_timer;  /* hlt ins emulation wakeup timer */
 };
 
 #define vmx_schedule_tail(next)         \
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/asm-x86/vmx_vpit.h
--- a/xen/include/asm-x86/vmx_vpit.h    Tue Jan 10 15:21:00 2006
+++ b/xen/include/asm-x86/vmx_vpit.h    Tue Jan 24 16:54:34 2006
@@ -6,7 +6,7 @@
 #include <xen/lib.h>
 #include <xen/time.h>
 #include <xen/errno.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
 #include <asm/vmx_vmcs.h>
 #include <asm/vmx_vpic.h>
 
@@ -23,7 +23,7 @@
     u64 inject_point; /* the time inject virt intr */
     u64 shift;  /* save the value of offset - drift */
     s_time_t scheduled;                 /* scheduled timer interrupt */
-    struct ac_timer pit_timer;  /* periodic timer for mode 2*/
+    struct timer pit_timer;  /* periodic timer for mode 2*/
     unsigned int channel;  /* the pit channel, counter 0~2 */
     unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
     u32 period;                /* pit frequency in ns */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/arch-ia64.h    Tue Jan 24 16:54:34 2006
@@ -9,7 +9,7 @@
 
 /* Maximum number of virtual CPUs in multi-processor guests. */
 /* WARNING: before changing this, check that shared_info fits on a page */
-#define MAX_VIRT_CPUS 1
+#define MAX_VIRT_CPUS 4
 
 #ifndef __ASSEMBLY__
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h  Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/arch-x86_32.h  Tue Jan 24 16:54:34 2006
@@ -135,6 +135,7 @@
     unsigned long max_pfn;                  /* max pfn that appears in table */
     /* Frame containing list of mfns containing list of mfns containing p2m. */
     unsigned long pfn_to_mfn_frame_list_list; 
+    unsigned long nmi_reason;
 } arch_shared_info_t;
 
 typedef struct {
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h  Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/arch-x86_64.h  Tue Jan 24 16:54:34 2006
@@ -88,11 +88,20 @@
 #define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
 
 /*
- * int HYPERVISOR_switch_to_user(void)
+ * int HYPERVISOR_iret(void)
  * All arguments are on the kernel stack, in the following format.
  * Never returns if successful. Current kernel context is lost.
+ * The saved CS is mapped as follows:
+ *   RING0 -> RING3 kernel mode.
+ *   RING1 -> RING3 kernel mode.
+ *   RING2 -> RING3 kernel mode.
+ *   RING3 -> RING3 user mode.
+ * However RING0 indicates that the guest kernel should return to iteself
+ * directly with
+ *      orb   $3,1*8(%rsp)
+ *      iretq
  * If flags contains VGCF_IN_SYSCALL:
- *   Restore RAX, RIP, RFLAGS, RSP. 
+ *   Restore RAX, RIP, RFLAGS, RSP.
  *   Discard R11, RCX, CS, SS.
  * Otherwise:
  *   Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
@@ -100,10 +109,19 @@
  */
 /* Guest exited in SYSCALL context? Return to guest with SYSRET? */
 #define VGCF_IN_SYSCALL (1<<8)
+struct iret_context {
+    /* Top of stack (%rsp at point of hypercall). */
+    uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
+    /* Bottom of iret stack frame. */
+};
+/*
+ * For compatibility with HYPERVISOR_switch_to_user which is the old
+ * name for HYPERVISOR_iret.
+ */
 struct switch_to_user {
     /* Top of stack (%rsp at point of hypercall). */
     uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
-    /* Bottom of switch_to_user stack frame. */
+    /* Bottom of iret stack frame. */
 };
 
 /*
@@ -202,6 +220,7 @@
     unsigned long max_pfn;                  /* max pfn that appears in table */
     /* Frame containing list of mfns containing list of mfns containing p2m. */
     unsigned long pfn_to_mfn_frame_list_list; 
+    unsigned long nmi_reason;
 } arch_shared_info_t;
 
 typedef struct {
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/xen.h  Tue Jan 24 16:54:34 2006
@@ -53,12 +53,14 @@
 #define __HYPERVISOR_grant_table_op       20
 #define __HYPERVISOR_vm_assist            21
 #define __HYPERVISOR_update_va_mapping_otherdomain 22
-#define __HYPERVISOR_switch_vm86          23 /* x86/32 only */
-#define __HYPERVISOR_switch_to_user       23 /* x86/64 only */
+#define __HYPERVISOR_iret                 23 /* x86 only */
+#define __HYPERVISOR_switch_vm86          23 /* x86/32 only (obsolete name) */
+#define __HYPERVISOR_switch_to_user       23 /* x86/64 only (obsolete name) */
 #define __HYPERVISOR_vcpu_op              24
 #define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
 #define __HYPERVISOR_mmuext_op            26
 #define __HYPERVISOR_acm_op               27
+#define __HYPERVISOR_nmi_op               28
 
 /* 
  * VIRTUAL INTERRUPTS
@@ -69,10 +71,7 @@
 #define VIRQ_DEBUG      1  /* Request guest to dump debug info.           */
 #define VIRQ_CONSOLE    2  /* (DOM0) Bytes received on emergency console. */
 #define VIRQ_DOM_EXC    3  /* (DOM0) Exceptional event for some domain.   */
-#define VIRQ_PARITY_ERR 4  /* (DOM0) NMI parity error (port 0x61, bit 7). */
-#define VIRQ_IO_ERR     5  /* (DOM0) NMI I/O error    (port 0x61, bit 6). */
 #define VIRQ_DEBUGGER   6  /* (DOM0) A domain has paused for debugging.   */
-#define VIRQ_NMI        7  /* (DOM0) Unknown NMI (not from ISA port 0x61).*/
 #define NR_VIRQS        8
 
 /*
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/domain.h
--- a/xen/include/xen/domain.h  Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/domain.h  Tue Jan 24 16:54:34 2006
@@ -13,12 +13,12 @@
 
 extern void free_vcpu_struct(struct vcpu *v);
 
-extern int arch_do_createdomain(struct vcpu *v);
+extern int arch_domain_create(struct domain *d);
+
+extern void arch_domain_destroy(struct domain *d);
 
 extern int arch_set_info_guest(
     struct vcpu *v, struct vcpu_guest_context *c);
-
-extern void free_perdomain_pt(struct domain *d);
 
 extern void domain_relinquish_resources(struct domain *d);
 
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/domain_page.h
--- a/xen/include/xen/domain_page.h     Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/domain_page.h     Tue Jan 24 16:54:34 2006
@@ -2,6 +2,8 @@
  * domain_page.h
  * 
  * Allow temporary mapping of domain page frames into Xen space.
+ * 
+ * Copyright (c) 2003-2006, Keir Fraser <keir@xxxxxxxxxxxxx>
  */
 
 #ifndef __XEN_DOMAIN_PAGE_H__
@@ -10,22 +12,27 @@
 #include <xen/config.h>
 #include <xen/mm.h>
 
-#define map_domain_page(pfn)   map_domain_pages(pfn,0)
-#define unmap_domain_page(va)  unmap_domain_pages(va,0)
-
 #ifdef CONFIG_DOMAIN_PAGE
 
 /*
- * Maps a given range of page frames, returning the mapped virtual address. The
- * pages are now accessible until a corresponding call to unmap_domain_page().
+ * Map a given page frame, returning the mapped virtual address. The page is
+ * then accessible within the current VCPU until a corresponding unmap call.
  */
-extern void *map_domain_pages(unsigned long pfn, unsigned int order);
+extern void *map_domain_page(unsigned long pfn);
 
 /*
- * Pass a VA within the first page of a range previously mapped with
- * map_omain_pages(). Those pages will then be removed from the mapping lists.
+ * Pass a VA within a page previously mapped in the context of the
+ * currently-executing VCPU via a call to map_domain_pages().
  */
-extern void unmap_domain_pages(void *va, unsigned int order);
+extern void unmap_domain_page(void *va);
+
+/*
+ * Similar to the above calls, except the mapping is accessible in all
+ * address spaces (not just within the VCPU that created the mapping). Global
+ * mappings can also be unmapped from any context.
+ */
+extern void *map_domain_page_global(unsigned long pfn);
+extern void unmap_domain_page_global(void *va);
 
 #define DMCACHE_ENTRY_VALID 1U
 #define DMCACHE_ENTRY_HELD  2U
@@ -87,8 +94,11 @@
 
 #else /* !CONFIG_DOMAIN_PAGE */
 
-#define map_domain_pages(pfn,order)         phys_to_virt((pfn)<<PAGE_SHIFT)
-#define unmap_domain_pages(va,order)        ((void)((void)(va),(void)(order)))
+#define map_domain_page(pfn)                phys_to_virt((pfn)<<PAGE_SHIFT)
+#define unmap_domain_page(va)               ((void)(va))
+
+#define map_domain_page_global(pfn)         phys_to_virt((pfn)<<PAGE_SHIFT)
+#define unmap_domain_page_global(va)        ((void)(va))
 
 struct domain_mmap_cache { 
 };
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/perfc_defn.h
--- a/xen/include/xen/perfc_defn.h      Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/perfc_defn.h      Tue Jan 24 16:54:34 2006
@@ -32,7 +32,7 @@
 PERFCOUNTER_CPU(irq_time,               "cycles spent in irq handler")
 
 PERFCOUNTER_CPU(apic_timer,             "apic timer interrupts")
-PERFCOUNTER_CPU(ac_timer_max,           "ac_timer max error (ns)")
+PERFCOUNTER_CPU(timer_max,           "timer max error (ns)")
 PERFCOUNTER_CPU(sched_irq,              "sched: timer")
 PERFCOUNTER_CPU(sched_run,              "sched: runs through scheduler")
 PERFCOUNTER_CPU(sched_ctx,              "sched: context switches")
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/sched-if.h
--- a/xen/include/xen/sched-if.h        Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/sched-if.h        Tue Jan 24 16:54:34 2006
@@ -16,16 +16,47 @@
     struct vcpu        *curr;           /* current task                    */
     struct vcpu        *idle;           /* idle task for this cpu          */
     void               *sched_priv;
-    struct ac_timer     s_timer;        /* scheduling timer                */
+    struct timer        s_timer;        /* scheduling timer                */
     unsigned long       tick;           /* current periodic 'tick'         */
 #ifdef BUCKETS
     u32                 hist[BUCKETS];  /* for scheduler latency histogram */
 #endif
 } __cacheline_aligned;
 
+extern struct schedule_data schedule_data[];
+
+static inline void vcpu_schedule_lock(struct vcpu *v)
+{
+    unsigned int cpu;
+
+    for ( ; ; )
+    {
+        cpu = v->processor;
+        spin_lock(&schedule_data[cpu].schedule_lock);
+        if ( likely(v->processor == cpu) )
+            break;
+        spin_unlock(&schedule_data[cpu].schedule_lock);
+    }
+}
+
+#define vcpu_schedule_lock_irq(v) \
+    do { local_irq_disable(); vcpu_schedule_lock(v); } while ( 0 )
+#define vcpu_schedule_lock_irqsave(v, flags) \
+    do { local_irq_save(flags); vcpu_schedule_lock(v); } while ( 0 )
+
+static inline void vcpu_schedule_unlock(struct vcpu *v)
+{
+    spin_unlock(&schedule_data[v->processor].schedule_lock);
+}
+
+#define vcpu_schedule_unlock_irq(v) \
+    do { vcpu_schedule_unlock(v); local_irq_enable(); } while ( 0 )
+#define vcpu_schedule_unlock_irqrestore(v, flags) \
+    do { vcpu_schedule_unlock(v); local_irq_restore(flags); } while ( 0 )
+
 struct task_slice {
     struct vcpu *task;
-    s_time_t            time;
+    s_time_t     time;
 };
 
 struct scheduler {
@@ -48,6 +79,4 @@
     void         (*dump_cpu_state) (int);
 };
 
-extern struct schedule_data schedule_data[];
-
 #endif /* __XEN_SCHED_IF_H__ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/sched.h   Tue Jan 24 16:54:34 2006
@@ -9,7 +9,7 @@
 #include <public/xen.h>
 #include <public/dom0_ops.h>
 #include <xen/time.h>
-#include <xen/ac_timer.h>
+#include <xen/timer.h>
 #include <xen/grant_table.h>
 #include <xen/rangeset.h>
 #include <asm/domain.h>
@@ -63,7 +63,7 @@
 
     struct vcpu     *next_in_list;
 
-    struct ac_timer  timer;         /* one-shot timer for timeout values */
+    struct timer  timer;         /* one-shot timer for timeout values */
     unsigned long    sleep_tick;    /* tick at which this vcpu started sleep */
 
     s_time_t         lastschd;      /* time this domain was last scheduled */
@@ -80,6 +80,8 @@
 
     /* Bitmask of CPUs on which this VCPU may run. */
     cpumask_t        cpu_affinity;
+
+    unsigned long    nmi_addr;      /* NMI callback address. */
 
     /* Bitmask of CPUs which are holding onto this VCPU's state. */
     cpumask_t        vcpu_dirty_cpumask;
@@ -183,13 +185,13 @@
 struct domain *alloc_domain(void);
 void free_domain(struct domain *d);
 
-#define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */
+#define DOMAIN_DESTROYED (1<<31) /* assumes atomic_t is >= 32 bits */
 #define put_domain(_d) \
-  if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destruct(_d)
+  if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destroy(_d)
 
 /*
  * Use this when you don't have an existing reference to @d. It returns
- * FALSE if @d is being destructed.
+ * FALSE if @d is being destroyed.
  */
 static always_inline int get_domain(struct domain *d)
 {
@@ -197,7 +199,7 @@
     do
     {
         old = seen;
-        if ( unlikely(_atomic_read(old) & DOMAIN_DESTRUCTED) )
+        if ( unlikely(_atomic_read(old) & DOMAIN_DESTROYED) )
             return 0;
         _atomic_set(new, _atomic_read(old) + 1);
         seen = atomic_compareandswap(old, new, &d->refcnt);
@@ -208,15 +210,15 @@
 
 /*
  * Use this when you already have, or are borrowing, a reference to @d.
- * In this case we know that @d cannot be destructed under our feet.
+ * In this case we know that @d cannot be destroyed under our feet.
  */
 static inline void get_knownalive_domain(struct domain *d)
 {
     atomic_inc(&d->refcnt);
-    ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTRUCTED));
+    ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
 }
 
-extern struct domain *do_createdomain(
+extern struct domain *domain_create(
     domid_t dom_id, unsigned int cpu);
 extern int construct_dom0(
     struct domain *d,
@@ -226,7 +228,7 @@
 extern int set_info_guest(struct domain *d, dom0_setvcpucontext_t *);
 
 struct domain *find_domain_by_id(domid_t dom);
-extern void domain_destruct(struct domain *d);
+extern void domain_destroy(struct domain *d);
 extern void domain_kill(struct domain *d);
 extern void domain_shutdown(struct domain *d, u8 reason);
 extern void domain_pause_for_debugger(void);
@@ -361,6 +363,12 @@
  /* VCPU is not-runnable */
 #define _VCPUF_down            5
 #define VCPUF_down             (1UL<<_VCPUF_down)
+ /* NMI callback pending for this VCPU? */
+#define _VCPUF_nmi_pending     8
+#define VCPUF_nmi_pending      (1UL<<_VCPUF_nmi_pending)
+ /* Avoid NMI reentry by allowing NMIs to be masked for short periods. */
+#define _VCPUF_nmi_masked      9
+#define VCPUF_nmi_masked       (1UL<<_VCPUF_nmi_masked)
 
 /*
  * Per-domain flags (domain_flags).
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/softirq.h
--- a/xen/include/xen/softirq.h Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/softirq.h Tue Jan 24 16:54:34 2006
@@ -2,11 +2,11 @@
 #define __XEN_SOFTIRQ_H__
 
 /* Common softirqs come first in the following list. */
-#define AC_TIMER_SOFTIRQ                  0
+#define TIMER_SOFTIRQ                     0
 #define SCHEDULE_SOFTIRQ                  1
 #define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2
 #define KEYPRESS_SOFTIRQ                  3
-#define NMI_DOM0_SOFTIRQ                  4
+#define NMI_SOFTIRQ                       4
 #define PAGE_SCRUB_SOFTIRQ                5
 #define DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ  6
 #define NR_SOFTIRQS                       7
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/mach_traps.h       
Tue Jan 24 16:54:34 2006
@@ -0,0 +1,33 @@
+/*
+ *  include/asm-xen/asm-i386/mach-xen/mach_traps.h
+ *
+ *  Machine specific NMI handling for Xen
+ */
+#ifndef _MACH_TRAPS_H
+#define _MACH_TRAPS_H
+
+#include <linux/bitops.h>
+#include <asm-xen/xen-public/nmi.h>
+
+static inline void clear_mem_error(unsigned char reason) {}
+static inline void clear_io_check_error(unsigned char reason) {}
+
+static inline unsigned char get_nmi_reason(void)
+{
+       shared_info_t *s = HYPERVISOR_shared_info;
+       unsigned char reason = 0;
+
+       /* construct a value which looks like it came from
+        * port 0x61.
+        */
+       if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
+               reason |= 0x40;
+       if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
+               reason |= 0x80;
+
+        return reason;
+}
+
+static inline void reassert_nmi(void) {}
+
+#endif /* !_MACH_TRAPS_H */
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/nmi.h
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/nmi.h     Tue Jan 24 
16:54:34 2006
@@ -0,0 +1,75 @@
+/*
+ *  linux/include/asm-i386/nmi.h
+ */
+#ifndef ASM_NMI_H
+#define ASM_NMI_H
+
+#include <linux/pm.h>
+
+#include <asm-xen/xen-public/nmi.h>
+
+struct pt_regs;
+ 
+typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu);
+ 
+/** 
+ * set_nmi_callback
+ *
+ * Set a handler for an NMI. Only one handler may be
+ * set. Return 1 if the NMI was handled.
+ */
+void set_nmi_callback(nmi_callback_t callback);
+ 
+/** 
+ * unset_nmi_callback
+ *
+ * Remove the handler previously set.
+ */
+void unset_nmi_callback(void);
+ 
+#ifdef CONFIG_PM
+ 
+/** Replace the PM callback routine for NMI. */
+struct pm_dev * set_nmi_pm_callback(pm_callback callback);
+
+/** Unset the PM callback routine back to the default. */
+void unset_nmi_pm_callback(struct pm_dev * dev);
+
+#else
+
+static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
+{
+       return 0;
+} 
+ 
+static inline void unset_nmi_pm_callback(struct pm_dev * dev)
+{
+}
+
+#endif /* CONFIG_PM */
+ 
+extern void default_do_nmi(struct pt_regs *);
+extern void die_nmi(char *str, struct pt_regs *regs);
+
+static inline unsigned char get_nmi_reason(void)
+{
+        shared_info_t *s = HYPERVISOR_shared_info;
+        unsigned char reason = 0;
+
+        /* construct a value which looks like it came from
+         * port 0x61.
+         */
+        if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
+                reason |= 0x40;
+        if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
+                reason |= 0x80;
+
+        return reason;
+}
+
+extern int panic_on_timeout;
+extern int unknown_nmi_panic;
+
+extern int check_nmi_watchdog(void);
+ 
+#endif /* ASM_NMI_H */
diff -r 40bb46f599d9 -r a38c292e8390 
patches/linux-2.6.12/i386-mach-io-check-nmi.patch
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/patches/linux-2.6.12/i386-mach-io-check-nmi.patch Tue Jan 24 16:54:34 2006
@@ -0,0 +1,43 @@
+--- ref-linux-2.6.12/arch/i386/kernel/traps.c  2005-12-19 09:23:44.000000000 
+0000
++++ linux-2.6.12-xen0/arch/i386/kernel/traps.c 2006-01-05 15:51:52.000000000 
+0000
+@@ -521,18 +521,11 @@
+ 
+ static void io_check_error(unsigned char reason, struct pt_regs * regs)
+ {
+-      unsigned long i;
+-
+       printk("NMI: IOCK error (debug interrupt?)\n");
+       show_registers(regs);
+ 
+       /* Re-enable the IOCK line, wait for a few seconds */
+-      reason = (reason & 0xf) | 8;
+-      outb(reason, 0x61);
+-      i = 2000;
+-      while (--i) udelay(1000);
+-      reason &= ~8;
+-      outb(reason, 0x61);
++      clear_io_check_error(reason);
+ }
+ 
+ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
+--- ref-linux-2.6.12/include/asm-i386/mach-default/mach_traps.h        
2005-06-17 20:48:29.000000000 +0100
++++ linux-2.6.12-xen0/include/asm-i386/mach-default/mach_traps.h       
2006-01-05 15:52:33.000000000 +0000
+@@ -15,6 +15,18 @@
+       outb(reason, 0x61);
+ }
+ 
++static inline void clear_io_check_error(unsigned char reason)
++{
++      unsigned long i;
++
++      reason = (reason & 0xf) | 8;
++      outb(reason, 0x61);
++      i = 2000;
++      while (--i) udelay(1000);
++      reason &= ~8;
++      outb(reason, 0x61);
++}
++
+ static inline unsigned char get_nmi_reason(void)
+ {
+       return inb(0x61);
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/ia64/xen/gdbstub.c
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/xen/arch/ia64/xen/gdbstub.c       Tue Jan 24 16:54:34 2006
@@ -0,0 +1,811 @@
+/*
+ * ia64-specific cdb routines
+ * cdb xen/ia64 by Isaku Yamahta <yamahata at valinux co jp>
+ *                 VA Linux Systems Japan K.K.
+ *  some routines are stolen from kgdb/ia64.
+ */
+/*
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+/*
+ * Copyright (C) 2000-2001 VERITAS Software Corporation.
+ */
+/*
+ *  Contributor:     Lake Stevens Instrument Division$
+ *  Written by:      Glenn Engel $
+ *  Updated by:             Amit Kale<akale@xxxxxxxxxxx>
+ *  Modified for 386 by Jim Kingdon, Cygnus Support.
+ *  Origianl kgdb, compatibility with 2.1.xx kernel by David Grothe 
<dave@xxxxxxxx>
+ *
+ */
+
+
+#include <xen/lib.h>
+#include <asm/byteorder.h>
+#include <asm/debugger.h>
+#include <asm/uaccess.h>
+
+#define USE_UNWIND
+
+#ifdef USE_UNWIND
+#include <asm/unwind.h>
+#endif
+
+/* Printk isn't particularly safe just after we've trapped to the
+   debugger. so avoid it. */
+#define dbg_printk(...)
+//#define dbg_printk(...)      printk(__VA_ARGS__)
+
+u16
+gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
+{
+    /* XXX */
+    return 1;
+}
+
+void 
+gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+    gdb_send_reply("", ctx);
+}
+
+void 
+gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
+                         struct gdb_context *ctx)
+{
+    /* XXX TODO */
+    gdb_send_reply("E02", ctx);
+}
+
+/* Like copy_from_user, but safe to call with interrupts disabled.
+   Trust me, and don't look behind the curtain. */
+unsigned
+gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
+{
+       int val;
+       __asm__ __volatile__(
+               "cmp4.eq p6, p0 = r0, %1\n"
+               "(p6) br.cond.dptk 2f\n"
+               "[1:]\n"
+               ".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
+               "[99:] ld1 %0 = [%3], 1\n"
+               ";;\n"
+               ".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
+               "[99:] st1 [%2] = %0, 1\n"
+               "adds %1 = -1, %1\n"
+               ";;\n"
+               "cmp4.eq p0, p6 = r0, %1\n"
+               "(p6) br.cond.dptk 1b\n"
+               "[2:]\n"
+               : "=r"(val), "=r"(len), "=r"(dest), "=r"(src)
+               :  "1"(len), "2"(dest), "3"(src)
+               : "memory", "p6");
+       return len;
+}
+
+unsigned int 
+gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
+{
+    /* XXX  */
+    return len;
+}
+
+#define NUM_REGS 590
+#define REGISTER_BYTES (NUM_REGS*8+128*8)
+#define REGISTER_BYTE(N) (((N) * 8)                                            
                        \
+       + ((N) <= IA64_FR0_REGNUM ?                                     \
+       0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM)))
+#define REGISTER_SIZE(N)                                               \
+       (((N) >= IA64_FR0_REGNUM && (N) <= IA64_FR127_REGNUM) ? 16 : 8)
+#define IA64_GR0_REGNUM         0
+#define IA64_FR0_REGNUM         128
+#define IA64_FR127_REGNUM       (IA64_FR0_REGNUM+127)
+#define IA64_PR0_REGNUM         256
+#define IA64_BR0_REGNUM         320
+#define IA64_VFP_REGNUM         328
+#define IA64_PR_REGNUM          330
+#define IA64_IP_REGNUM          331
+#define IA64_PSR_REGNUM         332
+#define IA64_CFM_REGNUM         333
+#define IA64_AR0_REGNUM         334
+#define IA64_NAT0_REGNUM        462
+#define IA64_NAT31_REGNUM       (IA64_NAT0_REGNUM+31)
+#define IA64_NAT32_REGNUM       (IA64_NAT0_REGNUM+32)
+#define IA64_RSC_REGNUM                        (IA64_AR0_REGNUM+16)
+#define IA64_BSP_REGNUM                        (IA64_AR0_REGNUM+17)
+#define IA64_BSPSTORE_REGNUM   (IA64_AR0_REGNUM+18)
+#define IA64_RNAT_REGNUM               (IA64_AR0_REGNUM+19)
+#define IA64_FCR_REGNUM                        (IA64_AR0_REGNUM+21)
+#define IA64_EFLAG_REGNUM              (IA64_AR0_REGNUM+24)
+#define IA64_CSD_REGNUM                        (IA64_AR0_REGNUM+25)
+#define IA64_SSD_REGNUM                        (IA64_AR0_REGNUM+26)
+#define IA64_CFLG_REGNUM               (IA64_AR0_REGNUM+27)
+#define IA64_FSR_REGNUM                        (IA64_AR0_REGNUM+28)
+#define IA64_FIR_REGNUM                        (IA64_AR0_REGNUM+29)
+#define IA64_FDR_REGNUM                        (IA64_AR0_REGNUM+30)
+#define IA64_CCV_REGNUM                        (IA64_AR0_REGNUM+32)
+#define IA64_UNAT_REGNUM               (IA64_AR0_REGNUM+36)
+#define IA64_FPSR_REGNUM               (IA64_AR0_REGNUM+40)
+#define IA64_ITC_REGNUM                        (IA64_AR0_REGNUM+44)
+#define IA64_PFS_REGNUM                        (IA64_AR0_REGNUM+64)
+#define IA64_LC_REGNUM                 (IA64_AR0_REGNUM+65)
+#define IA64_EC_REGNUM                 (IA64_AR0_REGNUM+66)
+
+#ifndef USE_UNWIND
+struct regs_to_cpu_user_resgs_index {
+       unsigned int reg;
+       unsigned int ptregoff;
+};
+
+#define ptoff(V)               ((unsigned int)&((struct cpu_user_regs*)0x0)->V)
+
+// gr
+static const struct regs_to_cpu_user_resgs_index
+gr_reg_to_cpu_user_regs_index[] = {
+       {IA64_GR0_REGNUM + 8,  ptoff(r8)},
+       {IA64_GR0_REGNUM + 9,  ptoff(r9)},
+       {IA64_GR0_REGNUM + 10, ptoff(r10)},
+       {IA64_GR0_REGNUM + 11, ptoff(r11)},
+       {IA64_GR0_REGNUM + 1,  ptoff(r1)},
+       {IA64_GR0_REGNUM + 12, ptoff(r12)},
+       {IA64_GR0_REGNUM + 13, ptoff(r13)},
+       {IA64_GR0_REGNUM + 15, ptoff(r15)},
+
+       {IA64_GR0_REGNUM + 14, ptoff(r14)},
+       {IA64_GR0_REGNUM + 2,  ptoff(r2)},
+       {IA64_GR0_REGNUM + 3,  ptoff(r3)},
+       {IA64_GR0_REGNUM + 16, ptoff(r16)},
+       {IA64_GR0_REGNUM + 17, ptoff(r17)},
+       {IA64_GR0_REGNUM + 18, ptoff(r18)},
+       {IA64_GR0_REGNUM + 19, ptoff(r19)},
+       {IA64_GR0_REGNUM + 20, ptoff(r20)},
+       {IA64_GR0_REGNUM + 21, ptoff(r21)},
+       {IA64_GR0_REGNUM + 22, ptoff(r22)},
+       {IA64_GR0_REGNUM + 23, ptoff(r23)},
+       {IA64_GR0_REGNUM + 24, ptoff(r24)},
+       {IA64_GR0_REGNUM + 25, ptoff(r25)},
+       {IA64_GR0_REGNUM + 26, ptoff(r26)},
+       {IA64_GR0_REGNUM + 27, ptoff(r27)},
+       {IA64_GR0_REGNUM + 28, ptoff(r28)},
+       {IA64_GR0_REGNUM + 29, ptoff(r29)},
+       {IA64_GR0_REGNUM + 30, ptoff(r30)},
+       {IA64_GR0_REGNUM + 31, ptoff(r31)},
+
+       {IA64_GR0_REGNUM + 4,  ptoff(r4)},
+       {IA64_GR0_REGNUM + 5,  ptoff(r5)},
+       {IA64_GR0_REGNUM + 6,  ptoff(r6)},
+       {IA64_GR0_REGNUM + 7,  ptoff(r7)},
+};
+static const int gr_reg_to_cpu_user_regs_index_max =
+       sizeof(gr_reg_to_cpu_user_regs_index) /
+       sizeof(gr_reg_to_cpu_user_regs_index[0]); 
+
+// br
+static const struct regs_to_cpu_user_resgs_index
+br_reg_to_cpu_user_regs_index[] = {
+       {IA64_BR0_REGNUM + 0, ptoff(b0)},
+       {IA64_BR0_REGNUM + 6, ptoff(b6)},
+       {IA64_BR0_REGNUM + 7, ptoff(b7)},
+};
+static const int br_reg_to_cpu_user_regs_index_max =
+       sizeof(br_reg_to_cpu_user_regs_index) /
+       sizeof(br_reg_to_cpu_user_regs_index[0]); 
+
+// f
+static const struct regs_to_cpu_user_resgs_index
+fr_reg_to_cpu_user_regs_index[] = {
+       {IA64_FR0_REGNUM + 6,  ptoff(f6)},
+       {IA64_FR0_REGNUM + 7,  ptoff(f7)},
+       {IA64_FR0_REGNUM + 8,  ptoff(f8)},
+       {IA64_FR0_REGNUM + 9,  ptoff(f9)},
+       {IA64_FR0_REGNUM + 10, ptoff(f10)},
+       {IA64_FR0_REGNUM + 11, ptoff(f11)},
+};
+static const int fr_reg_to_cpu_user_regs_index_max =
+       sizeof(fr_reg_to_cpu_user_regs_index) /
+       sizeof(fr_reg_to_cpu_user_regs_index[0]); 
+       
+
+void 
+gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
+                  struct gdb_context *ctx)
+{
+       unsigned long reg = IA64_IP_REGNUM;
+       char buf[9];
+       int i;
+
+       dbg_printk("Register read regnum = 0x%lx\n", regnum);
+       if (IA64_GR0_REGNUM <= regnum && regnum <= IA64_GR0_REGNUM + 31) {
+               for (i = 0; i < gr_reg_to_cpu_user_regs_index_max; i++) {
+                       if (gr_reg_to_cpu_user_regs_index[i].reg == regnum) {
+                               reg = *(unsigned long*)(((char*)regs) + 
gr_reg_to_cpu_user_regs_index[i].ptregoff);
+                               break;
+                       }
+               }
+               if (i == gr_reg_to_cpu_user_regs_index_max) {
+                       goto out_err;
+               }
+       } else if (IA64_BR0_REGNUM <= regnum && regnum <= IA64_BR0_REGNUM + 7) {
+               for (i = 0; i < br_reg_to_cpu_user_regs_index_max; i++) {
+                       if (br_reg_to_cpu_user_regs_index[i].reg == regnum) {
+                               reg = *(unsigned long*)(((char*)regs) + 
br_reg_to_cpu_user_regs_index[i].ptregoff);
+                               break;
+                       }
+               }
+               if (i == br_reg_to_cpu_user_regs_index_max) {
+                       goto out_err;
+               }
+       } else if (IA64_FR0_REGNUM + 6 <= regnum && regnum <= IA64_FR0_REGNUM + 
11) {
+               for (i = 0; i < fr_reg_to_cpu_user_regs_index_max; i++) {
+                       if (fr_reg_to_cpu_user_regs_index[i].reg == regnum) {
+                               reg = *(unsigned long*)(((char*)regs) + 
fr_reg_to_cpu_user_regs_index[i].ptregoff);
+                               break;
+                       }
+               }
+               if (i == fr_reg_to_cpu_user_regs_index_max) {
+                       goto out_err;
+               }
+       } else if (regnum == IA64_CSD_REGNUM) {
+               reg = regs->ar_csd;
+       } else if (regnum == IA64_SSD_REGNUM) {
+               reg = regs->ar_ssd;
+       } else if (regnum == IA64_PSR_REGNUM) {
+               reg = regs->cr_ipsr;
+       } else if (regnum == IA64_IP_REGNUM) {
+               reg = regs->cr_iip;
+       } else if (regnum == IA64_CFM_REGNUM) {
+               reg = regs->cr_ifs;
+       } else if (regnum == IA64_UNAT_REGNUM) {
+               reg = regs->ar_unat;
+       } else if (regnum == IA64_PFS_REGNUM) {
+               reg = regs->ar_pfs;
+       } else if (regnum == IA64_RSC_REGNUM) {
+               reg = regs->ar_rsc;
+       } else if (regnum == IA64_RNAT_REGNUM) {
+               reg = regs->ar_rnat;
+       } else if (regnum == IA64_BSPSTORE_REGNUM) {
+               reg = regs->ar_bspstore;
+       } else if (regnum == IA64_PR_REGNUM) {
+               reg = regs->pr;
+       } else if (regnum == IA64_FPSR_REGNUM) {
+               reg = regs->ar_fpsr;
+       } else if (regnum == IA64_CCV_REGNUM) {
+               reg = regs->ar_ccv;
+       } else {
+               // emul_unat, rfi_pfs
+               goto out_err;
+       }
+
+       dbg_printk("Register read regnum = 0x%lx, val = 0x%lx\n", regnum, reg); 
+       sprintf(buf, "%.08lx", swab64(reg));
+out:
+       return gdb_send_reply(buf, ctx);
+
+out_err:
+       dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
+       sprintf(buf, "%s", "x");
+       goto out;
+}
+#else
+
+#define        ptoff(V)        ((unsigned int) &((struct pt_regs *)0x0)->V)
+struct reg_to_ptreg_index {
+       unsigned int reg;
+       unsigned int ptregoff;
+};
+
+static struct reg_to_ptreg_index gr_reg_to_ptreg_index[] = {
+       {IA64_GR0_REGNUM + 1, ptoff(r1)},
+       {IA64_GR0_REGNUM + 2, ptoff(r2)},
+       {IA64_GR0_REGNUM + 3, ptoff(r3)},
+       {IA64_GR0_REGNUM + 8, ptoff(r8)},
+       {IA64_GR0_REGNUM + 9, ptoff(r9)},
+       {IA64_GR0_REGNUM + 10, ptoff(r10)},
+       {IA64_GR0_REGNUM + 11, ptoff(r11)},
+       {IA64_GR0_REGNUM + 12, ptoff(r12)},
+       {IA64_GR0_REGNUM + 13, ptoff(r13)},
+       {IA64_GR0_REGNUM + 14, ptoff(r14)},
+       {IA64_GR0_REGNUM + 15, ptoff(r15)},
+       {IA64_GR0_REGNUM + 16, ptoff(r16)},
+       {IA64_GR0_REGNUM + 17, ptoff(r17)},
+       {IA64_GR0_REGNUM + 18, ptoff(r18)},
+       {IA64_GR0_REGNUM + 19, ptoff(r19)},
+       {IA64_GR0_REGNUM + 20, ptoff(r20)},
+       {IA64_GR0_REGNUM + 21, ptoff(r21)},
+       {IA64_GR0_REGNUM + 22, ptoff(r22)},
+       {IA64_GR0_REGNUM + 23, ptoff(r23)},
+       {IA64_GR0_REGNUM + 24, ptoff(r24)},
+       {IA64_GR0_REGNUM + 25, ptoff(r25)},
+       {IA64_GR0_REGNUM + 26, ptoff(r26)},
+       {IA64_GR0_REGNUM + 27, ptoff(r27)},
+       {IA64_GR0_REGNUM + 28, ptoff(r28)},
+       {IA64_GR0_REGNUM + 29, ptoff(r29)},
+       {IA64_GR0_REGNUM + 30, ptoff(r30)},
+       {IA64_GR0_REGNUM + 31, ptoff(r31)},
+};
+
+static struct reg_to_ptreg_index br_reg_to_ptreg_index[] = {
+       {IA64_BR0_REGNUM, ptoff(b0)},
+       {IA64_BR0_REGNUM + 6, ptoff(b6)},
+       {IA64_BR0_REGNUM + 7, ptoff(b7)},
+};
+
+static struct reg_to_ptreg_index ar_reg_to_ptreg_index[] = {
+       {IA64_PFS_REGNUM, ptoff(ar_pfs)},
+       {IA64_UNAT_REGNUM, ptoff(ar_unat)},
+       {IA64_RNAT_REGNUM, ptoff(ar_rnat)},
+       {IA64_BSPSTORE_REGNUM, ptoff(ar_bspstore)},
+       {IA64_RSC_REGNUM, ptoff(ar_rsc)},
+       {IA64_CSD_REGNUM, ptoff(ar_csd)},
+       {IA64_SSD_REGNUM, ptoff(ar_ssd)},
+       {IA64_FPSR_REGNUM, ptoff(ar_fpsr)},
+       {IA64_CCV_REGNUM, ptoff(ar_ccv)},
+};
+
+#ifndef XEN
+extern atomic_t cpu_doing_single_step;
+#endif
+
+static int kgdb_gr_reg(int regnum, struct unw_frame_info *info,
+       unsigned long *reg, int rw)
+{
+       char nat;
+
+       if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
+               (regnum >= (IA64_GR0_REGNUM + 4) &&
+               regnum <= (IA64_GR0_REGNUM + 7)))
+               return !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
+               reg, &nat, rw);
+       else
+               return 0;
+}
+static int kgdb_gr_ptreg(int regnum, struct pt_regs * ptregs,
+       struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+       int i, result = 1;
+       char nat;
+
+       if (!((regnum >= (IA64_GR0_REGNUM + 2) &&
+               regnum <= (IA64_GR0_REGNUM + 3)) ||
+               (regnum >= (IA64_GR0_REGNUM + 8) &&
+               regnum <= (IA64_GR0_REGNUM + 15)) ||
+               (regnum >= (IA64_GR0_REGNUM + 16) &&
+               regnum <= (IA64_GR0_REGNUM + 31))))
+               return 0;
+       else if (rw && ptregs) {
+               for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
+                       if (gr_reg_to_ptreg_index[i].reg == regnum) {
+                               *((unsigned long *)(((void *)ptregs) +
+                               gr_reg_to_ptreg_index[i].ptregoff)) = *reg;
+                               break;
+                       }
+       } else if (!rw && ptregs) {
+               for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
+                       if (gr_reg_to_ptreg_index[i].reg == regnum) {
+                               *reg = *((unsigned long *)
+                               (((void *)ptregs) +
+                                gr_reg_to_ptreg_index[i].ptregoff));
+                               break;
+                       }
+       } else
+               result = !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
+                                       reg, &nat, rw);
+       return result;
+}
+
+static int kgdb_br_reg(int regnum, struct pt_regs * ptregs,
+       struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+       int i, result = 1;
+
+       if (!(regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7)))
+               return 0;
+
+       switch (regnum) {
+       case IA64_BR0_REGNUM:
+       case IA64_BR0_REGNUM + 6:
+       case IA64_BR0_REGNUM + 7:
+               if (rw) {
+                       for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
+                               if (br_reg_to_ptreg_index[i].reg == regnum) {
+                                       *((unsigned long *)
+                                       (((void *)ptregs) +
+                                       br_reg_to_ptreg_index[i].ptregoff)) =
+                                       *reg;
+                                       break;
+                               }
+               } else
+                       for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
+                               if (br_reg_to_ptreg_index[i].reg == regnum) {
+                                               *reg = *((unsigned long *)
+                                               (((void *)ptregs) +
+                                               br_reg_to_ptreg_index[i].
+                                               ptregoff));
+                                               break;
+                               }
+               break;
+       case IA64_BR0_REGNUM + 1:
+       case IA64_BR0_REGNUM + 2:
+       case IA64_BR0_REGNUM + 3:
+       case IA64_BR0_REGNUM + 4:
+       case IA64_BR0_REGNUM + 5:
+               result = !unw_access_br(info, regnum - IA64_BR0_REGNUM,
+                               reg, rw);
+               break;
+       }
+
+       return result;
+}
+
+static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs,
+       struct unw_frame_info *info, unsigned long *reg,
+       struct ia64_fpreg *freg, int rw)
+{
+       int result = 1;
+
+       if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127)))
+               return 0;
+
+       switch (regnum) {
+       case IA64_FR0_REGNUM + 6:
+       case IA64_FR0_REGNUM + 7:
+       case IA64_FR0_REGNUM + 8:
+       case IA64_FR0_REGNUM + 9:
+       case IA64_FR0_REGNUM + 10:
+       case IA64_FR0_REGNUM + 11:
+       case IA64_FR0_REGNUM + 12:
+               if (rw) {
+#ifndef XEN
+                       char *ptr = inbuffer;
+
+                       freg->u.bits[0] = *reg;
+                       kgdb_hex2long(&ptr, &freg->u.bits[1]);
+                       *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
+                               *freg;
+#else
+                       printk("%s: %d: writing to fpreg is not supported.\n",
+                                  __func__, __LINE__);
+#endif
+                       break;
+               } else if (!ptregs)
+                       result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
+                               freg, rw);
+               else
+#ifndef XEN
+                       *freg =
+                       *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)));
+#else
+                   //XXX struct ia64_fpreg and struct pt_fpreg are same.
+                       *freg = *((struct ia64_fpreg*)(&ptregs->f6 +
+                                                                               
   (regnum - (IA64_FR0_REGNUM + 6))));
+#endif
+               break;
+       default:
+               if (!rw)
+                       result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
+                               freg, rw);
+               else
+                       result = 0;
+               break;
+       }
+
+       return result;
+}
+
+static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs,
+       struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+       int result = 0, i;
+
+       if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM))
+               return 0;
+
+       if (rw && ptregs) {
+               for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
+                       if (ar_reg_to_ptreg_index[i].reg == regnum) {
+                               *((unsigned long *) (((void *)ptregs) +
+                               ar_reg_to_ptreg_index[i].ptregoff)) =
+                                       *reg;
+                               result = 1;
+                               break;
+                       }
+       } else if (ptregs) {
+               for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
+                       if (ar_reg_to_ptreg_index[i].reg == regnum) {
+                               *reg = *((unsigned long *) (((void *)ptregs) +
+                                       ar_reg_to_ptreg_index[i].ptregoff));
+                                       result = 1;
+                               break;
+                       }
+       }
+
+       if (result)
+               return result;
+
+       result = 1;
+
+       switch (regnum) {
+       case IA64_CSD_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_CSD, reg, rw);
+               break;
+       case IA64_SSD_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_SSD, reg, rw);
+               break;
+       case IA64_UNAT_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+               break;
+               case IA64_RNAT_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+               break;
+       case IA64_BSPSTORE_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+               break;
+       case IA64_PFS_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+               break;
+       case IA64_LC_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_LC, reg, rw);
+               break;
+       case IA64_EC_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_EC, reg, rw);
+               break;
+       case IA64_FPSR_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw);
+               break;
+       case IA64_RSC_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_RSC, reg, rw);
+               break;
+       case IA64_CCV_REGNUM:
+               result = !unw_access_ar(info, UNW_AR_CCV, reg, rw);
+               break;
+       default:
+               result = 0;
+       }
+
+       return result;
+}
+
+#ifndef XEN
+void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
+       struct pt_regs *ptregs)
+#else
+static int
+kgdb_get_reg(int regnum, struct unw_frame_info *info,
+                        struct cpu_user_regs* ptregs,
+                        unsigned long* __reg, struct ia64_fpreg* __freg)
+#endif
+{
+       unsigned long reg, size = 0, *mem = &reg;
+       struct ia64_fpreg freg;
+
+       if (kgdb_gr_reg(regnum, info, &reg, 0) ||
+               kgdb_gr_ptreg(regnum, ptregs, info, &reg, 0) ||
+               kgdb_br_reg(regnum, ptregs, info, &reg, 0) ||
+               kgdb_ar_reg(regnum, ptregs, info, &reg, 0))
+                       size = sizeof(reg);
+       else if (kgdb_fr_reg(regnum, NULL, ptregs, info, &reg, &freg, 0)) {
+               size = sizeof(freg);
+               mem = (unsigned long *)&freg;
+       } else if (regnum == IA64_IP_REGNUM) {
+               if (!ptregs) {
+                       unw_get_ip(info, &reg);
+                       size = sizeof(reg);
+               } else {
+                       reg = ptregs->cr_iip;
+                       size = sizeof(reg);
+               }
+       } else if (regnum == IA64_CFM_REGNUM) {
+               if (!ptregs)
+                       unw_get_cfm(info, &reg);
+               else
+                       reg = ptregs->cr_ifs;
+               size = sizeof(reg);
+       } else if (regnum == IA64_PSR_REGNUM) {
+#ifndef XEN
+               if (!ptregs && kgdb_usethread)
+                       ptregs = (struct pt_regs *)
+                       ((unsigned long)kgdb_usethread +
+                       IA64_STK_OFFSET) - 1;
+#endif
+               if (ptregs)
+                       reg = ptregs->cr_ipsr;
+               size = sizeof(reg);
+       } else if (regnum == IA64_PR_REGNUM) {
+               if (ptregs)
+                       reg = ptregs->pr;
+               else
+                       unw_access_pr(info, &reg, 0);
+               size = sizeof(reg);
+       } else if (regnum == IA64_BSP_REGNUM) {
+               unw_get_bsp(info, &reg);
+               size = sizeof(reg);
+       }
+
+#ifndef XEN
+       if (size) {
+               kgdb_mem2hex((char *) mem, outbuffer, size);
+               outbuffer[size*2] = 0;
+       }
+       else
+               strcpy(outbuffer, "E0");
+
+       return;
+#else
+       if (size) {
+               if (size == sizeof(reg)) {
+                       *__reg = reg;
+               } else {
+                       BUG_ON(size != sizeof(freg));
+                       *__freg = freg;
+               }
+               return 0;
+       }
+
+       return -1;
+#endif
+}
+
+#ifndef XEN
+static int inline kgdb_get_blocked_state(struct task_struct *p,
+                                        struct unw_frame_info *unw)
+#else
+static int
+kgdb_get_blocked_state(struct vcpu *p,
+                                          struct cpu_user_regs *regs,
+                                          struct unw_frame_info *unw)
+#endif
+{
+       unsigned long ip;
+       int count = 0;
+
+#ifndef XEN
+       unw_init_from_blocked_task(unw, p);
+#endif
+       ip = 0UL;
+       do {
+               if (unw_unwind(unw) < 0)
+                       return -1;
+               unw_get_ip(unw, &ip);
+#ifndef XEN
+               if (!in_sched_functions(ip))
+                       break;
+#else
+               dbg_printk("ip 0x%lx cr_iip 0x%lx\n", ip, regs->cr_iip);
+               if (ip == regs->cr_iip)
+                       break;
+#endif
+       } while (count++ < 16);
+
+       if (!ip)
+               return -1;
+       else
+               return 0;
+}
+
+struct gdb_callback_arg
+{
+       struct cpu_user_regs*           regs;
+       unsigned long                           regnum;
+       unsigned long*                          reg;
+       struct pt_fpreg*                        freg;
+
+       int                                                     error;
+                                   //  1: not supported
+                                                               //  0: success
+                                                               // -1: failure
+};
+
+static void
+gdb_get_reg_callback(struct unw_frame_info* info, void* __arg)
+{
+       struct gdb_callback_arg* arg = (struct gdb_callback_arg*)__arg;
+
+       if (kgdb_get_blocked_state(current, arg->regs, info) < 0) {
+               dbg_printk("%s: kgdb_get_blocked_state failed\n", __func__);
+               arg->error = -1;
+               return;
+       }
+       //XXX struct ia64_fpreg and struct pt_fpreg are same.
+       if (kgdb_get_reg(arg->regnum, info, arg->regs, arg->reg, 
+                                        (struct ia64_fpreg*)arg->freg) < 0) {
+               dbg_printk("%s: kgdb_get_reg failed\n", __func__);
+               arg->error = 1;
+               return;
+       }
+       arg->error = 0;
+       return;
+}
+
+void 
+gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
+                  struct gdb_context *ctx)
+{
+       struct gdb_callback_arg arg;
+       unsigned long reg;
+       struct pt_fpreg freg;
+       char buf[16 * 2 + 1];
+
+       if (regnum >= NUM_REGS) {
+               dbg_printk("%s: regnum %ld\n", __func__, regnum);
+               goto out_err;
+       }
+
+       arg.regs = regs;
+       arg.regnum = regnum;
+       arg.reg = &reg;
+       arg.freg = &freg;
+       arg.error = 0;
+       unw_init_running(&gdb_get_reg_callback, (void*)&arg);
+       if (arg.error < 0) {
+               dbg_printk("%s: gdb_get_reg_callback failed\n", __func__);
+               goto out_err;
+       }
+
+       if (arg.error > 0) {
+               // notify gdb that this register is not supported.
+               // see fetch_register_using_p() in gdb/remote.c.
+               sprintf(buf, "%s", "x");
+       } else if (IA64_FR0_REGNUM <= regnum && regnum <= IA64_FR0_REGNUM + 
127) {
+               sprintf(buf, "%.016lx", swab64(freg.u.bits[0]));
+               sprintf(buf + 16, "%.016lx", swab64(freg.u.bits[1]));
+       } else {
+               sprintf(buf, "%.016lx", swab64(reg));
+       }
+out:
+       return gdb_send_reply(buf, ctx);
+
+out_err:
+       dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
+       sprintf(buf, "%s", "E0");
+       goto out;
+}
+#endif
+
+void 
+gdb_arch_resume(struct cpu_user_regs *regs,
+                unsigned long addr, unsigned long type,
+                struct gdb_context *ctx)
+{
+    /* XXX */
+    if (type == GDB_STEP) {
+        gdb_send_reply("S01", ctx);
+    }
+}
+
+void
+gdb_arch_print_state(struct cpu_user_regs *regs)
+{
+    /* XXX */
+}
+
+void
+gdb_arch_enter(struct cpu_user_regs *regs)
+{
+    /* nothing */
+}
+
+void
+gdb_arch_exit(struct cpu_user_regs *regs)
+{
+    /* nothing */
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/gdbstub.c
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/xen/arch/x86/gdbstub.c    Tue Jan 24 16:54:34 2006
@@ -0,0 +1,146 @@
+/*
+ * x86-specific gdb stub routines
+ * based on x86 cdb(xen/arch/x86/cdb.c), but Extensively modified.
+ * 
+ * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan. K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+#include <asm/debugger.h>
+
+u16
+gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
+{
+    /* XXX */
+    return 1;
+}
+
+void 
+gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+#define GDB_REG(r) gdb_write_to_packet_hex(r, sizeof(r), ctx);
+    GDB_REG(regs->eax);
+    GDB_REG(regs->ecx);
+    GDB_REG(regs->edx);
+    GDB_REG(regs->ebx);
+    GDB_REG(regs->esp);
+    GDB_REG(regs->ebp);
+    GDB_REG(regs->esi);
+    GDB_REG(regs->edi);
+    GDB_REG(regs->eip);
+    GDB_REG(regs->eflags);
+#undef GDB_REG
+#define GDB_SEG_REG(s)  gdb_write_to_packet_hex(s, sizeof(u32), ctx);
+    /* sizeof(segment) = 16bit */
+    /* but gdb requires its return value as 32bit value */
+    GDB_SEG_REG(regs->cs);
+    GDB_SEG_REG(regs->ss);
+    GDB_SEG_REG(regs->ds);
+    GDB_SEG_REG(regs->es);
+    GDB_SEG_REG(regs->fs);
+    GDB_SEG_REG(regs->gs);
+#undef GDB_SEG_REG
+    gdb_send_packet(ctx);
+}
+
+void 
+gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
+                         struct gdb_context *ctx)
+{
+    /* XXX TODO */
+    gdb_send_reply("E02", ctx);
+}
+
+void 
+gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
+                  struct gdb_context *ctx)
+{
+    gdb_send_reply("", ctx);
+}
+
+/* Like copy_from_user, but safe to call with interrupts disabled.
+   Trust me, and don't look behind the curtain. */
+unsigned 
+gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
+{
+    int __d0, __d1, __d2;
+    ASSERT(!local_irq_is_enabled());
+    __asm__ __volatile__(
+        "1: rep; movsb\n"
+        "2:\n"
+        ".section .fixup,\"ax\"\n"
+        "3:     addl $4, %%esp\n"
+        "       jmp 2b\n"
+        ".previous\n"
+        ".section __pre_ex_table,\"a\"\n"
+        "   "__FIXUP_ALIGN"\n"
+        "   "__FIXUP_WORD" 1b,3b\n"
+        ".previous\n"
+        ".section __ex_table,\"a\"\n"
+        "   "__FIXUP_ALIGN"\n"
+        "   "__FIXUP_WORD" 1b,2b\n"
+        ".previous\n"
+        : "=c"(__d2), "=D" (__d0), "=S" (__d1)
+        : "0"(len), "1"(dest), "2"(src)
+        : "memory");
+    ASSERT(!local_irq_is_enabled());
+    return __d2;
+}
+
+unsigned int 
+gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
+{
+    /* XXX  */
+    return len;
+}
+
+void 
+gdb_arch_resume(struct cpu_user_regs *regs,
+                unsigned long addr, unsigned long type,
+                struct gdb_context *ctx)
+{
+    /* XXX */
+    if (type == GDB_STEP) {
+        gdb_send_reply("S01", ctx);
+    }
+}
+
+void
+gdb_arch_print_state(struct cpu_user_regs *regs)
+{
+    /* XXX */
+}
+
+void
+gdb_arch_enter(struct cpu_user_regs *regs)
+{
+    /* nothing */
+}
+
+void
+gdb_arch_exit(struct cpu_user_regs *regs)
+{
+    /* nothing */
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/gdbstub.c
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/xen/common/gdbstub.c      Tue Jan 24 16:54:34 2006
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2005 Jimi Xenidis <jimix@xxxxxxxxxxxxxx>, IBM Corporation
+ * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan. K.K.
+ * 
+ * gdbstub arch neutral part
+ * Based on x86 cdb (xen/arch/x86/cdb.c) and ppc gdbstub(xen/common/gdbstub.c)
+ * But extensively modified.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+/*
+ * gdbstub: implements the architecture independant parts of the
+ * gdb remote protocol.
+ */
+
+/* We try to avoid assuming much about what the rest of the system is
+   doing.  In particular, dynamic memory allocation is out of the
+   question. */
+
+/* Resuming after we've stopped used to work, but more through luck
+   than any actual intention.  It doesn't at the moment. */
+
+#include <xen/lib.h>
+#include <asm/uaccess.h>
+#include <xen/spinlock.h>
+#include <xen/serial.h>
+#include <xen/irq.h>
+#include <asm/debugger.h>
+#include <xen/init.h>
+#include <xen/smp.h>
+#include <xen/console.h>
+
+/* Printk isn't particularly safe just after we've trapped to the
+   debugger. so avoid it. */
+#define dbg_printk(...)
+/*#define dbg_printk(...)   printk(__VA_ARGS__)*/
+
+#define GDB_RETRY_MAX   10
+
+static char opt_gdb[30] = "none";
+string_param("gdb", opt_gdb);
+
+/* value <-> char (de)serialzers */
+char
+hex2char(unsigned long x)
+{
+    const char array[] = "0123456789abcdef";
+
+    return array[x & 15];
+}
+
+int
+char2hex(unsigned char c)
+{
+    if ( (c >= '0') && (c <= '9') )
+        return c - '0';
+    else if ( (c >= 'a') && (c <= 'f') )
+        return c - 'a' + 10;
+    else if ( (c >= 'A') && (c <= 'F') )
+        return c - 'A' + 10;
+    else
+        BUG();
+    return -1;
+}
+
+char
+str2hex(const char *str)
+{
+    return (char2hex(str[0]) << 4) | char2hex(str[1]);
+}
+
+unsigned long
+str2ulong(const char *str, unsigned long bytes)
+{
+    unsigned long x = 0;
+    unsigned long i = 0;
+
+    while ( *str && (i < (bytes * 2)) )
+    {
+        x <<= 4;
+        x += char2hex(*str);
+        ++str;
+        ++i;
+    }
+
+    return x;
+}
+
+/* gdb io wrappers */
+static signed long
+gdb_io_write(const char *buf, unsigned long len, struct gdb_context *ctx)
+{
+    int i;
+    for ( i = 0; i < len; i++ )
+        serial_putc(ctx->serhnd, buf[i]);
+    return i;
+}
+
+static int
+gdb_io_write_char(u8 data, struct gdb_context *ctx)
+{
+    return gdb_io_write((char*)&data, 1, ctx);
+}
+
+static unsigned char
+gdb_io_read(struct gdb_context *ctx)
+{
+    return serial_getc(ctx->serhnd);
+}
+
+/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
+/* Does not acknowledge. */
+static int 
+attempt_receive_packet(struct gdb_context *ctx)
+{
+    u8 csum;
+    u8 received_csum;
+    u8 ch;
+
+    /* Skip over everything up to the first '$' */
+    while ( (ch = gdb_io_read(ctx)) != '$' )
+        continue;
+
+    csum = 0;
+    for ( ctx->in_bytes = 0;
+          ctx->in_bytes < sizeof(ctx->in_buf);
+          ctx->in_bytes++ )
+    {
+        ch = gdb_io_read(ctx);
+        if ( ch == '#' )
+            break;
+        ctx->in_buf[ctx->in_bytes] = ch;
+        csum += ch;
+    }
+
+    if ( ctx->in_bytes == sizeof(ctx->in_buf) )
+    {
+        dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
+        return -1;
+    }
+
+    ctx->in_buf[ctx->in_bytes] = '\0';
+    received_csum = char2hex(gdb_io_read(ctx)) * 16 +
+        char2hex(gdb_io_read(ctx));
+
+    return (received_csum == csum) ? 0 : -1;
+}
+
+/* Receive a command, discarding up to ten packets with csum
+ * errors.  Acknowledges all received packets. */
+static int 
+receive_command(struct gdb_context *ctx)
+{
+    int r, count = 0;
+
+    count = 0;
+    do {
+        r = attempt_receive_packet(ctx);
+        gdb_io_write_char((r < 0) ? '-' : '+', ctx);
+        count++;
+    } while ( (r < 0) && (count < GDB_RETRY_MAX) );
+
+    return r;
+}
+
+/* routines to send reply packets */
+
+static void 
+gdb_start_packet(struct gdb_context *ctx)
+{
+    ctx->out_buf[0] = '$';
+    ctx->out_offset = 1;
+    ctx->out_csum = 0;
+}
+
+static void 
+gdb_write_to_packet_char(u8 data, struct gdb_context *ctx)
+{
+    ctx->out_csum += data;
+    ctx->out_buf[ctx->out_offset] = data;
+    ctx->out_offset++;
+}
+
+void 
+gdb_write_to_packet(const char *buf, int count, struct gdb_context *ctx)
+{
+    int x;
+    for ( x = 0; x < count; x++ )
+        gdb_write_to_packet_char(buf[x], ctx);
+}
+
+void 
+gdb_write_to_packet_str(const char *buf, struct gdb_context *ctx)
+{
+    gdb_write_to_packet(buf, strlen(buf), ctx);
+}
+
+void
+gdb_write_to_packet_hex(unsigned long x, int int_size, struct gdb_context *ctx)
+{
+    char buf[sizeof(unsigned long) * 2 + 1];
+    int i = sizeof(unsigned long) * 2;
+    int width = int_size * 2;
+
+    buf[sizeof(unsigned long) * 2] = 0;
+
+    switch ( int_size )
+    {
+    case sizeof(u8):
+    case sizeof(u16):
+    case sizeof(u32):
+    case sizeof(u64):
+        break;
+    default:
+        dbg_printk("WARNING: %s x: 0x%lx int_size: %d\n",
+                   __func__, x, int_size);
+        break;
+    }
+
+    do {
+        buf[--i] = hex2char(x & 15);
+        x >>= 4;
+    } while ( x );
+
+    while ( (i + width) > (sizeof(unsigned long) * 2) )
+        buf[--i] = '0';
+
+    gdb_write_to_packet(&buf[i], width, ctx);
+}
+
+static int
+gdb_check_ack(struct gdb_context *ctx)
+{
+    u8 c = gdb_io_read(ctx);
+
+    switch ( c )
+    {
+    case '+':
+        return 1;
+    case '-':
+        return 0;
+    default:
+        printk("Bad ack: %c\n", c);
+        return 0;
+    }
+}
+
+/* Return 0 if the reply was successfully received, !0 otherwise. */
+void 
+gdb_send_packet(struct gdb_context *ctx)
+{
+    char buf[3];
+    int count;
+
+    sprintf(buf, "%.02x\n", ctx->out_csum);
+
+    gdb_write_to_packet_char('#', ctx);
+    gdb_write_to_packet(buf, 2, ctx);
+
+    count = 0;
+    do {
+        gdb_io_write(ctx->out_buf, ctx->out_offset, ctx);
+    } while ( !gdb_check_ack(ctx) && (count++ < GDB_RETRY_MAX) );
+
+    if ( count == GDB_RETRY_MAX )
+        dbg_printk("WARNING: %s reached max retry %d\n",
+                   __func__, GDB_RETRY_MAX);
+}
+
+void 
+gdb_send_reply(const char *buf, struct gdb_context *ctx)
+{
+    gdb_start_packet(ctx);
+    gdb_write_to_packet_str(buf, ctx);
+    gdb_send_packet(ctx);
+}
+
+/* arch neutral command handlers */
+
+static void 
+gdb_cmd_signum(struct gdb_context *ctx)
+{
+    gdb_write_to_packet_char('S', ctx);
+    gdb_write_to_packet_hex(ctx->signum, sizeof(ctx->signum), ctx);
+    gdb_send_packet(ctx);
+}
+
+static void 
+gdb_cmd_read_mem(unsigned long addr, unsigned long length,
+                 struct gdb_context *ctx)
+{
+    int x, r;
+    unsigned char val;
+
+    dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
+               length);
+
+    for ( x = 0; x < length; x++ )
+    {
+        r = gdb_arch_copy_from_user(&val, (void *)(addr + x), 1);
+        if ( r != 0 )
+        {
+            dbg_printk("Error reading from %lx.\n", addr + x);
+            break;
+        }
+        gdb_write_to_packet_hex(val, sizeof(val), ctx);
+    }
+
+    if ( x == 0 )
+        gdb_write_to_packet_str("E05", ctx);
+
+    dbg_printk("Read done.\n");
+
+    gdb_send_packet(ctx);
+}
+
+static void 
+gdb_cmd_write_mem(unsigned long addr, unsigned long length,
+                  const char *buf, struct gdb_context *ctx)
+{
+    int x, r;
+    unsigned char val;
+
+    dbg_printk("Memory write starting at %lx, length %lx.\n", addr, length);
+
+    for ( x = 0; x < length; x++, addr++, buf += 2 )
+    {
+        val = str2ulong(buf, sizeof(val));
+        r = gdb_arch_copy_to_user((void*)addr, (void*)&val, 1);
+        if ( r != 0 )
+        {
+            dbg_printk("Error writing to %lx.\n", addr);
+            break;
+        }
+    }
+
+    gdb_write_to_packet_str((x != length) ? "OK" : "E11", ctx);
+
+    dbg_printk("Write done.\n");
+
+    gdb_send_packet(ctx);
+}
+
+/* command dispatcher */
+static int 
+process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
+{
+    char *ptr;
+    unsigned long addr, length;
+    int resume = 0;
+
+    /* XXX check ctx->in_bytes >= 2 or similar. */
+
+    gdb_start_packet(ctx);
+    switch ( ctx->in_buf[0] )
+    {
+    case '?':    /* query signal number */
+        gdb_cmd_signum(ctx);
+        break;
+    case 'H':    /* thread operations */
+        gdb_send_reply("OK", ctx);
+        break;
+    case 'g': /* Read registers */
+        gdb_arch_read_reg_array(regs, ctx);
+        ASSERT(!local_irq_is_enabled());
+        break;
+    case 'G': /* Write registers */
+        gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
+        break;
+    case 'm': /* Read memory */
+        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
+        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
+        {
+            gdb_send_reply("E03", ctx);
+            return 0;
+        }
+        length = simple_strtoul(ptr + 1, &ptr, 16);
+        if ( ptr[0] != 0 )
+        {
+            gdb_send_reply("E04", ctx);
+            return 0;
+        }
+        gdb_cmd_read_mem(addr, length, ctx);
+        ASSERT(!local_irq_is_enabled());
+        break;
+    case 'M': /* Write memory */
+        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
+        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ':') )
+        {
+            gdb_send_reply("E03", ctx);
+            return 0;
+        }
+        length = simple_strtoul(ptr + 1, &ptr, 16);
+        gdb_cmd_write_mem(addr, length, ptr, ctx);
+        break;
+    case 'p': /* read register */
+        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
+        if ( ptr == (ctx->in_buf + 1) )
+        {
+            gdb_send_reply("E03", ctx);
+            return 0;
+        }
+        if ( ptr[0] != 0 )
+        {
+            gdb_send_reply("E04", ctx);
+            return 0;
+        }
+        gdb_arch_read_reg(addr, regs, ctx);
+        break;
+    case 'Z': /* We need to claim to support these or gdb
+                 won't let you continue the process. */
+    case 'z':
+        gdb_send_reply("OK", ctx);
+        break;
+
+    case 'D':
+        ctx->currently_attached = 0;
+        gdb_send_reply("OK", ctx);
+        /* fall through */
+    case 'k':
+        ctx->connected = 0;
+        /* fall through */
+    case 's': /* Single step */
+    case 'c': /* Resume at current address */
+    {
+        unsigned long addr = ~((unsigned long)0);
+        unsigned long type = GDB_CONTINUE;
+        if ( ctx->in_buf[0] == 's' )
+            type = GDB_STEP;
+        if ( ((ctx->in_buf[0] == 's') || (ctx->in_buf[0] == 'c')) &&
+             ctx->in_buf[1] )
+            addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
+        if ( ctx->in_buf[0] != 'D' )
+            ctx->currently_attached = 1;
+        resume = 1;
+        gdb_arch_resume(regs, addr, type, ctx);
+        break;
+    }
+
+    default:
+        gdb_send_reply("", ctx);
+        break;
+    }
+    return resume;
+}
+
+static struct gdb_context
+__gdb_ctx = {
+    .serhnd             = -1,
+    .currently_attached = 0,
+    .running            = ATOMIC_INIT(1),
+    .connected          = 0,
+    .signum             = 1,
+    .in_bytes           = 0,
+    .out_offset         = 0,
+    .out_csum           = 0,
+};
+static struct gdb_context *gdb_ctx = &__gdb_ctx;
+
+/* trap handler: main entry point */
+int 
+__trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
+{
+    int resume = 0;
+    int r;
+    unsigned flags;
+
+    if ( gdb_ctx->serhnd < 0 )
+    {
+        dbg_printk("Debugger not ready yet.\n");
+        return 0;
+    }
+
+    /* We rely on our caller to ensure we're only on one processor
+     * at a time... We should probably panic here, but given that
+     * we're a debugger we should probably be a little tolerant of
+     * things going wrong. */
+    /* We don't want to use a spin lock here, because we're doing
+       two distinct things:
+
+       1 -- we don't want to run on more than one processor at a time,
+            and
+       2 -- we want to do something sensible if we re-enter ourselves.
+
+       Spin locks are good for 1, but useless for 2. */
+    if ( !atomic_dec_and_test(&gdb_ctx->running) )
+    {
+        printk("WARNING WARNING WARNING: Avoiding recursive gdb.\n");
+        atomic_inc(&gdb_ctx->running);
+        return 0;
+    }
+
+    if ( !gdb_ctx->connected )
+    {
+        printk("GDB connection activated\n");
+        gdb_arch_print_state(regs);
+        gdb_ctx->connected = 1;
+    }
+
+    smp_send_stop();
+
+    /* Try to make things a little more stable by disabling
+       interrupts while we're here. */
+    local_irq_save(flags);
+
+    watchdog_disable();
+    console_start_sync();
+
+    /* Shouldn't really do this, but otherwise we stop for no
+       obvious reason, which is Bad */
+    printk("Waiting for GDB to attach to Gdb\n");
+
+    gdb_arch_enter(regs);
+    gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
+    /* If gdb is already attached, tell it we've stopped again. */
+    if ( gdb_ctx->currently_attached )
+    {
+        gdb_start_packet(gdb_ctx);
+        gdb_cmd_signum(gdb_ctx);
+    }
+
+    while ( resume == 0 )
+    {
+        ASSERT(!local_irq_is_enabled());
+        r = receive_command(gdb_ctx);
+        ASSERT(!local_irq_is_enabled());
+        if ( r < 0 )
+        {
+            dbg_printk("GDB disappeared, trying to resume Xen...\n");
+            resume = 1;
+        }
+        else
+        {
+            ASSERT(!local_irq_is_enabled());
+            resume = process_command(regs, gdb_ctx);
+            ASSERT(!local_irq_is_enabled());
+        }
+    }
+
+    gdb_arch_exit(regs);
+    console_end_sync();
+    watchdog_enable();
+    atomic_inc(&gdb_ctx->running);
+
+    local_irq_restore(flags);
+
+    return 0;
+}
+
+/*
+ * initialization
+ * XXX TODO
+ *     This should be an explicit call from architecture code.               
+ *     initcall is far too late for some early debugging, and only the 
+ *     architecture code knows when this call can be made.          
+ */
+static int
+initialize_gdb(void)
+{
+    if ( !strcmp(opt_gdb, "none") )
+        return 0;
+    gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
+    if ( gdb_ctx->serhnd == -1 )
+        panic("Can't parse %s as GDB serial info.\n", opt_gdb);
+
+    printk("Gdb initialised.\n");
+    return 0;
+}
+
+__initcall(initialize_gdb);
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/timer.c
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/xen/common/timer.c        Tue Jan 24 16:54:34 2006
@@ -0,0 +1,308 @@
+/******************************************************************************
+ * timer.c
+ * 
+ * Copyright (c) 2002-2003 Rolf Neugebauer
+ * Copyright (c) 2002-2005 K A Fraser
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/types.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/lib.h>
+#include <xen/smp.h>
+#include <xen/perfc.h>
+#include <xen/time.h>
+#include <xen/softirq.h>
+#include <xen/timer.h>
+#include <xen/keyhandler.h>
+#include <asm/system.h>
+#include <asm/desc.h>
+
+/*
+ * We pull handlers off the timer list this far in future,
+ * rather than reprogramming the time hardware.
+ */
+#define TIMER_SLOP (50*1000) /* ns */
+
+struct timers {
+    spinlock_t     lock;
+    struct timer **heap;
+    struct timer  *running;
+} __cacheline_aligned;
+
+struct timers timers[NR_CPUS];
+
+extern int reprogram_timer(s_time_t timeout);
+
+/****************************************************************************
+ * HEAP OPERATIONS.
+ */
+
+#define GET_HEAP_SIZE(_h)     ((int)(((u16 *)(_h))[0]))
+#define SET_HEAP_SIZE(_h,_v)  (((u16 *)(_h))[0] = (u16)(_v))
+
+#define GET_HEAP_LIMIT(_h)    ((int)(((u16 *)(_h))[1]))
+#define SET_HEAP_LIMIT(_h,_v) (((u16 *)(_h))[1] = (u16)(_v))
+
+/* Sink down element @pos of @heap. */
+static void down_heap(struct timer **heap, int pos)
+{
+    int sz = GET_HEAP_SIZE(heap), nxt;
+    struct timer *t = heap[pos];
+
+    while ( (nxt = (pos << 1)) <= sz )
+    {
+        if ( ((nxt+1) <= sz) && (heap[nxt+1]->expires < heap[nxt]->expires) )
+            nxt++;
+        if ( heap[nxt]->expires > t->expires )
+            break;
+        heap[pos] = heap[nxt];
+        heap[pos]->heap_offset = pos;
+        pos = nxt;
+    }
+
+    heap[pos] = t;
+    t->heap_offset = pos;
+}
+
+/* Float element @pos up @heap. */
+static void up_heap(struct timer **heap, int pos)
+{
+    struct timer *t = heap[pos];
+
+    while ( (pos > 1) && (t->expires < heap[pos>>1]->expires) )
+    {
+        heap[pos] = heap[pos>>1];
+        heap[pos]->heap_offset = pos;
+        pos >>= 1;
+    }
+
+    heap[pos] = t;
+    t->heap_offset = pos;
+}
+
+
+/* Delete @t from @heap. Return TRUE if new top of heap. */
+static int remove_entry(struct timer **heap, struct timer *t)
+{
+    int sz = GET_HEAP_SIZE(heap);
+    int pos = t->heap_offset;
+
+    t->heap_offset = 0;
+
+    if ( unlikely(pos == sz) )
+    {
+        SET_HEAP_SIZE(heap, sz-1);
+        goto out;
+    }
+
+    heap[pos] = heap[sz];
+    heap[pos]->heap_offset = pos;
+
+    SET_HEAP_SIZE(heap, --sz);
+
+    if ( (pos > 1) && (heap[pos]->expires < heap[pos>>1]->expires) )
+        up_heap(heap, pos);
+    else
+        down_heap(heap, pos);
+
+ out:
+    return (pos == 1);
+}
+
+
+/* Add new entry @t to @heap. Return TRUE if new top of heap. */
+static int add_entry(struct timer ***pheap, struct timer *t)
+{
+    struct timer **heap = *pheap;
+    int sz = GET_HEAP_SIZE(heap);
+
+    /* Copy the heap if it is full. */
+    if ( unlikely(sz == GET_HEAP_LIMIT(heap)) )
+    {
+        /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
+        int old_limit = GET_HEAP_LIMIT(heap);
+        int new_limit = ((old_limit + 1) << 4) - 1;
+        heap = xmalloc_array(struct timer *, new_limit + 1);
+        BUG_ON(heap == NULL);
+        memcpy(heap, *pheap, (old_limit + 1) * sizeof(*heap));
+        SET_HEAP_LIMIT(heap, new_limit);
+        if ( old_limit != 0 )
+            xfree(*pheap);
+        *pheap = heap;
+    }
+
+    SET_HEAP_SIZE(heap, ++sz);
+    heap[sz] = t;
+    t->heap_offset = sz;
+    up_heap(heap, sz);
+    return (t->heap_offset == 1);
+}
+
+
+/****************************************************************************
+ * TIMER OPERATIONS.
+ */
+
+static inline void __add_timer(struct timer *timer)
+{
+    int cpu = timer->cpu;
+    if ( add_entry(&timers[cpu].heap, timer) )
+        cpu_raise_softirq(cpu, TIMER_SOFTIRQ);
+}
+
+
+static inline void __stop_timer(struct timer *timer)
+{
+    int cpu = timer->cpu;
+    if ( remove_entry(timers[cpu].heap, timer) )
+        cpu_raise_softirq(cpu, TIMER_SOFTIRQ);
+}
+
+
+void set_timer(struct timer *timer, s_time_t expires)
+{
+    int           cpu = timer->cpu;
+    unsigned long flags;
+
+    spin_lock_irqsave(&timers[cpu].lock, flags);
+    if ( active_timer(timer) )
+        __stop_timer(timer);
+    timer->expires = expires;
+    if ( likely(!timer->killed) )
+        __add_timer(timer);
+    spin_unlock_irqrestore(&timers[cpu].lock, flags);
+}
+
+
+void stop_timer(struct timer *timer)
+{
+    int           cpu = timer->cpu;
+    unsigned long flags;
+
+    spin_lock_irqsave(&timers[cpu].lock, flags);
+    if ( active_timer(timer) )
+        __stop_timer(timer);
+    spin_unlock_irqrestore(&timers[cpu].lock, flags);
+}
+
+
+void kill_timer(struct timer *timer)
+{
+    int           cpu = timer->cpu;
+    unsigned long flags;
+
+    BUG_ON(timers[cpu].running == timer);
+
+    spin_lock_irqsave(&timers[cpu].lock, flags);
+    if ( active_timer(timer) )
+        __stop_timer(timer);
+    timer->killed = 1;
+    spin_unlock_irqrestore(&timers[cpu].lock, flags);
+
+    for_each_online_cpu ( cpu )
+        while ( timers[cpu].running == timer )
+            cpu_relax();
+}
+
+
+static void timer_softirq_action(void)
+{
+    int           cpu = smp_processor_id();
+    struct timer *t, **heap;
+    s_time_t      now;
+    void        (*fn)(void *);
+    void         *data;
+
+    spin_lock_irq(&timers[cpu].lock);
+    
+    do {
+        heap = timers[cpu].heap;
+        now  = NOW();
+
+        while ( (GET_HEAP_SIZE(heap) != 0) &&
+                ((t = heap[1])->expires < (now + TIMER_SLOP)) )
+        {
+            remove_entry(heap, t);
+
+            timers[cpu].running = t;
+
+            fn   = t->function;
+            data = t->data;
+
+            spin_unlock_irq(&timers[cpu].lock);
+            (*fn)(data);
+            spin_lock_irq(&timers[cpu].lock);
+
+            /* Heap may have grown while the lock was released. */
+            heap = timers[cpu].heap;
+        }
+
+        timers[cpu].running = NULL;
+    }
+    while ( !reprogram_timer(GET_HEAP_SIZE(heap) ? heap[1]->expires : 0) );
+
+    spin_unlock_irq(&timers[cpu].lock);
+}
+
+
+static void dump_timerq(unsigned char key)
+{
+    struct timer *t;
+    unsigned long flags; 
+    s_time_t      now = NOW();
+    int           i, j;
+
+    printk("Dumping timer queues: NOW=0x%08X%08X\n",
+           (u32)(now>>32), (u32)now); 
+
+    for_each_online_cpu( i )
+    {
+        printk("CPU[%02d] ", i);
+        spin_lock_irqsave(&timers[i].lock, flags);
+        for ( j = 1; j <= GET_HEAP_SIZE(timers[i].heap); j++ )
+        {
+            t = timers[i].heap[j];
+            printk ("  %d : %p ex=0x%08X%08X %p\n",
+                    j, t, (u32)(t->expires>>32), (u32)t->expires, t->data);
+        }
+        spin_unlock_irqrestore(&timers[i].lock, flags);
+        printk("\n");
+    }
+}
+
+
+void __init timer_init(void)
+{
+    static struct timer *dummy_heap;
+    int i;
+
+    open_softirq(TIMER_SOFTIRQ, timer_softirq_action);
+
+    /*
+     * All CPUs initially share an empty dummy heap. Only those CPUs that
+     * are brought online will be dynamically allocated their own heap.
+     */
+    SET_HEAP_SIZE(&dummy_heap, 0);
+    SET_HEAP_LIMIT(&dummy_heap, 0);
+
+    for ( i = 0; i < NR_CPUS; i++ )
+    {
+        spin_lock_init(&timers[i].lock);
+        timers[i].heap = &dummy_heap;
+    }
+
+    register_keyhandler('a', dump_timerq, "dump timer queues");
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/public/nmi.h
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/xen/include/public/nmi.h  Tue Jan 24 16:54:34 2006
@@ -0,0 +1,54 @@
+/******************************************************************************
+ * nmi.h
+ * 
+ * NMI callback registration and reason codes.
+ * 
+ * Copyright (c) 2005, Keir Fraser <keir@xxxxxxxxxxxxx>
+ */
+
+#ifndef __XEN_PUBLIC_NMI_H__
+#define __XEN_PUBLIC_NMI_H__
+
+/*
+ * NMI reason codes:
+ * Currently these are x86-specific, stored in arch_shared_info.nmi_reason.
+ */
+ /* I/O-check error reported via ISA port 0x61, bit 6. */
+#define _XEN_NMIREASON_io_error     0
+#define XEN_NMIREASON_io_error      (1UL << _XEN_NMIREASON_io_error)
+ /* Parity error reported via ISA port 0x61, bit 7. */
+#define _XEN_NMIREASON_parity_error 1
+#define XEN_NMIREASON_parity_error  (1UL << _XEN_NMIREASON_parity_error)
+ /* Unknown hardware-generated NMI. */
+#define _XEN_NMIREASON_unknown      2
+#define XEN_NMIREASON_unknown       (1UL << _XEN_NMIREASON_unknown)
+
+/*
+ * long nmi_op(unsigned int cmd, void *arg)
+ * NB. All ops return zero on success, else a negative error code.
+ */
+
+/*
+ * Register NMI callback for this (calling) VCPU. Currently this only makes
+ * sense for domain 0, vcpu 0. All other callers will be returned EINVAL.
+ * arg == address of callback function.
+ */
+#define XENNMI_register_callback   0
+
+/*
+ * Deregister NMI callback for this (calling) VCPU.
+ * arg == NULL.
+ */
+#define XENNMI_unregister_callback 1
+
+#endif /* __XEN_PUBLIC_NMI_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/gdbstub.h
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/gdbstub.h Tue Jan 24 16:54:34 2006
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2005 Hollis Blanchard <hollisb@xxxxxxxxxx>, IBM Corporation
+ * Copyright (C) 2006 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan. K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef __XEN_GDBSTUB_H__
+#define __XEN_GDBSTUB_H__
+
+/* value <-> char (de)serialzers for arch specific gdb backends */
+char hex2char(unsigned long x); 
+int char2hex(unsigned char c); 
+char str2hex(const char *str); 
+unsigned long str2ulong(const char *str, unsigned long bytes); 
+
+struct gdb_context {
+    int                 serhnd;
+    int                 currently_attached:1;
+    atomic_t            running;
+    unsigned long       connected;
+    u8                  signum;
+
+    char                in_buf[PAGE_SIZE];
+    unsigned long       in_bytes;
+
+    char                out_buf[PAGE_SIZE];
+    unsigned long       out_offset;
+    u8                  out_csum;
+};
+
+/* interface to arch specific routines */
+void gdb_write_to_packet(
+    const char *buf, int count, struct gdb_context *ctx);
+void gdb_write_to_packet_hex(
+    unsigned long x, int int_size, struct gdb_context *ctx);
+void gdb_send_packet(struct gdb_context *ctx); 
+void gdb_send_reply(const char *buf, struct gdb_context *ctx);
+
+/* gdb stub trap handler: entry point */
+int __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie);
+
+/* arch specific routines */
+u16 gdb_arch_signal_num(
+    struct cpu_user_regs *regs, unsigned long cookie);
+void gdb_arch_read_reg_array(
+    struct cpu_user_regs *regs, struct gdb_context *ctx);
+void gdb_arch_write_reg_array(
+    struct cpu_user_regs *regs, const char* buf, struct gdb_context *ctx);
+void gdb_arch_read_reg(
+    unsigned long regnum, struct cpu_user_regs *regs, struct gdb_context *ctx);
+unsigned int gdb_arch_copy_from_user(
+    void *dest, const void *src, unsigned len);
+unsigned int gdb_arch_copy_to_user(
+    void *dest, const void *src, unsigned len);
+void gdb_arch_resume(
+    struct cpu_user_regs *regs, unsigned long addr,
+    unsigned long type, struct gdb_context *ctx);
+void gdb_arch_print_state(struct cpu_user_regs *regs);
+void gdb_arch_enter(struct cpu_user_regs *regs);
+void gdb_arch_exit(struct cpu_user_regs *regs);
+
+#define GDB_CONTINUE     0
+#define GDB_STEP         1
+
+#define SIGILL           4
+#define SIGTRAP          5
+#define SIGBUS           7
+#define SIGFPE           8
+#define SIGSEGV         11
+#define SIGALRM         14
+#define SIGTERM         15
+
+#endif /* __XEN_GDBSTUB_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/timer.h
--- /dev/null   Tue Jan 10 15:21:00 2006
+++ b/xen/include/xen/timer.h   Tue Jan 24 16:54:34 2006
@@ -0,0 +1,90 @@
+/******************************************************************************
+ * timer.h
+ * 
+ * Copyright (c) 2002-2003 Rolf Neugebauer
+ * Copyright (c) 2002-2005 K A Fraser
+ */
+
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+#include <xen/spinlock.h>
+#include <xen/time.h>
+#include <xen/string.h>
+
+struct timer {
+    /* System time expiry value (nanoseconds since boot). */
+    s_time_t      expires;
+    /* CPU on which this timer will be installed and executed. */
+    unsigned int  cpu;
+    /* On expiry, '(*function)(data)' will be executed in softirq context. */
+    void        (*function)(void *);
+    void         *data;
+    /* Timer-heap offset. */
+    unsigned int  heap_offset;
+    /* Has this timer been killed (cannot be activated)? */
+    int           killed;
+};
+
+/*
+ * All functions below can be called for any CPU from any CPU in any context.
+ */
+
+/* Returns TRUE if the given timer is on a timer list. */
+static __inline__ int active_timer(struct timer *timer)
+{
+    return (timer->heap_offset != 0);
+}
+
+/*
+ * It initialises the static fields of the timer structure.
+ * It can be called multiple times to reinitialise a single (inactive) timer.
+ */
+static __inline__ void init_timer(
+    struct timer *timer,
+    void           (*function)(void *),
+    void            *data,
+    unsigned int     cpu)
+{
+    memset(timer, 0, sizeof(*timer));
+    timer->function = function;
+    timer->data     = data;
+    timer->cpu      = cpu;
+}
+
+/*
+ * Set the expiry time and activate a timer (which must previously have been
+ * initialised by init_timer).
+ */
+extern void set_timer(struct timer *timer, s_time_t expires);
+
+/*
+ * Deactivate a timer (which must previously have been initialised by
+ * init_timer). This function has no effect if the timer is not currently
+ * active.
+ */
+extern void stop_timer(struct timer *timer);
+
+/*
+ * Deactivate a timer and prevent it from being re-set (future calls to
+ * set_timer will silently fail). When this function returns it is guaranteed
+ * that the timer callback handler is not running on any CPU.
+ */
+extern void kill_timer(struct timer *timer);
+
+/*
+ * Initialisation. Must be called before any other timer function.
+ */
+extern void timer_init(void);
+
+#endif /* _TIMER_H_ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/blkfront/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/Kconfig Tue Jan 10 15:21:00 2006
+++ /dev/null   Tue Jan 24 16:54:34 2006
@@ -1,6 +0,0 @@
-
-config XENBLOCK
-       tristate "Block device driver"
-       depends on ARCH_XEN
-       help
-         Block device driver for Xen
diff -r 40bb46f599d9 -r a38c292e8390 
linux-2.6-xen-sparse/drivers/xen/netfront/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/Kconfig Tue Jan 10 15:21:00 2006
+++ /dev/null   Tue Jan 24 16:54:34 2006
@@ -1,6 +0,0 @@
-
-config XENNET
-       tristate "Xen network driver"
-       depends on NETDEVICES && ARCH_XEN
-       help
-         Network driver for Xen
diff -r 40bb46f599d9 -r a38c292e8390 xen/arch/x86/cdb.c
--- a/xen/arch/x86/cdb.c        Tue Jan 10 15:21:00 2006
+++ /dev/null   Tue Jan 24 16:54:34 2006
@@ -1,414 +0,0 @@
-/* Simple hacked-up version of pdb for use in post-mortem debugging of
-   Xen and domain 0. This should be a little cleaner, hopefully.  Note
-   that we can't share a serial line with PDB. */
-/* We try to avoid assuming much about what the rest of the system is
-   doing.  In particular, dynamic memory allocation is out of the
-   question. */
-/* Resuming after we've stopped used to work, but more through luck
-   than any actual intention.  It doesn't at the moment. */
-#include <xen/lib.h>
-#include <asm/uaccess.h>
-#include <xen/spinlock.h>
-#include <xen/serial.h>
-#include <xen/irq.h>
-#include <asm/debugger.h>
-#include <xen/init.h>
-#include <xen/smp.h>
-#include <xen/console.h>
-#include <asm/apic.h>
-
-/* Printk isn't particularly safe just after we've trapped to the
-   debugger. so avoid it. */
-#define dbg_printk(...)
-
-static char opt_cdb[30] = "none";
-string_param("cdb", opt_cdb);
-
-struct xendbg_context {
-       int serhnd;
-       u8 reply_csum;
-       int currently_attached:1;
-};
-
-/* Like copy_from_user, but safe to call with interrupts disabled.
-
-   Trust me, and don't look behind the curtain. */
-static unsigned
-dbg_copy_from_user(void *dest, const void *src, unsigned len)
-{
-       int __d0, __d1, __d2;
-       ASSERT(!local_irq_is_enabled());
-       __asm__ __volatile__(
-               "1:     rep; movsb\n"
-               "2:\n"
-               ".section .fixup,\"ax\"\n"
-               "3:     addl $4, %%esp\n"
-               "       jmp 2b\n"
-               ".previous\n"
-               ".section __pre_ex_table,\"a\"\n"
-               "       .align 4\n"
-               "       .long 1b,3b\n"
-               ".previous\n"
-               ".section __ex_table,\"a\"\n"
-               "       .align 4\n"
-               "       .long 1b,2b\n"
-               ".previous\n"
-               : "=c"(__d2), "=D" (__d0), "=S" (__d1)
-               : "0"(len), "1"(dest), "2"(src)
-               : "memory");
-       ASSERT(!local_irq_is_enabled());
-       return __d2;
-}
-
-static void
-xendbg_put_char(u8 data, struct xendbg_context *ctx)
-{
-       ctx->reply_csum += data;
-       serial_putc(ctx->serhnd, data);
-}
-
-static int
-hex_char_val(unsigned char c)
-{
-       if (c >= '0' && c <= '9')
-               return c - '0';
-       else if (c >= 'a' && c <= 'f')
-               return c - 'a' + 10;
-       else if (c >= 'A' && c <= 'F')
-               return c - 'A' + 10;
-       else
-               BUG();
-       return -1;
-}
-
-/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
-/* Does not acknowledge. */
-static int
-attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
-{
-       int count;
-       u8 csum;
-       u8 received_csum;
-       u8 ch;
-
-       /* Skip over everything up to the first '$' */
-       while ((ch = serial_getc(ctx->serhnd)) != '$')
-               ;
-       csum = 0;
-       for (count = 0; count < 4096; count++) {
-               ch = serial_getc(ctx->serhnd);
-               if (ch == '#')
-                       break;
-               recv_buf[count] = ch;
-               csum += ch;
-       }
-       if (count == 4096) {
-               dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
-               return -1;
-       }
-       recv_buf[count] = 0;
-       received_csum = hex_char_val(serial_getc(ctx->serhnd)) * 16 +
-               hex_char_val(serial_getc(ctx->serhnd));
-       if (received_csum == csum) {
-               return 0;
-       } else {
-               return -1;
-       }
-}
-
-/* Send a string of bytes to the debugger. */
-static void
-xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
-{
-       int x;
-       for (x = 0; x < count; x++)
-               xendbg_put_char(buf[x], ctx);
-}
-
-/* Receive a command, discarding up to ten packets with csum
- * errors.  Acknowledges all received packets. */
-static int
-receive_command(char *recv_buf, struct xendbg_context *ctx)
-{
-       int r;
-       int count;
-
-       count = 0;
-       do {
-               r = attempt_receive_packet(recv_buf, ctx);
-               if (r < 0)
-                       xendbg_put_char('-', ctx);
-               else
-                       xendbg_put_char('+', ctx);
-               count++;
-       } while (r < 0 && count < 10);
-       return r;
-}
-
-static void
-xendbg_start_reply(struct xendbg_context *ctx)
-{
-       xendbg_put_char('$', ctx);
-       ctx->reply_csum = 0;
-}
-
-/* Return 0 if the reply was successfully received, !0 otherwise. */
-static int
-xendbg_finish_reply(struct xendbg_context *ctx)
-{
-       char ch;
-       char buf[3];
-
-       sprintf(buf, "%.02x\n", ctx->reply_csum);
-
-       xendbg_put_char('#', ctx);
-       xendbg_send(buf, 2, ctx);
-
-       ch = serial_getc(ctx->serhnd);
-       if (ch == '+')
-               return 0;
-       else
-               return 1;
-}
-
-/* Swap the order of the bytes in a work. */
-static inline unsigned
-bswab32(unsigned val)
-{
-       return (((val >> 0) & 0xff) << 24) |
-               (((val >> 8) & 0xff) << 16) |
-               (((val >> 16) & 0xff) << 8) |
-               (((val >> 24) & 0xff) << 0);
-}
-
-static int
-handle_memory_read_command(unsigned long addr, unsigned long length,
-                          struct xendbg_context *ctx)
-{
-       int x;
-       unsigned char val;
-       int r;
-       char buf[2];
-
-       dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
-                  length);
-       xendbg_start_reply(ctx);
-       for (x = 0; x < length; x++) {
-               r = dbg_copy_from_user(&val, (void *)(addr + x), 1);
-               if (r != 0) {
-                       dbg_printk("Error reading from %lx.\n", addr + x);
-                       break;
-               }
-               sprintf(buf, "%.02x", val);
-               xendbg_send(buf, 2, ctx);
-       }
-       if (x == 0)
-               xendbg_send("E05", 3, ctx);
-       dbg_printk("Read done.\n");
-       return xendbg_finish_reply(ctx);
-}
-
-static int
-xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
-{
-       xendbg_start_reply(ctx);
-       xendbg_send(buf, strlen(buf), ctx);
-       return xendbg_finish_reply(ctx);
-}
-
-static int
-handle_register_read_command(struct cpu_user_regs *regs, struct xendbg_context 
*ctx)
-{
-       char buf[121];
-
-       sprintf(buf,
-               
"%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
-               bswab32(regs->eax),
-               bswab32(regs->ecx),
-               bswab32(regs->edx),
-               bswab32(regs->ebx),
-               bswab32(regs->esp),
-               bswab32(regs->ebp),
-               bswab32(regs->esi),
-               bswab32(regs->edi),
-               bswab32(regs->eip),
-               bswab32(regs->eflags),
-               bswab32(regs->cs),
-               bswab32(regs->ss),
-               bswab32(regs->ds),
-               bswab32(regs->es),
-               bswab32(regs->fs),
-               bswab32(regs->gs));
-       return xendbg_send_reply(buf, ctx);
-}
-
-static int
-process_command(char *received_packet, struct cpu_user_regs *regs,
-               struct xendbg_context *ctx)
-{
-       char *ptr;
-       unsigned long addr, length;
-       int retry;
-       int counter;
-       int resume = 0;
-
-       /* Repeat until gdb acks the reply */
-       counter = 0;
-       do {
-               switch (received_packet[0]) {
-               case 'g': /* Read registers */
-                       retry = handle_register_read_command(regs, ctx);
-                       ASSERT(!local_irq_is_enabled());
-                       break;
-               case 'm': /* Read memory */
-                       addr = simple_strtoul(received_packet + 1, &ptr, 16);
-                       if (ptr == received_packet + 1 ||
-                           ptr[0] != ',') {
-                               xendbg_send_reply("E03", ctx);
-                               return 0;
-                       }
-                       length = simple_strtoul(ptr + 1, &ptr, 16);
-                       if (ptr[0] != 0) {
-                               xendbg_send_reply("E04", ctx);
-                               return 0;
-                       }
-                       retry =
-                               handle_memory_read_command(addr,
-                                                          length,
-                                                          ctx);
-                       ASSERT(!local_irq_is_enabled());
-                       break;
-               case 'G': /* Write registers */
-               case 'M': /* Write memory */
-                       retry = xendbg_send_reply("E02", ctx);
-                       break;
-               case 'D':
-                       resume = 1;
-                       ctx->currently_attached = 0;
-                       retry = xendbg_send_reply("", ctx);
-                       break;
-               case 'c': /* Resume at current address */
-                       ctx->currently_attached = 1;
-                       resume = 1;
-                       retry = 0;
-                       break;
-               case 'Z': /* We need to claim to support these or gdb
-                            won't let you continue the process. */
-               case 'z':
-                       retry = xendbg_send_reply("OK", ctx);
-                       break;
-
-               case 's': /* Single step */
-               case '?':
-                       retry = xendbg_send_reply("S01", ctx);
-                       break;
-               default:
-                       retry = xendbg_send_reply("", ctx);
-                       break;
-               }
-               counter++;
-       } while (retry == 1 && counter < 10);
-       if (retry) {
-               dbg_printk("WARNING: gdb disappeared when we were trying to 
send it a reply.\n");
-               return 1;
-       }
-       return resume;
-}
-
-static struct xendbg_context
-xdb_ctx = {
-       serhnd : -1
-};
-
-int
-__trap_to_cdb(struct cpu_user_regs *regs)
-{
-       int resume = 0;
-       int r;
-       static atomic_t xendbg_running = ATOMIC_INIT(1);
-       static char recv_buf[4096];
-       unsigned flags;
-
-       if (xdb_ctx.serhnd < 0) {
-               dbg_printk("Debugger not ready yet.\n");
-               return 0;
-       }
-
-       /* We rely on our caller to ensure we're only on one processor
-        * at a time... We should probably panic here, but given that
-        * we're a debugger we should probably be a little tolerant of
-        * things going wrong. */
-       /* We don't want to use a spin lock here, because we're doing
-          two distinct things:
-
-          1 -- we don't want to run on more than one processor at a time,
-               and
-          2 -- we want to do something sensible if we re-enter ourselves.
-
-          Spin locks are good for 1, but useless for 2. */
-       if (!atomic_dec_and_test(&xendbg_running)) {
-               printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
-               atomic_inc(&xendbg_running);
-               return 0;
-       }
-
-       smp_send_stop();
-
-       /* Try to make things a little more stable by disabling
-          interrupts while we're here. */
-       local_irq_save(flags);
-
-       watchdog_disable();
-       console_start_sync();
-
-       /* Shouldn't really do this, but otherwise we stop for no
-          obvious reason, which is Bad */
-       printk("Waiting for GDB to attach to XenDBG\n");
-
-       /* If gdb is already attached, tell it we've stopped again. */
-       if (xdb_ctx.currently_attached) {
-               do {
-                       r = xendbg_send_reply("S01", &xdb_ctx);
-               } while (r != 0);
-       }
-
-       while (resume == 0) {
-               ASSERT(!local_irq_is_enabled());
-               r = receive_command(recv_buf, &xdb_ctx);
-               ASSERT(!local_irq_is_enabled());
-               if (r < 0) {
-                       dbg_printk("GDB disappeared, trying to resume 
Xen...\n");
-                       resume = 1;
-               } else {
-                       ASSERT(!local_irq_is_enabled());
-                       resume = process_command(recv_buf, regs, &xdb_ctx);
-                       ASSERT(!local_irq_is_enabled());
-               }
-       }
-
-       console_end_sync();
-       watchdog_enable();
-       atomic_inc(&xendbg_running);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-static int
-initialize_xendbg(void)
-{
-       if (!strcmp(opt_cdb, "none"))
-               return 0;
-       xdb_ctx.serhnd = serial_parse_handle(opt_cdb);
-       if (xdb_ctx.serhnd == -1)
-               panic("Can't parse %s as CDB serial info.\n", opt_cdb);
-
-       /* Acknowledge any spurious GDB packets. */
-       xendbg_put_char('+', &xdb_ctx);
-
-       printk("Xendbg initialised.\n");
-       return 0;
-}
-
-__initcall(initialize_xendbg);
diff -r 40bb46f599d9 -r a38c292e8390 xen/common/ac_timer.c
--- a/xen/common/ac_timer.c     Tue Jan 10 15:21:00 2006
+++ /dev/null   Tue Jan 24 16:54:34 2006
@@ -1,286 +0,0 @@
-/******************************************************************************
- * ac_timer.c
- * 
- * Copyright (c) 2002-2003 Rolf Neugebauer
- * Copyright (c) 2002-2005 K A Fraser
- */
-
-#include <xen/config.h>
-#include <xen/init.h>
-#include <xen/types.h>
-#include <xen/errno.h>
-#include <xen/sched.h>
-#include <xen/lib.h>
-#include <xen/smp.h>
-#include <xen/perfc.h>
-#include <xen/time.h>
-#include <xen/softirq.h>
-#include <xen/ac_timer.h>
-#include <xen/keyhandler.h>
-#include <asm/system.h>
-#include <asm/desc.h>
-
-/*
- * We pull handlers off the timer list this far in future,
- * rather than reprogramming the time hardware.
- */
-#define TIMER_SLOP (50*1000) /* ns */
-
-struct ac_timers {
-    spinlock_t        lock;
-    struct ac_timer **heap;
-    unsigned int      softirqs;
-} __cacheline_aligned;
-
-struct ac_timers ac_timers[NR_CPUS];
-
-extern int reprogram_ac_timer(s_time_t timeout);
-
-/****************************************************************************
- * HEAP OPERATIONS.
- */
-
-#define GET_HEAP_SIZE(_h)     ((int)(((u16 *)(_h))[0]))
-#define SET_HEAP_SIZE(_h,_v)  (((u16 *)(_h))[0] = (u16)(_v))
-
-#define GET_HEAP_LIMIT(_h)    ((int)(((u16 *)(_h))[1]))
-#define SET_HEAP_LIMIT(_h,_v) (((u16 *)(_h))[1] = (u16)(_v))
-
-/* Sink down element @pos of @heap. */
-static void down_heap(struct ac_timer **heap, int pos)
-{
-    int sz = GET_HEAP_SIZE(heap), nxt;
-    struct ac_timer *t = heap[pos];
-
-    while ( (nxt = (pos << 1)) <= sz )
-    {
-        if ( ((nxt+1) <= sz) && (heap[nxt+1]->expires < heap[nxt]->expires) )
-            nxt++;
-        if ( heap[nxt]->expires > t->expires )
-            break;
-        heap[pos] = heap[nxt];
-        heap[pos]->heap_offset = pos;
-        pos = nxt;
-    }
-
-    heap[pos] = t;
-    t->heap_offset = pos;
-}
-
-/* Float element @pos up @heap. */
-static void up_heap(struct ac_timer **heap, int pos)
-{
-    struct ac_timer *t = heap[pos];
-
-    while ( (pos > 1) && (t->expires < heap[pos>>1]->expires) )
-    {
-        heap[pos] = heap[pos>>1];
-        heap[pos]->heap_offset = pos;
-        pos >>= 1;
-    }
-
-    heap[pos] = t;
-    t->heap_offset = pos;
-}
-
-
-/* Delete @t from @heap. Return TRUE if new top of heap. */
-static int remove_entry(struct ac_timer **heap, struct ac_timer *t)
-{
-    int sz = GET_HEAP_SIZE(heap);
-    int pos = t->heap_offset;
-
-    t->heap_offset = 0;
-
-    if ( unlikely(pos == sz) )
-    {
-        SET_HEAP_SIZE(heap, sz-1);
-        goto out;
-    }
-
-    heap[pos] = heap[sz];
-    heap[pos]->heap_offset = pos;
-
-    SET_HEAP_SIZE(heap, --sz);
-
-    if ( (pos > 1) && (heap[pos]->expires < heap[pos>>1]->expires) )
-        up_heap(heap, pos);
-    else
-        down_heap(heap, pos);
-
- out:
-    return (pos == 1);
-}
-
-
-/* Add new entry @t to @heap. Return TRUE if new top of heap. */
-static int add_entry(struct ac_timer ***pheap, struct ac_timer *t)
-{
-    struct ac_timer **heap = *pheap;
-    int sz = GET_HEAP_SIZE(heap);
-
-    /* Copy the heap if it is full. */
-    if ( unlikely(sz == GET_HEAP_LIMIT(heap)) )
-    {
-        /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */
-        int old_limit = GET_HEAP_LIMIT(heap);
-        int new_limit = ((old_limit + 1) << 4) - 1;
-        heap = xmalloc_array(struct ac_timer *, new_limit + 1);
-        BUG_ON(heap == NULL);
-        memcpy(heap, *pheap, (old_limit + 1) * sizeof(*heap));
-        SET_HEAP_LIMIT(heap, new_limit);
-        if ( old_limit != 0 )
-            xfree(*pheap);
-        *pheap = heap;
-    }
-
-    SET_HEAP_SIZE(heap, ++sz);
-    heap[sz] = t;
-    t->heap_offset = sz;
-    up_heap(heap, sz);
-    return (t->heap_offset == 1);
-}
-
-
-/****************************************************************************
- * TIMER OPERATIONS.
- */
-
-static inline void __add_ac_timer(struct ac_timer *timer)
-{
-    int cpu = timer->cpu;
-    if ( add_entry(&ac_timers[cpu].heap, timer) )
-        cpu_raise_softirq(cpu, AC_TIMER_SOFTIRQ);
-}
-
-
-static inline void __rem_ac_timer(struct ac_timer *timer)
-{
-    int cpu = timer->cpu;
-    if ( remove_entry(ac_timers[cpu].heap, timer) )
-        cpu_raise_softirq(cpu, AC_TIMER_SOFTIRQ);
-}
-
-
-void set_ac_timer(struct ac_timer *timer, s_time_t expires)
-{
-    int           cpu = timer->cpu;
-    unsigned long flags;
-
-    spin_lock_irqsave(&ac_timers[cpu].lock, flags);
-    ASSERT(timer != NULL);
-    if ( active_ac_timer(timer) )
-        __rem_ac_timer(timer);
-    timer->expires = expires;
-    __add_ac_timer(timer);
-    spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
-}
-
-
-void rem_ac_timer(struct ac_timer *timer)
-{
-    int           cpu = timer->cpu;
-    unsigned long flags;
-
-    spin_lock_irqsave(&ac_timers[cpu].lock, flags);
-    ASSERT(timer != NULL);
-    if ( active_ac_timer(timer) )
-        __rem_ac_timer(timer);
-    spin_unlock_irqrestore(&ac_timers[cpu].lock, flags);
-}
-
-
-static void ac_timer_softirq_action(void)
-{
-    int              cpu = smp_processor_id();
-    struct ac_timer *t, **heap;
-    s_time_t         now;
-    void             (*fn)(void *);
-
-    spin_lock_irq(&ac_timers[cpu].lock);
-    
-    do {
-        heap = ac_timers[cpu].heap;
-        now  = NOW();
-
-        while ( (GET_HEAP_SIZE(heap) != 0) &&
-                ((t = heap[1])->expires < (now + TIMER_SLOP)) )
-        {
-            remove_entry(heap, t);
-
-            if ( (fn = t->function) != NULL )
-            {
-                void *data = t->data;
-                spin_unlock_irq(&ac_timers[cpu].lock);
-                (*fn)(data);
-                spin_lock_irq(&ac_timers[cpu].lock);
-            }
-
-            /* Heap may have grown while the lock was released. */
-            heap = ac_timers[cpu].heap;
-        }
-    }
-    while ( !reprogram_ac_timer(GET_HEAP_SIZE(heap) ? heap[1]->expires : 0) );
-
-    spin_unlock_irq(&ac_timers[cpu].lock);
-}
-
-
-static void dump_timerq(unsigned char key)
-{
-    struct ac_timer *t;
-    unsigned long    flags; 
-    s_time_t         now = NOW();
-    int              i, j;
-
-    printk("Dumping ac_timer queues: NOW=0x%08X%08X\n",
-           (u32)(now>>32), (u32)now); 
-
-    for_each_online_cpu( i )
-    {
-        printk("CPU[%02d] ", i);
-        spin_lock_irqsave(&ac_timers[i].lock, flags);
-        for ( j = 1; j <= GET_HEAP_SIZE(ac_timers[i].heap); j++ )
-        {
-            t = ac_timers[i].heap[j];
-            printk ("  %d : %p ex=0x%08X%08X %p\n",
-                    j, t, (u32)(t->expires>>32), (u32)t->expires, t->data);
-        }
-        spin_unlock_irqrestore(&ac_timers[i].lock, flags);
-        printk("\n");
-    }
-}
-
-
-void __init ac_timer_init(void)
-{
-    static struct ac_timer *dummy_heap;
-    int i;
-
-    open_softirq(AC_TIMER_SOFTIRQ, ac_timer_softirq_action);
-
-    /*
-     * All CPUs initially share an empty dummy heap. Only those CPUs that
-     * are brought online will be dynamically allocated their own heap.
-     */
-    SET_HEAP_SIZE(&dummy_heap, 0);
-    SET_HEAP_LIMIT(&dummy_heap, 0);
-
-    for ( i = 0; i < NR_CPUS; i++ )
-    {
-        spin_lock_init(&ac_timers[i].lock);
-        ac_timers[i].heap = &dummy_heap;
-    }
-
-    register_keyhandler('a', dump_timerq, "dump ac_timer queues");
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r 40bb46f599d9 -r a38c292e8390 xen/include/xen/ac_timer.h
--- a/xen/include/xen/ac_timer.h        Tue Jan 10 15:21:00 2006
+++ /dev/null   Tue Jan 24 16:54:34 2006
@@ -1,81 +0,0 @@
-/******************************************************************************
- * ac_timer.h
- * 
- * Copyright (c) 2002-2003 Rolf Neugebauer
- * Copyright (c) 2002-2005 K A Fraser
- */
-
-#ifndef _AC_TIMER_H_
-#define _AC_TIMER_H_
-
-#include <xen/spinlock.h>
-#include <xen/time.h>
-#include <xen/string.h>
-
-struct ac_timer {
-    /* System time expiry value (nanoseconds since boot). */
-    s_time_t      expires;
-    /* CPU on which this timer will be installed and executed. */
-    unsigned int  cpu;
-    /* On expiry, '(*function)(data)' will be executed in softirq context. */
-    void        (*function)(void *);
-    void         *data;
-    /* Timer-heap offset. */
-    unsigned int  heap_offset;
-};
-
-/*
- * All functions below can be called for any CPU from any CPU in any context.
- */
-
-/* Returns TRUE if the given timer is on a timer list. */
-static __inline__ int active_ac_timer(struct ac_timer *timer)
-{
-    return (timer->heap_offset != 0);
-}
-
-/*
- * It initialises the static fields of the ac_timer structure.
- * It can be called multiple times to reinitialise a single (inactive) timer.
- */
-static __inline__ void init_ac_timer(
-    struct ac_timer *timer,
-    void           (*function)(void *),
-    void            *data,
-    unsigned int     cpu)
-{
-    memset(timer, 0, sizeof(*timer));
-    timer->function = function;
-    timer->data     = data;
-    timer->cpu      = cpu;
-}
-
-/*
- * Set the expiry time and activate a timer (which must previously have been
- * initialised by init_ac_timer).
- */
-extern void set_ac_timer(struct ac_timer *timer, s_time_t expires);
-
-/*
- * Deactivate a timer (which must previously have been initialised by
- * init_ac_timer). This function has no effect if the timer is not currently
- * active.
- */
-extern void rem_ac_timer(struct ac_timer *timer);
-
-/*
- * Initialisation. Must be called before any other ac_timer function.
- */
-extern void ac_timer_init(void);
-
-#endif /* _AC_TIMER_H_ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */

_______________________________________________
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®.