WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] 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

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