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

[XenPPC] [xenppc-unstable] [ppc] merge



# HG changeset patch
# User Hollis Blanchard <hollisb@xxxxxxxxxx>
# Node ID 91ee504ed40e4513e196673d0554260904f1ce4f
# Parent  29861ae27914ea6905d75276fd0d612969878874
# Parent  fdc26ec44145cecc52518bc790e0611e831259f5
[ppc] merge
Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile              |   22 
 linux-2.6-xen-sparse/arch/ia64/xen/drivers/coreMakefile          |   20 
 linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c         |  261 ---
 linux-2.6-xen-sparse/arch/ia64/xen/xenconsole.c                  |   19 
 tools/vtpm/tpm_emulator-0.2b-x86_64.patch                        |  431 -----
 .hgignore                                                        |    6 
 Config.mk                                                        |   14 
 Makefile                                                         |    2 
 buildconfigs/linux-defconfig_xen0_ia64                           |    2 
 buildconfigs/linux-defconfig_xen_ia64                            |    2 
 config/ia64.mk                                                   |    4 
 config/x86_32.mk                                                 |    9 
 config/x86_64.mk                                                 |    9 
 extras/mini-os/Makefile                                          |    3 
 extras/mini-os/include/mm.h                                      |   21 
 extras/mini-os/minios-x86_32.lds                                 |    2 
 extras/mini-os/minios-x86_64.lds                                 |    2 
 extras/mini-os/mm.c                                              |   90 -
 extras/mini-os/x86_32.S                                          |    4 
 extras/mini-os/x86_64.S                                          |    4 
 linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S                 |    2 
 linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c              |   14 
 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c                 |   20 
 linux-2.6-xen-sparse/arch/i386/kernel/vm86.c                     |    4 
 linux-2.6-xen-sparse/arch/ia64/Kconfig                           |   36 
 linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c                  |   11 
 linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c                 |  197 ++
 linux-2.6-xen-sparse/arch/ia64/kernel/setup.c                    |   21 
 linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre               |    7 
 linux-2.6-xen-sparse/arch/ia64/xen/Makefile                      |    2 
 linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c        |    1 
 linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c                  |  285 ++-
 linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S                      |   45 
 linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c            |   15 
 linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c                |    2 
 linux-2.6-xen-sparse/drivers/xen/Kconfig                         |   26 
 linux-2.6-xen-sparse/drivers/xen/Makefile                        |    9 
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c               |    6 
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c             |   21 
 linux-2.6-xen-sparse/drivers/xen/blkfront/block.h                |    1 
 linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c                  |    1 
 linux-2.6-xen-sparse/drivers/xen/core/Makefile                   |   16 
 linux-2.6-xen-sparse/drivers/xen/core/smpboot.c                  |   18 
 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c              |    2 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h |    2 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h   |    7 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h      |   10 
 linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h                   |  145 +
 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h                |   40 
 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h               |    4 
 linux-2.6-xen-sparse/include/asm-ia64/irq.h                      |   69 
 linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h               |   32 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h |    7 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/system.h    |    4 
 linux-2.6-xen-sparse/include/xen/cpu_hotplug.h                   |    2 
 tools/Makefile                                                   |   47 
 tools/Rules.mk                                                   |    2 
 tools/debugger/libxendebug/xendebug.c                            |    5 
 tools/examples/network-bridge                                    |    1 
 tools/firmware/hvmloader/Makefile                                |   12 
 tools/firmware/rombios/Makefile                                  |    4 
 tools/ioemu/hw/cirrus_vga.c                                      |    5 
 tools/ioemu/hw/ne2000.c                                          |   36 
 tools/ioemu/hw/pc.c                                              |    5 
 tools/ioemu/hw/vga.c                                             |    2 
 tools/ioemu/vl.c                                                 |   21 
 tools/ioemu/vl.h                                                 |    2 
 tools/libxc/Makefile                                             |   77 
 tools/libxc/xc_core.c                                            |    2 
 tools/libxc/xc_hvm_build.c                                       |    2 
 tools/libxc/xc_linux_build.c                                     |   26 
 tools/libxc/xc_linux_restore.c                                   |    4 
 tools/libxc/xc_linux_save.c                                      |    6 
 tools/libxc/xc_load_elf.c                                        |    8 
 tools/libxc/xc_pagetab.c                                         |    2 
 tools/libxc/xc_ptrace.c                                          |   11 
 tools/libxc/xc_ptrace_core.c                                     |   15 
 tools/libxc/xg_private.c                                         |   15 
 tools/libxc/xg_private.h                                         |    8 
 tools/misc/Makefile                                              |    2 
 tools/python/xen/util/security.py                                |    9 
 tools/python/xen/xm/main.py                                      |    2 
 tools/vtpm/Makefile                                              |   14 
 tools/vtpm/Rules.mk                                              |    1 
 tools/vtpm/tpm_emulator-0.3-x86_64.patch                         |  381 ++++
 tools/vtpm/vtpm.patch                                            |  407 +++-
 xen/arch/ia64/Rules.mk                                           |   28 
 xen/arch/ia64/linux-xen/entry.S                                  |   17 
 xen/arch/ia64/linux-xen/iosapic.c                                |    2 
 xen/arch/ia64/linux-xen/sal.c                                    |    5 
 xen/arch/ia64/linux-xen/smp.c                                    |    2 
 xen/arch/ia64/linux-xen/smpboot.c                                |    7 
 xen/arch/ia64/linux-xen/time.c                                   |    8 
 xen/arch/ia64/tools/sparse-merge                                 |   10 
 xen/arch/ia64/vmx/pal_emul.c                                     |   24 
 xen/arch/ia64/vmx/vmmu.c                                         |   73 
 xen/arch/ia64/vmx/vmx_init.c                                     |    2 
 xen/arch/ia64/vmx/vmx_interrupt.c                                |   11 
 xen/arch/ia64/vmx/vmx_ivt.S                                      |  816 
++++------
 xen/arch/ia64/vmx/vmx_process.c                                  |  226 --
 xen/arch/ia64/vmx/vtlb.c                                         |  680 
+++-----
 xen/arch/ia64/xen/dom_fw.c                                       |   63 
 xen/arch/ia64/xen/domain.c                                       |  133 +
 xen/arch/ia64/xen/efi_emul.c                                     |    8 
 xen/arch/ia64/xen/hypercall.c                                    |   99 +
 xen/arch/ia64/xen/hyperprivop.S                                  |    5 
 xen/arch/ia64/xen/irq.c                                          |   78 
 xen/arch/ia64/xen/privop.c                                       |    8 
 xen/arch/ia64/xen/process.c                                      |  160 +
 xen/arch/ia64/xen/vcpu.c                                         |   54 
 xen/arch/ia64/xen/xensetup.c                                     |    6 
 xen/arch/ia64/xen/xentime.c                                      |    6 
 xen/arch/x86/audit.c                                             |    4 
 xen/arch/x86/cpu/mtrr/main.c                                     |    2 
 xen/arch/x86/dom0_ops.c                                          |    2 
 xen/arch/x86/domain.c                                            |   20 
 xen/arch/x86/domain_build.c                                      |    6 
 xen/arch/x86/hvm/io.c                                            |   10 
 xen/arch/x86/hvm/platform.c                                      |   24 
 xen/arch/x86/hvm/svm/svm.c                                       |  240 ++
 xen/arch/x86/hvm/vmx/vmx.c                                       |   12 
 xen/arch/x86/i8259.c                                             |    2 
 xen/arch/x86/microcode.c                                         |    2 
 xen/arch/x86/mm.c                                                |  143 -
 xen/arch/x86/setup.c                                             |    2 
 xen/arch/x86/shadow.c                                            |   12 
 xen/arch/x86/shadow32.c                                          |   17 
 xen/arch/x86/shadow_public.c                                     |   14 
 xen/arch/x86/smp.c                                               |    2 
 xen/arch/x86/smpboot.c                                           |   17 
 xen/arch/x86/time.c                                              |    6 
 xen/arch/x86/traps.c                                             |   10 
 xen/arch/x86/x86_32/domain_page.c                                |    2 
 xen/arch/x86/x86_32/mm.c                                         |    3 
 xen/arch/x86/x86_64/mm.c                                         |    3 
 xen/arch/x86/x86_64/traps.c                                      |    2 
 xen/arch/x86/x86_emulate.c                                       |   15 
 xen/common/dom0_ops.c                                            |    2 
 xen/common/domain.c                                              |  134 +
 xen/common/page_alloc.c                                          |    4 
 xen/common/perfc.c                                               |    2 
 xen/common/sched_bvt.c                                           |   36 
 xen/common/sched_credit.c                                        |   30 
 xen/common/sched_sedf.c                                          |   39 
 xen/common/schedule.c                                            |  108 -
 xen/common/trace.c                                               |   12 
 xen/common/xmalloc.c                                             |    2 
 xen/drivers/char/console.c                                       |    6 
 xen/include/asm-ia64/dom_fw.h                                    |   19 
 xen/include/asm-ia64/domain.h                                    |   17 
 xen/include/asm-ia64/event.h                                     |    4 
 xen/include/asm-ia64/linux-xen/asm/pgtable.h                     |    4 
 xen/include/asm-ia64/linux-xen/linux/interrupt.h                 |    4 
 xen/include/asm-ia64/linux/asm/README.origin                     |    1 
 xen/include/asm-ia64/linux/asm/fpswa.h                           |   73 
 xen/include/asm-ia64/mm.h                                        |    3 
 xen/include/asm-ia64/shadow.h                                    |    6 
 xen/include/asm-ia64/vcpu.h                                      |    2 
 xen/include/asm-ia64/vmmu.h                                      |  170 --
 xen/include/asm-ia64/vmx_pal.h                                   |    1 
 xen/include/asm-ia64/vmx_vcpu.h                                  |    5 
 xen/include/asm-x86/page.h                                       |   11 
 xen/include/asm-x86/shadow.h                                     |   31 
 xen/include/public/arch-ia64.h                                   |    6 
 xen/include/public/arch-x86_32.h                                 |    8 
 xen/include/public/arch-x86_64.h                                 |    3 
 xen/include/xen/console.h                                        |    2 
 xen/include/xen/domain.h                                         |   23 
 xen/include/xen/perfc.h                                          |    6 
 xen/include/xen/sched-if.h                                       |   11 
 xen/include/xen/sched.h                                          |   12 
 xen/tools/Makefile                                               |    3 
 xen/tools/figlet/Makefile                                        |    3 
 173 files changed, 4006 insertions(+), 3045 deletions(-)

diff -r 29861ae27914 -r 91ee504ed40e .hgignore
--- a/.hgignore Tue May 30 15:24:31 2006 -0500
+++ b/.hgignore Fri Jun 02 12:31:48 2006 -0500
@@ -113,9 +113,9 @@
 ^tools/firmware/acpi/acpigen$
 ^tools/firmware/hvmloader/hvmloader$
 ^tools/firmware/hvmloader/roms\.h$
-^tools/firmware/rombios/BIOS-bochs-latest$
-^tools/firmware/rombios/_rombios_\.c$
-^tools/firmware/rombios/rombios\.s$
+^tools/firmware/rombios/BIOS-bochs-[^/]*$
+^tools/firmware/rombios/_rombios[^/]*_\.c$
+^tools/firmware/rombios/rombios[^/]*\.s$
 ^tools/firmware/vmxassist/acpi\.h$
 ^tools/firmware/vmxassist/gen$
 ^tools/firmware/vmxassist/offsets\.h$
diff -r 29861ae27914 -r 91ee504ed40e Config.mk
--- a/Config.mk Tue May 30 15:24:31 2006 -0500
+++ b/Config.mk Fri Jun 02 12:31:48 2006 -0500
@@ -38,19 +38,7 @@ CFLAGS    += -g
 CFLAGS    += -g
 endif
 
-ifeq ($(XEN_TARGET_ARCH),x86_32)
-CFLAGS  += -m32 -march=i686
-endif
-
-ifeq ($(XEN_TARGET_ARCH),x86_64)
-CFLAGS  += -m64
-endif
-
-ifeq ($(XEN_TARGET_ARCH),x86_64)
-LIBDIR = lib64
-else
-LIBDIR = lib
-endif
+include $(XEN_ROOT)/config/$(XEN_TARGET_ARCH).mk
 
 ifneq ($(EXTRA_PREFIX),)
 EXTRA_INCLUDES += $(EXTRA_PREFIX)/include
diff -r 29861ae27914 -r 91ee504ed40e Makefile
--- a/Makefile  Tue May 30 15:24:31 2006 -0500
+++ b/Makefile  Fri Jun 02 12:31:48 2006 -0500
@@ -17,7 +17,7 @@ endif
 .PHONY: all
 all: dist
 
-XEN_ROOT=$(CURDIR)
+export XEN_ROOT=$(CURDIR)
 include Config.mk
 include buildconfigs/Rules.mk
 
diff -r 29861ae27914 -r 91ee504ed40e buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Tue May 30 15:24:31 2006 -0500
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Fri Jun 02 12:31:48 2006 -0500
@@ -1023,7 +1023,7 @@ CONFIG_SND_AC97_BUS=y
 CONFIG_SND_AC97_BUS=y
 CONFIG_SND_DUMMY=y
 CONFIG_SND_VIRMIDI=y
-CONFIG_SND_MTPAV=y
+# CONFIG_SND_MTPAV is not set
 CONFIG_SND_SERIAL_U16550=y
 CONFIG_SND_MPU401=y
 
diff -r 29861ae27914 -r 91ee504ed40e buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64     Tue May 30 15:24:31 2006 -0500
+++ b/buildconfigs/linux-defconfig_xen_ia64     Fri Jun 02 12:31:48 2006 -0500
@@ -1029,7 +1029,7 @@ CONFIG_SND_AC97_BUS=y
 CONFIG_SND_AC97_BUS=y
 CONFIG_SND_DUMMY=y
 CONFIG_SND_VIRMIDI=y
-CONFIG_SND_MTPAV=y
+# CONFIG_SND_MTPAV is not set
 CONFIG_SND_SERIAL_U16550=y
 CONFIG_SND_MPU401=y
 
diff -r 29861ae27914 -r 91ee504ed40e extras/mini-os/Makefile
--- a/extras/mini-os/Makefile   Tue May 30 15:24:31 2006 -0500
+++ b/extras/mini-os/Makefile   Fri Jun 02 12:31:48 2006 -0500
@@ -1,7 +1,8 @@ debug ?= y
 debug ?= y
 pae ?= n
 
-include $(CURDIR)/../../Config.mk
+XEN_ROOT = ../..
+include $(XEN_ROOT)/Config.mk
 
 # Set TARGET_ARCH
 override TARGET_ARCH     := $(XEN_TARGET_ARCH)
diff -r 29861ae27914 -r 91ee504ed40e extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h       Tue May 30 15:24:31 2006 -0500
+++ b/extras/mini-os/include/mm.h       Fri Jun 02 12:31:48 2006 -0500
@@ -53,7 +53,7 @@
 #define PADDR_BITS              32
 #define PADDR_MASK              (~0UL)
 
-#define UNMAPPED_PT_FRAMES        1
+#define NOT_L1_FRAMES           1
 #define PRIpte "08lx"
 typedef unsigned long pgentry_t;
 
@@ -71,7 +71,12 @@ typedef unsigned long pgentry_t;
 
 #define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
 
-#define UNMAPPED_PT_FRAMES        2
+/*
+ * If starting from virtual address greater than 0xc0000000,
+ * this value will be 2 to account for final mid-level page
+ * directory which is always mapped in at this location.
+ */
+#define NOT_L1_FRAMES           3
 #define PRIpte "016llx"
 typedef uint64_t pgentry_t;
 
@@ -94,20 +99,10 @@ typedef uint64_t pgentry_t;
 #define PADDR_MASK              ((1UL << PADDR_BITS)-1)
 #define VADDR_MASK              ((1UL << VADDR_BITS)-1)
 
-/* Get physical address of page mapped by pte (paddr_t). */
-#define l1e_get_paddr(x)           \
-    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l2e_get_paddr(x)           \
-    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l3e_get_paddr(x)           \
-    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l4e_get_paddr(x)           \
-    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-
 #define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
 #define L3_MASK  ((1UL << L4_PAGETABLE_SHIFT) - 1)
 
-#define UNMAPPED_PT_FRAMES        3
+#define NOT_L1_FRAMES           3
 #define PRIpte "016lx"
 typedef unsigned long pgentry_t;
 
diff -r 29861ae27914 -r 91ee504ed40e extras/mini-os/minios-x86_32.lds
--- a/extras/mini-os/minios-x86_32.lds  Tue May 30 15:24:31 2006 -0500
+++ b/extras/mini-os/minios-x86_32.lds  Fri Jun 02 12:31:48 2006 -0500
@@ -3,7 +3,7 @@ ENTRY(_start)
 ENTRY(_start)
 SECTIONS
 {
-  . = 0xC0000000;
+  . = 0x0;
   _text = .;                   /* Text and read-only data */
   .text : {
        *(.text)
diff -r 29861ae27914 -r 91ee504ed40e extras/mini-os/minios-x86_64.lds
--- a/extras/mini-os/minios-x86_64.lds  Tue May 30 15:24:31 2006 -0500
+++ b/extras/mini-os/minios-x86_64.lds  Fri Jun 02 12:31:48 2006 -0500
@@ -3,7 +3,7 @@ ENTRY(_start)
 ENTRY(_start)
 SECTIONS
 {
-  . = 0xFFFFFFFF80000000;
+  . = 0x0;
   _text = .;                   /* Text and read-only data */
   .text : {
        *(.text)
diff -r 29861ae27914 -r 91ee504ed40e extras/mini-os/mm.c
--- a/extras/mini-os/mm.c       Tue May 30 15:24:31 2006 -0500
+++ b/extras/mini-os/mm.c       Fri Jun 02 12:31:48 2006 -0500
@@ -375,7 +375,7 @@ void new_pt_frame(unsigned long *pt_pfn,
     struct mmuext_op pin_request;
     
     DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
-           "prev_l_mfn=%lx, offset=%lx\n", 
+           "prev_l_mfn=%lx, offset=%lx", 
            level, *pt_pfn, prev_l_mfn, offset);
 
     /* We need to clear the page, otherwise we might fail to map it
@@ -442,12 +442,64 @@ void new_pt_frame(unsigned long *pt_pfn,
     mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + 
sizeof(pgentry_t) * offset;
     mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
     if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0) 
-    {            
+    {
        printk("ERROR: mmu_update failed\n");
        do_exit();
     }
 
     *pt_pfn += 1;
+}
+
+/* Checks if a pagetable frame is needed (if weren't allocated by Xen) */
+static int need_pt_frame(unsigned long virt_address, int level)
+{
+    unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
+#if defined(__x86_64__)
+    unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
+#else
+    unsigned long hyp_virt_end = 0xffffffff;
+#endif
+
+    /* In general frames will _not_ be needed if they were already
+       allocated to map the hypervisor into our VA space */
+#if defined(__x86_64__)
+    if(level == L3_FRAME)
+    {
+        if(l4_table_offset(virt_address) >= 
+           l4_table_offset(hyp_virt_start) &&
+           l4_table_offset(virt_address) <= 
+           l4_table_offset(hyp_virt_end))
+            return 0;
+        return 1;
+    } else
+#endif
+
+#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
+    if(level == L2_FRAME)
+    {
+#if defined(__x86_64__)
+        if(l4_table_offset(virt_address) >= 
+           l4_table_offset(hyp_virt_start) &&
+           l4_table_offset(virt_address) <= 
+           l4_table_offset(hyp_virt_end))
+#endif
+            if(l3_table_offset(virt_address) >= 
+               l3_table_offset(hyp_virt_start) &&
+               l3_table_offset(virt_address) <= 
+               l3_table_offset(hyp_virt_end))
+                return 0;
+
+        return 1;
+    } else 
+#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */
+
+    /* Always need l1 frames */
+    if(level == L1_FRAME)
+        return 1;
+
+    printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n", 
+        level, hyp_virt_start, hyp_virt_end);
+    return -1;
 }
 
 void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
@@ -460,11 +512,21 @@ void build_pagetable(unsigned long *star
     unsigned long offset;
     int count = 0;
 
-    pfn_to_map = (start_info.nr_pt_frames - UNMAPPED_PT_FRAMES) * 
L1_PAGETABLE_ENTRIES;
+    pfn_to_map = (start_info.nr_pt_frames - NOT_L1_FRAMES) * 
L1_PAGETABLE_ENTRIES;
+
+    if (*max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START))
+    {
+        printk("WARNING: Mini-OS trying to use Xen virtual space. "
+               "Truncating memory from %dMB to ",
+               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned 
long)&_text)>>20);
+        *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
+        printk("%dMB\n",
+               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned 
long)&_text)>>20);
+    }
 
     start_address = (unsigned long)pfn_to_virt(pfn_to_map);
     end_address = (unsigned long)pfn_to_virt(*max_pfn);
-    
+
     /* We worked out the virtual memory range to map, now mapping loop */
     printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
 
@@ -477,8 +539,9 @@ void build_pagetable(unsigned long *star
         offset = l4_table_offset(start_address);
         /* Need new L3 pt frame */
         if(!(start_address & L3_MASK)) 
-            new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
-        
+            if(need_pt_frame(start_address, L3_FRAME)) 
+                new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
+
         page = tab[offset];
         mfn = pte_to_mfn(page);
         tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
@@ -486,8 +549,9 @@ void build_pagetable(unsigned long *star
 #if defined(__x86_64__) || defined(CONFIG_X86_PAE)
         offset = l3_table_offset(start_address);
         /* Need new L2 pt frame */
-        if(!(start_address & L2_MASK)) 
-            new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
+        if(!(start_address & L2_MASK))
+            if(need_pt_frame(start_address, L2_FRAME))
+                new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
 
         page = tab[offset];
         mfn = pte_to_mfn(page);
@@ -495,16 +559,16 @@ void build_pagetable(unsigned long *star
 #endif
         offset = l2_table_offset(start_address);        
         /* Need new L1 pt frame */
-        if(!(start_address & L1_MASK)) 
-            new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
-       
+        if(!(start_address & L1_MASK))
+            if(need_pt_frame(start_address, L1_FRAME)) 
+                new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
+
         page = tab[offset];
         mfn = pte_to_mfn(page);
         offset = l1_table_offset(start_address);
 
         mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + 
sizeof(pgentry_t) * offset;
-        mmu_updates[count].val = 
-            (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
+        mmu_updates[count].val = (pgentry_t)pfn_to_mfn(pfn_to_map++) << 
PAGE_SHIFT | L1_PROT;
         count++;
         if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
         {
diff -r 29861ae27914 -r 91ee504ed40e extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S   Tue May 30 15:24:31 2006 -0500
+++ b/extras/mini-os/x86_32.S   Fri Jun 02 12:31:48 2006 -0500
@@ -4,8 +4,8 @@
 .section __xen_guest
        .ascii  "GUEST_OS=Mini-OS"
        .ascii  ",XEN_VER=xen-3.0"
-       .ascii  ",VIRT_BASE=0xc0000000" /* &_text from minios_x86_32.lds */
-       .ascii  ",ELF_PADDR_OFFSET=0xc0000000"
+       .ascii  ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
+       .ascii  ",ELF_PADDR_OFFSET=0x0"
        .ascii  ",HYPERCALL_PAGE=0x2"
 #ifdef CONFIG_X86_PAE
        .ascii  ",PAE=yes"
diff -r 29861ae27914 -r 91ee504ed40e extras/mini-os/x86_64.S
--- a/extras/mini-os/x86_64.S   Tue May 30 15:24:31 2006 -0500
+++ b/extras/mini-os/x86_64.S   Fri Jun 02 12:31:48 2006 -0500
@@ -4,8 +4,8 @@
 .section __xen_guest
        .ascii  "GUEST_OS=Mini-OS"
        .ascii  ",XEN_VER=xen-3.0"
-       .ascii  ",VIRT_BASE=0xffffffff80000000" /* &_text from 
minios_x86_64.lds */
-       .ascii  ",ELF_PADDR_OFFSET=0xffffffff80000000"
+       .ascii  ",VIRT_BASE=0x0" /* &_text from minios_x86_64.lds */
+       .ascii  ",ELF_PADDR_OFFSET=0x0"
        .ascii  ",HYPERCALL_PAGE=0x2"
        .ascii  ",LOADER=generic"
        .byte   0
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S  Fri Jun 02 12:31:48 
2006 -0500
@@ -173,7 +173,7 @@ ENTRY(cpu_gdt_table)
        .ascii           "|pae_pgdir_above_4gb"
        .ascii           "|supervisor_mode_kernel"
 #ifdef CONFIG_X86_PAE
-       .ascii  ",PAE=yes"
+       .ascii  ",PAE=yes[extended-cr3]"
 #else
        .ascii  ",PAE=no"
 #endif
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c       Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c       Fri Jun 02 
12:31:48 2006 -0500
@@ -55,6 +55,7 @@
 
 #include <xen/interface/physdev.h>
 #include <xen/interface/vcpu.h>
+#include <xen/cpu_hotplug.h>
 
 #include <linux/err.h>
 
@@ -101,8 +102,6 @@ EXPORT_SYMBOL(enable_hlt);
 EXPORT_SYMBOL(enable_hlt);
 
 /* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-extern void stop_hz_timer(void);
-extern void start_hz_timer(void);
 void xen_idle(void)
 {
        local_irq_disable();
@@ -112,10 +111,7 @@ void xen_idle(void)
        else {
                clear_thread_flag(TIF_POLLING_NRFLAG);
                smp_mb__after_clear_bit();
-               stop_hz_timer();
-               /* Blocking includes an implicit local_irq_enable(). */
-               HYPERVISOR_block();
-               start_hz_timer();
+               safe_halt();
                set_thread_flag(TIF_POLLING_NRFLAG);
        }
 }
@@ -132,11 +128,7 @@ static inline void play_dead(void)
        cpu_clear(smp_processor_id(), cpu_initialized);
        preempt_enable_no_resched();
        HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
-       /* Same as drivers/xen/core/smpboot.c:cpu_bringup(). */
-       cpu_init();
-       touch_softlockup_watchdog();
-       preempt_disable();
-       local_irq_enable();
+       cpu_bringup();
 }
 #else
 static inline void play_dead(void)
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Fri Jun 02 12:31:48 
2006 -0500
@@ -973,7 +973,7 @@ EXPORT_SYMBOL(jiffies_to_st);
  * stop_hz_timer / start_hz_timer - enter/exit 'tickless mode' on an idle cpu
  * These functions are based on implementations from arch/s390/kernel/time.c
  */
-void stop_hz_timer(void)
+static void stop_hz_timer(void)
 {
        unsigned int cpu = smp_processor_id();
        unsigned long j;
@@ -993,10 +993,26 @@ void stop_hz_timer(void)
        BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
 }
 
-void start_hz_timer(void)
+static void start_hz_timer(void)
 {
        cpu_clear(smp_processor_id(), nohz_cpu_mask);
 }
+
+void safe_halt(void)
+{
+       stop_hz_timer();
+       /* Blocking includes an implicit local_irq_enable(). */
+       HYPERVISOR_block();
+       start_hz_timer();
+}
+EXPORT_SYMBOL(safe_halt);
+
+void halt(void)
+{
+       if (irqs_disabled())
+               HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
+}
+EXPORT_SYMBOL(halt);
 
 /* No locking required. We are only CPU running, and interrupts are off. */
 void time_resume(void)
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/i386/kernel/vm86.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c      Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c      Fri Jun 02 12:31:48 
2006 -0500
@@ -132,7 +132,9 @@ struct pt_regs * fastcall save_v86_state
        current->thread.sysenter_cs = __KERNEL_CS;
        load_esp0(tss, &current->thread);
        current->thread.saved_esp0 = 0;
+#ifndef CONFIG_X86_NO_TSS
        put_cpu();
+#endif
 
        loadsegment(fs, current->thread.saved_fs);
        loadsegment(gs, current->thread.saved_gs);
@@ -310,7 +312,9 @@ static void do_sys_vm86(struct kernel_vm
        if (cpu_has_sep)
                tsk->thread.sysenter_cs = 0;
        load_esp0(tss, &tsk->thread);
+#ifndef CONFIG_X86_NO_TSS
        put_cpu();
+#endif
 
        tsk->thread.screen_bitmap = info->screen_bitmap;
        if (info->flags & VM86_SCREEN_BITMAP)
diff -r 29861ae27914 -r 91ee504ed40e linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Tue May 30 15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Fri Jun 02 12:31:48 2006 -0500
@@ -73,7 +73,7 @@ config XEN_IA64_DOM0_VP
 
 config XEN_IA64_DOM0_NON_VP
        bool
-       depends on !(XEN && XEN_IA64_DOM0_VP)
+       depends on XEN && !XEN_IA64_DOM0_VP
        default y
        help
          dom0 P=M model
@@ -496,15 +496,39 @@ source "security/Kconfig"
 
 source "crypto/Kconfig"
 
+#
 # override default values of drivers/xen/Kconfig
-if !XEN_IA64_DOM0_VP
+#
+if XEN
+config XEN_UTIL
+       default n if XEN_IA64_DOM0_VP
+
 config HAVE_ARCH_ALLOC_SKB
-        bool
-        default n
+       default n if !XEN_IA64_DOM0_VP
 
 config HAVE_ARCH_DEV_ALLOC_SKB
-        bool
-        default n
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_BALLOON
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_SKBUFF
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_NETDEV_BACKEND
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_NETDEV_FRONTEND
+       default n if !XEN_IA64_DOM0_VP
+
+config XEN_DEVMEM
+       default n
+
+config XEN_REBOOT
+       default n
+
+config XEN_SMPBOOT
+       default n
 endif
 
 source "drivers/xen/Kconfig"
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c   Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c   Fri Jun 02 12:31:48 
2006 -0500
@@ -171,7 +171,7 @@ static inline void xen_iosapic_write(cha
 
 static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int 
reg)
 {
-       if (!running_on_xen) {
+       if (!is_running_on_xen()) {
                writel(reg, iosapic + IOSAPIC_REG_SELECT);
                return readl(iosapic + IOSAPIC_WINDOW);
        } else
@@ -180,7 +180,7 @@ static inline unsigned int iosapic_read(
 
 static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32 
val)
 {
-       if (!running_on_xen) {
+       if (!is_running_on_xen()) {
                writel(reg, iosapic + IOSAPIC_REG_SELECT);
                writel(val, iosapic + IOSAPIC_WINDOW);
        } else
@@ -669,6 +669,11 @@ register_intr (unsigned int gsi, int vec
        iosapic_intr_info[vector].polarity = polarity;
        iosapic_intr_info[vector].dmode    = delivery;
        iosapic_intr_info[vector].trigger  = trigger;
+
+#ifdef CONFIG_XEN
+       if (is_running_on_xen())
+               return 0;
+#endif
 
        if (trigger == IOSAPIC_EDGE)
                irq_type = &irq_type_iosapic_edge;
@@ -1013,7 +1018,7 @@ iosapic_system_init (int system_pcat_com
 
        pcat_compat = system_pcat_compat;
 #ifdef CONFIG_XEN
-       if (running_on_xen)
+       if (is_running_on_xen())
                return;
 #endif
        if (pcat_compat) {
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c  Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/irq_ia64.c  Fri Jun 02 12:31:48 
2006 -0500
@@ -68,7 +68,7 @@ assign_irq_vector (int irq)
        int pos, vector;
 #ifdef CONFIG_XEN
        extern int xen_assign_irq_vector(int);
-       if (running_on_xen)
+       if (is_running_on_xen())
                return xen_assign_irq_vector(irq);
 #endif /* CONFIG_XEN */
  again:
@@ -229,6 +229,151 @@ static struct irqaction ipi_irqaction = 
 };
 #endif
 
+#ifdef CONFIG_XEN
+#include <xen/evtchn.h>
+#include <xen/interface/callback.h>
+
+static char timer_name[NR_CPUS][15];
+static char ipi_name[NR_CPUS][15];
+static char resched_name[NR_CPUS][15];
+
+struct saved_irq {
+       unsigned int irq;
+       struct irqaction *action;
+};
+/* 16 should be far optimistic value, since only several percpu irqs
+ * are registered early.
+ */
+#define MAX_LATE_IRQ   16
+static struct saved_irq saved_percpu_irqs[MAX_LATE_IRQ];
+static unsigned short late_irq_cnt = 0;
+static unsigned short saved_irq_cnt = 0;
+static int xen_slab_ready = 0;
+
+/* Dummy stub. Though we may check RESCHEDULE_VECTOR before __do_IRQ,
+ * it ends up to issue several memory accesses upon percpu data and
+ * thus adds unnecessary traffic to other paths.
+ */
+static irqreturn_t
+handle_reschedule(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction resched_irqaction = {
+       .handler =      handle_reschedule,
+       .flags =        SA_INTERRUPT,
+       .name =         "RESCHED"
+};
+
+/*
+ * This is xen version percpu irq registration, which needs bind
+ * to xen specific evtchn sub-system. One trick here is that xen
+ * evtchn binding interface depends on kmalloc because related
+ * port needs to be freed at device/cpu down. So we cache the
+ * registration on BSP before slab is ready and then deal them
+ * at later point. For rest instances happening after slab ready,
+ * we hook them to xen evtchn immediately.
+ *
+ * FIXME: MCA is not supported by far, and thus "nomca" boot param is
+ * required.
+ */
+void
+xen_register_percpu_irq (unsigned int irq, struct irqaction *action, int save)
+{
+       char name[15];
+       unsigned int cpu = smp_processor_id();
+       int ret = 0;
+
+       if (xen_slab_ready) {
+               switch (irq) {
+               case IA64_TIMER_VECTOR:
+                       sprintf(timer_name[cpu], "%s%d", action->name, cpu);
+                       ret = bind_virq_to_irqhandler(VIRQ_ITC, cpu,
+                               action->handler, action->flags,
+                               timer_name[cpu], action->dev_id);
+                       printk(KERN_INFO "register VIRQ_ITC (%s) to xen irq 
(%d)\n", name, ret);
+                       break;
+               case IA64_IPI_RESCHEDULE:
+                       sprintf(resched_name[cpu], "%s%d", action->name, cpu);
+                       ret = bind_ipi_to_irqhandler(RESCHEDULE_VECTOR, cpu,
+                               action->handler, action->flags,
+                               resched_name[cpu], action->dev_id);
+                       printk(KERN_INFO "register RESCHEDULE_VECTOR (%s) to 
xen irq (%d)\n", name, ret);
+                       break;
+               case IA64_IPI_VECTOR:
+                       sprintf(ipi_name[cpu], "%s%d", action->name, cpu);
+                       ret = bind_ipi_to_irqhandler(IPI_VECTOR, cpu,
+                               action->handler, action->flags,
+                               ipi_name[cpu], action->dev_id);
+                       printk(KERN_INFO "register IPI_VECTOR (%s) to xen irq 
(%d)\n", name, ret);
+                       break;
+               default:
+                       printk(KERN_WARNING "Percpu irq %d is unsupported by 
xen!\n", irq);
+                       break;
+               }
+               BUG_ON(ret < 0);
+       } 
+
+       /* For BSP, we cache registered percpu irqs, and then re-walk
+        * them when initializing APs
+        */
+       if (!cpu && save) {
+               BUG_ON(saved_irq_cnt == MAX_LATE_IRQ);
+               saved_percpu_irqs[saved_irq_cnt].irq = irq;
+               saved_percpu_irqs[saved_irq_cnt].action = action;
+               saved_irq_cnt++;
+               if (!xen_slab_ready)
+                       late_irq_cnt++;
+       }
+}
+
+static void
+xen_bind_early_percpu_irq (void)
+{
+       int i;
+
+       xen_slab_ready = 1;
+       /* There's no race when accessing this cached array, since only
+        * BSP will face with such step shortly
+        */
+       for (i = 0; i < late_irq_cnt; i++)
+               xen_register_percpu_irq(saved_percpu_irqs[i].irq,
+                       saved_percpu_irqs[i].action, 0);
+}
+
+/* FIXME: There's no obvious point to check whether slab is ready. So
+ * a hack is used here by utilizing a late time hook.
+ */
+extern void (*late_time_init)(void);
+extern char xen_event_callback;
+extern void xen_init_IRQ(void);
+
+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
+void xen_smp_intr_init(void)
+{
+#ifdef CONFIG_SMP
+       unsigned int cpu = smp_processor_id();
+       unsigned int i = 0;
+       struct callback_register event = {
+               .type = CALLBACKTYPE_event,
+               .address = (unsigned long)&xen_event_callback,
+       };
+
+       if (!cpu)
+               return;
+
+       /* This should be piggyback when setup vcpu guest context */
+       BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
+
+       for (i = 0; i < saved_irq_cnt; i++)
+               xen_register_percpu_irq(saved_percpu_irqs[i].irq,
+                       saved_percpu_irqs[i].action, 0);
+#endif /* CONFIG_SMP */
+}
+#endif /* CONFIG_XEN */
+
 void
 register_percpu_irq (ia64_vector vec, struct irqaction *action)
 {
@@ -237,6 +382,10 @@ register_percpu_irq (ia64_vector vec, st
 
        for (irq = 0; irq < NR_IRQS; ++irq)
                if (irq_to_vector(irq) == vec) {
+#ifdef CONFIG_XEN
+                       if (is_running_on_xen())
+                               return xen_register_percpu_irq(vec, action, 1);
+#endif
                        desc = irq_descp(irq);
                        desc->status |= IRQ_PER_CPU;
                        desc->handler = &irq_type_ia64_lsapic;
@@ -248,6 +397,21 @@ void __init
 void __init
 init_IRQ (void)
 {
+#ifdef CONFIG_XEN
+       /* Maybe put into platform_irq_init later */
+       if (is_running_on_xen()) {
+               struct callback_register event = {
+                       .type = CALLBACKTYPE_event,
+                       .address = (unsigned long)&xen_event_callback,
+               };
+               xen_init_IRQ();
+               BUG_ON(HYPERVISOR_callback_op(CALLBACKOP_register, &event));
+               late_time_init = xen_bind_early_percpu_irq;
+#ifdef CONFIG_SMP
+               register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
+#endif /* CONFIG_SMP */
+       }
+#endif /* CONFIG_XEN */
        register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
 #ifdef CONFIG_SMP
        register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
@@ -266,10 +430,33 @@ ia64_send_ipi (int cpu, int vector, int 
        unsigned long phys_cpu_id;
 
 #ifdef CONFIG_XEN
-        if (running_on_xen) {
-                extern void xen_send_ipi (int cpu, int vec);
-                xen_send_ipi (cpu, vector);
-                return;
+        if (is_running_on_xen()) {
+               int irq = -1;
+
+               /* TODO: we need to call vcpu_up here */
+               if (unlikely(vector == ap_wakeup_vector)) {
+                       extern void xen_send_ipi (int cpu, int vec);
+                       xen_send_ipi (cpu, vector);
+                       //vcpu_prepare_and_up(cpu);
+                       return;
+               }
+
+               switch(vector) {
+               case IA64_IPI_VECTOR:
+                       irq = per_cpu(ipi_to_irq, cpu)[IPI_VECTOR];
+                       break;
+               case IA64_IPI_RESCHEDULE:
+                       irq = per_cpu(ipi_to_irq, cpu)[RESCHEDULE_VECTOR];
+                       break;
+               default:
+                       printk(KERN_WARNING"Unsupported IPI type 0x%x\n", 
vector);
+                       irq = 0;
+                       break;
+               }               
+       
+               BUG_ON(irq < 0);
+               notify_remote_via_irq(irq);
+               return;
         }
 #endif /* CONFIG_XEN */
 
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Fri Jun 02 12:31:48 
2006 -0500
@@ -248,7 +248,7 @@ reserve_memory (void)
        n++;
 
 #ifdef CONFIG_XEN
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                rsvd_region[n].start = (unsigned 
long)__va((HYPERVISOR_shared_info->arch.start_info_pfn << PAGE_SHIFT));
                rsvd_region[n].end   = rsvd_region[n].start + PAGE_SIZE;
                n++;
@@ -347,8 +347,14 @@ early_console_setup (char *cmdline)
        int earlycons = 0;
 
 #ifdef CONFIG_XEN
-       if (!early_xen_console_setup(cmdline))
+#ifndef CONFIG_IA64_HP_SIM
+       if (is_running_on_xen()) {
+               extern struct console hpsim_cons;
+               hpsim_cons.flags |= CON_BOOT;
+               register_console(&hpsim_cons);
                earlycons++;
+       }
+#endif
 #endif
 #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
        {
@@ -411,7 +417,7 @@ setup_arch (char **cmdline_p)
 {
        unw_init();
 #ifdef CONFIG_XEN
-       if (running_on_xen)
+       if (is_running_on_xen())
                setup_xen_features();
 #endif
 
@@ -512,7 +518,7 @@ setup_arch (char **cmdline_p)
 # endif
        }
 #ifdef CONFIG_XEN
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                extern shared_info_t *HYPERVISOR_shared_info;
                extern int xen_init (void);
 
@@ -923,6 +929,13 @@ cpu_init (void)
        /* size of physical stacked register partition plus 8 bytes: */
        __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
        platform_cpu_init();
+#ifdef CONFIG_XEN
+       /* Need to be moved into platform_cpu_init later */
+       if (is_running_on_xen()) {
+               extern void xen_smp_intr_init(void);
+               xen_smp_intr_init();
+       }
+#endif
        pm_idle = default_idle;
 }
 
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre
--- a/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre        Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre        Fri Jun 02 
12:31:48 2006 -0500
@@ -10,15 +10,8 @@
 #eventually asm-xsi-offsets needs to be part of hypervisor.h/hypercall.h
 ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/asm-ia64/xen/
 
-#ia64 drivers/xen isn't fully functional yet, workaround...
-#also ignore core/evtchn.c which uses a different irq mechanism than ia64
-#(warning: there be dragons here if these files diverge)
-ln -sf ../../arch/ia64/xen/drivers/Makefile drivers/xen/Makefile
-ln -sf ../../../arch/ia64/xen/drivers/coreMakefile drivers/xen/core/Makefile
-
 #not sure where these ia64-specific files will end up in the future
 ln -sf ../../../arch/ia64/xen/drivers/xenia64_init.c drivers/xen/core
-ln -sf ../../../arch/ia64/xen/drivers/evtchn_ia64.c drivers/xen/core
 
 #still a few x86-ism's in various drivers/xen files, patch them
 #cd drivers/xen
diff -r 29861ae27914 -r 91ee504ed40e linux-2.6-xen-sparse/arch/ia64/xen/Makefile
--- a/linux-2.6-xen-sparse/arch/ia64/xen/Makefile       Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/Makefile       Fri Jun 02 12:31:48 
2006 -0500
@@ -2,7 +2,7 @@
 # Makefile for Xen components
 #
 
-obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o 
xenconsole.o
+obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o
 
 obj-$(CONFIG_XEN_IA64_DOM0_VP) += hypervisor.o pci-dma-xen.o util.o
 pci-dma-xen-$(CONFIG_XEN_IA64_DOM0_VP) := ../../i386/kernel/pci-dma-xen.o
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c Fri Jun 02 
12:31:48 2006 -0500
@@ -33,7 +33,6 @@ int xen_init(void)
                s->arch.start_info_pfn, xen_start_info->nr_pages,
                xen_start_info->flags);
 
-       evtchn_init();
        initialized = 1;
        return 0;
 }
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Fri Jun 02 12:31:48 
2006 -0500
@@ -314,12 +314,6 @@ gnttab_map_grant_ref_pre(struct gnttab_m
        uint32_t flags;
 
        flags = uop->flags;
-       if (flags & GNTMAP_readonly) {
-#if 0
-               xprintd("GNTMAP_readonly is not supported yet\n");
-#endif
-               flags &= ~GNTMAP_readonly;
-       }
 
        if (flags & GNTMAP_host_map) {
                if (flags & GNTMAP_application_map) {
@@ -360,52 +354,179 @@ struct address_space xen_ia64_foreign_du
 
 ///////////////////////////////////////////////////////////////////////////
 // foreign mapping
+#include <linux/efi.h>
+#include <asm/meminit.h> // for IA64_GRANULE_SIZE, GRANULEROUND{UP,DOWN}()
+
+static unsigned long privcmd_resource_min = 0;
+// Xen/ia64 currently can handle pseudo physical address bits up to
+// (PAGE_SHIFT * 3)
+static unsigned long privcmd_resource_max = GRANULEROUNDDOWN((1UL << 
(PAGE_SHIFT * 3)) - 1);
+static unsigned long privcmd_resource_align = IA64_GRANULE_SIZE;
+
+static unsigned long
+md_end_addr(const efi_memory_desc_t *md)
+{
+       return md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+}
+
+#define XEN_IA64_PRIVCMD_LEAST_GAP_SIZE        (1024 * 1024 * 1024UL)
+static int
+xen_ia64_privcmd_check_size(unsigned long start, unsigned long end)
+{
+       return (start < end &&
+               (end - start) > XEN_IA64_PRIVCMD_LEAST_GAP_SIZE);
+}
+
+static int __init
+xen_ia64_privcmd_init(void)
+{
+       void *efi_map_start, *efi_map_end, *p;
+       u64 efi_desc_size;
+       efi_memory_desc_t *md;
+       unsigned long tmp_min;
+       unsigned long tmp_max;
+       unsigned long gap_size;
+       unsigned long prev_end;
+
+       if (!is_running_on_xen())
+               return -1;
+
+       efi_map_start = __va(ia64_boot_param->efi_memmap);
+       efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+       efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+       // at first check the used highest address
+       for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+               // nothing
+       }
+       md = p - efi_desc_size;
+       privcmd_resource_min = GRANULEROUNDUP(md_end_addr(md));
+       if (xen_ia64_privcmd_check_size(privcmd_resource_min,
+                                       privcmd_resource_max)) {
+               goto out;
+       }
+
+       // the used highest address is too large. try to find the largest gap.
+       tmp_min = privcmd_resource_max;
+       tmp_max = 0;
+       gap_size = 0;
+       prev_end = 0;
+       for (p = efi_map_start;
+            p < efi_map_end - efi_desc_size;
+            p += efi_desc_size) {
+               unsigned long end;
+               efi_memory_desc_t* next;
+               unsigned long next_start;
+
+               md = p;
+               end = md_end_addr(md);
+               if (end > privcmd_resource_max) {
+                       break;
+               }
+               if (end < prev_end) {
+                       // work around. 
+                       // Xen may pass incompletely sorted memory
+                       // descriptors like
+                       // [x, x + length]
+                       // [x, x]
+                       // this order should be reversed.
+                       continue;
+               }
+               next = p + efi_desc_size;
+               next_start = next->phys_addr;
+               if (next_start > privcmd_resource_max) {
+                       next_start = privcmd_resource_max;
+               }
+               if (end < next_start && gap_size < (next_start - end)) {
+                       tmp_min = end;
+                       tmp_max = next_start;
+                       gap_size = tmp_max - tmp_min;
+               }
+               prev_end = end;
+       }
+
+       privcmd_resource_min = GRANULEROUNDUP(tmp_min);
+       if (xen_ia64_privcmd_check_size(privcmd_resource_min, tmp_max)) {
+               privcmd_resource_max = tmp_max;
+               goto out;
+       }
+
+       privcmd_resource_min = tmp_min;
+       privcmd_resource_max = tmp_max;
+       if (!xen_ia64_privcmd_check_size(privcmd_resource_min,
+                                        privcmd_resource_max)) {
+               // Any large enough gap isn't found.
+               // go ahead anyway with the warning hoping that large region
+               // won't be requested.
+               printk(KERN_WARNING "xen privcmd: large enough region for 
privcmd mmap is not found.\n");
+       }
+
+out:
+       printk(KERN_INFO "xen privcmd uses pseudo physical addr range [0x%lx, 
0x%lx] (%ldMB)\n",
+              privcmd_resource_min, privcmd_resource_max, 
+              (privcmd_resource_max - privcmd_resource_min) >> 20);
+       BUG_ON(privcmd_resource_min >= privcmd_resource_max);
+       return 0;
+}
+late_initcall(xen_ia64_privcmd_init);
 
 struct xen_ia64_privcmd_entry {
        atomic_t        map_count;
-       struct page*    page;
+#define INVALID_GPFN   (~0UL)
+       unsigned long   gpfn;
+};
+
+struct xen_ia64_privcmd_range {
+       atomic_t                        ref_count;
+       unsigned long                   pgoff; // in PAGE_SIZE
+       struct resource*                res;
+
+       unsigned long                   num_entries;
+       struct xen_ia64_privcmd_entry   entries[0];
+};
+
+struct xen_ia64_privcmd_vma {
+       struct xen_ia64_privcmd_range*  range;
+
+       unsigned long                   num_entries;
+       struct xen_ia64_privcmd_entry*  entries;
 };
 
 static void
 xen_ia64_privcmd_init_entry(struct xen_ia64_privcmd_entry* entry)
 {
        atomic_set(&entry->map_count, 0);
-       entry->page = NULL;
-}
-
-//TODO alloc_page() to allocate pseudo physical address space is 
-//     waste of memory.
-//     When vti domain is created, qemu maps all of vti domain pages which 
-//     reaches to several hundred megabytes at least.
-//     remove alloc_page().
+       entry->gpfn = INVALID_GPFN;
+}
+
 static int
 xen_ia64_privcmd_entry_mmap(struct vm_area_struct* vma,
                            unsigned long addr,
-                           struct xen_ia64_privcmd_entry* entry,
+                           struct xen_ia64_privcmd_range* privcmd_range,
+                           int i,
                            unsigned long mfn,
                            pgprot_t prot,
                            domid_t domid)
 {
        int error = 0;
-       struct page* page;
+       struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
        unsigned long gpfn;
+       unsigned long flags;
 
        BUG_ON((addr & ~PAGE_MASK) != 0);
        BUG_ON(mfn == INVALID_MFN);
 
-       if (entry->page != NULL) {
+       if (entry->gpfn != INVALID_GPFN) {
                error = -EBUSY;
                goto out;
        }
-       page = alloc_page(GFP_KERNEL);
-       if (page == NULL) {
-               error = -ENOMEM;
-               goto out;
-       }
-       gpfn = page_to_pfn(page);
-
-       error = HYPERVISOR_add_physmap(gpfn, mfn, 0/* prot:XXX */,
-                                      domid);
+       gpfn = (privcmd_range->res->start >> PAGE_SHIFT) + i;
+
+       flags = ASSIGN_writable;
+       if (pgprot_val(prot) == PROT_READ) {
+               flags = ASSIGN_readonly;
+       }
+       error = HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
        if (error != 0) {
                goto out;
        }
@@ -413,15 +534,13 @@ xen_ia64_privcmd_entry_mmap(struct vm_ar
        prot = vma->vm_page_prot;
        error = remap_pfn_range(vma, addr, gpfn, 1 << PAGE_SHIFT, prot);
        if (error != 0) {
-               (void)HYPERVISOR_zap_physmap(gpfn, 0);
-               error = HYPERVISOR_populate_physmap(gpfn, 0, 0);
+               error = HYPERVISOR_zap_physmap(gpfn, 0);
                if (error) {
                        BUG();//XXX
                }
-               __free_page(page);
        } else {
                atomic_inc(&entry->map_count);
-               entry->page = page;
+               entry->gpfn = gpfn;
        }
 
 out:
@@ -429,30 +548,28 @@ out:
 }
 
 static void
-xen_ia64_privcmd_entry_munmap(struct xen_ia64_privcmd_entry* entry)
-{
-       struct page* page = entry->page;
-       unsigned long gpfn = page_to_pfn(page);
+xen_ia64_privcmd_entry_munmap(struct xen_ia64_privcmd_range* privcmd_range,
+                             int i)
+{
+       struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+       unsigned long gpfn = entry->gpfn;
+       //gpfn = (privcmd_range->res->start >> PAGE_SHIFT) +
+       //      (vma->vm_pgoff - privcmd_range->pgoff);
        int error;
 
        error = HYPERVISOR_zap_physmap(gpfn, 0);
        if (error) {
                BUG();//XXX
        }
-
-       error = HYPERVISOR_populate_physmap(gpfn, 0, 0);
-       if (error) {
-               BUG();//XXX
-       }
-
-       entry->page = NULL;
-       __free_page(page);
+       entry->gpfn = INVALID_GPFN;
 }
 
 static int
-xen_ia64_privcmd_entry_open(struct xen_ia64_privcmd_entry* entry)
-{
-       if (entry->page != NULL) {
+xen_ia64_privcmd_entry_open(struct xen_ia64_privcmd_range* privcmd_range,
+                           int i)
+{
+       struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+       if (entry->gpfn != INVALID_GPFN) {
                atomic_inc(&entry->map_count);
        } else {
                BUG_ON(atomic_read(&entry->map_count) != 0);
@@ -460,27 +577,15 @@ xen_ia64_privcmd_entry_open(struct xen_i
 }
 
 static int
-xen_ia64_privcmd_entry_close(struct xen_ia64_privcmd_entry* entry)
-{
-       if (entry->page != NULL && atomic_dec_and_test(&entry->map_count)) {
-               xen_ia64_privcmd_entry_munmap(entry);
-       }
-}
-
-struct xen_ia64_privcmd_range {
-       atomic_t                        ref_count;
-       unsigned long                   pgoff; // in PAGE_SIZE
-
-       unsigned long                   num_entries;
-       struct xen_ia64_privcmd_entry   entries[0];
-};
-
-struct xen_ia64_privcmd_vma {
-       struct xen_ia64_privcmd_range*  range;
-
-       unsigned long                   num_entries;
-       struct xen_ia64_privcmd_entry*  entries;
-};
+xen_ia64_privcmd_entry_close(struct xen_ia64_privcmd_range* privcmd_range,
+                            int i)
+{
+       struct xen_ia64_privcmd_entry* entry = &privcmd_range->entries[i];
+       if (entry->gpfn != INVALID_GPFN &&
+           atomic_dec_and_test(&entry->map_count)) {
+               xen_ia64_privcmd_entry_munmap(privcmd_range, i);
+       }
+}
 
 static void xen_ia64_privcmd_vma_open(struct vm_area_struct* vma);
 static void xen_ia64_privcmd_vma_close(struct vm_area_struct* vma);
@@ -507,7 +612,7 @@ __xen_ia64_privcmd_vma_open(struct vm_ar
        privcmd_vma->entries = &privcmd_range->entries[entry_offset];
        vma->vm_private_data = privcmd_vma;
        for (i = 0; i < privcmd_vma->num_entries; i++) {
-               xen_ia64_privcmd_entry_open(&privcmd_vma->entries[i]);
+               xen_ia64_privcmd_entry_open(privcmd_range, entry_offset + i);
        }
 
        vma->vm_private_data = privcmd_vma;
@@ -533,10 +638,11 @@ xen_ia64_privcmd_vma_close(struct vm_are
        struct xen_ia64_privcmd_vma* privcmd_vma =
                (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
        struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
+       unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
        unsigned long i;
 
        for (i = 0; i < privcmd_vma->num_entries; i++) {
-               xen_ia64_privcmd_entry_close(&privcmd_vma->entries[i]);
+               xen_ia64_privcmd_entry_close(privcmd_range, entry_offset + i);
        }
        vma->vm_private_data = NULL;
        kfree(privcmd_vma);
@@ -547,9 +653,11 @@ xen_ia64_privcmd_vma_close(struct vm_are
                        struct xen_ia64_privcmd_entry* entry =
                                &privcmd_range->entries[i];
                        BUG_ON(atomic_read(&entry->map_count) != 0);
-                       BUG_ON(entry->page != NULL);
+                       BUG_ON(entry->gpfn != INVALID_GPFN);
                }
 #endif
+               release_resource(privcmd_range->res);
+               kfree(privcmd_range->res);
                vfree(privcmd_range);
        }
 }
@@ -557,13 +665,18 @@ int
 int
 privcmd_mmap(struct file * file, struct vm_area_struct * vma)
 {
-       unsigned long num_entries = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-       struct xen_ia64_privcmd_range* privcmd_range;
-       struct xen_ia64_privcmd_vma* privcmd_vma;
+       int error;
+       unsigned long size = vma->vm_end - vma->vm_start;
+       unsigned long num_entries = size >> PAGE_SHIFT;
+       struct xen_ia64_privcmd_range* privcmd_range = NULL;
+       struct xen_ia64_privcmd_vma* privcmd_vma = NULL;
+       struct resource* res = NULL;
        unsigned long i;
-       BUG_ON(!running_on_xen);
+       BUG_ON(!is_running_on_xen());
 
        BUG_ON(file->private_data != NULL);
+
+       error = -ENOMEM;
        privcmd_range =
                vmalloc(sizeof(*privcmd_range) +
                        sizeof(privcmd_range->entries[0]) * num_entries);
@@ -574,6 +687,18 @@ privcmd_mmap(struct file * file, struct 
        if (privcmd_vma == NULL) {
                goto out_enomem1;
        }
+       res = kzalloc(sizeof(*res), GFP_KERNEL);
+       if (res == NULL) {
+               goto out_enomem1;
+       }
+       res->name = "Xen privcmd mmap";
+       error = allocate_resource(&iomem_resource, res, size,
+                                 privcmd_resource_min, privcmd_resource_max,
+                                 privcmd_resource_align, NULL, NULL);
+       if (error) {
+               goto out_enomem1;
+       }
+       privcmd_range->res = res;
 
        /* DONTCOPY is essential for Xen as copy_page_range is broken. */
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
@@ -589,10 +714,11 @@ privcmd_mmap(struct file * file, struct 
        return 0;
 
 out_enomem1:
+       kfree(res);
        kfree(privcmd_vma);
 out_enomem0:
        vfree(privcmd_range);
-       return -ENOMEM;
+       return error;
 }
 
 int
@@ -605,10 +731,13 @@ direct_remap_pfn_range(struct vm_area_st
 {
        struct xen_ia64_privcmd_vma* privcmd_vma =
                (struct xen_ia64_privcmd_vma*)vma->vm_private_data;
+       struct xen_ia64_privcmd_range* privcmd_range = privcmd_vma->range;
+       unsigned long entry_offset = vma->vm_pgoff - privcmd_range->pgoff;
+
        unsigned long i;
        unsigned long offset;
        int error = 0;
-       BUG_ON(!running_on_xen);
+       BUG_ON(!is_running_on_xen());
 
 #if 0
        if (prot != vm->vm_page_prot) {
@@ -618,9 +747,7 @@ direct_remap_pfn_range(struct vm_area_st
 
        i = (address - vma->vm_start) >> PAGE_SHIFT;
        for (offset = 0; offset < size; offset += PAGE_SIZE) {
-               struct xen_ia64_privcmd_entry* entry =
-                       &privcmd_vma->entries[i];
-               error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & 
PAGE_MASK, entry, mfn, prot, domid);
+               error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & 
PAGE_MASK, privcmd_range, entry_offset + i, mfn, prot, domid);
                if (error != 0) {
                        break;
                }
diff -r 29861ae27914 -r 91ee504ed40e linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S
--- a/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S       Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S       Fri Jun 02 12:31:48 
2006 -0500
@@ -206,9 +206,9 @@ ENTRY(vhpt_miss)
        mov r24=r8
        mov r8=r18
        ;;
-(p10)  XEN_HYPER_ITC_D
-       ;;
-(p11)  XEN_HYPER_ITC_I
+(p10)  XEN_HYPER_ITC_I
+       ;;
+(p11)  XEN_HYPER_ITC_D
        ;;
        mov r8=r24
        ;;
@@ -799,7 +799,16 @@ 1: ld8 r18=[r17]
        ;;
 (p6)   cmp.eq p6,p7=r26,r18                    // Only compare if page is 
present
        ;;
+#ifdef CONFIG_XEN
+(p6)   mov r18=r8
+(p6)   mov r8=r25
+       ;;
+(p6)   XEN_HYPER_ITC_D
+       ;;
+(p6)   mov r8=r18
+#else
 (p6)   itc.d r25                               // install updated PTE
+#endif 
        ;;
        /*
         * Tell the assemblers dependency-violation checker that the above 
"itc" instructions
@@ -2038,6 +2047,7 @@ GLOBAL_ENTRY(xen_bsw1)
        ld8 r28=[r30],16; ld8 r29=[r31],16;;
        ld8 r30=[r30]; ld8 r31=[r31];;
        br.ret.sptk.many b0
+END(xen_bsw1)
 #endif
 
        .org ia64_ivt+0x7f00
@@ -2130,5 +2140,32 @@ non_ia32_syscall:
        mov rp=r15
        br.ret.sptk.many rp
 END(dispatch_to_ia32_handler)
-
 #endif /* CONFIG_IA32_SUPPORT */
+
+#ifdef CONFIG_XEN
+       .section .text,"ax"
+GLOBAL_ENTRY(xen_event_callback)
+       mov r31=pr              // prepare to save predicates
+       ;;
+       SAVE_MIN_WITH_COVER     // uses r31; defines r2 and r3
+       ;;
+       movl r3=XSI_PSR_IC
+       mov r14=1
+       ;;
+       st4 [r3]=r14
+       ;;
+       adds r3=8,r2            // set up second base pointer for SAVE_REST
+       srlz.i                  // ensure everybody knows psr.ic is back on
+       ;;
+       SAVE_REST
+       ;;
+       alloc r14=ar.pfs,0,0,1,0 // must be first in an insn group
+       add out0=16,sp          // pass pointer to pt_regs as first arg
+       ;;
+       srlz.d                  // make sure we see the effect of cr.ivr
+       movl r14=ia64_leave_kernel
+       ;;
+       mov rp=r14
+       br.call.sptk.many b6=evtchn_do_upcall
+END(xen_event_callback)
+#endif
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c     Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c     Fri Jun 02 
12:31:48 2006 -0500
@@ -60,6 +60,8 @@
 #include <asm/ia32.h>
 #include <asm/idle.h>
 
+#include <xen/cpu_hotplug.h>
+
 asmlinkage extern void ret_from_fork(void);
 
 unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
@@ -118,8 +120,6 @@ void exit_idle(void)
 }
 
 /* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-extern void stop_hz_timer(void);
-extern void start_hz_timer(void);
 void xen_idle(void)
 {
        local_irq_disable();
@@ -129,10 +129,7 @@ void xen_idle(void)
        else {
                clear_thread_flag(TIF_POLLING_NRFLAG);
                smp_mb__after_clear_bit();
-               stop_hz_timer();
-               /* Blocking includes an implicit local_irq_enable(). */
-               HYPERVISOR_block();
-               start_hz_timer();
+               safe_halt();
                set_thread_flag(TIF_POLLING_NRFLAG);
        }
 }
@@ -145,11 +142,7 @@ static inline void play_dead(void)
        cpu_clear(smp_processor_id(), cpu_initialized);
        preempt_enable_no_resched();
        HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
-       /* Same as drivers/xen/core/smpboot.c:cpu_bringup(). */
-       cpu_init();
-       touch_softlockup_watchdog();
-       preempt_disable();
-       local_irq_enable();
+       cpu_bringup();
 }
 #else
 static inline void play_dead(void)
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c Fri Jun 02 12:31:48 
2006 -0500
@@ -488,7 +488,7 @@ static void smp_really_stop_cpu(void *du
 {
        smp_stop_cpu(); 
        for (;;) 
-               asm("hlt"); 
+               halt();
 } 
 
 void smp_send_stop(void)
diff -r 29861ae27914 -r 91ee504ed40e linux-2.6-xen-sparse/drivers/xen/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig  Tue May 30 15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig  Fri Jun 02 12:31:48 2006 -0500
@@ -228,4 +228,30 @@ config NO_IDLE_HZ
        bool
        default y
 
+config XEN_UTIL
+       bool
+       default y
+
+config XEN_BALLOON
+       bool
+       default y
+
+config XEN_DEVMEM
+       bool
+       default y
+
+config XEN_SKBUFF
+       bool
+       default y
+       depends on NET
+
+config XEN_REBOOT
+       bool
+       default y
+
+config XEN_SMPBOOT
+       bool
+       default y
+       depends on SMP
+
 endif
diff -r 29861ae27914 -r 91ee504ed40e linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Tue May 30 15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Fri Jun 02 12:31:48 2006 -0500
@@ -1,14 +1,12 @@
-
-obj-y  += util.o
-
 obj-y  += core/
-obj-y  += char/
 obj-y  += console/
 obj-y  += evtchn/
-obj-y  += balloon/
 obj-y  += privcmd/
 obj-y  += xenbus/
 
+obj-$(CONFIG_XEN_UTIL)                 += util.o
+obj-$(CONFIG_XEN_BALLOON)              += balloon/
+obj-$(CONFIG_XEN_DEVMEM)               += char/
 obj-$(CONFIG_XEN_BLKDEV_BACKEND)       += blkback/
 obj-$(CONFIG_XEN_NETDEV_BACKEND)       += netback/
 obj-$(CONFIG_XEN_TPMDEV_BACKEND)       += tpmback/
@@ -17,4 +15,3 @@ obj-$(CONFIG_XEN_BLKDEV_TAP)          += blkt
 obj-$(CONFIG_XEN_BLKDEV_TAP)           += blktap/
 obj-$(CONFIG_XEN_PCIDEV_BACKEND)       += pciback/
 obj-$(CONFIG_XEN_PCIDEV_FRONTEND)      += pcifront/
-
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Fri Jun 02 
12:31:48 2006 -0500
@@ -360,12 +360,6 @@ static void balloon_process(void *unused
 /* Resets the Xen limit, sets new target, and kicks off processing. */
 static void set_new_target(unsigned long target)
 {
-       unsigned long min_target;
-
-       /* Do not allow target to reduce below 2% of maximum memory size. */
-       min_target = max_pfn / 50;
-       target = max(target, min_target);
-
        /* No need for lock. Not read-modify-write updates. */
        hard_limit   = ~0UL;
        target_pages = target;
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Fri Jun 02 
12:31:48 2006 -0500
@@ -452,10 +452,6 @@ int blkif_ioctl(struct inode *inode, str
                      command, (long)argument, inode->i_rdev);
 
        switch (command) {
-       case HDIO_GETGEO:
-               /* return ENOSYS to use defaults */
-               return -ENOSYS;
-
        case CDROMMULTISESSION:
                DPRINTK("FIXME: support multisession CDs later\n");
                for (i = 0; i < sizeof(struct cdrom_multisession); i++)
@@ -469,6 +465,23 @@ int blkif_ioctl(struct inode *inode, str
                return -EINVAL; /* same return as native Linux */
        }
 
+       return 0;
+}
+
+
+int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
+{
+       /* We don't have real geometry info, but let's at least return
+          values consistent with the size of the device */
+       sector_t nsect = get_capacity(bd->bd_disk);
+       sector_t cylinders = nsect;
+
+       hg->heads = 0xff;
+       hg->sectors = 0x3f;
+       sector_div(cylinders, hg->heads * hg->sectors);
+       hg->cylinders = cylinders;
+       if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
+               hg->cylinders = 0xffff;
        return 0;
 }
 
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Fri Jun 02 12:31:48 
2006 -0500
@@ -140,6 +140,7 @@ extern int blkif_release(struct inode *i
 extern int blkif_release(struct inode *inode, struct file *filep);
 extern int blkif_ioctl(struct inode *inode, struct file *filep,
                        unsigned command, unsigned long argument);
+extern int blkif_getgeo(struct block_device *, struct hd_geometry *);
 extern int blkif_check(dev_t dev);
 extern int blkif_revalidate(dev_t dev);
 extern void do_blkif_request (request_queue_t *rq);
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c   Fri Jun 02 12:31:48 
2006 -0500
@@ -91,6 +91,7 @@ static struct block_device_operations xl
        .open = blkif_open,
        .release = blkif_release,
        .ioctl  = blkif_ioctl,
+       .getgeo = blkif_getgeo
 };
 
 DEFINE_SPINLOCK(blkif_io_lock);
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/drivers/xen/core/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile    Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile    Fri Jun 02 12:31:48 
2006 -0500
@@ -2,11 +2,13 @@
 # Makefile for the linux kernel.
 #
 
-obj-y   := evtchn.o reboot.o gnttab.o features.o
+obj-y := evtchn.o gnttab.o features.o
 
-obj-$(CONFIG_PROC_FS)     += xen_proc.o
-obj-$(CONFIG_NET)         += skbuff.o
-obj-$(CONFIG_SMP)         += smpboot.o
-obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
-obj-$(CONFIG_SYSFS)       += hypervisor_sysfs.o
-obj-$(CONFIG_XEN_SYSFS)   += xen_sysfs.o
+obj-$(CONFIG_PROC_FS)          += xen_proc.o
+obj-$(CONFIG_SYSFS)            += hypervisor_sysfs.o
+obj-$(CONFIG_HOTPLUG_CPU)      += cpu_hotplug.o
+obj-$(CONFIG_XEN_SYSFS)                += xen_sysfs.o
+obj-$(CONFIG_IA64)             += xenia64_init.o
+obj-$(CONFIG_XEN_SKBUFF)       += skbuff.o
+obj-$(CONFIG_XEN_REBOOT)       += reboot.o
+obj-$(CONFIG_XEN_SMPBOOT)      += smpboot.o
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/drivers/xen/core/smpboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c   Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c   Fri Jun 02 12:31:48 
2006 -0500
@@ -89,9 +89,8 @@ void __init prefill_possible_map(void)
 
        for (i = 0; i < NR_CPUS; i++) {
                rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
-               if (rc == -ENOENT)
-                       break;
-               cpu_set(i, cpu_possible_map);
+               if (rc >= 0)
+                       cpu_set(i, cpu_possible_map);
        }
 }
 
@@ -150,12 +149,17 @@ static void xen_smp_intr_exit(unsigned i
 }
 #endif
 
-static void cpu_bringup(void)
+void cpu_bringup(void)
 {
        cpu_init();
        touch_softlockup_watchdog();
        preempt_disable();
        local_irq_enable();
+}
+
+static void cpu_bringup_and_idle(void)
+{
+       cpu_bringup();
        cpu_idle();
 }
 
@@ -180,7 +184,7 @@ void cpu_initialize_context(unsigned int
        ctxt.user_regs.fs = 0;
        ctxt.user_regs.gs = 0;
        ctxt.user_regs.ss = __KERNEL_DS;
-       ctxt.user_regs.eip = (unsigned long)cpu_bringup;
+       ctxt.user_regs.eip = (unsigned long)cpu_bringup_and_idle;
        ctxt.user_regs.eflags = X86_EFLAGS_IF | 0x1000; /* IOPL_RING1 */
 
        memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
@@ -204,7 +208,7 @@ void cpu_initialize_context(unsigned int
        ctxt.failsafe_callback_cs  = __KERNEL_CS;
        ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
 
-       ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
+       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
 #else /* __x86_64__ */
        ctxt.user_regs.cs = __KERNEL_CS;
        ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs);
@@ -216,7 +220,7 @@ void cpu_initialize_context(unsigned int
        ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
        ctxt.syscall_callback_eip  = (unsigned long)system_call;
 
-       ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
+       ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt));
 
        ctxt.gs_base_kernel = (unsigned long)(cpu_pda(cpu));
 #endif
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Fri Jun 02 
12:31:48 2006 -0500
@@ -146,11 +146,13 @@ static void loopback_construct(struct ne
        dev->hard_start_xmit = loopback_start_xmit;
        dev->get_stats       = loopback_get_stats;
        dev->set_multicast_list = loopback_set_multicast_list;
+       dev->change_mtu      = NULL; /* allow arbitrary mtu */
 
        dev->tx_queue_len    = 0;
 
        dev->features        = (NETIF_F_HIGHDMA |
                                NETIF_F_LLTX |
+                               NETIF_F_SG |
                                NETIF_F_IP_CSUM);
 
        SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h  Tue May 
30 15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h  Fri Jun 
02 12:31:48 2006 -0500
@@ -128,8 +128,6 @@ dma_get_cache_alignment(void)
         * maximum possible, to be safe */
        return (1 << INTERNODE_CACHE_SHIFT);
 }
-#else
-extern int dma_get_cache_alignment(void);
 #endif
 
 #define dma_is_consistent(d)   (1)
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h    Tue May 
30 15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h    Fri Jun 
02 12:31:48 2006 -0500
@@ -260,6 +260,13 @@ HYPERVISOR_event_channel_op(
 }
 
 static inline int
+HYPERVISOR_acm_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
 HYPERVISOR_xen_version(
        int cmd, void *arg)
 {
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h       Tue May 
30 15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h       Fri Jun 
02 12:31:48 2006 -0500
@@ -116,10 +116,12 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t"
        __asm__ ( \
                "movl %%cr3,%0\n\t" \
                :"=r" (__dummy)); \
-       machine_to_phys(__dummy); \
+       __dummy = xen_cr3_to_pfn(__dummy); \
+       mfn_to_pfn(__dummy) << PAGE_SHIFT; \
 })
 #define write_cr3(x) ({                                                \
-       maddr_t __dummy = phys_to_machine(x);                   \
+       unsigned int __dummy = pfn_to_mfn((x) >> PAGE_SHIFT);   \
+       __dummy = xen_pfn_to_cr3(__dummy);                      \
        __asm__ __volatile__("movl %0,%%cr3": :"r" (__dummy));  \
 })
 
@@ -625,8 +627,8 @@ do {                                                        
                \
                preempt_enable_no_resched();                            \
 } while (0)
 
-#define safe_halt()            ((void)0)
-#define halt()                 ((void)0)
+void safe_halt(void);
+void halt(void);
 
 #define __save_and_cli(x)                                              \
 do {                                                                   \
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Fri Jun 02 12:31:48 
2006 -0500
@@ -247,6 +247,13 @@ HYPERVISOR_event_channel_op(
 }
 
 static inline int
+HYPERVISOR_acm_op(
+       unsigned int cmd, void *arg)
+{
+    return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
 HYPERVISOR_xen_version(
     int cmd, void *arg)
 {
@@ -313,9 +320,20 @@ HYPERVISOR_suspend(
        return rc;
 }
 
+static inline int
+HYPERVISOR_callback_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, callback_op, cmd, arg);
+}
+
 extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
 static inline void exit_idle(void) {}
-#define do_IRQ(irq, regs) __do_IRQ((irq), (regs))
+#define do_IRQ(irq, regs) ({                   \
+       irq_enter();                            \
+       __do_IRQ((irq), (regs));                \
+       irq_exit();                             \
+})
 
 #ifdef CONFIG_XEN_IA64_DOM0_VP
 #include <linux/err.h>
@@ -418,12 +436,14 @@ HYPERVISOR_ioremap(unsigned long ioaddr,
 HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
 {
        unsigned long ret = ioaddr;
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_ioremap(ioaddr, size);
-               if (unlikely(IS_ERR_VALUE(ret)))
+               if (unlikely(ret == -ENOSYS))
                        panic("hypercall %s failed with %ld. "
                              "Please check Xen and Linux config mismatch\n",
                              __func__, -ret);
+               else if (unlikely(IS_ERR_VALUE(ret)))
+                       ret = ioaddr;
        }
        return ret;
 }
@@ -439,7 +459,7 @@ HYPERVISOR_phystomach(unsigned long gpfn
 HYPERVISOR_phystomach(unsigned long gpfn)
 {
        unsigned long ret = gpfn;
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_phystomach(gpfn);
        }
        return ret;
@@ -456,7 +476,7 @@ HYPERVISOR_machtophys(unsigned long mfn)
 HYPERVISOR_machtophys(unsigned long mfn)
 {
        unsigned long ret = mfn;
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_machtophys(mfn);
        }
        return ret;
@@ -473,7 +493,7 @@ HYPERVISOR_zap_physmap(unsigned long gpf
 HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
 {
        unsigned long ret = 0;
-       if (running_on_xen) {
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_zap_physmap(gpfn, extent_order);
        }
        return ret;
@@ -481,7 +501,7 @@ HYPERVISOR_zap_physmap(unsigned long gpf
 
 static inline unsigned long
 __HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
-                        unsigned int flags, domid_t domid)
+                        unsigned long flags, domid_t domid)
 {
        return _hypercall_imm4(unsigned long, ia64_dom0vp_op,
                               IA64_DOM0VP_add_physmap, gpfn, mfn, flags,
@@ -490,11 +510,11 @@ __HYPERVISOR_add_physmap(unsigned long g
 
 static inline unsigned long
 HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
-                      unsigned int flags, domid_t domid)
+                      unsigned long flags, domid_t domid)
 {
        unsigned long ret = 0;
-       BUG_ON(!running_on_xen);//XXX
-       if (running_on_xen) {
+       BUG_ON(!is_running_on_xen());//XXX
+       if (is_running_on_xen()) {
                ret = __HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
        }
        return ret;
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Fri Jun 02 
12:31:48 2006 -0500
@@ -46,14 +46,12 @@
 #include <asm/hypercall.h>
 #include <asm/ptrace.h>
 #include <asm/page.h>
-#include <asm/xen/privop.h> // for running_on_xen
+#include <asm/xen/privop.h> // for is_running_on_xen()
 
 extern shared_info_t *HYPERVISOR_shared_info;
 extern start_info_t *xen_start_info;
 
 void force_evtchn_callback(void);
-
-#define is_running_on_xen() running_on_xen
 
 /* Turn jiffies into Xen system time. XXX Implement me. */
 #define jiffies_to_st(j)       0
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h        Tue May 30 
15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h        Fri Jun 02 
12:31:48 2006 -0500
@@ -43,6 +43,7 @@
 
 #ifndef __ASSEMBLY__
 extern int running_on_xen;
+#define is_running_on_xen() running_on_xen
 
 #define        XEN_HYPER_SSM_I         asm("break %0" : : "i" 
(HYPERPRIVOP_SSM_I))
 #define        XEN_HYPER_GET_IVR       asm("break %0" : : "i" 
(HYPERPRIVOP_GET_IVR))
@@ -122,7 +123,7 @@ extern void xen_set_eflag(unsigned long)
 
 #define xen_ia64_intrin_local_irq_restore(x)                           \
 {                                                                      \
-     if (running_on_xen) {                                             \
+     if (is_running_on_xen()) {                                                
\
        if ((x) & IA64_PSR_I) { xen_ssm_i(); }                          \
        else { xen_rsm_i(); }                                           \
     }                                                                  \
@@ -131,7 +132,7 @@ extern void xen_set_eflag(unsigned long)
 
 #define        xen_get_psr_i()                                                 
\
 (                                                                      \
-       (running_on_xen) ?                                              \
+       (is_running_on_xen()) ?                                         \
                (xen_get_virtual_psr_i() ? IA64_PSR_I : 0)              \
                : __ia64_get_psr_i()                                    \
 )
@@ -139,7 +140,7 @@ extern void xen_set_eflag(unsigned long)
 #define xen_ia64_ssm(mask)                                             \
 {                                                                      \
        if ((mask)==IA64_PSR_I) {                                       \
-               if (running_on_xen) { xen_ssm_i(); }                    \
+               if (is_running_on_xen()) { xen_ssm_i(); }                       
\
                else { __ia64_ssm(mask); }                              \
        }                                                               \
        else { __ia64_ssm(mask); }                                      \
@@ -148,7 +149,7 @@ extern void xen_set_eflag(unsigned long)
 #define xen_ia64_rsm(mask)                                             \
 {                                                                      \
        if ((mask)==IA64_PSR_I) {                                       \
-               if (running_on_xen) { xen_rsm_i(); }                    \
+               if (is_running_on_xen()) { xen_rsm_i(); }                       
\
                else { __ia64_rsm(mask); }                              \
        }                                                               \
        else { __ia64_rsm(mask); }                                      \
@@ -167,10 +168,11 @@ extern void xen_set_rr(unsigned long ind
 extern void xen_set_rr(unsigned long index, unsigned long val);
 extern unsigned long xen_get_rr(unsigned long index);
 extern void xen_set_kr(unsigned long index, unsigned long val);
-
-/* Note: It may look wrong to test for running_on_xen in each case.
+extern void xen_ptcga(unsigned long addr, unsigned long size);
+
+/* Note: It may look wrong to test for is_running_on_xen() in each case.
  * However regnum is always a constant so, as written, the compiler
- * eliminates the switch statement, whereas running_on_xen must be
+ * eliminates the switch statement, whereas is_running_on_xen() must be
  * tested dynamically. */
 #define xen_ia64_getreg(regnum)                                                
\
 ({                                                                     \
@@ -178,17 +180,17 @@ extern void xen_set_kr(unsigned long ind
                                                                        \
        switch(regnum) {                                                \
        case _IA64_REG_CR_IVR:                                          \
-               ia64_intri_res = (running_on_xen) ?                     \
+               ia64_intri_res = (is_running_on_xen()) ?                        
\
                        xen_get_ivr() :                                 \
                        __ia64_getreg(regnum);                          \
                break;                                                  \
        case _IA64_REG_CR_TPR:                                          \
-               ia64_intri_res = (running_on_xen) ?                     \
+               ia64_intri_res = (is_running_on_xen()) ?                        
\
                        xen_get_tpr() :                                 \
                        __ia64_getreg(regnum);                          \
                break;                                                  \
        case _IA64_REG_AR_EFLAG:                                        \
-               ia64_intri_res = (running_on_xen) ?                     \
+               ia64_intri_res = (is_running_on_xen()) ?                        
\
                        xen_get_eflag() :                               \
                        __ia64_getreg(regnum);                          \
                break;                                                  \
@@ -203,27 +205,27 @@ extern void xen_set_kr(unsigned long ind
 ({                                                                     \
        switch(regnum) {                                                \
        case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:                     \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_set_kr((regnum-_IA64_REG_AR_KR0), val) :    \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
        case _IA64_REG_CR_ITM:                                          \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_set_itm(val) :                              \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
        case _IA64_REG_CR_TPR:                                          \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_set_tpr(val) :                              \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
        case _IA64_REG_CR_EOI:                                          \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_eoi() :                                     \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
        case _IA64_REG_AR_EFLAG:                                        \
-               (running_on_xen) ?                                      \
+               (is_running_on_xen()) ?                                 \
                        xen_set_eflag(val) :                            \
                        __ia64_setreg(regnum,val);                      \
                break;                                                  \
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h  Tue May 
30 15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h  Fri Jun 
02 12:31:48 2006 -0500
@@ -258,6 +258,13 @@ HYPERVISOR_event_channel_op(
 }
 
 static inline int
+HYPERVISOR_acm_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, acm_op, cmd, arg);
+}
+
+static inline int
 HYPERVISOR_xen_version(
        int cmd, void *arg)
 {
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/system.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/system.h     Tue May 
30 15:24:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/system.h     Fri Jun 
02 12:31:48 2006 -0500
@@ -424,8 +424,8 @@ do {                                                        
                \
        preempt_enable_no_resched();                                    \
        ___x; })
 
-#define safe_halt()            ((void)0)
-#define halt()                 ((void)0)
+void safe_halt(void);
+void halt(void);
 
 void cpu_idle_wait(void);
 
diff -r 29861ae27914 -r 91ee504ed40e 
linux-2.6-xen-sparse/include/xen/cpu_hotplug.h
--- a/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h    Tue May 30 15:24:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/xen/cpu_hotplug.h    Fri Jun 02 12:31:48 
2006 -0500
@@ -17,6 +17,8 @@ void init_xenbus_allowed_cpumask(void);
 void init_xenbus_allowed_cpumask(void);
 int smp_suspend(void);
 void smp_resume(void);
+
+void cpu_bringup(void);
 
 #else /* !defined(CONFIG_HOTPLUG_CPU) */
 
diff -r 29861ae27914 -r 91ee504ed40e tools/Makefile
--- a/tools/Makefile    Tue May 30 15:24:31 2006 -0500
+++ b/tools/Makefile    Fri Jun 02 12:31:48 2006 -0500
@@ -1,39 +1,38 @@ XEN_ROOT = ../
 XEN_ROOT = ../
 include $(XEN_ROOT)/tools/Rules.mk
 
-SUBDIRS :=
-SUBDIRS += libxc
-SUBDIRS += xenstore
-SUBDIRS += misc
-SUBDIRS += examples
-SUBDIRS += xentrace
-SUBDIRS += xcutils
-SUBDIRS += firmware
-SUBDIRS += security
-SUBDIRS += console
-SUBDIRS += xenmon
-SUBDIRS += guest-headers
-ifeq ($(VTPM_TOOLS),y)
-SUBDIRS += vtpm_manager
-SUBDIRS += vtpm
-endif
-SUBDIRS += xenstat
+SUBDIRS-y :=
+SUBDIRS-y += libxc
+SUBDIRS-y += xenstore
+SUBDIRS-y += misc
+SUBDIRS-y += examples
+SUBDIRS-y += xentrace
+SUBDIRS-$(CONFIG_X86) += xcutils
+SUBDIRS-y += firmware
+SUBDIRS-y += security
+SUBDIRS-y += console
+SUBDIRS-y += xenmon
+SUBDIRS-y += guest-headers
+SUBDIRS-$(VTPM_TOOLS) += vtpm_manager
+SUBDIRS-$(VTPM_TOOLS) += vtpm
+SUBDIRS-y += xenstat
+
 # These don't cross-compile
 ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
-SUBDIRS += python
-SUBDIRS += pygrub
+SUBDIRS-y += python
+SUBDIRS-y += pygrub
 endif
 
 .PHONY: all
 all: check
-       @set -e; for subdir in $(SUBDIRS); do \
+       @set -e; for subdir in $(SUBDIRS-y); do \
                $(MAKE) -C $$subdir $@; \
        done
        $(MAKE) ioemu
 
 .PHONY: install
 install: check
-       @set -e; for subdir in $(SUBDIRS); do \
+       @set -e; for subdir in $(SUBDIRS-y); do \
                $(MAKE) -C $$subdir $@; \
        done
        $(MAKE) ioemuinstall
@@ -41,7 +40,7 @@ install: check
 
 .PHONY: clean
 clean: check_clean
-       @set -e; for subdir in $(SUBDIRS); do \
+       @set -e; for subdir in $(SUBDIRS-y); do \
                $(MAKE) -C $$subdir $@; \
        done
        $(MAKE) ioemuclean
@@ -55,10 +54,10 @@ check_clean:
        $(MAKE) -C check clean
 
 .PHONY: ioemu ioemuinstall ioemuclean
-ifndef XEN_NO_IOEMU
+ifdef CONFIG_IOEMU
 ioemu ioemuinstall ioemuclean:
        [ -f ioemu/config-host.h ] || \
-       (cd ioemu; ./configure --prefix=usr)
+       (cd ioemu; sh ./configure --prefix=usr)
        $(MAKE) -C ioemu $(patsubst ioemu%,%,$@)
 else
 ioemu ioemuinstall ioemuclean:
diff -r 29861ae27914 -r 91ee504ed40e tools/Rules.mk
--- a/tools/Rules.mk    Tue May 30 15:24:31 2006 -0500
+++ b/tools/Rules.mk    Fri Jun 02 12:31:48 2006 -0500
@@ -4,6 +4,8 @@ all:
 all:
 
 include $(XEN_ROOT)/Config.mk
+
+CONFIG_$(shell uname -s) := y
 
 XEN_XC             = $(XEN_ROOT)/tools/python/xen/lowlevel/xc
 XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
diff -r 29861ae27914 -r 91ee504ed40e tools/debugger/libxendebug/xendebug.c
--- a/tools/debugger/libxendebug/xendebug.c     Tue May 30 15:24:31 2006 -0500
+++ b/tools/debugger/libxendebug/xendebug.c     Fri Jun 02 12:31:48 2006 -0500
@@ -346,8 +346,9 @@ xendebug_memory_page (domain_context_p c
         ctxt->cr3_phys[vcpu] = vcpu_ctxt->ctrlreg[3];
         if ( ctxt->cr3_virt[vcpu] )
             munmap(ctxt->cr3_virt[vcpu], PAGE_SIZE);
-        ctxt->cr3_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid,
-                    PAGE_SIZE, PROT_READ, ctxt->cr3_phys[vcpu] >> PAGE_SHIFT);
+        ctxt->cr3_virt[vcpu] = xc_map_foreign_range(
+            xc_handle, ctxt->domid, PAGE_SIZE, PROT_READ,
+            xen_cr3_to_pfn(ctxt->cr3_phys[vcpu]));
         if ( ctxt->cr3_virt[vcpu] == NULL )
             return 0;
     } 
diff -r 29861ae27914 -r 91ee504ed40e tools/examples/network-bridge
--- a/tools/examples/network-bridge     Tue May 30 15:24:31 2006 -0500
+++ b/tools/examples/network-bridge     Fri Jun 02 12:31:48 2006 -0500
@@ -60,6 +60,7 @@ evalVariables "$@"
 evalVariables "$@"
 
 vifnum=${vifnum:-$(ip route list | awk '/^default / { print $NF }' | sed 
's/^[^0-9]*//')}
+vifnum=${vifnum:-0}
 bridge=${bridge:-xenbr${vifnum}}
 netdev=${netdev:-eth${vifnum}}
 antispoof=${antispoof:-no}
diff -r 29861ae27914 -r 91ee504ed40e tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Tue May 30 15:24:31 2006 -0500
+++ b/tools/firmware/hvmloader/Makefile Fri Jun 02 12:31:48 2006 -0500
@@ -51,12 +51,12 @@ hvmloader: roms.h hvmloader.c acpi_madt.
        $(OBJCOPY) hvmloader.tmp hvmloader
        rm -f hvmloader.tmp
 
-roms.h:        ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
-       ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
-       ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
-       ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> 
roms.h
-       ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
-       ./mkhex acpi ../acpi/acpi.bin >> roms.h
+roms.h:        ../rombios/BIOS-bochs-8-processors 
../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin 
../vmxassist/vmxassist.bin
+       sh ./mkhex rombios ../rombios/BIOS-bochs-8-processors > roms.h
+       sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
+       sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin 
>> roms.h
+       sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
+       sh ./mkhex acpi ../acpi/acpi.bin >> roms.h
 
 .PHONY: clean
 clean:
diff -r 29861ae27914 -r 91ee504ed40e tools/firmware/rombios/Makefile
--- a/tools/firmware/rombios/Makefile   Tue May 30 15:24:31 2006 -0500
+++ b/tools/firmware/rombios/Makefile   Fri Jun 02 12:31:48 2006 -0500
@@ -1,7 +1,7 @@ BIOS_BUILDS = BIOS-bochs-latest
-BIOS_BUILDS = BIOS-bochs-latest
+#BIOS_BUILDS = BIOS-bochs-latest
 #BIOS_BUILDS += BIOS-bochs-2-processors
 #BIOS_BUILDS += BIOS-bochs-4-processors
-#BIOS_BUILDS += BIOS-bochs-8-processors
+BIOS_BUILDS += BIOS-bochs-8-processors
 
 .PHONY: all
 all: bios
diff -r 29861ae27914 -r 91ee504ed40e tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c       Tue May 30 15:24:31 2006 -0500
+++ b/tools/ioemu/hw/cirrus_vga.c       Fri Jun 02 12:31:48 2006 -0500
@@ -2460,7 +2460,6 @@ static CPUWriteMemoryFunc *cirrus_linear
 };
 
 extern FILE *logfile;
-#if defined(__i386__) || defined (__x86_64__)
 static void * set_vram_mapping(unsigned long begin, unsigned long end)
 {
     unsigned long * extent_start = NULL;
@@ -2540,10 +2539,6 @@ static int unset_vram_mapping(unsigned l
     return 0;
 }
 
-#elif defined(__ia64__)
-static void * set_vram_mapping(unsigned long addr, unsigned long end) {}
-static int unset_vram_mapping(unsigned long addr, unsigned long end) {}
-#endif
 extern int vga_accelerate;
 
 /* Compute the memory access functions */
diff -r 29861ae27914 -r 91ee504ed40e tools/ioemu/hw/ne2000.c
--- a/tools/ioemu/hw/ne2000.c   Tue May 30 15:24:31 2006 -0500
+++ b/tools/ioemu/hw/ne2000.c   Fri Jun 02 12:31:48 2006 -0500
@@ -147,9 +147,33 @@ static void ne2000_reset(NE2000State *s)
     }
 }
 
+static int ne2000_buffer_full(NE2000State *s)
+{
+    int avail, index, boundary;
+
+    index = s->curpag << 8;
+    boundary = s->boundary << 8;
+    if (index <= boundary)
+        /* when index == boundary, we should assume the
+         * buffer is full instead of empty!
+         */
+        avail = boundary - index;
+    else
+        avail = (s->stop - s->start) - (index - boundary);
+
+    return (avail < (MAX_ETH_FRAME_SIZE + 4));
+}
+
 static void ne2000_update_irq(NE2000State *s)
 {
     int isr;
+
+    if (ne2000_buffer_full(s)) {
+        /* The freeing space is not enough, tell the ne2k driver
+         * to fetch these packets!
+         */
+        s->isr |= ENISR_RX;
+    }
     isr = s->isr & s->imr;
 #if defined(DEBUG_NE2000)
     printf("NE2000: Set IRQ line %d to %d (%02x %02x)\n",
@@ -168,19 +192,11 @@ static int ne2000_can_receive(void *opaq
 static int ne2000_can_receive(void *opaque)
 {
     NE2000State *s = opaque;
-    int avail, index, boundary;
     
     if (s->cmd & E8390_STOP)
         return 0;
-    index = s->curpag << 8;
-    boundary = s->boundary << 8;
-    if (index < boundary)
-        avail = boundary - index;
-    else
-        avail = (s->stop - s->start) - (index - boundary);
-    if (avail < (MAX_ETH_FRAME_SIZE + 4))
-        return 0;
-    return MAX_ETH_FRAME_SIZE;
+
+    return (ne2000_buffer_full(s) ? 0 : MAX_ETH_FRAME_SIZE);
 }
 
 #define MIN_BUF_SIZE 60
diff -r 29861ae27914 -r 91ee504ed40e tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Tue May 30 15:24:31 2006 -0500
+++ b/tools/ioemu/hw/pc.c       Fri Jun 02 12:31:48 2006 -0500
@@ -537,8 +537,11 @@ void pc_init(uint64_t ram_size, int vga_
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
             sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
-            if (i == SUMMA_PORT)
+            if (i == serial_summa_port) {
                summa_init(sp, serial_hds[i]);
+               fprintf(stderr, "Serial port %d (COM%d) initialized for 
Summagraphics\n",
+                       i, i+1);
+           }
         }
     }
 
diff -r 29861ae27914 -r 91ee504ed40e tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Tue May 30 15:24:31 2006 -0500
+++ b/tools/ioemu/hw/vga.c      Fri Jun 02 12:31:48 2006 -0500
@@ -1995,6 +1995,7 @@ void vga_common_init(VGAState *s, Displa
     s->get_resolution = vga_get_resolution;
     /* XXX: currently needed for display */
     vga_state = s;
+    vga_bios_init(s);
 }
 
 
@@ -2082,7 +2083,6 @@ int vga_initialize(PCIBus *bus, DisplayS
 #endif
     }
 
-    vga_bios_init(s);
     return 0;
 }
 
diff -r 29861ae27914 -r 91ee504ed40e tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue May 30 15:24:31 2006 -0500
+++ b/tools/ioemu/vl.c  Fri Jun 02 12:31:48 2006 -0500
@@ -146,6 +146,7 @@ int repeat_key = 1;
 int repeat_key = 1;
 TextConsole *vga_console;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+int serial_summa_port = -1;
 int xc_handle;
 time_t timeoffset = 0;
 
@@ -2498,7 +2499,7 @@ int set_mm_mapping(int xc_handle,
     xc_domain_getinfo(xc_handle, domid, 1, &info);
 
     if ( xc_domain_setmaxmem(xc_handle, domid,
-                             (info.nr_pages + nr_pages) * PAGE_SIZE/1024) != 0)
+                             info.max_memkb + nr_pages * PAGE_SIZE/1024) !=0)
     {
         fprintf(logfile, "set maxmem returned error %d\n", errno);
         return -1;
@@ -2588,8 +2589,8 @@ int main(int argc, char **argv)
     pstrcpy(monitor_device, sizeof(monitor_device), "vc");
 
     pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
-    pstrcpy(serial_devices[1], sizeof(serial_devices[1]), "null");
-    for(i = 2; i < MAX_SERIAL_PORTS; i++)
+    serial_summa_port = -1;
+    for(i = 1; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i][0] = '\0';
     serial_device_index = 0;
 
@@ -3173,6 +3174,20 @@ int main(int argc, char **argv)
     }
     monitor_init(monitor_hd, !nographic);
 
+    /* Find which port should be the Summagraphics port */
+    /* It's the first unspecified serial line. Note that COM1 is set */
+    /* by default, so the Summagraphics port would be COM2 or higher */
+
+    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+      if (serial_devices[i][0] != '\0')
+       continue;
+      serial_summa_port = i;
+      pstrcpy(serial_devices[serial_summa_port], sizeof(serial_devices[0]), 
"null");
+      break;
+    }
+
+    /* Now, open the ports */
+
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_devices[i][0] != '\0') {
             serial_hds[i] = qemu_chr_open(serial_devices[i]);
diff -r 29861ae27914 -r 91ee504ed40e tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue May 30 15:24:31 2006 -0500
+++ b/tools/ioemu/vl.h  Fri Jun 02 12:31:48 2006 -0500
@@ -238,9 +238,9 @@ void console_select(unsigned int index);
 /* serial ports */
 
 #define MAX_SERIAL_PORTS 4
-#define SUMMA_PORT     1
 
 extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+extern int serial_summa_port;
 
 /* network redirectors support */
 
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/Makefile
--- a/tools/libxc/Makefile      Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/Makefile      Fri Jun 02 12:31:48 2006 -0500
@@ -10,43 +10,30 @@ XEN_ROOT = ../..
 XEN_ROOT = ../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-SRCS       :=
-SRCS       += xc_bvtsched.c
-SRCS       += xc_core.c
-SRCS       += xc_domain.c
-SRCS       += xc_evtchn.c
-SRCS       += xc_misc.c
-SRCS       += xc_acm.c   
-SRCS       += xc_physdev.c
-SRCS       += xc_private.c
-SRCS       += xc_sedf.c
-SRCS       += xc_csched.c
-SRCS       += xc_tbuf.c
+CTRL_SRCS-y       :=
+CTRL_SRCS-y       += xc_bvtsched.c
+CTRL_SRCS-y       += xc_core.c
+CTRL_SRCS-y       += xc_domain.c
+CTRL_SRCS-y       += xc_evtchn.c
+CTRL_SRCS-y       += xc_misc.c
+CTRL_SRCS-y       += xc_acm.c   
+CTRL_SRCS-y       += xc_physdev.c
+CTRL_SRCS-y       += xc_private.c
+CTRL_SRCS-y       += xc_sedf.c
+CTRL_SRCS-y       += xc_csched.c
+CTRL_SRCS-y       += xc_tbuf.c
+CTRL_SRCS-$(CONFIG_X86) += xc_ptrace.c xc_ptrace_core.c xc_pagetab.c
+CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
 
-ifeq ($(patsubst x86%,x86,$(XEN_TARGET_ARCH)),x86)
-SRCS       += xc_ptrace.c
-SRCS       += xc_ptrace_core.c
-SRCS       += xc_pagetab.c
-endif
-
-SRCS_Linux += xc_linux.c
-
-SRCS       += $(SRCS_Linux)
-
-BUILD_SRCS :=
-#BUILD_SRCS += xc_linux_build.c
-BUILD_SRCS += xc_load_bin.c
-BUILD_SRCS += xc_load_elf.c
-#BUILD_SRCS += xg_private.c
-
-ifeq ($(XEN_TARGET_ARCH),ia64)
-BUILD_SRCS += xc_ia64_stubs.c
-else
-BUILD_SRCS += xc_load_aout9.c
-BUILD_SRCS += xc_linux_restore.c
-BUILD_SRCS += xc_linux_save.c
-BUILD_SRCS += xc_hvm_build.c
-endif
+GUEST_SRCS-y :=
+GUEST_SRCS-y += xc_linux_build.c
+GUEST_SRCS-y += xc_load_bin.c
+GUEST_SRCS-y += xc_load_elf.c
+GUEST_SRCS-y += xg_private.c
+GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c
+GUEST_SRCS-$(CONFIG_PLAN9) += xc_load_aout9.c
+GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
+GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
 
 CFLAGS   += -Werror
 CFLAGS   += -fno-strict-aliasing
@@ -61,11 +48,11 @@ LDFLAGS  += -L.
 LDFLAGS  += -L.
 DEPS     = .*.d
 
-LIB_OBJS := $(patsubst %.c,%.o,$(SRCS))
-PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS))
+CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y))
+CTRL_PIC_OBJS := $(patsubst %.c,%.opic,$(CTRL_SRCS-y))
 
-LIB_BUILD_OBJS := $(patsubst %.c,%.o,$(BUILD_SRCS))
-PIC_BUILD_OBJS := $(patsubst %.c,%.opic,$(BUILD_SRCS))
+GUEST_LIB_OBJS := $(patsubst %.c,%.o,$(GUEST_SRCS-y))
+GUEST_PIC_OBJS := $(patsubst %.c,%.opic,$(GUEST_SRCS-y))
 
 LIB := libxenctrl.a
 LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR)
@@ -125,7 +112,7 @@ rpm: build
 
 # libxenctrl
 
-libxenctrl.a: $(LIB_OBJS)
+libxenctrl.a: $(CTRL_LIB_OBJS)
        $(AR) rc $@ $^
 
 libxenctrl.so: libxenctrl.so.$(MAJOR)
@@ -133,12 +120,12 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(
 libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR)
        ln -sf $< $@
 
-libxenctrl.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
+libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
        $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenctrl.so.$(MAJOR) 
-shared -o $@ $^
 
 # libxenguest
 
-libxenguest.a: $(LIB_BUILD_OBJS)
+libxenguest.a: $(GUEST_LIB_OBJS)
        $(AR) rc $@ $^
 
 libxenguest.so: libxenguest.so.$(MAJOR)
@@ -146,7 +133,7 @@ libxenguest.so.$(MAJOR): libxenguest.so.
 libxenguest.so.$(MAJOR): libxenguest.so.$(MAJOR).$(MINOR)
        ln -sf $< $@
 
-libxenguest.so.$(MAJOR).$(MINOR): $(PIC_BUILD_OBJS) libxenctrl.so
-       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenguest.so.$(MAJOR) 
-shared -o $@ $^ -lxenctrl
+libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenguest.so.$(MAJOR) 
-shared -o $@ $^ -lz -lxenctrl
 
 -include $(DEPS)
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c     Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_core.c     Fri Jun 02 12:31:48 2006 -0500
@@ -1,6 +1,4 @@
 #include "xg_private.h"
-#define ELFSIZE 32
-#include "xc_elf.h"
 #include <stdlib.h>
 #include <unistd.h>
 
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_hvm_build.c        Fri Jun 02 12:31:48 2006 -0500
@@ -2,9 +2,9 @@
  * xc_hvm_build.c
  */
 
+#define ELFSIZE 32
 #include <stddef.h>
 #include "xg_private.h"
-#define ELFSIZE 32
 #include "xc_elf.h"
 #include <stdlib.h>
 #include <unistd.h>
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_linux_build.c      Fri Jun 02 12:31:48 2006 -0500
@@ -5,14 +5,6 @@
 #include "xg_private.h"
 #include "xc_private.h"
 #include <xenctrl.h>
-
-#if defined(__i386__)
-#define ELFSIZE 32
-#endif
-
-#if defined(__x86_64__) || defined(__ia64__)
-#define ELFSIZE 64
-#endif
 
 #include "xc_elf.h"
 #include "xc_aout9.h"
@@ -213,9 +205,9 @@ static int setup_pg_tables(int xc_handle
     alloc_pt(l2tab, vl2tab, pl2tab);
     vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
     if (shadow_mode_enabled)
-        ctxt->ctrlreg[3] = pl2tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl2tab >> PAGE_SHIFT);
     else
-        ctxt->ctrlreg[3] = l2tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT);
 
     for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
     {
@@ -276,9 +268,9 @@ static int setup_pg_tables_pae(int xc_ha
     alloc_pt(l3tab, vl3tab, pl3tab);
     vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
     if (shadow_mode_enabled)
-        ctxt->ctrlreg[3] = pl3tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl3tab >> PAGE_SHIFT);
     else
-        ctxt->ctrlreg[3] = l3tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT);
 
     for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
     {
@@ -369,9 +361,9 @@ static int setup_pg_tables_64(int xc_han
     alloc_pt(l4tab, vl4tab, pl4tab);
     vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
     if (shadow_mode_enabled)
-        ctxt->ctrlreg[3] = pl4tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl4tab >> PAGE_SHIFT);
     else
-        ctxt->ctrlreg[3] = l4tab;
+        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT);
 
     for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
     {
@@ -835,13 +827,13 @@ static int setup_guest(int xc_handle,
         if ( dsi.pae_kernel )
         {
             if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
-                           ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
+                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
                 goto error_out;
         }
         else
         {
             if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
-                           ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
+                           xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
                 goto error_out;
         }
     }
@@ -853,7 +845,7 @@ static int setup_guest(int xc_handle,
      * correct protection for the page
      */
     if ( pin_table(xc_handle, MMUEXT_PIN_L4_TABLE,
-                   ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
+                   xen_cr3_to_pfn(ctxt->ctrlreg[3]), dom) )
         goto error_out;
 #endif
 
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_linux_restore.c    Fri Jun 02 12:31:48 2006 -0500
@@ -536,7 +536,7 @@ int xc_linux_restore(int xc_handle, int 
     }
 
     /* Uncanonicalise the page table base pointer. */
-    pfn = ctxt.ctrlreg[3] >> PAGE_SHIFT;
+    pfn = xen_cr3_to_pfn(ctxt.ctrlreg[3]);
 
     if (pfn >= max_pfn) {
         ERR("PT base is bad: pfn=%lu max_pfn=%lu type=%08lx",
@@ -552,7 +552,7 @@ int xc_linux_restore(int xc_handle, int 
         goto out;
     }
 
-    ctxt.ctrlreg[3] = p2m[pfn] << PAGE_SHIFT;
+    ctxt.ctrlreg[3] = xen_pfn_to_cr3(p2m[pfn]);
 
     /* clear any pending events and the selector */
     memset(&(shared_info->evtchn_pending[0]), 0,
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_linux_save.c       Fri Jun 02 12:31:48 2006 -0500
@@ -1129,12 +1129,12 @@ int xc_linux_save(int xc_handle, int io_
     }
 
     /* Canonicalise the page table base pointer. */
-    if ( !MFN_IS_IN_PSEUDOPHYS_MAP(ctxt.ctrlreg[3] >> PAGE_SHIFT) ) {
+    if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn(ctxt.ctrlreg[3])) ) {
         ERR("PT base is not in range of pseudophys map");
         goto out;
     }
-    ctxt.ctrlreg[3] = mfn_to_pfn(ctxt.ctrlreg[3] >> PAGE_SHIFT) <<
-        PAGE_SHIFT;
+    ctxt.ctrlreg[3] = 
+        xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3])));
 
     if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) ||
         !write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_load_elf.c Fri Jun 02 12:31:48 2006 -0500
@@ -3,14 +3,6 @@
  */
 
 #include "xg_private.h"
-
-#if defined(__i386__)
-#define ELFSIZE 32
-#endif
-#if defined(__x86_64__) || defined(__ia64__) || defined(__powerpc64__)
-#define ELFSIZE 64
-#endif
-
 #include "xc_elf.h"
 #include <stdlib.h>
 #include <endian.h>
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_pagetab.c
--- a/tools/libxc/xc_pagetab.c  Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_pagetab.c  Fri Jun 02 12:31:48 2006 -0500
@@ -78,7 +78,7 @@ unsigned long xc_translate_foreign_addre
         fprintf(stderr, "failed to retreive vcpu context\n");
         goto out;
     }
-    cr3 = ctx.ctrlreg[3];
+    cr3 = ((unsigned long long)xen_cr3_to_pfn(ctx.ctrlreg[3])) << PAGE_SHIFT;
 
     /* Page Map Level 4 */
 
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_ptrace.c   Fri Jun 02 12:31:48 2006 -0500
@@ -190,7 +190,8 @@ map_domain_va_32(
     static void *v[MAX_VIRT_CPUS];
 
     l2 = xc_map_foreign_range(
-         xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
+         xc_handle, current_domid, PAGE_SIZE, PROT_READ,
+         xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3]));
     if ( l2 == NULL )
         return NULL;
 
@@ -230,7 +231,8 @@ map_domain_va_pae(
     static void *v[MAX_VIRT_CPUS];
 
     l3 = xc_map_foreign_range(
-        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
+        xc_handle, current_domid, PAGE_SIZE, PROT_READ,
+        xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3]));
     if ( l3 == NULL )
         return NULL;
 
@@ -282,8 +284,9 @@ map_domain_va_64(
     if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
         return map_domain_va_32(xc_handle, cpu, guest_va, perm);
 
-    l4 = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE,
-            PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
+    l4 = xc_map_foreign_range(
+        xc_handle, current_domid, PAGE_SIZE, PROT_READ,
+        xen_cr3_to_pfn(ctxt[cpu].ctrlreg[3]));
     if ( l4 == NULL )
         return NULL;
 
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xc_ptrace_core.c
--- a/tools/libxc/xc_ptrace_core.c      Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xc_ptrace_core.c      Fri Jun 02 12:31:48 2006 -0500
@@ -12,8 +12,8 @@ static long   nr_pages = 0;
 static long   nr_pages = 0;
 static unsigned long  *p2m_array = NULL;
 static unsigned long  *m2p_array = NULL;
-static unsigned long            pages_offset;
-static unsigned long            cr3[MAX_VIRT_CPUS];
+static unsigned long   pages_offset;
+static unsigned long   cr3[MAX_VIRT_CPUS];
 
 /* --------------------- */
 
@@ -47,7 +47,7 @@ map_domain_va_core(unsigned long domfd, 
             munmap(cr3_virt[cpu], PAGE_SIZE);
         v = mmap(
             NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd,
-            map_mtop_offset(cr3_phys[cpu]));
+            map_mtop_offset(xen_cr3_to_pfn(cr3_phys[cpu])));
         if (v == MAP_FAILED)
         {
             perror("mmap failed");
@@ -127,14 +127,15 @@ xc_waitdomain_core(
             sizeof(vcpu_guest_context_t)*nr_vcpus)
             return -1;
 
-        for (i = 0; i < nr_vcpus; i++) {
+        for (i = 0; i < nr_vcpus; i++)
             cr3[i] = ctxt[i].ctrlreg[3];
-        }
+
         if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL)
         {
             printf("Could not allocate p2m_array\n");
             return -1;
         }
+
         if (read(domfd, p2m_array, sizeof(unsigned long)*nr_pages) !=
             sizeof(unsigned long)*nr_pages)
             return -1;
@@ -146,10 +147,8 @@ xc_waitdomain_core(
         }
         bzero(m2p_array, sizeof(unsigned long)* 1 << 20);
 
-        for (i = 0; i < nr_pages; i++) {
+        for (i = 0; i < nr_pages; i++)
             m2p_array[p2m_array[i]] = i;
-        }
-
     }
     return 0;
 }
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c  Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xg_private.c  Fri Jun 02 12:31:48 2006 -0500
@@ -145,3 +145,18 @@ unsigned long csum_page(void *page)
 
     return sum ^ (sum>>32);
 }
+
+__attribute__((weak)) int xc_hvm_build(
+    int xc_handle,
+    uint32_t domid,
+    int memsize,
+    const char *image_name,
+    unsigned int vcpus,
+    unsigned int pae,
+    unsigned int acpi,
+    unsigned int apic,
+    unsigned int store_evtchn,
+    unsigned long *store_mfn)
+{
+    return -ENOSYS;
+}
diff -r 29861ae27914 -r 91ee504ed40e tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Tue May 30 15:24:31 2006 -0500
+++ b/tools/libxc/xg_private.h  Fri Jun 02 12:31:48 2006 -0500
@@ -25,6 +25,14 @@
 #define DECLARE_DOM0_OP dom0_op_t op
 #endif
 
+#ifndef ELFSIZE
+#include <limits.h>
+#if UINT_MAX == ULONG_MAX
+#define ELFSIZE 32
+#else
+#define ELFSIZE 64
+#endif
+#endif
 
 char *xc_read_image(const char *filename, unsigned long *size);
 char *xc_inflate_buffer(const char *in_buf,
diff -r 29861ae27914 -r 91ee504ed40e tools/misc/Makefile
--- a/tools/misc/Makefile       Tue May 30 15:24:31 2006 -0500
+++ b/tools/misc/Makefile       Fri Jun 02 12:31:48 2006 -0500
@@ -25,7 +25,7 @@ build: $(TARGETS)
 build: $(TARGETS)
        $(MAKE) -C miniterm
        $(MAKE) -C cpuperf
-ifneq ($(XEN_TARGET_ARCH),ia64)
+ifeq ($(CONFIG_MBOOTPACK),y)
        $(MAKE) -C mbootpack
 endif
        $(MAKE) -C lomount
diff -r 29861ae27914 -r 91ee504ed40e tools/python/xen/util/security.py
--- a/tools/python/xen/util/security.py Tue May 30 15:24:31 2006 -0500
+++ b/tools/python/xen/util/security.py Fri Jun 02 12:31:48 2006 -0500
@@ -426,6 +426,15 @@ def get_decision(arg1, arg2):
             err("Argument type not supported.")
         ssidref = label2ssidref(arg2[2][1], arg2[1][1])
         arg2 = ['ssidref', str(ssidref)]
+
+    # accept only int or string types for domid and ssidref
+    if isinstance(arg1[1], int):
+        arg1[1] = str(arg1[1])
+    if isinstance(arg2[1], int):
+        arg2[1] = str(arg2[1])
+    if not isinstance(arg1[1], str) or not isinstance(arg2[1], str):
+        err("Invalid id or ssidref type, string or int required")
+
     try:
         decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1])
     except:
diff -r 29861ae27914 -r 91ee504ed40e tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Tue May 30 15:24:31 2006 -0500
+++ b/tools/python/xen/xm/main.py       Fri Jun 02 12:31:48 2006 -0500
@@ -806,7 +806,7 @@ def xm_top(args):
     os.execvp('xentop', ['xentop'])
 
 def xm_dmesg(args):
-    arg_check(args, "dmesg", 0)
+    arg_check(args, "dmesg", 0, 1)
     
     gopts = Opts(use="""[-c|--clear]
 
diff -r 29861ae27914 -r 91ee504ed40e tools/vtpm/Makefile
--- a/tools/vtpm/Makefile       Tue May 30 15:24:31 2006 -0500
+++ b/tools/vtpm/Makefile       Fri Jun 02 12:31:48 2006 -0500
@@ -9,7 +9,7 @@ VTPM_DIR = vtpm
 VTPM_DIR = vtpm
 
 # Emulator tarball name
-TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
+TPM_EMULATOR_TARFILE = tpm_emulator-0.3.tar.gz
 
 GMP_HEADER = /usr/include/gmp.h
 
@@ -47,23 +47,23 @@ mrproper:
 
 # Create vtpm and TPM emulator dirs
 # apply patches for 1) used as dom0 tpm driver 2) used as vtpm device instance
-$(TPM_EMULATOR_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator.patch 
tpm_emulator-0.2b-x86_64.patch
+$(TPM_EMULATOR_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator.patch 
tpm_emulator-0.3-x86_64.patch
        if [ "$(BUILD_EMULATOR)" = "y" ]; then \
                tar -xzf $(TPM_EMULATOR_TARFILE); \
                rm -rf $(TPM_EMULATOR_DIR); \
-               mv tpm_emulator-0.2 $(TPM_EMULATOR_DIR); \
+               mv tpm_emulator-0.3 $(TPM_EMULATOR_DIR); \
                cd $(TPM_EMULATOR_DIR); \
-               patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
+               patch -p1 < ../tpm_emulator-0.3-x86_64.patch; \
                patch -p1 <../tpm_emulator.patch; \
        fi
 
-$(VTPM_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator-0.2b-x86_64.patch vtpm.patch
+$(VTPM_DIR): $(TPM_EMULATOR_TARFILE) tpm_emulator-0.3-x86_64.patch vtpm.patch
        tar -xzf $(TPM_EMULATOR_TARFILE);  
        rm -rf $(VTPM_DIR)
-       mv tpm_emulator-0.2 $(VTPM_DIR); 
+       mv tpm_emulator-0.3 $(VTPM_DIR); 
 
        cd $(VTPM_DIR); \
-       patch -p1 < ../tpm_emulator-0.2b-x86_64.patch; \
+       patch -p1 < ../tpm_emulator-0.3-x86_64.patch; \
        patch -p1 <../vtpm.patch
 
 .PHONY: build_sub
diff -r 29861ae27914 -r 91ee504ed40e tools/vtpm/Rules.mk
--- a/tools/vtpm/Rules.mk       Tue May 30 15:24:31 2006 -0500
+++ b/tools/vtpm/Rules.mk       Fri Jun 02 12:31:48 2006 -0500
@@ -33,6 +33,7 @@ OBJS  = $(patsubst %.c,%.o,$(SRCS))
 
 -include $(DEP_FILES)
 
+# Emulator does not work on 64-bit systems, and may be broken on 32 right now
 BUILD_EMULATOR = n
 
 # Make sure these are just rules
diff -r 29861ae27914 -r 91ee504ed40e tools/vtpm/vtpm.patch
--- a/tools/vtpm/vtpm.patch     Tue May 30 15:24:31 2006 -0500
+++ b/tools/vtpm/vtpm.patch     Fri Jun 02 12:31:48 2006 -0500
@@ -1,23 +1,24 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS vtpm/AUTHORS
---- orig/tpm_emulator-0.2-x86_64/AUTHORS       2005-08-15 00:58:57.000000000 
-0700
-+++ vtpm/AUTHORS       2006-05-17 09:31:11.000000000 -0700
-@@ -1 +1,2 @@
+diff -uprN orig/tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS
+--- orig/tpm_emulator-0.3-x86_64/AUTHORS       2006-01-10 04:21:45.000000000 
-0800
++++ vtpm/AUTHORS       2006-05-30 12:23:26.000000000 -0700
+@@ -1,2 +1,3 @@
  Mario Strasser <mast@xxxxxxx>
-+INTEL Corp <>
-diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog vtpm/ChangeLog
---- orig/tpm_emulator-0.2-x86_64/ChangeLog     2005-08-15 00:58:57.000000000 
-0700
-+++ vtpm/ChangeLog     2006-05-17 09:31:11.000000000 -0700
+ Heiko Stamer <stamer@xxxxxxxx> [DAA]
++INTEL Corp <> [VTPM Extensions]
+diff -uprN orig/tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog
+--- orig/tpm_emulator-0.3-x86_64/ChangeLog     2006-01-10 04:21:45.000000000 
-0800
++++ vtpm/ChangeLog     2006-05-30 12:23:26.000000000 -0700
 @@ -1,3 +1,7 @@
 +2005-08-16 Intel Corp
-+      Moved module out of kernel to run as a ring 3 app
-+      Modified save_to_file and load_from_file to call a xen backend driver 
to call a VTPM manager
-+
- 2005-08-15  Mario Strasser <mast@xxxxxxx>
-       * all: some typos corrected
-       * tpm_integrity.c: bug in TPM_Extend fixed
-diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c 
vtpm/crypto/gmp_kernel_wrapper.c
---- orig/tpm_emulator-0.2-x86_64/crypto/gmp_kernel_wrapper.c   2006-05-17 
09:34:13.000000000 -0700
-+++ vtpm/crypto/gmp_kernel_wrapper.c   2006-05-17 09:31:11.000000000 -0700
++      * Moved module out of kernel to run as a ring 3 app
++      * Modified save_to_file and load_from_file to call a xen backend driver 
to call a VTPM manager
++
+ 2005-12-24  Mario Strasser <mast@xxxxxxx>
+       * tpm_transport.c, tpm_marshalling.c, tpm_structures.h:
+               Transport session functionality added
+diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 
vtpm/crypto/gmp_kernel_wrapper.c
+--- orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c   2006-05-30 
12:28:02.000000000 -0700
++++ vtpm/crypto/gmp_kernel_wrapper.c   2006-05-30 12:23:26.000000000 -0700
 @@ -1,5 +1,6 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -77,9 +78,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
    }
  }
  
-diff -uprN orig/tpm_emulator-0.2-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
---- orig/tpm_emulator-0.2-x86_64/crypto/rsa.c  2005-08-15 00:58:57.000000000 
-0700
-+++ vtpm/crypto/rsa.c  2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
+--- orig/tpm_emulator-0.3-x86_64/crypto/rsa.c  2006-01-10 04:21:45.000000000 
-0800
++++ vtpm/crypto/rsa.c  2006-05-30 12:23:26.000000000 -0700
 @@ -1,5 +1,6 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -87,7 +88,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
   *
   * This module is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published
-@@ -363,7 +364,7 @@ static int encode_message(int type, uint
+@@ -381,7 +382,7 @@ static int encode_message(int type, uint
        msg[0] = 0x00;
        get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
        sha1_init(&ctx);
@@ -96,7 +97,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
        sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
        memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00, 
          msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
-@@ -411,7 +412,7 @@ static int decode_message(int type, uint
+@@ -429,7 +430,7 @@ static int decode_message(int type, uint
        mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
          &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
        sha1_init(&ctx);
@@ -105,10 +106,10 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
        sha1_final(&ctx, &msg[1]);
        if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
            SHA1_DIGEST_LENGTH) != 0) return -1;
-diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.c vtpm/linux_module.c
---- orig/tpm_emulator-0.2-x86_64/linux_module.c        2006-05-17 
09:34:13.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c
+--- orig/tpm_emulator-0.3-x86_64/linux_module.c        2006-05-30 
12:28:02.000000000 -0700
 +++ vtpm/linux_module.c        1969-12-31 16:00:00.000000000 -0800
-@@ -1,163 +0,0 @@
+@@ -1,194 +0,0 @@
 -/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
 - * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
 - *
@@ -122,7 +123,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 - * GNU General Public License for more details.
 - *
-- * $Id: linux_module.c 19 2005-05-18 08:29:37Z mast $
+- * $Id: linux_module.c 76 2006-01-02 22:17:58Z hstamer $
 - */
 -
 -#include <linux/module.h>
@@ -140,11 +141,11 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -
 -/* module startup parameters */
 -char *startup = "save";
--MODULE_PARM(startup, "s");
+-module_param(startup, charp, 0444);
 -MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. "
 -  "Possible values are 'clear', 'save' (default) and 'deactivated.");
--char *storage_file = "/var/tpm/tpm_emulator-1.2.0.1";
--MODULE_PARM(storage_file, "s");
+-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.2";
+-module_param(storage_file, charp, 0644);
 -MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage " 
 -  "file of the TPM.");
 -
@@ -172,6 +173,12 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -{
 -  debug("%s()", __FUNCTION__);
 -  clear_bit(STATE_IS_OPEN, (void*)&module_state);
+-  down(&tpm_mutex);
+-  if (tpm_response.data != NULL) {
+-    kfree(tpm_response.data);
+-    tpm_response.data = NULL;
+-  }
+-  up(&tpm_mutex);
 -  return 0;
 -}
 -
@@ -183,6 +190,10 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -    count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
 -    count -= copy_to_user(buf, &tpm_response.data[*ppos], count);
 -    *ppos += count;
+-    if ((size_t)tpm_response.size == (size_t)*ppos) {
+-      kfree(tpm_response.data);
+-      tpm_response.data = NULL;
+-    }
 -  } else {
 -    count = 0;
 -  }
@@ -205,9 +216,29 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -  return count;
 -}
 -
+-#define TPMIOC_CANCEL   _IO('T', 0x00)
+-#define TPMIOC_TRANSMIT _IO('T', 0x01)
+-
 -static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int 
cmd, unsigned long arg)
 -{
--  debug("%s(%d, %ld)", __FUNCTION__, cmd, arg);
+-  debug("%s(%d, %p)", __FUNCTION__, cmd, (char*)arg);
+-  if (cmd == TPMIOC_TRANSMIT) {
+-    uint32_t count = ntohl(*(uint32_t*)(arg + 2));
+-    down(&tpm_mutex);
+-    if (tpm_response.data != NULL) kfree(tpm_response.data);
+-    if (tpm_handle_command((char*)arg, count, &tpm_response.data,
+-                           &tpm_response.size) == 0) {
+-      tpm_response.size -= copy_to_user((char*)arg, tpm_response.data,
+-                            tpm_response.size);
+-      kfree(tpm_response.data);
+-      tpm_response.data = NULL;
+-    } else {
+-      tpm_response.size = 0;
+-      tpm_response.data = NULL;
+-    }
+-    up(&tpm_mutex);
+-    return tpm_response.size;
+-  }
 -  return -1;
 -}
 -
@@ -240,7 +271,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -  /* initialize TPM emulator */
 -  if (!strcmp(startup, "clear")) {
 -    tpm_emulator_init(1);
--  } else if (!strcmp(startup, "save")) { 
+-  } else if (!strcmp(startup, "save")) {
 -    tpm_emulator_init(2);
 -  } else if (!strcmp(startup, "deactivated")) {
 -    tpm_emulator_init(3);
@@ -257,6 +288,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -{
 -  tpm_emulator_shutdown();
 -  misc_deregister(&tpm_dev);
+-  if (tpm_response.data != NULL) kfree(tpm_response.data);
 -}
 -
 -module_init(init_tpm_module);
@@ -264,7 +296,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -
 -uint64_t tpm_get_ticks(void)
 -{
--  static struct timespec old_time = {0, 0}; 
+-  static struct timespec old_time = {0, 0};
 -  struct timespec new_time = current_kernel_time();
 -  uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000
 -                   + (old_time.tv_nsec - new_time.tv_nsec) / 1000;
@@ -272,9 +304,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -  return (ticks > 0) ? ticks : 1;
 -}
 -
-diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h vtpm/linux_module.h
---- orig/tpm_emulator-0.2-x86_64/linux_module.h        2006-05-17 
09:34:13.000000000 -0700
-+++ vtpm/linux_module.h        2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h
+--- orig/tpm_emulator-0.3-x86_64/linux_module.h        2006-05-30 
12:28:02.000000000 -0700
++++ vtpm/linux_module.h        2006-05-30 12:23:26.000000000 -0700
 @@ -1,5 +1,6 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -374,15 +406,15 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  #define BE16_TO_CPU(x) __be16_to_cpu(x)
  #define LE16_TO_CPU(x) __le16_to_cpu(x)
  
-diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile vtpm/Makefile
---- orig/tpm_emulator-0.2-x86_64/Makefile      2006-05-17 09:34:13.000000000 
-0700
-+++ vtpm/Makefile      2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile
+--- orig/tpm_emulator-0.3-x86_64/Makefile      2006-05-30 12:28:02.000000000 
-0700
++++ vtpm/Makefile      2006-05-30 12:23:26.000000000 -0700
 @@ -1,22 +1,31 @@
  # Software-Based Trusted Platform Module (TPM) Emulator for Linux
  # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
-+# Copyright (C) 2005 INTEL Corp.
++# Copyright (C) 2006 INTEL Corp.
  #
- # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
+ # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
  
 -# kernel settings
 -KERNEL_RELEASE := $(shell uname -r)
@@ -394,11 +426,11 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -MODULE_NAME    := tpm_emulator
 +BIN            := vtpmd
  VERSION_MAJOR  := 0
- VERSION_MINOR  := 2
+ VERSION_MINOR  := 3
  VERSION_BUILD  := $(shell date +"%s")
  
 -# enable/disable DEBUG messages
--EXTRA_CFLAGS   += -DDEBUG -g  
+-EXTRA_CFLAGS   += -Wall -DDEBUG -g  
 +# Installation program and options
 +INSTALL         = install
 +INSTALL_PROG    = $(INSTALL) -m0755
@@ -468,10 +500,10 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  
  $(src)/crypto/libgmp.a:
        test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) 
$(src)/crypto/libgmp.a
-diff -uprN orig/tpm_emulator-0.2-x86_64/README vtpm/README
---- orig/tpm_emulator-0.2-x86_64/README        2006-05-17 09:34:13.000000000 
-0700
-+++ vtpm/README        2006-05-17 09:31:11.000000000 -0700
-@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
+diff -uprN orig/tpm_emulator-0.3-x86_64/README vtpm/README
+--- orig/tpm_emulator-0.3-x86_64/README        2006-05-30 12:28:02.000000000 
-0700
++++ vtpm/README        2006-05-30 12:23:26.000000000 -0700
+@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
  Copyright
  --------------------------------------------------------------------------
  Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal 
@@ -481,9 +513,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
                
  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
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_audit.c       2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_audit.c       2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c       2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_audit.c       2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -546,9 +578,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
    return TPM_SUCCESS;
  }
 -
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c 
vtpm/tpm/tpm_authorization.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_authorization.c       2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_authorization.c       2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 
vtpm/tpm/tpm_authorization.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c       2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_authorization.c       2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -557,7 +589,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
   *
   * This module is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published
-@@ -268,7 +269,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
+@@ -279,7 +280,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
  {
    hmac_ctx_t ctx;
    TPM_SESSION_DATA *session;
@@ -565,16 +597,10 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 +  UINT32 auth_handle = CPU_TO_BE32(auth->authHandle);
    
    info("tpm_verify_auth(%08x)", auth->authHandle);
-   /* get dedicated authorization session */
-@@ -316,5 +317,3 @@ void tpm_decrypt_auth_secret(TPM_ENCAUTH
-   for (i = 0; i < sizeof(TPM_SECRET); i++)
-     plainAuth[i] ^= encAuth[i];
- }
--
--
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c 
vtpm/tpm/tpm_capability.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_capability.c  2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_capability.c  2006-05-17 09:31:11.000000000 -0700
+   /* get dedicated authorization or transport session */
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 
vtpm/tpm/tpm_capability.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c  2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_capability.c  2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -583,7 +609,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
   *
   * This module is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published
-@@ -398,7 +399,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+@@ -406,7 +407,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
  
      case TPM_CAP_KEY_HANDLE:
        debug("[TPM_CAP_KEY_HANDLE]");
@@ -592,14 +618,14 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
        return cap_handle(4, (BYTE*)&subCapSize, respSize, resp);
  
      case TPM_CAP_CHECK_LOADED:
-@@ -472,4 +473,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+@@ -480,4 +481,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
        return TPM_BAD_MODE;
    }
  }
 -
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c 
vtpm/tpm/tpm_cmd_handler.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_cmd_handler.c 2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_cmd_handler.c 2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 
vtpm/tpm/tpm_cmd_handler.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_cmd_handler.c 2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -608,17 +634,17 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
   *
   * This module is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published
-@@ -26,7 +27,7 @@ static void tpm_compute_in_param_digest(
+@@ -73,7 +74,7 @@ void tpm_compute_in_param_digest(TPM_REQ
  {
    sha1_ctx_t sha1;
-   UINT32 offset;
+   UINT32 offset = tpm_get_param_offset(req->ordinal);
 -  UINT32 ord = cpu_to_be32(req->ordinal);
 +  UINT32 ord = CPU_TO_BE32(req->ordinal);
  
-   /* skip all key-handles at the beginning */
-   switch (req->ordinal) {
-@@ -82,8 +83,8 @@ static void tpm_compute_in_param_digest(
- static void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, 
TPM_RESPONSE *rsp)
+   /* compute SHA1 hash */
+   if (offset <= req->paramSize) {
+@@ -89,8 +90,8 @@ void tpm_compute_in_param_digest(TPM_REQ
+ void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
  {
    sha1_ctx_t sha1;
 -  UINT32 res = cpu_to_be32(rsp->result);
@@ -628,7 +654,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  
    /* compute SHA1 hash */
    sha1_init(&sha1);
-@@ -3081,7 +3082,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+@@ -3123,7 +3124,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
        hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
  #if 0
        if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) {
@@ -637,7 +663,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
          hmac_update(&hmac, (BYTE*)&handle, 4);
        }
  #endif
-@@ -3096,7 +3097,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+@@ -3138,7 +3139,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
        hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
  #if 0
        if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) {
@@ -646,25 +672,20 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
          hmac_update(&hmac, (BYTE*)&handle, 4);
        }
  #endif
-@@ -3179,7 +3180,9 @@ extern const char *tpm_error_to_string(T
- static void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
+@@ -3221,7 +3222,9 @@ extern const char *tpm_error_to_string(T
+ void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
  {
    TPM_RESULT res;
 -  
 +
-+  req->tag = (BYTE) req->tag;  // VIN HACK!!! 
++  req->tag = (BYTE) req->tag;  // FIXME: Why is this here
 +
    /* setup authorisation as well as response tag and size */
    memset(rsp, 0, sizeof(*rsp));
    switch (req->tag) {
-@@ -3878,4 +3881,3 @@ int tpm_handle_command(const uint8_t *in
-   tpm_free(rsp.param);
-   return 0;
- }
--
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_crypto.c      2006-05-17 
09:34:13.000000000 -0700
-+++ vtpm/tpm/tpm_crypto.c      2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c      2006-05-30 
12:28:02.000000000 -0700
++++ vtpm/tpm/tpm_crypto.c      2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -683,13 +704,170 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
      if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, 
          buf, areaToSignSize + 30, *sig)) {
 @@ -383,4 +384,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
-   }  
+   }
    return TPM_SUCCESS;
  }
 -
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c        2006-05-17 
09:34:13.000000000 -0700
-+++ vtpm/tpm/tpm_data.c        2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-01-10 04:21:45.000000000 
-0800
++++ vtpm/tpm/tpm_daa.c 2006-05-30 12:23:26.000000000 -0700
+@@ -700,14 +700,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -787,14 +787,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1440,14 +1440,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1660,14 +1660,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1740,14 +1740,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -2828,14 +2828,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -3050,7 +3050,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+         sha1_init(&sha1);
+         sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest, 
+           sizeof(session->DAA_session.DAA_digest));
+-        sha1_update(&sha1, "\x01", 1);
++        sha1_update(&sha1, (BYTE *) "\x01", 1);
+         sha1_update(&sha1, inputData1, inputSize1);
+         sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
+       }
+@@ -3078,7 +3078,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+         sha1_init(&sha1);
+         sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest, 
+           sizeof(session->DAA_session.DAA_digest));
+-        sha1_update(&sha1, "\x01", 1);
++        sha1_update(&sha1, (BYTE *) "\x01", 1);
+         rsa_export_modulus(&aikData->key, scratch, &size);
+         sha1_update(&sha1, scratch, size);
+         sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
+@@ -3134,14 +3134,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -3213,14 +3213,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c        2006-05-30 
12:28:02.000000000 -0700
++++ vtpm/tpm/tpm_data.c        2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -698,8 +876,8 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
   *
   * This module is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published
-@@ -15,9 +16,15 @@
-  * $Id: tpm_data.c 9 2005-04-26 18:15:31Z mast $
+@@ -15,10 +16,15 @@
+  * $Id: tpm_data.c 36 2005-10-26 20:31:19Z hstamer $
   */
  
 +#include <sys/types.h>
@@ -710,11 +888,12 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  #include "tpm_emulator.h"
  #include "tpm_structures.h"
  #include "tpm_marshalling.h"
+-#include "linux_module.h"
 +#include "vtpm_manager.h"
  
  TPM_DATA tpmData;
  
-@@ -28,6 +35,7 @@ BOOL tpm_get_physical_presence(void)
+@@ -39,6 +45,7 @@ static inline void init_pcr_attr(int pcr
  
  void tpm_init_data(void)
  {
@@ -722,7 +901,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
    /* endorsement key */
    uint8_t ek_n[] =  "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7"
      "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93"
-@@ -66,6 +74,8 @@ void tpm_init_data(void)
+@@ -77,6 +84,8 @@ void tpm_init_data(void)
      "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b"
      "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47"
      "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f";
@@ -731,18 +910,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
    int i;
    /* reset all data to NULL, FALSE or 0 */
    memset(&tpmData, 0, sizeof(tpmData));
-@@ -85,6 +95,10 @@ void tpm_init_data(void)
-   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
-   /* setup PCR attributes */
-   for (i = 0; i < TPM_NUM_PCR; i++) {
-+    int j;
-+    for (j=0; j < TPM_NUM_LOCALITY; j++) {
-+      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
-+    }
-     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
-   }
-   /* set tick type */
-@@ -115,49 +129,235 @@ void tpm_release_data(void)
+@@ -150,49 +159,235 @@ void tpm_release_data(void)
  
  #ifdef TPM_STORE_TO_FILE
  
@@ -1009,7 +1177,7 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  }
  
  #else
-@@ -232,7 +432,6 @@ int tpm_restore_permanent_data(void)
+@@ -267,7 +462,6 @@ int tpm_restore_permanent_data(void)
  
  int tpm_erase_permanent_data(void)
  {
@@ -1018,9 +1186,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
    return res;
  }
 -
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c 
vtpm/tpm/tpm_deprecated.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_deprecated.c  2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_deprecated.c  2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 
vtpm/tpm/tpm_deprecated.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c  2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_deprecated.c  2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1047,9 +1215,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
                          authContextSize, &contextBlob);
    if (res != TPM_SUCCESS) return res;
    len = *authContextSize;
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h 
vtpm/tpm/tpm_emulator.h
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_emulator.h    2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_emulator.h    2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 
vtpm/tpm/tpm_emulator.h
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h    2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_emulator.h    2006-05-30 12:23:26.000000000 -0700
 @@ -1,5 +1,6 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1064,12 +1232,12 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -#undef  TPM_GENERATE_EK
 +//#undef  TPM_GENERATE_EK
 +#define  TPM_GENERATE_EK
- 
- /**
-  * tpm_emulator_init - initialises and starts the TPM emulator
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c 
vtpm/tpm/tpm_integrity.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_integrity.c   2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_integrity.c   2006-05-17 09:31:11.000000000 -0700
+ #undef  TPM_GENERATE_SEED_DAA
+ 
+ #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */        
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 
vtpm/tpm/tpm_integrity.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c   2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_integrity.c   2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1083,9 +1251,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
    return TPM_SUCCESS;
  }
 -
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h 
vtpm/tpm/tpm_structures.h
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_structures.h  2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_structures.h  2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 
vtpm/tpm/tpm_structures.h
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h  2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_structures.h  2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1103,9 +1271,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  #include "crypto/rsa.h"
  
  /*
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c 
vtpm/tpm/tpm_testing.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_testing.c     2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_testing.c     2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 
vtpm/tpm/tpm_testing.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c     2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_testing.c     2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1221,9 +1389,9 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
    rsa_private_key_t priv_key;
    rsa_public_key_t pub_key;
  
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_ticks.c       2005-08-15 
00:58:57.000000000 -0700
-+++ vtpm/tpm/tpm_ticks.c       2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c       2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_ticks.c       2006-05-30 12:23:26.000000000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1306,9 +1474,69 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  }
    
  
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpmd.c vtpm/tpmd.c
---- orig/tpm_emulator-0.2-x86_64/tpmd.c        1969-12-31 16:00:00.000000000 
-0800
-+++ vtpm/tpmd.c        2006-05-17 09:31:11.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 
vtpm/tpm/tpm_transport.c
+--- orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c   2006-01-10 
04:21:45.000000000 -0800
++++ vtpm/tpm/tpm_transport.c   2006-05-30 12:23:26.000000000 -0700
+@@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE
+ static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20],
+                              BYTE pubKeyHash[20], TPM_DIGEST *transDigest)
+ {
+-  UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_IN);
++  UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_IN);
+   BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_IN(x)];
+   UINT32 len = sizeof(buf);
+   sha1_ctx_t sha1;
+@@ -76,7 +76,7 @@ static void transport_log_in(TPM_COMMAND
+ static void transport_log_out(TPM_CURRENT_TICKS *currentTicks, BYTE 
parameters[20],
+                               TPM_MODIFIER_INDICATOR locality, TPM_DIGEST 
*transDigest)
+ {
+-  UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_OUT);
++  UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_OUT);
+   BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_OUT(x)];
+   UINT32 len = sizeof(buf);
+   sha1_ctx_t sha1;
+@@ -191,7 +191,7 @@ static void decrypt_wrapped_command(BYTE
+     sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
+     sha1_update(&sha1, "in", 2);
+     sha1_update(&sha1, secret, sizeof(TPM_SECRET));
+-    j = cpu_to_be32(i);
++    j = CPU_TO_BE32(i);
+     sha1_update(&sha1, (BYTE*)&j, 4);
+     sha1_final(&sha1, mask);
+     for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 
+@@ -213,7 +213,7 @@ static void encrypt_wrapped_command(BYTE
+     sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
+     sha1_update(&sha1, "out", 3);
+     sha1_update(&sha1, secret, sizeof(TPM_SECRET));
+-    j = cpu_to_be32(i);
++    j = CPU_TO_BE32(i);
+     sha1_update(&sha1, (BYTE*)&j, 4);
+     sha1_final(&sha1, mask);
+     for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 
+@@ -253,9 +253,9 @@ TPM_RESULT TPM_ExecuteTransport(UINT32 i
+   /* verify authorization */
+   tpm_compute_in_param_digest(&req);
+   sha1_init(&sha1);
+-  res = cpu_to_be32(TPM_ORD_ExecuteTransport);
++  res = CPU_TO_BE32(TPM_ORD_ExecuteTransport);
+   sha1_update(&sha1, (BYTE*)&res, 4);
+-  res = cpu_to_be32(inWrappedCmdSize);
++  res = CPU_TO_BE32(inWrappedCmdSize);
+   sha1_update(&sha1, (BYTE*)&res, 4);
+   sha1_update(&sha1, req.auth1.digest, sizeof(req.auth1.digest));
+   sha1_final(&sha1, auth1->digest);
+@@ -357,7 +357,7 @@ TPM_RESULT TPM_ReleaseTransportSigned(TP
+   /* setup a TPM_SIGN_INFO structure */
+   memcpy(&buf[0], "\x05\x00TRAN", 6);
+   memcpy(&buf[6], antiReplay->nonce, 20);
+-  *(UINT32*)&buf[26] = cpu_to_be32(20);
++  *(UINT32*)&buf[26] = CPU_TO_BE32(20);
+   memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
+   /* sign info structure */ 
+   res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize);
+diff -uprN orig/tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c
+--- orig/tpm_emulator-0.3-x86_64/tpmd.c        1969-12-31 16:00:00.000000000 
-0800
++++ vtpm/tpmd.c        2006-05-30 12:23:26.000000000 -0700
 @@ -0,0 +1,207 @@
 +/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 + * Copyright (C) 2005 INTEL Corp
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/Rules.mk
--- a/xen/arch/ia64/Rules.mk    Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/Rules.mk    Fri Jun 02 12:31:48 2006 -0500
@@ -11,25 +11,25 @@ endif
 endif
 
 # Used only by linux/Makefile.
-AFLAGS_KERNEL  += -mconstant-gp
+AFLAGS_KERNEL  += -mconstant-gp -nostdinc $(CPPFLAGS)
 
 # Note: .S -> .o rule uses AFLAGS and CFLAGS.
 
-CFLAGS  += -nostdinc -fno-builtin -fno-common -fno-strict-aliasing
-CFLAGS  += -mconstant-gp
+CFLAGS += -nostdinc -fno-builtin -fno-common -fno-strict-aliasing
+CFLAGS += -mconstant-gp
 #CFLAGS  += -O3                # -O3 over-inlines making debugging tough!
-CFLAGS  += -O2         # but no optimization causes compile errors!
-CFLAGS  += -fomit-frame-pointer -D__KERNEL__
-CFLAGS  += -iwithprefix include
-CPPFLAGS+= -I$(BASEDIR)/include                                         \
-           -I$(BASEDIR)/include/asm-ia64                                \
-           -I$(BASEDIR)/include/asm-ia64/linux                                 
\
-           -I$(BASEDIR)/include/asm-ia64/linux-xen                     \
+CFLAGS += -O2          # but no optimization causes compile errors!
+CFLAGS += -fomit-frame-pointer -D__KERNEL__
+CFLAGS += -iwithprefix include
+CPPFLAGS+= -I$(BASEDIR)/include                                                
\
+          -I$(BASEDIR)/include/asm-ia64                                \
+          -I$(BASEDIR)/include/asm-ia64/linux                          \
+          -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 += $(CPPFLAGS)
+          -I$(BASEDIR)/arch/ia64/linux -I$(BASEDIR)/arch/ia64/linux-xen
+CFLAGS += $(CPPFLAGS)
 #CFLAGS  += -Wno-pointer-arith -Wredundant-decls
-CFLAGS  += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY
+CFLAGS += -DIA64 -DXEN -DLINUX_2_6 -DV_IOSAPIC_READY
 CFLAGS += -ffixed-r13 -mfixed-range=f2-f5,f12-f127
 CFLAGS += -g
 #CFLAGS  += -DVTI_DEBUG
@@ -40,7 +40,7 @@ CFLAGS        += -DCONFIG_XEN_IA64_DOM0_VP
 CFLAGS += -DCONFIG_XEN_IA64_DOM0_VP
 endif
 ifeq ($(no_warns),y)
-CFLAGS += -Wa,--fatal-warnings
+CFLAGS += -Wa,--fatal-warnings -Werror -Wno-uninitialized
 endif
 
 LDFLAGS := -g
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/linux-xen/entry.S
--- a/xen/arch/ia64/linux-xen/entry.S   Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/entry.S   Fri Jun 02 12:31:48 2006 -0500
@@ -906,17 +906,12 @@ GLOBAL_ENTRY(ia64_leave_kernel)
     ;;
        alloc loc0=ar.pfs,0,1,1,0
        adds out0=16,r12
-    adds r7 = PT(EML_UNAT)+16,r12
-       ;;
-    ld8 r7 = [r7]
-       ;;
-#if 0
-leave_kernel_self:
-    cmp.ne p8,p0 = r0, r7
-(p8) br.sptk.few leave_kernel_self
-       ;; 
-#endif
-(pUStk)        br.call.sptk.many b0=deliver_pending_interrupt
+       adds r7 = PT(EML_UNAT)+16,r12
+       ;;
+       ld8 r7 = [r7]
+       ;;
+(pUStk)        br.call.sptk.many b0=reflect_event
+//(pUStk)      br.call.sptk.many b0=deliver_pending_interrupt
     ;;
        mov ar.pfs=loc0
        mov ar.unat=r7  /* load eml_unat  */
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/linux-xen/iosapic.c
--- a/xen/arch/ia64/linux-xen/iosapic.c Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/iosapic.c Fri Jun 02 12:31:48 2006 -0500
@@ -1112,12 +1112,14 @@ map_iosapic_to_node(unsigned int gsi_bas
 }
 #endif
 
+#ifndef XEN
 static int __init iosapic_enable_kmalloc (void)
 {
        iosapic_kmalloc_ok = 1;
        return 0;
 }
 core_initcall (iosapic_enable_kmalloc);
+#endif
 
 #ifdef XEN
 /* nop for now */
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/linux-xen/sal.c
--- a/xen/arch/ia64/linux-xen/sal.c     Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/sal.c     Fri Jun 02 12:31:48 2006 -0500
@@ -229,7 +229,12 @@ ia64_sal_init (struct ia64_sal_systab *s
                return;
        }
 
+#ifdef XEN /* warning cleanup */
+       if (strncmp((char *)systab->signature, "SST_", 4) != 0)
+#else
        if (strncmp(systab->signature, "SST_", 4) != 0)
+#endif
+               
                printk(KERN_ERR "bad signature in system table!");
 
        check_versions(systab);
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c     Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/smp.c     Fri Jun 02 12:31:48 2006 -0500
@@ -196,7 +196,9 @@ handle_IPI (int irq, void *dev_id, struc
                mb();   /* Order data access and bit testing. */
        }
        put_cpu();
+#ifndef XEN
        return IRQ_HANDLED;
+#endif
 }
 
 /*
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/linux-xen/smpboot.c
--- a/xen/arch/ia64/linux-xen/smpboot.c Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/smpboot.c Fri Jun 02 12:31:48 2006 -0500
@@ -62,6 +62,7 @@
 #include <asm/unistd.h>
 
 #ifdef XEN
+#include <xen/domain.h>
 #include <asm/hw_irq.h>
 int ht_per_core = 1;
 #ifndef CONFIG_SMP
@@ -197,7 +198,11 @@ sync_master (void *arg)
  * negative that it is behind.
  */
 static inline long
+#ifdef XEN /* warning cleanup */
+get_delta (unsigned long *rt, unsigned long *master)
+#else
 get_delta (long *rt, long *master)
+#endif
 {
        unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0;
        unsigned long tcenter, t0, t1, tm;
@@ -483,7 +488,7 @@ do_rest:
 #else
        struct vcpu *v;
 
-       v = idle_vcpu[cpu] = alloc_vcpu(idle_vcpu[0]->domain, cpu, cpu);
+       v = alloc_idle_vcpu(cpu);
        BUG_ON(v == NULL);
 
        //printf ("do_boot_cpu: cpu=%d, domain=%p, vcpu=%p\n", cpu, idle, v);
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/linux-xen/time.c
--- a/xen/arch/ia64/linux-xen/time.c    Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/time.c    Fri Jun 02 12:31:48 2006 -0500
@@ -158,7 +158,11 @@ ia64_init_itm (void)
 {
        unsigned long platform_base_freq, itc_freq;
        struct pal_freq_ratio itc_ratio, proc_ratio;
+#ifdef XEN /* warning cleanup */
+       unsigned long status, platform_base_drift, itc_drift;
+#else
        long status, platform_base_drift, itc_drift;
+#endif
 
        /*
         * According to SAL v2.6, we need to use a SAL call to determine the 
platform base
@@ -197,7 +201,11 @@ ia64_init_itm (void)
        itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
 
        local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
+#ifdef XEN /* warning cleanup */
+       printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%u/%u, "
+#else
        printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
+#endif
               "ITC freq=%lu.%03luMHz", smp_processor_id(),
               platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
               itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 
1000) % 1000);
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/tools/sparse-merge
--- a/xen/arch/ia64/tools/sparse-merge  Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/tools/sparse-merge  Fri Jun 02 12:31:48 2006 -0500
@@ -33,9 +33,17 @@ cd $LINUXPATH || exit 1
 cd $LINUXPATH || exit 1
 OLDCSET=$(hg parents | awk '/^changeset:/{print($2)}' | cut -f 1 -d :)
 for t in $OLDTAG $NEWTAG; do
+    [[ $t == *.* ]] || continue
     if ! hg tags | cut -f1 -d' ' | grep -Fx $t; then
        echo "Tag $t not found, ketching up"
-       hg up -C ${t%.*} || exit 1
+       if [[ $t == *-* ]]; then
+           # rc/pre/git versions start at the previous stable release
+           micro=${t%%-*}; micro=${micro##*.}
+           stable=${t%%-*}; stable=${stable%.*}.$((micro-1))
+           hg up -C $stable
+       else
+           hg up -C ${t%.*} || exit 1
+       fi
        ketchup ${t#v} || exit 1
        hg addremove
        hg ci -m $t
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/vmx/pal_emul.c
--- a/xen/arch/ia64/vmx/pal_emul.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/vmx/pal_emul.c      Fri Jun 02 12:31:48 2006 -0500
@@ -21,6 +21,7 @@
 #include <asm/vmx_vcpu.h>
 #include <asm/pal.h>
 #include <asm/sal.h>
+#include <asm/dom_fw.h>
 #include <asm/tlb.h>
 #include <asm/vmx_mm_def.h>
 
@@ -42,7 +43,14 @@ set_pal_result (VCPU *vcpu,struct ia64_p
        vcpu_set_gr(vcpu,11, result.v2,0);
 }
 
-
+static void
+set_sal_result (VCPU *vcpu,struct sal_ret_values result) {
+
+       vcpu_set_gr(vcpu,8, result.r8,0);
+       vcpu_set_gr(vcpu,9, result.r9,0);
+       vcpu_set_gr(vcpu,10, result.r10,0);
+       vcpu_set_gr(vcpu,11, result.r11,0);
+}
 static struct ia64_pal_retval
 pal_cache_flush (VCPU *vcpu) {
        UINT64 gr28,gr29, gr30, gr31;
@@ -196,6 +204,10 @@ pal_debug_info(VCPU *vcpu){
 
 static struct ia64_pal_retval
 pal_fixed_addr(VCPU *vcpu){
+       struct ia64_pal_retval result;
+
+       result.status= -1; //unimplemented
+       return result;
 }
 
 static struct ia64_pal_retval
@@ -450,4 +462,12 @@ pal_emul( VCPU *vcpu) {
                set_pal_result (vcpu, result);
 }
 
-
+void
+sal_emul(VCPU *v) {
+       struct sal_ret_values result;
+       result = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33),
+                             vcpu_get_gr(v,34),vcpu_get_gr(v,35),
+                             vcpu_get_gr(v,36),vcpu_get_gr(v,37),
+                             vcpu_get_gr(v,38),vcpu_get_gr(v,39));
+       set_sal_result(v, result);      
+}
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c  Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmmu.c  Fri Jun 02 12:31:48 2006 -0500
@@ -199,8 +199,11 @@ void machine_tlb_insert(struct vcpu *d, 
     mtlb.page_flags = tlb->page_flags & ~PAGE_FLAGS_RV_MASK;
     mtlb.ppn = get_mfn(d->domain,tlb->ppn);
     mtlb_ppn=mtlb.ppn;
+
+#if 0
     if (mtlb_ppn == INVALID_MFN)
         panic_domain(vcpu_regs(d),"Machine tlb insert with invalid mfn 
number.\n");
+#endif
 
     psr = ia64_clear_ic();
     if ( cl == ISIDE_TLB ) {
@@ -319,17 +322,17 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod
 //        if( tlb == NULL )
 //             tlb = vtlb_lookup(vcpu, gip, DSIDE_TLB );
         if (tlb)
-               gpip = (tlb->ppn >>(tlb->ps-12)<<tlb->ps) | ( gip & 
(PSIZE(tlb->ps)-1) );
+            gpip = (tlb->ppn >>(tlb->ps-12)<<tlb->ps) | ( gip & 
(PSIZE(tlb->ps)-1) );
     }
     if( gpip){
-        mfn = gmfn_to_mfn(vcpu->domain, gpip >>PAGE_SHIFT);
-       if( mfn == INVALID_MFN )  panic_domain(vcpu_regs(vcpu),"fetch_code: 
invalid memory\n");
-       vpa =(u64 *)__va( (gip & (PAGE_SIZE-1)) | (mfn<<PAGE_SHIFT));
+        mfn = gmfn_to_mfn(vcpu->domain, gpip >>PAGE_SHIFT);
+        if( mfn == INVALID_MFN )  panic_domain(vcpu_regs(vcpu),"fetch_code: 
invalid memory\n");
+        vpa =(u64 *)__va( (gip & (PAGE_SIZE-1)) | (mfn<<PAGE_SHIFT));
     }else{
-       tlb = vhpt_lookup(gip);
-       if( tlb == NULL)
-           panic_domain(vcpu_regs(vcpu),"No entry found in ITLB and DTLB\n");
-       vpa =(u64 
*)__va((tlb->ppn>>(PAGE_SHIFT-ARCH_PAGE_SHIFT)<<PAGE_SHIFT)|(gip&(PAGE_SIZE-1)));
+        tlb = vhpt_lookup(gip);
+        if( tlb == NULL)
+            panic_domain(vcpu_regs(vcpu),"No entry found in ITLB and DTLB\n");
+        vpa =(u64 
*)__va((tlb->ppn>>(PAGE_SHIFT-ARCH_PAGE_SHIFT)<<PAGE_SHIFT)|(gip&(PAGE_SIZE-1)));
     }
     *code1 = *vpa++;
     *code2 = *vpa;
@@ -338,6 +341,7 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod
 
 IA64FAULT vmx_vcpu_itc_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
 {
+#ifdef VTLB_DEBUG
     int slot;
     u64 ps, va;
     ps = itir_ps(itir);
@@ -348,14 +352,17 @@ IA64FAULT vmx_vcpu_itc_i(VCPU *vcpu, UIN
         panic_domain(vcpu_regs(vcpu),"Tlb conflict!!");
         return IA64_FAULT;
     }
+#endif //VTLB_DEBUG    
     thash_purge_and_insert(vcpu, pte, itir, ifa);
     return IA64_NO_FAULT;
 }
 
 IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa)
 {
+    u64 gpfn;
+#ifdef VTLB_DEBUG    
     int slot;
-    u64 ps, va, gpfn;
+    u64 ps, va;
     ps = itir_ps(itir);
     va = PAGEALIGN(ifa, ps);
     slot = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
@@ -364,9 +371,18 @@ IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UIN
         panic_domain(vcpu_regs(vcpu),"Tlb conflict!!");
         return IA64_FAULT;
     }
+#endif //VTLB_DEBUG
     gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT;
-    if(VMX_DOMAIN(vcpu) && __gpfn_is_io(vcpu->domain,gpfn))
-        pte |= VTLB_PTE_IO;
+    if (VMX_DOMAIN(vcpu)) {
+        if (__gpfn_is_io(vcpu->domain, gpfn))
+            pte |= VTLB_PTE_IO;
+        else
+            /* Ensure WB attribute if pte is related to a normal mem page,
+             * which is required by vga acceleration since qemu maps shared
+             * vram buffer with WB.
+             */
+            pte &= ~_PAGE_MA_MASK;
+    }
     thash_purge_and_insert(vcpu, pte, itir, ifa);
     return IA64_NO_FAULT;
 
@@ -377,11 +393,14 @@ IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UIN
 
 IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa)
 {
+#ifdef VTLB_DEBUG
     int index;
+#endif    
     u64 ps, va, rid;
-
+    thash_data_t * p_itr;
     ps = itir_ps(itir);
     va = PAGEALIGN(ifa, ps);
+#ifdef VTLB_DEBUG    
     index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
     if (index >=0) {
         // generate MCA.
@@ -389,9 +408,11 @@ IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, u64
         return IA64_FAULT;
     }
     thash_purge_entries(vcpu, va, ps);
+#endif    
     vcpu_get_rr(vcpu, va, &rid);
     rid = rid& RR_RID_MASK;
-    vmx_vcpu_set_tr((thash_data_t *)&vcpu->arch.itrs[slot], pte, itir, va, 
rid);
+    p_itr = (thash_data_t *)&vcpu->arch.itrs[slot];
+    vmx_vcpu_set_tr(p_itr, pte, itir, va, rid);
     vcpu_quick_region_set(PSCBX(vcpu,itr_regions),va);
     return IA64_NO_FAULT;
 }
@@ -399,11 +420,15 @@ IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, u64
 
 IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, u64 slot, u64 pte, u64 itir, u64 ifa)
 {
+#ifdef VTLB_DEBUG
     int index;
-    u64 ps, va, gpfn, rid;
-
+    u64 gpfn;
+#endif    
+    u64 ps, va, rid;
+    thash_data_t * p_dtr;
     ps = itir_ps(itir);
     va = PAGEALIGN(ifa, ps);
+#ifdef VTLB_DEBUG    
     index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
     if (index>=0) {
         // generate MCA.
@@ -412,10 +437,12 @@ IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, u64
     }
     thash_purge_entries(vcpu, va, ps);
     gpfn = (pte & _PAGE_PPN_MASK)>> PAGE_SHIFT;
-    if(__gpfn_is_io(vcpu->domain,gpfn))
+    if(VMX_DOMAIN(vcpu) && _gpfn_is_io(vcpu->domain,gpfn))
         pte |= VTLB_PTE_IO;
+#endif    
     vcpu_get_rr(vcpu, va, &rid);
     rid = rid& RR_RID_MASK;
+    p_dtr = (thash_data_t *)&vcpu->arch.dtrs[slot];
     vmx_vcpu_set_tr((thash_data_t *)&vcpu->arch.dtrs[slot], pte, itir, va, 
rid);
     vcpu_quick_region_set(PSCBX(vcpu,dtr_regions),va);
     return IA64_NO_FAULT;
@@ -432,7 +459,6 @@ IA64FAULT vmx_vcpu_ptr_d(VCPU *vcpu,UINT
     index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
     if (index>=0) {
         vcpu->arch.dtrs[index].pte.p=0;
-        index = vtr_find_overlap(vcpu, va, ps, DSIDE_TLB);
     }
     thash_purge_entries(vcpu, va, ps);
     return IA64_NO_FAULT;
@@ -447,7 +473,6 @@ IA64FAULT vmx_vcpu_ptr_i(VCPU *vcpu,UINT
     index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
     if (index>=0) {
         vcpu->arch.itrs[index].pte.p=0;
-        index = vtr_find_overlap(vcpu, va, ps, ISIDE_TLB);
     }
     thash_purge_entries(vcpu, va, ps);
     return IA64_NO_FAULT;
@@ -530,7 +555,7 @@ IA64FAULT vmx_vcpu_tpa(VCPU *vcpu, UINT6
     visr.ir=pt_isr.ir;
     vpsr.val = vmx_vcpu_get_psr(vcpu);
     if(vpsr.ic==0){
-         visr.ni=1;
+        visr.ni=1;
     }
     visr.na=1;
     data = vtlb_lookup(vcpu, vadr, DSIDE_TLB);
@@ -648,14 +673,14 @@ long
 long
 __domain_va_to_ma(unsigned long va, unsigned long* ma, unsigned long *len)
 {
-    unsigned long      mpfn, gpfn, m, n = *len;
-    unsigned long      end;    /* end of the area mapped by current entry */
-    thash_data_t       *entry;
+    unsigned long  mpfn, gpfn, m, n = *len;
+    unsigned long  end;   /* end of the area mapped by current entry */
+    thash_data_t   *entry;
     struct vcpu *v = current;
 
     entry = vtlb_lookup(v, va, DSIDE_TLB);
     if (entry == NULL)
-       return -EFAULT;
+        return -EFAULT;
 
     gpfn =(entry->ppn>>(PAGE_SHIFT-12));
     gpfn =PAGEALIGN(gpfn,(entry->ps-PAGE_SHIFT));
@@ -668,7 +693,7 @@ __domain_va_to_ma(unsigned long va, unsi
     /*end = PAGEALIGN(m, entry->ps) + PSIZE(entry->ps);*/
     /* Current entry can't map all requested area */
     if ((m + n) > end)
-       n = end - m;
+        n = end - m;
 
     *ma = m;
     *len = n;
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_init.c      Fri Jun 02 12:31:48 2006 -0500
@@ -346,7 +346,7 @@ int vmx_build_physmap_table(struct domai
            for (j = io_ranges[i].start;
                 j < io_ranges[i].start + io_ranges[i].size;
                 j += PAGE_SIZE)
-               __assign_domain_page(d, j, io_ranges[i].type);
+               __assign_domain_page(d, j, io_ranges[i].type, ASSIGN_writable);
        }
 
        /* Map normal memory below 3G */
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/vmx/vmx_interrupt.c
--- a/xen/arch/ia64/vmx/vmx_interrupt.c Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_interrupt.c Fri Jun 02 12:31:48 2006 -0500
@@ -390,3 +390,14 @@ page_not_present(VCPU *vcpu, u64 vadr)
     inject_guest_interruption(vcpu, IA64_PAGE_NOT_PRESENT_VECTOR);
 }
 
+/* Deal with
+ *  Data access rights vector
+ */
+void
+data_access_rights(VCPU *vcpu, u64 vadr)
+{
+    /* If vPSR.ic, IFA, ITIR */
+    set_ifa_itir_iha (vcpu, vadr, 1, 1, 0);
+    inject_guest_interruption(vcpu, IA64_DATA_ACCESS_RIGHTS_VECTOR);
+}
+
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/vmx/vmx_ivt.S
--- a/xen/arch/ia64/vmx/vmx_ivt.S       Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_ivt.S       Fri Jun 02 12:31:48 2006 -0500
@@ -2,10 +2,10 @@
  * arch/ia64/kernel/vmx_ivt.S
  *
  * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
- *     Stephane Eranian <eranian@xxxxxxxxxx>
- *     David Mosberger <davidm@xxxxxxxxxx>
+ *      Stephane Eranian <eranian@xxxxxxxxxx>
+ *      David Mosberger <davidm@xxxxxxxxxx>
  * Copyright (C) 2000, 2002-2003 Intel Co
- *     Asit Mallick <asit.k.mallick@xxxxxxxxx>
+ *      Asit Mallick <asit.k.mallick@xxxxxxxxx>
  *      Suresh Siddha <suresh.b.siddha@xxxxxxxxx>
  *      Kenneth Chen <kenneth.w.chen@xxxxxxxxx>
  *      Fenghua Yu <fenghua.yu@xxxxxxxxx>
@@ -31,7 +31,7 @@
  *
  *  For each entry, the comment is as follows:
  *
- *             // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
+ *              // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
  *  entry offset ----/     /         /                  /          /
  *  entry number ---------/         /                  /          /
  *  size of the entry -------------/                  /          /
@@ -96,13 +96,13 @@ vmx_fault_##n:;          \
     ;;                  \
 
 
-#define VMX_REFLECT(n)                         \
-       mov r31=pr;                                                             
        \
-       mov r19=n;                      /* prepare to save predicates */        
        \
-    mov r29=cr.ipsr;        \
+#define VMX_REFLECT(n)    \
+    mov r31=pr;           \
+    mov r19=n;       /* prepare to save predicates */ \
+    mov r29=cr.ipsr;      \
     ;;      \
     tbit.z p6,p7=r29,IA64_PSR_VM_BIT;       \
-(p7) br.sptk.many vmx_dispatch_reflection;        \
+(p7)br.sptk.many vmx_dispatch_reflection;        \
     VMX_FAULT(n);            \
 
 
@@ -115,10 +115,10 @@ END(vmx_panic)
 
 
 
-       .section .text.ivt,"ax"
-
-       .align 32768    // align on 32KB boundary
-       .global vmx_ia64_ivt
+    .section .text.ivt,"ax"
+
+    .align 32768    // align on 32KB boundary
+    .global vmx_ia64_ivt
 vmx_ia64_ivt:
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
@@ -127,7 +127,7 @@ ENTRY(vmx_vhpt_miss)
     VMX_FAULT(0)
 END(vmx_vhpt_miss)
 
-       .org vmx_ia64_ivt+0x400
+    .org vmx_ia64_ivt+0x400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x0400 Entry 1 (size 64 bundles) ITLB (21)
 ENTRY(vmx_itlb_miss)
@@ -141,9 +141,13 @@ ENTRY(vmx_itlb_miss)
     mov r16 = cr.ifa
     ;;
     thash r17 = r16
-    ;;
     ttag r20 = r16
-    mov r18 = r17      
+    ;;
+    mov r18 = r17
+    adds r28 = VLE_TITAG_OFFSET,r17
+    adds r19 = VLE_CCHAIN_OFFSET, r17
+    ;;
+    ld8 r17 = [r19]
     ;;
 vmx_itlb_loop:
     cmp.eq p6,p0 = r0, r17
@@ -161,43 +165,22 @@ vmx_itlb_loop:
 (p7)mov r17 = r23;
 (p7)br.sptk vmx_itlb_loop
     ;;
-    adds r23 = VLE_PGFLAGS_OFFSET, r17
-    adds r24 = VLE_ITIR_OFFSET, r17
-    ;;
-    ld8 r25 = [r23]
-    ld8 r26 = [r24]
-    ;;
-    cmp.eq p6,p7=r18,r17
-(p6) br vmx_itlb_loop1
-    ;;
+    ld8 r25 = [r17]
     ld8 r27 = [r18]
-    ;;
-    extr.u r19 = r27, 56, 8
-    extr.u r20 = r25, 56, 8
-    ;;
-    dep r27 = r20, r27, 56, 8
-    dep r25 = r19, r25, 56, 8
-    ;;
-    st8 [r18] = r25,8
-    st8 [r23] = r27
-    ;;
-    ld8 r28 = [r18]
-    ;;
-    st8 [r18] = r26,8
-    st8 [r24] = r28
-    ;;
-    ld8 r30 = [r18]
-    ;;
-    st8 [r18] = r22
-    st8 [r16] = r30 
-    ;;
-vmx_itlb_loop1:
-    mov cr.itir = r26
+    ld8 r29 = [r28]
+    ;;
+    st8 [r16] = r29
+    st8 [r28] = r22
+    extr.u r19 = r27, 56, 4
+    ;;
+    dep r27 = r0, r27, 56, 4
+    dep r25 = r19, r25, 56, 4
+    ;;
+    st8 [r18] = r25
+    st8 [r17] = r27
     ;;
     itc.i r25
-    ;;
-    srlz.i
-    ;;
+    dv_serialize_data
     mov r17=cr.isr
     mov r23=r31
     mov r22=b0
@@ -219,7 +202,7 @@ vmx_itlb_out:
     VMX_FAULT(1);
 END(vmx_itlb_miss)
 
-       .org vmx_ia64_ivt+0x0800
+    .org vmx_ia64_ivt+0x0800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
 ENTRY(vmx_dtlb_miss)
@@ -232,9 +215,13 @@ ENTRY(vmx_dtlb_miss)
     mov r16 = cr.ifa
     ;;
     thash r17 = r16
-    ;;
     ttag r20 = r16
-    mov r18 = r17      
+    ;;
+    mov r18 = r17
+    adds r28 = VLE_TITAG_OFFSET,r17
+    adds r19 = VLE_CCHAIN_OFFSET, r17
+    ;;
+    ld8 r17 = [r19]
     ;;
 vmx_dtlb_loop:
     cmp.eq p6,p0 = r0, r17
@@ -252,43 +239,22 @@ vmx_dtlb_loop:
 (p7)mov r17 = r23;
 (p7)br.sptk vmx_dtlb_loop
     ;;
-    adds r23 = VLE_PGFLAGS_OFFSET, r17
-    adds r24 = VLE_ITIR_OFFSET, r17
-    ;;
-    ld8 r25 = [r23]
-    ld8 r26 = [r24]
-    ;;
-    cmp.eq p6,p7=r18,r17
-(p6) br vmx_dtlb_loop1
-    ;;
+    ld8 r25 = [r17]
     ld8 r27 = [r18]
-    ;;
-    extr.u r19 = r27, 56, 8
-    extr.u r20 = r25, 56, 8
-    ;;
-    dep r27 = r20, r27, 56, 8
-    dep r25 = r19, r25, 56, 8
-    ;;
-    st8 [r18] = r25,8
-    st8 [r23] = r27
-    ;;
-    ld8 r28 = [r18]
-    ;;
-    st8 [r18] = r26,8
-    st8 [r24] = r28
-    ;;
-    ld8 r30 = [r18]
-    ;;
-    st8 [r18] = r22
-    st8 [r16] = r30 
-    ;;
-vmx_dtlb_loop1:
-    mov cr.itir = r26
-    ;;
+    ld8 r29 = [r28]
+    ;;
+    st8 [r16] = r29
+    st8 [r28] = r22
+    extr.u r19 = r27, 56, 4
+    ;;
+    dep r27 = r0, r27, 56, 4
+    dep r25 = r19, r25, 56, 4
+    ;;
+    st8 [r18] = r25
+    st8 [r17] = r27
+    ;;    
     itc.d r25
-    ;;
-    srlz.d;
-    ;;
+    dv_serialize_data
     mov r17=cr.isr
     mov r23=r31
     mov r22=b0
@@ -310,7 +276,7 @@ vmx_dtlb_out:
     VMX_FAULT(2);
 END(vmx_dtlb_miss)
 
-       .org vmx_ia64_ivt+0x0c00
+    .org vmx_ia64_ivt+0x0c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
 ENTRY(vmx_alt_itlb_miss)
@@ -321,88 +287,84 @@ ENTRY(vmx_alt_itlb_miss)
     tbit.z p6,p7=r29,IA64_PSR_VM_BIT;
 (p7)br.spnt vmx_fault_3
 vmx_alt_itlb_miss_1:
-       mov r16=cr.ifa          // get address that caused the TLB miss
+    mov r16=cr.ifa    // get address that caused the TLB miss
     ;;
     tbit.z p6,p7=r16,63
 (p6)br.spnt vmx_fault_3
     ;;
-       movl r17=PAGE_KERNEL
-       mov r24=cr.ipsr
-       movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-       ;;
-       and r19=r19,r16         // clear ed, reserved bits, and PTE control bits
-       shr.u r18=r16,55        // move address bit 59 to bit 4
-       ;;
-       and r18=0x10,r18        // bit 4=address-bit(61)
-       or r19=r17,r19          // insert PTE control bits into r19
-       ;;
-       movl r20=IA64_GRANULE_SHIFT<<2
-       or r19=r19,r18          // set bit 4 (uncached) if the access was to 
region 6
-       ;;
-       mov cr.itir=r20
-       ;;
-       srlz.i
-       ;;
-       itc.i r19               // insert the TLB entry
-       mov pr=r31,-1
-       rfi
+    movl r17=PAGE_KERNEL
+    mov r24=cr.ipsr
+    movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
+    ;;
+    and r19=r19,r16     // clear ed, reserved bits, and PTE control bits
+    shr.u r18=r16,55    // move address bit 59 to bit 4
+    ;;
+    and r18=0x10,r18    // bit 4=address-bit(61)
+    or r19=r17,r19      // insert PTE control bits into r19
+    ;;
+    movl r20=IA64_GRANULE_SHIFT<<2
+    or r19=r19,r18     // set bit 4 (uncached) if the access was to region 6
+    ;;
+    mov cr.itir=r20
+    ;;
+    itc.i r19          // insert the TLB entry
+    mov pr=r31,-1
+    rfi
     VMX_FAULT(3);
 END(vmx_alt_itlb_miss)
 
 
-       .org vmx_ia64_ivt+0x1000
+    .org vmx_ia64_ivt+0x1000
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
 ENTRY(vmx_alt_dtlb_miss)
     VMX_DBG_FAULT(4)
-       mov r31=pr
+    mov r31=pr
     mov r29=cr.ipsr;
     ;;
     tbit.z p6,p7=r29,IA64_PSR_VM_BIT;
 (p7)br.spnt vmx_fault_4
 vmx_alt_dtlb_miss_1:
-       mov r16=cr.ifa          // get address that caused the TLB miss
+    mov r16=cr.ifa             // get address that caused the TLB miss
     ;;
 #ifdef CONFIG_VIRTUAL_FRAME_TABLE
-       // Test for the address of virtual frame_table
-       shr r22=r16,56;;
-       cmp.eq p8,p0=((VIRT_FRAME_TABLE_ADDR>>56)&0xff)-0x100,r22
-(p8)   br.cond.sptk frametable_miss ;;
+    // Test for the address of virtual frame_table
+    shr r22=r16,56;;
+    cmp.eq p8,p0=((VIRT_FRAME_TABLE_ADDR>>56)&0xff)-0x100,r22
+(p8)br.cond.sptk frametable_miss ;;
 #endif
     tbit.z p6,p7=r16,63
 (p6)br.spnt vmx_fault_4
     ;;
-       movl r17=PAGE_KERNEL
-       mov r20=cr.isr
-       movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-       mov r24=cr.ipsr
-       ;;
-       and r22=IA64_ISR_CODE_MASK,r20          // get the isr.code field
-       tbit.nz p6,p7=r20,IA64_ISR_SP_BIT       // is speculation bit on?
-       shr.u r18=r16,55                        // move address bit 59 to bit 4
-       and r19=r19,r16                         // clear ed, reserved bits, and 
PTE control bits
-       tbit.nz p9,p0=r20,IA64_ISR_NA_BIT       // is non-access bit on?
-       ;;
-       and r18=0x10,r18        // bit 4=address-bit(61)
-(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22    // check isr.code field
-       dep r24=-1,r24,IA64_PSR_ED_BIT,1
-       or r19=r19,r17          // insert PTE control bits into r19
-       ;;
-       or r19=r19,r18          // set bit 4 (uncached) if the access was to 
region 6
-(p6) mov cr.ipsr=r24
-       movl r20=IA64_GRANULE_SHIFT<<2
-       ;;
-       mov cr.itir=r20
-       ;;
-       srlz.i
-       ;;
-(p7) itc.d r19         // insert the TLB entry
-       mov pr=r31,-1
-       rfi
+    movl r17=PAGE_KERNEL
+    mov r20=cr.isr
+    movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
+    mov r24=cr.ipsr
+    ;;
+    and r22=IA64_ISR_CODE_MASK,r20             // get the isr.code field
+    tbit.nz p6,p7=r20,IA64_ISR_SP_BIT          // is speculation bit on?
+    shr.u r18=r16,55                           // move address bit 59 to bit 4
+    and r19=r19,r16                            // clear ed, reserved bits, and 
PTE control bits
+    tbit.nz p9,p0=r20,IA64_ISR_NA_BIT          // is non-access bit on?
+    ;;
+    and r18=0x10,r18                           // bit 4=address-bit(61)
+(p9)cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22     // check isr.code field
+    dep r24=-1,r24,IA64_PSR_ED_BIT,1
+    or r19=r19,r17                             // insert PTE control bits into 
r19
+    ;;
+    or r19=r19,r18                             // set bit 4 (uncached) if the 
access was to region 6
+(p6)mov cr.ipsr=r24
+    movl r20=IA64_GRANULE_SHIFT<<2
+    ;;
+    mov cr.itir=r20
+    ;;
+(p7)itc.d r19          // insert the TLB entry
+    mov pr=r31,-1
+    rfi
     VMX_FAULT(4);
 END(vmx_alt_dtlb_miss)
 
-       .org vmx_ia64_ivt+0x1400
+    .org vmx_ia64_ivt+0x1400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
 ENTRY(vmx_nested_dtlb_miss)
@@ -410,52 +372,52 @@ ENTRY(vmx_nested_dtlb_miss)
     VMX_FAULT(5)
 END(vmx_nested_dtlb_miss)
 
-       .org vmx_ia64_ivt+0x1800
+    .org vmx_ia64_ivt+0x1800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
 ENTRY(vmx_ikey_miss)
     VMX_DBG_FAULT(6)
-       VMX_REFLECT(6)
+    VMX_REFLECT(6)
 END(vmx_ikey_miss)
 
-       .org vmx_ia64_ivt+0x1c00
+    .org vmx_ia64_ivt+0x1c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
 ENTRY(vmx_dkey_miss)
     VMX_DBG_FAULT(7)
-       VMX_REFLECT(7)
+    VMX_REFLECT(7)
 END(vmx_dkey_miss)
 
-       .org vmx_ia64_ivt+0x2000
+    .org vmx_ia64_ivt+0x2000
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
 ENTRY(vmx_dirty_bit)
     VMX_DBG_FAULT(8)
-       VMX_REFLECT(8)
+    VMX_REFLECT(8)
 END(vmx_dirty_bit)
 
-       .org vmx_ia64_ivt+0x2400
+    .org vmx_ia64_ivt+0x2400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
 ENTRY(vmx_iaccess_bit)
     VMX_DBG_FAULT(9)
-       VMX_REFLECT(9)
+    VMX_REFLECT(9)
 END(vmx_iaccess_bit)
 
-       .org vmx_ia64_ivt+0x2800
+    .org vmx_ia64_ivt+0x2800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
 ENTRY(vmx_daccess_bit)
     VMX_DBG_FAULT(10)
-       VMX_REFLECT(10)
+    VMX_REFLECT(10)
 END(vmx_daccess_bit)
 
-       .org vmx_ia64_ivt+0x2c00
+    .org vmx_ia64_ivt+0x2c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
 ENTRY(vmx_break_fault)
     VMX_DBG_FAULT(11)
-       mov r31=pr
+    mov r31=pr
     mov r19=11
     mov r30=cr.iim
     movl r29=0x1100
@@ -473,12 +435,12 @@ ENTRY(vmx_break_fault)
     VMX_FAULT(11);
 END(vmx_break_fault)
 
-       .org vmx_ia64_ivt+0x3000
+    .org vmx_ia64_ivt+0x3000
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
 ENTRY(vmx_interrupt)
 //    VMX_DBG_FAULT(12)
-       mov r31=pr              // prepare to save predicates
+    mov r31=pr         // prepare to save predicates
     mov r19=12
     mov r29=cr.ipsr
     ;;
@@ -487,58 +449,58 @@ ENTRY(vmx_interrupt)
     ;;
 (p7) br.sptk vmx_dispatch_interrupt
     ;;
-       mov r27=ar.rsc                  /* M */
-       mov r20=r1                      /* A */
-       mov r25=ar.unat         /* M */
-       mov r26=ar.pfs                  /* I */
-       mov r28=cr.iip                  /* M */
-       cover               /* B (or nothing) */
-       ;;
-       mov r1=sp
-       ;;
-       invala                          /* M */
-       mov r30=cr.ifs
-       ;;
+    mov r27=ar.rsc             /* M */
+    mov r20=r1                 /* A */
+    mov r25=ar.unat            /* M */
+    mov r26=ar.pfs             /* I */
+    mov r28=cr.iip             /* M */
+    cover                      /* B (or nothing) */
+    ;;
+    mov r1=sp
+    ;;
+    invala                     /* M */
+    mov r30=cr.ifs
+    ;;
     addl r1=-IA64_PT_REGS_SIZE,r1
     ;;
-       adds r17=2*L1_CACHE_BYTES,r1            /* really: biggest cache-line 
size */
-       adds r16=PT(CR_IPSR),r1
-       ;;
-       lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES
-       st8 [r16]=r29           /* save cr.ipsr */
-       ;;
-       lfetch.fault.excl.nt1 [r17]
-       mov r29=b0
-       ;;
-       adds r16=PT(R8),r1      /* initialize first base pointer */
-       adds r17=PT(R9),r1      /* initialize second base pointer */
-       mov r18=r0                      /* make sure r18 isn't NaT */
-       ;;
+    adds r17=2*L1_CACHE_BYTES,r1       /* really: biggest cache-line size */
+    adds r16=PT(CR_IPSR),r1
+    ;;
+    lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES
+    st8 [r16]=r29                      /* save cr.ipsr */
+    ;;
+    lfetch.fault.excl.nt1 [r17]
+    mov r29=b0
+    ;;
+    adds r16=PT(R8),r1         /* initialize first base pointer */
+    adds r17=PT(R9),r1         /* initialize second base pointer */
+    mov r18=r0                 /* make sure r18 isn't NaT */
+    ;;
 .mem.offset 0,0; st8.spill [r16]=r8,16
 .mem.offset 8,0; st8.spill [r17]=r9,16
         ;;
 .mem.offset 0,0; st8.spill [r16]=r10,24
 .mem.offset 8,0; st8.spill [r17]=r11,24
         ;;
-       st8 [r16]=r28,16        /* save cr.iip */
-       st8 [r17]=r30,16        /* save cr.ifs */
-       mov r8=ar.fpsr          /* M */
-       mov r9=ar.csd
-       mov r10=ar.ssd
-       movl r11=FPSR_DEFAULT   /* L-unit */
-       ;;
-       st8 [r16]=r25,16        /* save ar.unat */
-       st8 [r17]=r26,16        /* save ar.pfs */
-       shl r18=r18,16          /* compute ar.rsc to be used for "loadrs" */
-       ;;
-    st8 [r16]=r27,16   /* save ar.rsc */
-    adds r17=16,r17    /* skip over ar_rnat field */
-    ;;          /* avoid RAW on r16 & r17 */
-    st8 [r17]=r31,16   /* save predicates */
-    adds r16=16,r16    /* skip over ar_bspstore field */
-    ;;
-    st8 [r16]=r29,16   /* save b0 */
-    st8 [r17]=r18,16   /* save ar.rsc value for "loadrs" */
+    st8 [r16]=r28,16           /* save cr.iip */
+    st8 [r17]=r30,16           /* save cr.ifs */
+    mov r8=ar.fpsr             /* M */
+    mov r9=ar.csd
+    mov r10=ar.ssd
+    movl r11=FPSR_DEFAULT      /* L-unit */
+    ;;
+    st8 [r16]=r25,16           /* save ar.unat */
+    st8 [r17]=r26,16           /* save ar.pfs */
+    shl r18=r18,16             /* compute ar.rsc to be used for "loadrs" */
+    ;;
+    st8 [r16]=r27,16           /* save ar.rsc */
+    adds r17=16,r17            /* skip over ar_rnat field */
+    ;;
+    st8 [r17]=r31,16           /* save predicates */
+    adds r16=16,r16            /* skip over ar_bspstore field */
+    ;;
+    st8 [r16]=r29,16           /* save b0 */
+    st8 [r17]=r18,16           /* save ar.rsc value for "loadrs" */
     ;;
 .mem.offset 0,0; st8.spill [r16]=r20,16    /* save original r1 */
 .mem.offset 8,0; st8.spill [r17]=r12,16
@@ -561,18 +523,18 @@ ENTRY(vmx_interrupt)
     ;;                                          \
     bsw.1
     ;;
-       alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
-       mov out0=cr.ivr         // pass cr.ivr as first arg
-       add out1=16,sp          // pass pointer to pt_regs as second arg
-
-       ssm psr.ic
+    alloc r14=ar.pfs,0,0,2,0   // must be first in an insn group
+    mov out0=cr.ivr            // pass cr.ivr as first arg
+    add out1=16,sp             // pass pointer to pt_regs as second arg
+
+    ssm psr.ic
     ;;
     srlz.i
-       ;;
+    ;;
     (p15) ssm psr.i
-       adds r3=8,r2            // set up second base pointer for SAVE_REST
-       srlz.i                  // ensure everybody knows psr.ic is back on
-       ;;
+    adds r3=8,r2               // set up second base pointer for SAVE_REST
+    srlz.i                     // ensure everybody knows psr.ic is back on
+    ;;
 .mem.offset 0,0; st8.spill [r2]=r16,16
 .mem.offset 8,0; st8.spill [r3]=r17,16
     ;;
@@ -599,8 +561,8 @@ ENTRY(vmx_interrupt)
 .mem.offset 0,0; st8.spill [r2]=r30,16
 .mem.offset 8,0; st8.spill [r3]=r31,32
     ;;
-    mov ar.fpsr=r11     /* M-unit */
-    st8 [r2]=r8,8      /* ar.ccv */
+    mov ar.fpsr=r11       /* M-unit */
+    st8 [r2]=r8,8         /* ar.ccv */
     adds r24=PT(B6)-PT(F7),r3
     ;;
     stf.spill [r2]=f6,32
@@ -619,95 +581,95 @@ ENTRY(vmx_interrupt)
     st8 [r24]=r9           /* ar.csd */
     st8 [r25]=r10          /* ar.ssd */
     ;;
-       srlz.d                  // make sure we see the effect of cr.ivr
-       movl r14=ia64_leave_nested
-       ;;
-       mov rp=r14
-       br.call.sptk.many b6=ia64_handle_irq
-       ;;
+    srlz.d             // make sure we see the effect of cr.ivr
+    movl r14=ia64_leave_nested
+    ;;
+    mov rp=r14
+    br.call.sptk.many b6=ia64_handle_irq
+    ;;
 END(vmx_interrupt)
 
-       .org vmx_ia64_ivt+0x3400
+    .org vmx_ia64_ivt+0x3400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x3400 Entry 13 (size 64 bundles) Reserved
 ENTRY(vmx_virtual_exirq)
-       VMX_DBG_FAULT(13)
-       mov r31=pr
-        mov r19=13
-        br.sptk vmx_dispatch_vexirq
+    VMX_DBG_FAULT(13)
+    mov r31=pr
+    mov r19=13
+    br.sptk vmx_dispatch_vexirq
 END(vmx_virtual_exirq)
 
-       .org vmx_ia64_ivt+0x3800
+    .org vmx_ia64_ivt+0x3800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x3800 Entry 14 (size 64 bundles) Reserved
     VMX_DBG_FAULT(14)
-       VMX_FAULT(14)
-
-
-       .org vmx_ia64_ivt+0x3c00
+    VMX_FAULT(14)
+
+
+    .org vmx_ia64_ivt+0x3c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x3c00 Entry 15 (size 64 bundles) Reserved
     VMX_DBG_FAULT(15)
-       VMX_FAULT(15)
-
-
-       .org vmx_ia64_ivt+0x4000
+    VMX_FAULT(15)
+
+
+    .org vmx_ia64_ivt+0x4000
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x4000 Entry 16 (size 64 bundles) Reserved
     VMX_DBG_FAULT(16)
-       VMX_FAULT(16)
-
-       .org vmx_ia64_ivt+0x4400
+    VMX_FAULT(16)
+
+    .org vmx_ia64_ivt+0x4400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x4400 Entry 17 (size 64 bundles) Reserved
     VMX_DBG_FAULT(17)
-       VMX_FAULT(17)
-
-       .org vmx_ia64_ivt+0x4800
+    VMX_FAULT(17)
+
+    .org vmx_ia64_ivt+0x4800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x4800 Entry 18 (size 64 bundles) Reserved
     VMX_DBG_FAULT(18)
-       VMX_FAULT(18)
-
-       .org vmx_ia64_ivt+0x4c00
+    VMX_FAULT(18)
+
+    .org vmx_ia64_ivt+0x4c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x4c00 Entry 19 (size 64 bundles) Reserved
     VMX_DBG_FAULT(19)
-       VMX_FAULT(19)
+    VMX_FAULT(19)
 
     .org vmx_ia64_ivt+0x5000
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5000 Entry 20 (size 16 bundles) Page Not Present
 ENTRY(vmx_page_not_present)
-       VMX_DBG_FAULT(20)
-       VMX_REFLECT(20)
+    VMX_DBG_FAULT(20)
+    VMX_REFLECT(20)
 END(vmx_page_not_present)
 
     .org vmx_ia64_ivt+0x5100
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5100 Entry 21 (size 16 bundles) Key Permission vector
 ENTRY(vmx_key_permission)
-       VMX_DBG_FAULT(21)
-       VMX_REFLECT(21)
+    VMX_DBG_FAULT(21)
+    VMX_REFLECT(21)
 END(vmx_key_permission)
 
     .org vmx_ia64_ivt+0x5200
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
 ENTRY(vmx_iaccess_rights)
-       VMX_DBG_FAULT(22)
-       VMX_REFLECT(22)
+    VMX_DBG_FAULT(22)
+    VMX_REFLECT(22)
 END(vmx_iaccess_rights)
 
-       .org vmx_ia64_ivt+0x5300
+    .org vmx_ia64_ivt+0x5300
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
 ENTRY(vmx_daccess_rights)
-       VMX_DBG_FAULT(23)
-       VMX_REFLECT(23)
+    VMX_DBG_FAULT(23)
+    VMX_REFLECT(23)
 END(vmx_daccess_rights)
 
-       .org vmx_ia64_ivt+0x5400
+    .org vmx_ia64_ivt+0x5400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
 ENTRY(vmx_general_exception)
@@ -716,106 +678,106 @@ ENTRY(vmx_general_exception)
 //    VMX_FAULT(24)
 END(vmx_general_exception)
 
-       .org vmx_ia64_ivt+0x5500
+    .org vmx_ia64_ivt+0x5500
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
 ENTRY(vmx_disabled_fp_reg)
-       VMX_DBG_FAULT(25)
-       VMX_REFLECT(25)
+    VMX_DBG_FAULT(25)
+    VMX_REFLECT(25)
 END(vmx_disabled_fp_reg)
 
-       .org vmx_ia64_ivt+0x5600
+    .org vmx_ia64_ivt+0x5600
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
 ENTRY(vmx_nat_consumption)
-       VMX_DBG_FAULT(26)
-       VMX_REFLECT(26)
+    VMX_DBG_FAULT(26)
+    VMX_REFLECT(26)
 END(vmx_nat_consumption)
 
-       .org vmx_ia64_ivt+0x5700
+    .org vmx_ia64_ivt+0x5700
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5700 Entry 27 (size 16 bundles) Speculation (40)
 ENTRY(vmx_speculation_vector)
-       VMX_DBG_FAULT(27)
-       VMX_REFLECT(27)
+    VMX_DBG_FAULT(27)
+    VMX_REFLECT(27)
 END(vmx_speculation_vector)
 
-       .org vmx_ia64_ivt+0x5800
+    .org vmx_ia64_ivt+0x5800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5800 Entry 28 (size 16 bundles) Reserved
     VMX_DBG_FAULT(28)
-       VMX_FAULT(28)
-
-       .org vmx_ia64_ivt+0x5900
+    VMX_FAULT(28)
+
+    .org vmx_ia64_ivt+0x5900
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
 ENTRY(vmx_debug_vector)
     VMX_DBG_FAULT(29)
-       VMX_FAULT(29)
+    VMX_FAULT(29)
 END(vmx_debug_vector)
 
-       .org vmx_ia64_ivt+0x5a00
+    .org vmx_ia64_ivt+0x5a00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
 ENTRY(vmx_unaligned_access)
-       VMX_DBG_FAULT(30)
-       VMX_REFLECT(30)
+    VMX_DBG_FAULT(30)
+    VMX_REFLECT(30)
 END(vmx_unaligned_access)
 
-       .org vmx_ia64_ivt+0x5b00
+    .org vmx_ia64_ivt+0x5b00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
 ENTRY(vmx_unsupported_data_reference)
-       VMX_DBG_FAULT(31)
-       VMX_REFLECT(31)
+    VMX_DBG_FAULT(31)
+    VMX_REFLECT(31)
 END(vmx_unsupported_data_reference)
 
-       .org vmx_ia64_ivt+0x5c00
+    .org vmx_ia64_ivt+0x5c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
 ENTRY(vmx_floating_point_fault)
-       VMX_DBG_FAULT(32)
-       VMX_REFLECT(32)
+    VMX_DBG_FAULT(32)
+    VMX_REFLECT(32)
 END(vmx_floating_point_fault)
 
-       .org vmx_ia64_ivt+0x5d00
+    .org vmx_ia64_ivt+0x5d00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
 ENTRY(vmx_floating_point_trap)
-       VMX_DBG_FAULT(33)
-       VMX_REFLECT(33)
+    VMX_DBG_FAULT(33)
+    VMX_REFLECT(33)
 END(vmx_floating_point_trap)
 
-       .org vmx_ia64_ivt+0x5e00
+    .org vmx_ia64_ivt+0x5e00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
 ENTRY(vmx_lower_privilege_trap)
-       VMX_DBG_FAULT(34)
-       VMX_REFLECT(34)
+    VMX_DBG_FAULT(34)
+    VMX_REFLECT(34)
 END(vmx_lower_privilege_trap)
 
-       .org vmx_ia64_ivt+0x5f00
+    .org vmx_ia64_ivt+0x5f00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
 ENTRY(vmx_taken_branch_trap)
-       VMX_DBG_FAULT(35)
-       VMX_REFLECT(35)
+    VMX_DBG_FAULT(35)
+    VMX_REFLECT(35)
 END(vmx_taken_branch_trap)
 
-       .org vmx_ia64_ivt+0x6000
+    .org vmx_ia64_ivt+0x6000
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
 ENTRY(vmx_single_step_trap)
-       VMX_DBG_FAULT(36)
-       VMX_REFLECT(36)
+    VMX_DBG_FAULT(36)
+    VMX_REFLECT(36)
 END(vmx_single_step_trap)
 
-       .org vmx_ia64_ivt+0x6100
+    .org vmx_ia64_ivt+0x6100
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6100 Entry 37 (size 16 bundles) Virtualization Fault
 ENTRY(vmx_virtualization_fault)
 //    VMX_DBG_FAULT(37)
-       mov r31=pr
+    mov r31=pr
     mov r19=37
     adds r16 = IA64_VCPU_CAUSE_OFFSET,r21
     adds r17 = IA64_VCPU_OPCODE_OFFSET,r21
@@ -826,197 +788,197 @@ ENTRY(vmx_virtualization_fault)
     br.sptk vmx_dispatch_virtualization_fault
 END(vmx_virtualization_fault)
 
-       .org vmx_ia64_ivt+0x6200
+    .org vmx_ia64_ivt+0x6200
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6200 Entry 38 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(38)
-       VMX_FAULT(38)
-
-       .org vmx_ia64_ivt+0x6300
+    VMX_DBG_FAULT(38)
+    VMX_FAULT(38)
+
+    .org vmx_ia64_ivt+0x6300
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6300 Entry 39 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(39)
-       VMX_FAULT(39)
-
-       .org vmx_ia64_ivt+0x6400
+    VMX_DBG_FAULT(39)
+    VMX_FAULT(39)
+
+    .org vmx_ia64_ivt+0x6400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6400 Entry 40 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(40)
-       VMX_FAULT(40)
-
-       .org vmx_ia64_ivt+0x6500
+    VMX_DBG_FAULT(40)
+    VMX_FAULT(40)
+
+    .org vmx_ia64_ivt+0x6500
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6500 Entry 41 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(41)
-       VMX_FAULT(41)
-
-       .org vmx_ia64_ivt+0x6600
+    VMX_DBG_FAULT(41)
+    VMX_FAULT(41)
+
+    .org vmx_ia64_ivt+0x6600
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6600 Entry 42 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(42)
-       VMX_FAULT(42)
-
-       .org vmx_ia64_ivt+0x6700
+    VMX_DBG_FAULT(42)
+    VMX_FAULT(42)
+
+    .org vmx_ia64_ivt+0x6700
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6700 Entry 43 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(43)
-       VMX_FAULT(43)
-
-       .org vmx_ia64_ivt+0x6800
+    VMX_DBG_FAULT(43)
+    VMX_FAULT(43)
+
+    .org vmx_ia64_ivt+0x6800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6800 Entry 44 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(44)
-       VMX_FAULT(44)
-
-       .org vmx_ia64_ivt+0x6900
+    VMX_DBG_FAULT(44)
+    VMX_FAULT(44)
+
+    .org vmx_ia64_ivt+0x6900
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception 
(17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77)
 ENTRY(vmx_ia32_exception)
-       VMX_DBG_FAULT(45)
-       VMX_FAULT(45)
+    VMX_DBG_FAULT(45)
+    VMX_FAULT(45)
 END(vmx_ia32_exception)
 
-       .org vmx_ia64_ivt+0x6a00
+    .org vmx_ia64_ivt+0x6a00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
 ENTRY(vmx_ia32_intercept)
-       VMX_DBG_FAULT(46)
-       VMX_FAULT(46)
+    VMX_DBG_FAULT(46)
+    VMX_FAULT(46)
 END(vmx_ia32_intercept)
 
-       .org vmx_ia64_ivt+0x6b00
+    .org vmx_ia64_ivt+0x6b00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
 ENTRY(vmx_ia32_interrupt)
-       VMX_DBG_FAULT(47)
-       VMX_FAULT(47)
+    VMX_DBG_FAULT(47)
+    VMX_FAULT(47)
 END(vmx_ia32_interrupt)
 
-       .org vmx_ia64_ivt+0x6c00
+    .org vmx_ia64_ivt+0x6c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6c00 Entry 48 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(48)
-       VMX_FAULT(48)
-
-       .org vmx_ia64_ivt+0x6d00
+    VMX_DBG_FAULT(48)
+    VMX_FAULT(48)
+
+    .org vmx_ia64_ivt+0x6d00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6d00 Entry 49 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(49)
-       VMX_FAULT(49)
-
-       .org vmx_ia64_ivt+0x6e00
+    VMX_DBG_FAULT(49)
+    VMX_FAULT(49)
+
+    .org vmx_ia64_ivt+0x6e00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6e00 Entry 50 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(50)
-       VMX_FAULT(50)
-
-       .org vmx_ia64_ivt+0x6f00
+    VMX_DBG_FAULT(50)
+    VMX_FAULT(50)
+
+    .org vmx_ia64_ivt+0x6f00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x6f00 Entry 51 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(51)
-       VMX_FAULT(51)
-
-       .org vmx_ia64_ivt+0x7000
+    VMX_DBG_FAULT(51)
+    VMX_FAULT(51)
+
+    .org vmx_ia64_ivt+0x7000
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7000 Entry 52 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(52)
-       VMX_FAULT(52)
-
-       .org vmx_ia64_ivt+0x7100
+    VMX_DBG_FAULT(52)
+    VMX_FAULT(52)
+
+    .org vmx_ia64_ivt+0x7100
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7100 Entry 53 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(53)
-       VMX_FAULT(53)
-
-       .org vmx_ia64_ivt+0x7200
+    VMX_DBG_FAULT(53)
+    VMX_FAULT(53)
+
+    .org vmx_ia64_ivt+0x7200
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7200 Entry 54 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(54)
-       VMX_FAULT(54)
-
-       .org vmx_ia64_ivt+0x7300
+    VMX_DBG_FAULT(54)
+    VMX_FAULT(54)
+
+    .org vmx_ia64_ivt+0x7300
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7300 Entry 55 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(55)
-       VMX_FAULT(55)
-
-       .org vmx_ia64_ivt+0x7400
+    VMX_DBG_FAULT(55)
+    VMX_FAULT(55)
+
+    .org vmx_ia64_ivt+0x7400
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7400 Entry 56 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(56)
-       VMX_FAULT(56)
-
-       .org vmx_ia64_ivt+0x7500
+    VMX_DBG_FAULT(56)
+    VMX_FAULT(56)
+
+    .org vmx_ia64_ivt+0x7500
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7500 Entry 57 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(57)
-       VMX_FAULT(57)
-
-       .org vmx_ia64_ivt+0x7600
+    VMX_DBG_FAULT(57)
+    VMX_FAULT(57)
+
+    .org vmx_ia64_ivt+0x7600
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7600 Entry 58 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(58)
-       VMX_FAULT(58)
-
-       .org vmx_ia64_ivt+0x7700
+    VMX_DBG_FAULT(58)
+    VMX_FAULT(58)
+
+    .org vmx_ia64_ivt+0x7700
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7700 Entry 59 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(59)
-       VMX_FAULT(59)
-
-       .org vmx_ia64_ivt+0x7800
+    VMX_DBG_FAULT(59)
+    VMX_FAULT(59)
+
+    .org vmx_ia64_ivt+0x7800
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7800 Entry 60 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(60)
-       VMX_FAULT(60)
-
-       .org vmx_ia64_ivt+0x7900
+    VMX_DBG_FAULT(60)
+    VMX_FAULT(60)
+
+    .org vmx_ia64_ivt+0x7900
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7900 Entry 61 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(61)
-       VMX_FAULT(61)
-
-       .org vmx_ia64_ivt+0x7a00
+    VMX_DBG_FAULT(61)
+    VMX_FAULT(61)
+
+    .org vmx_ia64_ivt+0x7a00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7a00 Entry 62 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(62)
-       VMX_FAULT(62)
-
-       .org vmx_ia64_ivt+0x7b00
+    VMX_DBG_FAULT(62)
+    VMX_FAULT(62)
+
+    .org vmx_ia64_ivt+0x7b00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7b00 Entry 63 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(63)
-       VMX_FAULT(63)
-
-       .org vmx_ia64_ivt+0x7c00
+    VMX_DBG_FAULT(63)
+    VMX_FAULT(63)
+
+    .org vmx_ia64_ivt+0x7c00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7c00 Entry 64 (size 16 bundles) Reserved
     VMX_DBG_FAULT(64)
-       VMX_FAULT(64)
-
-       .org vmx_ia64_ivt+0x7d00
+    VMX_FAULT(64)
+
+    .org vmx_ia64_ivt+0x7d00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7d00 Entry 65 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(65)
-       VMX_FAULT(65)
-
-       .org vmx_ia64_ivt+0x7e00
+    VMX_DBG_FAULT(65)
+    VMX_FAULT(65)
+
+    .org vmx_ia64_ivt+0x7e00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7e00 Entry 66 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(66)
-       VMX_FAULT(66)
-
-       .org vmx_ia64_ivt+0x7f00
+    VMX_DBG_FAULT(66)
+    VMX_FAULT(66)
+
+    .org vmx_ia64_ivt+0x7f00
 
/////////////////////////////////////////////////////////////////////////////////////////
 // 0x7f00 Entry 67 (size 16 bundles) Reserved
-       VMX_DBG_FAULT(67)
-       VMX_FAULT(67)
-
-       .org vmx_ia64_ivt+0x8000
-    // There is no particular reason for this code to be here, other than that
-    // there happens to be space here that would go unused otherwise.  If this
-    // fault ever gets "unreserved", simply moved the following code to a more
-    // suitable spot...
+    VMX_DBG_FAULT(67)
+    VMX_FAULT(67)
+
+    .org vmx_ia64_ivt+0x8000
+// There is no particular reason for this code to be here, other than that
+// there happens to be space here that would go unused otherwise.  If this
+// fault ever gets "unreserved", simply moved the following code to a more
+// suitable spot...
 
 
 ENTRY(vmx_dispatch_reflection)
@@ -1165,24 +1127,24 @@ END(vmx_hypercall_dispatch)
 
 
 ENTRY(vmx_dispatch_interrupt)
-       VMX_SAVE_MIN_WITH_COVER_R19     // uses r31; defines r2 and r3
-       ;;
-       alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
-       mov out0=cr.ivr         // pass cr.ivr as first arg
-       adds r3=8,r2            // set up second base pointer for SAVE_REST
-    ;;
-       ssm psr.ic
-       ;;
+    VMX_SAVE_MIN_WITH_COVER_R19        // uses r31; defines r2 and r3
+    ;;
+    alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
+    mov out0=cr.ivr            // pass cr.ivr as first arg
+    adds r3=8,r2               // set up second base pointer for SAVE_REST
+    ;;
+    ssm psr.ic
+    ;;
     srlz.i
     ;;
     (p15) ssm psr.i
-       movl r14=ia64_leave_hypervisor
-       ;;
-       VMX_SAVE_REST
-       mov rp=r14
-       ;;
-       add out1=16,sp          // pass pointer to pt_regs as second arg
-       br.call.sptk.many b6=ia64_handle_irq
+    movl r14=ia64_leave_hypervisor
+    ;;
+    VMX_SAVE_REST
+    mov rp=r14
+    ;;
+    add out1=16,sp             // pass pointer to pt_regs as second arg
+    br.call.sptk.many b6=ia64_handle_irq
 END(vmx_dispatch_interrupt)
 
 
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_process.c   Fri Jun 02 12:31:48 2006 -0500
@@ -64,6 +64,7 @@ extern void ivhpt_fault (VCPU *vcpu, u64
 extern void ivhpt_fault (VCPU *vcpu, u64 vadr);
 
 #define DOMN_PAL_REQUEST    0x110000
+#define DOMN_SAL_REQUEST    0x110001
 
 static UINT64 vec2off[68] = {0x0,0x400,0x800,0xc00,0x1000, 0x1400,0x1800,
     0x1c00,0x2000,0x2400,0x2800,0x2c00,0x3000,0x3400,0x3800,0x3c00,0x4000,
@@ -96,85 +97,6 @@ void vmx_reflect_interruption(UINT64 ifa
     inject_guest_interruption(vcpu, vector);
 }
 
-static void
-vmx_handle_hypercall (VCPU *v, REGS *regs)
-{
-    struct ia64_pal_retval y;
-    struct sal_ret_values x;
-    unsigned long i, sal_param[8];
-
-    switch (regs->r2) {
-        case FW_HYPERCALL_PAL_CALL:
-            //printf("*** PAL hypercall: index=%d\n",regs->r28);
-            //FIXME: This should call a C routine
-            y = pal_emulator_static(VCPU(v, vgr[12]));
-            regs->r8 = y.status; regs->r9 = y.v0;
-            regs->r10 = y.v1; regs->r11 = y.v2;
-#if 0
-            if (regs->r8)
-                printk("Failed vpal emulation, with index:0x%lx\n",
-                       VCPU(v, vgr[12]));
-#endif
-            break;
-        case FW_HYPERCALL_SAL_CALL:
-            for (i = 0; i < 8; i++)
-                vcpu_get_gr_nat(v, 32+i, &sal_param[i]);
-            x = sal_emulator(sal_param[0], sal_param[1],
-                             sal_param[2], sal_param[3],
-                             sal_param[4], sal_param[5],
-                             sal_param[6], sal_param[7]);
-            regs->r8 = x.r8; regs->r9 = x.r9;
-            regs->r10 = x.r10; regs->r11 = x.r11;
-#if 0
-            if (regs->r8)
-                printk("Failed vsal emulation, with index:0x%lx\n",
-                       sal_param[0]);
-#endif
-            break;
-        case FW_HYPERCALL_EFI_RESET_SYSTEM:
-            printf("efi.reset_system called ");
-            if (current->domain == dom0) {
-                printf("(by dom0)\n ");
-                (*efi.reset_system)(EFI_RESET_WARM,0,0,NULL);
-            }
-            printf("(not supported for non-0 domain)\n");
-            regs->r8 = EFI_UNSUPPORTED;
-            break;
-        case FW_HYPERCALL_EFI_GET_TIME:
-            {
-                unsigned long *tv, *tc;
-                vcpu_get_gr_nat(v, 32, (u64 *)&tv);
-                vcpu_get_gr_nat(v, 33, (u64 *)&tc);
-                printf("efi_get_time(%p,%p) called...",tv,tc);
-                tv = __va(translate_domain_mpaddr((unsigned long)tv));
-                if (tc) tc = __va(translate_domain_mpaddr((unsigned long)tc));
-                regs->r8 = (*efi.get_time)((efi_time_t *)tv,(efi_time_cap_t 
*)tc);
-                printf("and returns %lx\n",regs->r8);
-            }
-            break;
-        case FW_HYPERCALL_EFI_SET_TIME:
-        case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
-        case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
-            // FIXME: need fixes in efi.h from 2.6.9
-        case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
-            // FIXME: WARNING!! IF THIS EVER GETS IMPLEMENTED
-            // SOME OF THE OTHER EFI EMULATIONS WILL CHANGE AS
-            // POINTER ARGUMENTS WILL BE VIRTUAL!!
-        case FW_HYPERCALL_EFI_GET_VARIABLE:
-            // FIXME: need fixes in efi.h from 2.6.9
-        case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
-        case FW_HYPERCALL_EFI_SET_VARIABLE:
-        case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
-            // FIXME: need fixes in efi.h from 2.6.9
-            regs->r8 = EFI_UNSUPPORTED;
-            break;
-    }
-#if 0
-    if (regs->r8)
-        printk("Failed vgfw emulation, with index:0x%lx\n",
-               regs->r2);
-#endif
-}
 
 IA64FAULT
 vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long 
isr, unsigned long iim)
@@ -183,12 +105,12 @@ vmx_ia64_handle_break (unsigned long ifa
     struct vcpu *v = current;
 
 #ifdef CRASH_DEBUG
-       if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) &&
+    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
+        if (iim == 0)
+            show_registers(regs);
+        debugger_trap_fatal(0 /* don't care */, regs);
+    } else
 #endif
     {
         if (iim == 0) 
@@ -197,13 +119,17 @@ vmx_ia64_handle_break (unsigned long ifa
         if (!user_mode(regs)) {
             /* Allow hypercalls only when cpl = 0.  */
             if (iim == d->arch.breakimm) {
-                vmx_handle_hypercall (v ,regs);
-                vmx_vcpu_increment_iip(current);
+                ia64_hypercall(regs);
+                vmx_vcpu_increment_iip(v);
                 return IA64_NO_FAULT;
             }
             else if(iim == DOMN_PAL_REQUEST){
-                pal_emul(current);
-                vmx_vcpu_increment_iip(current);
+                pal_emul(v);
+                vmx_vcpu_increment_iip(v);
+                return IA64_NO_FAULT;
+            }else if(iim == DOMN_SAL_REQUEST){
+                sal_emul(v);
+                vmx_vcpu_increment_iip(v);
                 return IA64_NO_FAULT;
             }
         }
@@ -247,45 +173,45 @@ void save_banked_regs_to_vpd(VCPU *v, RE
 // NEVER successful if already reflecting a trap/fault because psr.i==0
 void leave_hypervisor_tail(struct pt_regs *regs)
 {
-       struct domain *d = current->domain;
-       struct vcpu *v = current;
-       // FIXME: Will this work properly if doing an RFI???
-       if (!is_idle_domain(d) ) {      // always comes from guest
-               extern void vmx_dorfirfi(void);
-               struct pt_regs *user_regs = vcpu_regs(current);
-               if (local_softirq_pending())
-                       do_softirq();
-               local_irq_disable();
- 
-               if (user_regs != regs)
-                       printk("WARNING: checking pending interrupt in nested 
interrupt!!!\n");
-
-               /* VMX Domain N has other interrupt source, saying DM  */
-                if (test_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags))
+    struct domain *d = current->domain;
+    struct vcpu *v = current;
+    // FIXME: Will this work properly if doing an RFI???
+    if (!is_idle_domain(d) ) { // always comes from guest
+        extern void vmx_dorfirfi(void);
+        struct pt_regs *user_regs = vcpu_regs(current);
+        if (local_softirq_pending())
+            do_softirq();
+        local_irq_disable();
+
+        if (user_regs != regs)
+            printk("WARNING: checking pending interrupt in nested 
interrupt!!!\n");
+
+        /* VMX Domain N has other interrupt source, saying DM  */
+        if (test_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags))
                       vmx_intr_assist(v);
 
-               /* FIXME: Check event pending indicator, and set
-                * pending bit if necessary to inject back to guest.
-                * Should be careful about window between this check
-                * and above assist, since IOPACKET_PORT shouldn't be
-                * injected into vmx domain.
-                *
-                * Now hardcode the vector as 0x10 temporarily
-                */
-//             if (event_pending(v)&&(!(VLSAPIC_INSVC(v,0)&(1UL<<0x10)))) {
-//                     VCPU(v, irr[0]) |= 1UL << 0x10;
-//                     v->arch.irq_new_pending = 1;
-//             }
-
-               if ( v->arch.irq_new_pending ) {
-                       v->arch.irq_new_pending = 0;
-                       vmx_check_pending_irq(v);
-               }
+        /* FIXME: Check event pending indicator, and set
+         * pending bit if necessary to inject back to guest.
+         * Should be careful about window between this check
+         * and above assist, since IOPACKET_PORT shouldn't be
+         * injected into vmx domain.
+         *
+         * Now hardcode the vector as 0x10 temporarily
+         */
+//       if (event_pending(v)&&(!(VLSAPIC_INSVC(v,0)&(1UL<<0x10)))) {
+//           VCPU(v, irr[0]) |= 1UL << 0x10;
+//           v->arch.irq_new_pending = 1;
+//       }
+
+        if ( v->arch.irq_new_pending ) {
+            v->arch.irq_new_pending = 0;
+            vmx_check_pending_irq(v);
+        }
 //        if (VCPU(v,vac).a_bsw){
 //            save_banked_regs_to_vpd(v,regs);
 //        }
 
-       }
+    }
 }
 
 extern ia64_rr vmx_vcpu_rr(VCPU *vcpu,UINT64 vadr);
@@ -302,7 +228,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
 {
     IA64_PSR vpsr;
     int type=ISIDE_TLB;
-    u64 vhpt_adr, gppa;
+    u64 vhpt_adr, gppa, pteval, rr, itir;
     ISR misr;
 //    REGS *regs;
     thash_data_t *data;
@@ -314,18 +240,6 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
     vpsr.val = vmx_vcpu_get_psr(v);
     misr.val=VMX(v,cr_isr);
 
-/*  TODO
-    if(v->domain->id && vec == 2 &&
-       vpsr.dt == 0 && is_gpa_io(MASK_PMA(vaddr))){
-        emulate_ins(&v);
-        return;
-    }
-*/
-/*    if(vadr == 0x1ea18c00 ){
-        ia64_clear_ic();
-        while(1);
-    }
- */
     if(is_physical_mode(v)&&(!(vadr<<1>>62))){
         if(vec==2){
             
if(v->domain!=dom0&&__gpfn_is_io(v->domain,(vadr<<1)>>(PAGE_SHIFT+1))){
@@ -338,31 +252,25 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
     }
     if(vec == 1) type = ISIDE_TLB;
     else if(vec == 2) type = DSIDE_TLB;
-    else panic_domain(regs,"wrong vec:%0xlx\n",vec);
+    else panic_domain(regs,"wrong vec:%lx\n",vec);
 
 //    prepare_if_physical_mode(v);
 
     if((data=vtlb_lookup(v, vadr,type))!=0){
-//     gppa = (vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
-//        if(v->domain!=dom0&&type==DSIDE_TLB && 
__gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){
+//       gppa = 
(vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
+//       if(v->domain!=dom0&&type==DSIDE_TLB && 
__gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){
         if(v->domain!=dom0 && data->io && type==DSIDE_TLB ){
-               gppa = 
(vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
-            emulate_io_inst(v, gppa, data->ma);
+            if(data->pl >= ((regs->cr_ipsr>>IA64_PSR_CPL0_BIT)&3)){
+                gppa = 
(vadr&((1UL<<data->ps)-1))+(data->ppn>>(data->ps-12)<<data->ps);
+                emulate_io_inst(v, gppa, data->ma);
+            }else{
+                vcpu_set_isr(v,misr.val);
+                data_access_rights(v, vadr);
+            }
             return IA64_FAULT;
         }
 
-//     if ( data->ps != vrr.ps ) {
-//             machine_tlb_insert(v, data);
-//     }
-//     else {
-/*        if ( data->contiguous&&(!data->tc)){
-               machine_tlb_insert(v, data);
-        }
-        else{
- */
-            thash_vhpt_insert(&v->arch.vhpt,data->page_flags, data->itir 
,vadr);
-//        }
-//         }
+        thash_vhpt_insert(v,data->page_flags, data->itir ,vadr);
     }else if(type == DSIDE_TLB){
         if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){
             if(vpsr.ic){
@@ -381,7 +289,13 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
             }
         } else{
             vmx_vcpu_thash(v, vadr, &vhpt_adr);
-            if(vhpt_lookup(vhpt_adr) ||  vtlb_lookup(v, vhpt_adr, DSIDE_TLB)){
+            if(!guest_vhpt_lookup(vhpt_adr, &pteval)){
+                if (pteval & _PAGE_P){
+                    vcpu_get_rr(v, vadr, &rr);
+                    itir = rr&(RR_RID_MASK | RR_PS_MASK);
+                    thash_purge_and_insert(v, pteval, itir , vadr);
+                    return IA64_NO_FAULT;
+                }
                 if(vpsr.ic){
                     vcpu_set_isr(v, misr.val);
                     dtlb_fault(v, vadr);
@@ -423,7 +337,13 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r
             return IA64_FAULT;
         } else{
             vmx_vcpu_thash(v, vadr, &vhpt_adr);
-            if(vhpt_lookup(vhpt_adr) || vtlb_lookup(v, vhpt_adr, DSIDE_TLB)){
+            if(!guest_vhpt_lookup(vhpt_adr, &pteval)){
+                if (pteval & _PAGE_P){
+                    vcpu_get_rr(v, vadr, &rr);
+                    itir = rr&(RR_RID_MASK | RR_PS_MASK);
+                    thash_purge_and_insert(v, pteval, itir , vadr);
+                    return IA64_NO_FAULT;
+                }
                 if(!vpsr.ic){
                     misr.ni=1;
                 }
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c  Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vtlb.c  Fri Jun 02 12:31:48 2006 -0500
@@ -36,27 +36,26 @@ thash_data_t *__alloc_chain(thash_cb_t *
 
 static void cch_mem_init(thash_cb_t *hcb)
 {
-    thash_data_t *p, *q;
+    int num;
+    thash_data_t *p;
 
     hcb->cch_freelist = p = hcb->cch_buf;
-
-    for ( q=p+1; (u64)(q + 1) <= (u64)hcb->cch_buf + hcb->cch_sz;
-        p++, q++ ) {
-        p->next = q;
-    }
+    num = (hcb->cch_sz/sizeof(thash_data_t))-1;
+    do{
+        p->next =p+1;
+        p++;
+        num--;
+    }while(num);
     p->next = NULL;
 }
 
 static thash_data_t *cch_alloc(thash_cb_t *hcb)
 {
     thash_data_t *p;
-
     if ( (p = hcb->cch_freelist) != NULL ) {
         hcb->cch_freelist = p->next;
-        return p;
-    }else{
-        return NULL;
-    }
+    }
+    return p;
 }
 
 static void cch_free(thash_cb_t *hcb, thash_data_t *cch)
@@ -101,17 +100,13 @@ static void __rem_hash_head(thash_cb_t *
 static void __rem_hash_head(thash_cb_t *hcb, thash_data_t *hash)
 {
     thash_data_t *next=hash->next;
-
-/*    if ( hcb->remove_notifier ) {
-        (hcb->remove_notifier)(hcb,hash);
-    } */
-    if ( next != NULL ) {
+    if ( next) {
         next->len=hash->len-1;
         *hash = *next;
         cch_free (hcb, next);
     }
     else {
-        INVALIDATE_HASH_HEADER(hcb, hash);
+        hash->ti=1;
     }
 }
 
@@ -145,125 +140,109 @@ thash_data_t *__vtr_lookup(VCPU *vcpu, u
 }
 
 
-/*
- * Get the machine format of VHPT entry.
- *    PARAS:
- *  1: tlb: means the tlb format hash entry converting to VHPT.
- *  2: va means the guest virtual address that must be coverd by
- *     the translated machine VHPT.
- *  3: vhpt: means the machine format VHPT converting from tlb.
- *    NOTES:
- *  1: In case of the machine address is discontiguous,
- *     "tlb" needs to be covered by several machine VHPT. va
- *     is used to choice one of them.
- *  2: Foreign map is supported in this API.
- *    RETURN:
- *  0/1: means successful or fail.
- *
- */
-int __tlb_to_vhpt(thash_cb_t *hcb, thash_data_t *vhpt, u64 va)
-{
-    u64 padr,pte;
-    ASSERT ( hcb->ht == THASH_VHPT );
-    padr = vhpt->ppn >>(vhpt->ps-ARCH_PAGE_SHIFT)<<vhpt->ps;
-    padr += va&((1UL<<vhpt->ps)-1);
-    pte=lookup_domain_mpa(current->domain,padr);
-    if((pte>>56))
-        return 0;
-    vhpt->etag = ia64_ttag(va);
-    vhpt->ps = PAGE_SHIFT;
-    vhpt->ppn = 
(pte&((1UL<<IA64_MAX_PHYS_BITS)-(1UL<<PAGE_SHIFT)))>>ARCH_PAGE_SHIFT;
-    vhpt->next = 0;
-    return 1;
-}
-
-static void thash_remove_cch(thash_cb_t *hcb, thash_data_t *hash)
+static void thash_recycle_cch(thash_cb_t *hcb, thash_data_t *hash)
 {
     thash_data_t *p;
-    if(hash->next){
-        p=hash->next;
-        while(p->next)
-            p=p->next;
-        p->next=hcb->cch_freelist;
-        hcb->cch_freelist=hash->next;
-        hash->next=0;
+    int i=0;
+    
+    p=hash;
+    for(i=0; i < MAX_CCN_DEPTH; i++){
+        p=p->next;
+    }
+    p->next=hcb->cch_freelist;
+    hcb->cch_freelist=hash->next;
+    hash->len=0;
+    hash->next=0;
+}
+
+
+
+
+static void vmx_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa)
+{
+    u64 tag;
+    thash_data_t *head, *cch;
+    pte = pte & ~PAGE_FLAGS_RV_MASK;
+
+    head = (thash_data_t *)ia64_thash(ifa);
+    tag = ia64_ttag(ifa);
+    if( INVALID_VHPT(head) ) {
+        head->page_flags = pte;
+        head->etag = tag;
+        return;
+    }
+
+    if(head->len>=MAX_CCN_DEPTH){
+        thash_recycle_cch(hcb, head);
+        cch = cch_alloc(hcb);
+    }
+    else{
+        cch = __alloc_chain(hcb);
+    }
+    cch->page_flags=head->page_flags;
+    cch->etag=head->etag;
+    cch->next=head->next;
+    head->page_flags=pte;
+    head->etag=tag;
+    head->next = cch;
+    head->len = cch->len+1;
+    cch->len = 0;
+    return;
+}
+
+void thash_vhpt_insert(VCPU *v, u64 pte, u64 itir, u64 va)
+{
+    u64 phy_pte;
+    phy_pte=translate_phy_pte(v, &pte, itir, va);
+    vmx_vhpt_insert(vcpu_get_vhpt(v), phy_pte, itir, va);
+}
+/*
+ *   vhpt lookup
+ */
+
+thash_data_t * vhpt_lookup(u64 va)
+{
+    thash_data_t *hash, *head;
+    u64 tag, pte;
+    head = (thash_data_t *)ia64_thash(va);
+    hash=head;
+    tag = ia64_ttag(va);
+    do{
+        if(hash->etag == tag)
+            break;
+        hash=hash->next;
+    }while(hash);
+    if(hash && hash!=head){
+        pte = hash->page_flags;
+        hash->page_flags = head->page_flags;
+        head->page_flags = pte;
+        tag = hash->etag;
+        hash->etag = head->etag;
+        head->etag = tag;
+        head->len = hash->len;
         hash->len=0;
-    }
-}
-
-/*  vhpt only has entries with PAGE_SIZE page size */
-
-void thash_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa)
-{
-    thash_data_t   vhpt_entry, *hash_table, *cch;
-    vhpt_entry.page_flags = pte & ~PAGE_FLAGS_RV_MASK;
-    vhpt_entry.itir=itir;
-
-    if ( !__tlb_to_vhpt(hcb, &vhpt_entry, ifa) ) {
-        return;
-    //panic("Can't convert to machine VHPT entry\n");
-    }
-
-    hash_table = (thash_data_t *)ia64_thash(ifa);
-    if( INVALID_VHPT(hash_table) ) {
-        *hash_table = vhpt_entry;
-        hash_table->next = 0;
-       return;
-    }
-
-    cch = hash_table;
-    while(cch){
-        if(cch->etag == vhpt_entry.etag){
-            if(cch->ppn == vhpt_entry.ppn)
-                return;
-            else
-                while(1);
-        }
-        cch = cch->next;
-    }
-
-    if(hash_table->len>=MAX_CCN_DEPTH){
-       thash_remove_cch(hcb, hash_table);
-       cch = cch_alloc(hcb);
-       *cch = *hash_table;
-        *hash_table = vhpt_entry;
-       hash_table->len = 1;
-        hash_table->next = cch;
-       return;
-    }
-
-    // TODO: Add collision chain length limitation.
-     cch = __alloc_chain(hcb);
-     if(cch == NULL){
-           *hash_table = vhpt_entry;
-            hash_table->next = 0;
-     }else{
-            *cch = *hash_table;
-            *hash_table = vhpt_entry;
-            hash_table->next = cch;
-           hash_table->len = cch->len + 1;
-           cch->len = 0;
-
-    }
-    return /*hash_table*/;
-}
-
-/*
- *   vhpt lookup
- */
-
-thash_data_t * vhpt_lookup(u64 va)
-{
-    thash_data_t *hash;
-    u64 tag;
-    hash = (thash_data_t *)ia64_thash(va);
-    tag = ia64_ttag(va);
-    while(hash){
-       if(hash->etag == tag)
-               return hash;
-        hash=hash->next;
-    }
-    return NULL;
+        return head;
+    }
+    return hash;
+}
+
+u64 guest_vhpt_lookup(u64 iha, u64 *pte)
+{
+    u64 ret;
+    vhpt_lookup(iha);
+    asm volatile ("rsm psr.ic|psr.i;;"
+                  "srlz.d;;"
+                  "ld8.s r9=[%1];;"
+                  "tnat.nz p6,p7=r9;;"
+                  "(p6) mov %0=1;"
+                  "(p6) mov r9=r0;"
+                  "(p7) mov %0=r0;"
+                  "(p7) st8 [%2]=r9;;"
+                  "ssm psr.ic;;"
+                  "srlz.d;;"
+                  "ssm psr.i;;"
+             : "=r"(ret) : "r"(iha), "r"(pte):"memory");
+    return ret;
 }
 
 
@@ -310,7 +289,6 @@ static void vtlb_purge(thash_cb_t *hcb, 
 /*
  *  purge VHPT and machine TLB
  */
-
 static void vhpt_purge(thash_cb_t *hcb, u64 va, u64 ps)
 {
     thash_data_t *hash_table, *prev, *next;
@@ -332,7 +310,7 @@ static void vhpt_purge(thash_cb_t *hcb, 
                     prev->next=next->next;
                     cch_free(hcb,next);
                     hash_table->len--;
-                    break;
+                    break; 
                 }
                 prev=next;
                 next=next->next;
@@ -347,16 +325,21 @@ static void vhpt_purge(thash_cb_t *hcb, 
  * Recycle all collisions chain in VTLB or VHPT.
  *
  */
-
-void thash_recycle_cch(thash_cb_t *hcb)
-{
-    thash_data_t    *hash_table;
-
-    hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
-    for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
-        thash_remove_cch(hcb,hash_table);
-    }
-}
+void thash_recycle_cch_all(thash_cb_t *hcb)
+{
+    int num;
+    thash_data_t *head;
+    head=hcb->hash;
+    num = (hcb->hash_sz/sizeof(thash_data_t));
+    do{
+        head->len = 0;
+        head->next = 0;
+        head++;
+        num--;
+    }while(num);
+    cch_mem_init(hcb);
+}
+
 
 thash_data_t *__alloc_chain(thash_cb_t *hcb)
 {
@@ -364,7 +347,7 @@ thash_data_t *__alloc_chain(thash_cb_t *
 
     cch = cch_alloc(hcb);
     if(cch == NULL){
-        thash_recycle_cch(hcb);
+        thash_recycle_cch_all(hcb);
         cch = cch_alloc(hcb);
     }
     return cch;
@@ -385,51 +368,38 @@ void vtlb_insert(thash_cb_t *hcb, u64 pt
     /* int flag; */
     ia64_rr vrr;
     /* u64 gppn, ppns, ppne; */
-    u64 tag, ps;
-    ps = itir_ps(itir);
+    u64 tag;
     vcpu_get_rr(current, va, &vrr.rrval);
-    if (vrr.ps != ps) {
+#ifdef VTLB_DEBUG    
+    if (vrr.ps != itir_ps(itir)) {
 //        machine_tlb_insert(hcb->vcpu, entry);
         panic_domain(NULL, "not preferred ps with va: 0x%lx vrr.ps=%d 
ps=%ld\n",
-                     va, vrr.ps, ps);
+             va, vrr.ps, itir_ps(itir));
         return;
     }
+#endif
     hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
     if( INVALID_TLB(hash_table) ) {
         hash_table->page_flags = pte;
         hash_table->itir=itir;
         hash_table->etag=tag;
         hash_table->next = 0;
-    }
-    else if (hash_table->len>=MAX_CCN_DEPTH){
-        thash_remove_cch(hcb, hash_table);
+        return;
+    }
+    if (hash_table->len>=MAX_CCN_DEPTH){
+        thash_recycle_cch(hcb, hash_table);
         cch = cch_alloc(hcb);
-        *cch = *hash_table;
-        hash_table->page_flags = pte;
-        hash_table->itir=itir;
-        hash_table->etag=tag;
-        hash_table->len = 1;
-        hash_table->next = cch;
-    }
-
+    }
     else {
-        // TODO: Add collision chain length limitation.
         cch = __alloc_chain(hcb);
-        if(cch == NULL){
-            hash_table->page_flags = pte;
-            hash_table->itir=itir;
-            hash_table->etag=tag;
-            hash_table->next = 0;
-        }else{
-            *cch = *hash_table;
-            hash_table->page_flags = pte;
-            hash_table->itir=itir;
-            hash_table->etag=tag;
-            hash_table->next = cch;
-            hash_table->len = cch->len + 1;
-            cch->len = 0;
-        }
-    }
+    }
+    *cch = *hash_table;
+    hash_table->page_flags = pte;
+    hash_table->itir=itir;
+    hash_table->etag=tag;
+    hash_table->next = cch;
+    hash_table->len = cch->len + 1;
+    cch->len = 0;
     return ;
 }
 
@@ -473,6 +443,23 @@ void thash_purge_entries(VCPU *v, u64 va
     vhpt_purge(&v->arch.vhpt, va, ps);
 }
 
+u64 translate_phy_pte(VCPU *v, u64 *pte, u64 itir, u64 va)
+{
+    u64 ps, addr;
+    union pte_flags phy_pte;
+    ps = itir_ps(itir);
+    phy_pte.val = *pte;
+    addr = *pte;
+    addr = ((addr & _PAGE_PPN_MASK)>>ps<<ps)|(va&((1UL<<ps)-1));
+    addr = lookup_domain_mpa(v->domain, addr);
+    if(addr & GPFN_IO_MASK){
+        *pte |= VTLB_PTE_IO;
+        return -1;
+    }
+    phy_pte.ppn = addr >> ARCH_PAGE_SHIFT;
+    return phy_pte.val;
+}
+
 
 /*
  * Purge overlap TCs and then insert the new entry to emulate itc ops.
@@ -480,59 +467,79 @@ void thash_purge_entries(VCPU *v, u64 va
  */
 void thash_purge_and_insert(VCPU *v, u64 pte, u64 itir, u64 ifa)
 {
-    u64 ps, va;
+    u64 ps;//, va;
+    u64 phy_pte;
     ps = itir_ps(itir);
-    va = PAGEALIGN(ifa,ps);
-    if(vcpu_quick_region_check(v->arch.tc_regions,va))
-        vtlb_purge(&v->arch.vtlb, va, ps);
-    vhpt_purge(&v->arch.vhpt, va, ps);
-    if((ps!=PAGE_SHIFT)||(pte&VTLB_PTE_IO)){
-        vtlb_insert(&v->arch.vtlb, pte, itir, va);
-       vcpu_quick_region_set(PSCBX(v,tc_regions),va);
-    }  
-    if(!(pte&VTLB_PTE_IO)){
-        va = PAGEALIGN(ifa,PAGE_SHIFT);
-        thash_vhpt_insert(&v->arch.vhpt, pte, itir, va);
-    }
-}
-
-
+
+    if(VMX_DOMAIN(v)){
+        phy_pte = translate_phy_pte(v, &pte, itir, ifa);
+        if(ps==PAGE_SHIFT){
+            if(!(pte&VTLB_PTE_IO)){
+                vhpt_purge(&v->arch.vhpt, ifa, ps);
+                vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
+            }
+            else{
+                vhpt_purge(&v->arch.vhpt, ifa, ps);
+                vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
+                vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
+            }
+        }
+        else{
+            vhpt_purge(&v->arch.vhpt, ifa, ps);
+            vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
+            vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
+            if(!(pte&VTLB_PTE_IO)){
+                vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
+            }
+        }
+    }
+    else{
+        phy_pte = translate_phy_pte(v, &pte, itir, ifa);
+        if(ps!=PAGE_SHIFT){
+            vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
+            vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
+        }
+        machine_tlb_purge(ifa, ps);
+        vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
+    }
+}
 
 /*
  * Purge all TCs or VHPT entries including those in Hash table.
  *
  */
 
-// TODO: add sections.
+//TODO: add sections.
 void thash_purge_all(VCPU *v)
 {
-    thash_data_t    *hash_table;
-    /* thash_data_t    *entry; */
-    thash_cb_t  *hcb,*vhpt;
-    /* u64 i, start, end; */
-    hcb =&v->arch.vtlb;
+    int num;
+    thash_data_t *head;
+    thash_cb_t  *vtlb,*vhpt;
+    vtlb =&v->arch.vtlb;
     vhpt =&v->arch.vhpt;
-#ifdef  VTLB_DEBUG
-       extern u64  sanity_check;
-    static u64 statistics_before_purge_all=0;
-    if ( statistics_before_purge_all ) {
-       sanity_check = 1;
-        check_vtlb_sanity(hcb);
-    }
-#endif
-    ASSERT ( hcb->ht == THASH_TLB );
-
-    hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
-    for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
-        INVALIDATE_TLB_HEADER(hash_table);
-    }
-    cch_mem_init (hcb);
-
-    hash_table = (thash_data_t*)((u64)vhpt->hash + vhpt->hash_sz);
-    for (--hash_table;(u64)hash_table >= (u64)vhpt->hash;hash_table--) {
-        INVALIDATE_VHPT_HEADER(hash_table);
-    }
-    cch_mem_init (vhpt);
+
+    head=vtlb->hash;
+    num = (vtlb->hash_sz/sizeof(thash_data_t));
+    do{
+        head->page_flags = 0;
+        head->etag = 1UL<<63;
+        head->next = 0;
+        head++;
+        num--;
+    }while(num);
+    cch_mem_init(vtlb);
+    
+    head=vhpt->hash;
+    num = (vhpt->hash_sz/sizeof(thash_data_t));
+    do{
+        head->page_flags = 0;
+        head->etag = 1UL<<63;
+        head->next = 0;
+        head++;
+        num--;
+    }while(num);
+    cch_mem_init(vhpt);
+
     local_flush_tlb_all();
 }
 
@@ -547,7 +554,7 @@ void thash_purge_all(VCPU *v)
 
 thash_data_t *vtlb_lookup(VCPU *v, u64 va,int is_data)
 {
-    thash_data_t    *hash_table, *cch;
+    thash_data_t  *cch;
     u64     tag;
     ia64_rr vrr;
     thash_cb_t * hcb= &v->arch.vtlb;
@@ -559,18 +566,14 @@ thash_data_t *vtlb_lookup(VCPU *v, u64 v
     if(vcpu_quick_region_check(v->arch.tc_regions,va)==0)
         return NULL;
     
-
     vcpu_get_rr(v,va,&vrr.rrval);
-    hash_table = vsa_thash( hcb->pta, va, vrr.rrval, &tag);
-
-    if ( INVALID_ENTRY(hcb, hash_table ) )
-        return NULL;
-
-
-    for (cch=hash_table; cch; cch = cch->next) {
+    cch = vsa_thash( hcb->pta, va, vrr.rrval, &tag);
+
+    do{
         if(cch->etag == tag)
             return cch;
-    }
+        cch = cch->next;
+    }while(cch);
     return NULL;
 }
 
@@ -580,198 +583,33 @@ thash_data_t *vtlb_lookup(VCPU *v, u64 v
  */
 void thash_init(thash_cb_t *hcb, u64 sz)
 {
-    thash_data_t    *hash_table;
-
-    cch_mem_init (hcb);
+    int num;
+    thash_data_t *head, *p;
+
     hcb->pta.val = (unsigned long)hcb->hash;
     hcb->pta.vf = 1;
     hcb->pta.ve = 1;
     hcb->pta.size = sz;
-//    hcb->get_rr_fn = vmmu_get_rr;
-    ASSERT ( hcb->hash_sz % sizeof(thash_data_t) == 0 );
-    hash_table = (thash_data_t*)((u64)hcb->hash + hcb->hash_sz);
-
-    for (--hash_table;(u64)hash_table >= (u64)hcb->hash;hash_table--) {
-        INVALIDATE_HASH_HEADER(hcb,hash_table);
-    }
-}
-
-#ifdef  VTLB_DEBUG
-/*
-static  u64 cch_length_statistics[MAX_CCH_LENGTH+1];
-u64  sanity_check=0;
-u64 vtlb_chain_sanity(thash_cb_t *vtlb, thash_cb_t *vhpt, thash_data_t *hash)
-{
-    thash_data_t *cch;
-    thash_data_t    *ovl;
-    search_section_t s_sect;
-    u64     num=0;
-
-    s_sect.v = 0;
-    for (cch=hash; cch; cch=cch->next) {
-        ovl = thash_find_overlap(vhpt, cch, s_sect);
-        while ( ovl != NULL ) {
-            ovl->checked = 1;
-            ovl = (vhpt->next_overlap)(vhpt);
-        };
-        num ++;
-    }
-    if ( num >= MAX_CCH_LENGTH ) {
-       cch_length_statistics[MAX_CCH_LENGTH] ++;
-    }
-    else {
-       cch_length_statistics[num] ++;
-    }
-    return num;
-}
-
-void check_vtlb_sanity(thash_cb_t *vtlb)
-{
-//    struct page_info *page;
-    u64  hash_num, i, psr;
-    static u64 check_ok_num, check_fail_num,check_invalid;
-//  void *vb1, *vb2;
-    thash_data_t  *hash, *cch;
-    thash_data_t    *ovl;
-    search_section_t s_sect;
-    thash_cb_t *vhpt = vtlb->vhpt;
-    u64   invalid_ratio;
- 
-    if ( sanity_check == 0 ) return;
-    sanity_check --;
-    s_sect.v = 0;
-//    page = alloc_domheap_pages (NULL, VCPU_TLB_ORDER, 0);
-//    if ( page == NULL ) {
-//        panic("No enough contiguous memory for init_domain_mm\n");
-//    };
-//    vb1 = page_to_virt(page);
-//    printf("Allocated page=%lp vbase=%lp\n", page, vb1);
-//    vb2 = vb1 + vtlb->hash_sz;
-    hash_num = vhpt->hash_sz / sizeof(thash_data_t);
-//    printf("vb2=%lp, size=%lx hash_num=%lx\n", vb2, vhpt->hash_sz, hash_num);
-    printf("vtlb=%p, hash=%p size=0x%lx; vhpt=%p, hash=%p size=0x%lx\n", 
-                vtlb, vtlb->hash,vtlb->hash_sz,
-                vhpt, vhpt->hash, vhpt->hash_sz);
-    //memcpy(vb1, vtlb->hash, vtlb->hash_sz);
-    //memcpy(vb2, vhpt->hash, vhpt->hash_sz);
-    for ( i=0; i < 
sizeof(cch_length_statistics)/sizeof(cch_length_statistics[0]); i++ ) {
-       cch_length_statistics[i] = 0;
-    }
-
-    local_irq_save(psr);
-
-    hash = vhpt->hash;
-    for (i=0; i < hash_num; i++) {
-        if ( !INVALID_ENTRY(vhpt, hash) ) {
-            for ( cch= hash; cch; cch=cch->next) {
-                cch->checked = 0;
-            }
-        }
-        hash ++;
-    }
-    printf("Done vhpt clear checked flag, hash_num=0x%lx\n", hash_num);
-    check_invalid = 0;
-    check_ok_num=0;
-    hash = vtlb->hash;
-    for ( i=0; i< hash_num; i++ ) {
-        if ( !INVALID_ENTRY(vtlb, hash) ) {
-            check_ok_num += vtlb_chain_sanity(vtlb, vhpt, hash);
-        }
-        else {
-            check_invalid++;
-        }
-        hash ++;
-    }
-    printf("Done vtlb entry check, hash=%p\n", hash);
-    printf("check_ok_num = 0x%lx check_invalid=0x%lx\n", 
check_ok_num,check_invalid);
-    invalid_ratio = 1000*check_invalid / hash_num;
-    printf("%02ld.%01ld%% entries are invalid\n", 
-               invalid_ratio/10, invalid_ratio % 10 );
-    for (i=0; i<NDTRS; i++) {
-        ovl = thash_find_overlap(vhpt, &vtlb->ts->dtr[i], s_sect);
-        while ( ovl != NULL ) {
-            ovl->checked = 1;
-            ovl = (vhpt->next_overlap)(vhpt);
-        };
-    }
-    printf("Done dTR\n");
-    for (i=0; i<NITRS; i++) {
-        ovl = thash_find_overlap(vhpt, &vtlb->ts->itr[i], s_sect);
-        while ( ovl != NULL ) {
-            ovl->checked = 1;
-            ovl = (vhpt->next_overlap)(vhpt);
-        };
-    }
-    printf("Done iTR\n");
-    check_fail_num = 0;
-    check_invalid = 0;
-    check_ok_num=0;
-    hash = vhpt->hash;
-    for (i=0; i < hash_num; i++) {
-        if ( !INVALID_ENTRY(vhpt, hash) ) {
-            for ( cch= hash; cch; cch=cch->next) {
-                if ( !cch->checked ) {
-                    printf ("!!!Hash=%p cch=%p not within vtlb\n", hash, cch);
-                    check_fail_num ++;
-                }
-                else {
-                    check_ok_num++;
-                }
-            }
-        }
-        else {
-            check_invalid ++;
-        }
-        hash ++;
-    }
-    local_irq_restore(psr);
-    printf("check_ok_num=0x%lx check_fail_num=0x%lx check_invalid=0x%lx\n", 
-            check_ok_num, check_fail_num, check_invalid);
-    //memcpy(vtlb->hash, vb1, vtlb->hash_sz);
-    //memcpy(vhpt->hash, vb2, vhpt->hash_sz);
-    printf("The statistics of collision chain length is listed\n");
-    for ( i=0; i < 
sizeof(cch_length_statistics)/sizeof(cch_length_statistics[0]); i++ ) {
-       printf("CCH length=%02ld, chain number=%ld\n", i, 
cch_length_statistics[i]);
-    }
-//    free_domheap_pages(page, VCPU_TLB_ORDER);
-    printf("Done check_vtlb\n");
-}
-
-void dump_vtlb(thash_cb_t *vtlb)
-{
-    static u64  dump_vtlb=0;
-    thash_data_t  *hash, *cch, *tr;
-    u64     hash_num,i;
-
-    if ( dump_vtlb == 0 ) return;
-    dump_vtlb --;
-    hash_num = vtlb->hash_sz / sizeof(thash_data_t);
-    hash = vtlb->hash;
-
-    printf("Dump vTC\n");
-    for ( i = 0; i < hash_num; i++ ) {
-        if ( !INVALID_ENTRY(vtlb, hash) ) {
-            printf("VTLB at hash=%p\n", hash);
-            for (cch=hash; cch; cch=cch->next) {
-                printf("Entry %p va=%lx ps=%d rid=%d\n",
-                    cch, cch->vadr, cch->ps, cch->rid);
-            }
-        }
-        hash ++;
-    }
-    printf("Dump vDTR\n");
-    for (i=0; i<NDTRS; i++) {
-        tr = &DTR(vtlb,i);
-        printf("Entry %p va=%lx ps=%d rid=%d\n",
-                    tr, tr->vadr, tr->ps, tr->rid);
-    }
-    printf("Dump vITR\n");
-    for (i=0; i<NITRS; i++) {
-        tr = &ITR(vtlb,i);
-        printf("Entry %p va=%lx ps=%d rid=%d\n",
-                    tr, tr->vadr, tr->ps, tr->rid);
-    }
-    printf("End of vTLB dump\n");
-}
-*/
-#endif
+    hcb->cch_rec_head = hcb->hash;
+    
+    head=hcb->hash;
+    num = (hcb->hash_sz/sizeof(thash_data_t));
+    do{
+        head->itir = PAGE_SHIFT<<2;
+        head->etag = 1UL<<63;
+        head->next = 0;
+        head++;
+        num--;
+    }while(num);
+    
+    hcb->cch_freelist = p = hcb->cch_buf;
+    num = (hcb->cch_sz/sizeof(thash_data_t))-1;
+    do{
+        p->itir = PAGE_SHIFT<<2;
+        p->next =p+1;
+        p++;
+        num--;
+    }while(num);
+    p->itir = PAGE_SHIFT<<2;
+    p->next = NULL;
+}
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/dom_fw.c        Fri Jun 02 12:31:48 2006 -0500
@@ -15,6 +15,7 @@
 #include <asm/pal.h>
 #include <asm/sal.h>
 #include <asm/meminit.h>
+#include <asm/fpswa.h>
 #include <xen/compile.h>
 #include <xen/acpi.h>
 
@@ -60,6 +61,29 @@ dom_pa(unsigned long imva)
     } while (0)
 
 // builds a hypercall bundle at domain physical address
+static void dom_fpswa_hypercall_patch(struct domain *d)
+{
+       unsigned long *entry_imva, *patch_imva;
+       unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
+       unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
+
+#ifndef CONFIG_XEN_IA64_DOM0_VP
+       if (d == dom0) {
+               entry_paddr += dom0_start;
+               patch_paddr += dom0_start;
+       }
+#endif
+       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, entry_paddr);
+       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, patch_paddr);
+       entry_imva = (unsigned long *) domain_mpa_to_imva(d, entry_paddr);
+       patch_imva = (unsigned long *) domain_mpa_to_imva(d, patch_paddr);
+
+       *entry_imva++ = patch_paddr;
+       *entry_imva   = 0;
+       build_hypercall_bundle(patch_imva, d->arch.breakimm, 
FW_HYPERCALL_FPSWA, 1);
+}
+
+// builds a hypercall bundle at domain physical address
 static void dom_efi_hypercall_patch(struct domain *d, unsigned long paddr, 
unsigned long hypercall)
 {
        unsigned long *imva;
@@ -71,7 +95,6 @@ static void dom_efi_hypercall_patch(stru
        imva = (unsigned long *) domain_mpa_to_imva(d, paddr);
        build_hypercall_bundle(imva, d->arch.breakimm, hypercall, 1);
 }
-
 
 // builds a hypercall bundle at domain physical address
 static void dom_fw_hypercall_patch(struct domain *d, unsigned long paddr, 
unsigned long hypercall,unsigned long ret)
@@ -697,6 +720,7 @@ struct dom0_passthrough_arg {
 struct dom0_passthrough_arg {
 #ifdef CONFIG_XEN_IA64_DOM0_VP
     struct domain*      d;
+    int                 flags;
 #endif
     efi_memory_desc_t *md;
     int*                i;
@@ -711,7 +735,7 @@ dom_fw_dom0_passthrough(efi_memory_desc_
 #ifdef CONFIG_XEN_IA64_DOM0_VP
     struct domain* d = arg->d;
     u64 start = md->phys_addr;
-    u64 end = start + (md->num_pages << EFI_PAGE_SHIFT);
+    u64 size = md->num_pages << EFI_PAGE_SHIFT;
 
     if (md->type == EFI_MEMORY_MAPPED_IO ||
         md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
@@ -720,13 +744,12 @@ dom_fw_dom0_passthrough(efi_memory_desc_
         //    It requires impractical memory to map such a huge region
         //    to a domain.
         //    For now we don't map it, but later we must fix this.
-        if (md->type == EFI_MEMORY_MAPPED_IO &&
-            ((md->num_pages << EFI_PAGE_SHIFT) > 0x100000000UL))
+        if (md->type == EFI_MEMORY_MAPPED_IO && (size > 0x100000000UL))
             return 0;
 
-        paddr = assign_domain_mmio_page(d, start, end - start);
+        paddr = assign_domain_mmio_page(d, start, size);
     } else
-        paddr = assign_domain_mach_page(d, start, end - start);
+        paddr = assign_domain_mach_page(d, start, size, arg->flags);
 #else
     paddr = md->phys_addr;
 #endif
@@ -771,6 +794,7 @@ dom_fw_init (struct domain *d, const cha
        struct ia64_sal_systab *sal_systab;
        struct ia64_sal_desc_entry_point *sal_ed;
        struct ia64_sal_desc_ap_wakeup *sal_wakeup;
+       fpswa_interface_t *fpswa_inf;
        efi_memory_desc_t *efi_memmap, *md;
        struct ia64_boot_param *bp;
        unsigned long *pfn;
@@ -812,6 +836,7 @@ dom_fw_init (struct domain *d, const cha
        sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
        sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
        sal_wakeup  = (void *) cp; cp += sizeof(*sal_wakeup);
+       fpswa_inf   = (void *) cp; cp += sizeof(*fpswa_inf);
        efi_memmap  = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
        bp          = (void *) cp; cp += sizeof(*bp);
        pfn         = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
@@ -819,6 +844,7 @@ dom_fw_init (struct domain *d, const cha
 
        /* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
        d->arch.efi_runtime = efi_runtime;
+       d->arch.fpswa_inf   = fpswa_inf;
 
        if (args) {
                if (arglen >= 1024)
@@ -874,9 +900,10 @@ dom_fw_init (struct domain *d, const cha
        }
        if (d == dom0) {
 #ifdef CONFIG_XEN_IA64_DOM0_VP
-# define ASSIGN_DOMAIN_MACH_PAGE(d, p) assign_domain_mach_page(d, p, PAGE_SIZE)
+# define ASSIGN_DOMAIN_MACH_PAGE(d, p) \
+        assign_domain_mach_page((d), (p), PAGE_SIZE, ASSIGN_readonly)
 #else
-# define ASSIGN_DOMAIN_MACH_PAGE(d, p) ({p;})
+# define ASSIGN_DOMAIN_MACH_PAGE(d, p) (p)
 #endif
 
                printf("Domain0 EFI passthrough:");
@@ -960,6 +987,11 @@ dom_fw_init (struct domain *d, const cha
                checksum += *cp;
 
        sal_systab->checksum = -checksum;
+
+       /* Fill in the FPSWA interface: */
+       fpswa_inf->revision = fpswa_interface->revision;
+       dom_fpswa_hypercall_patch(d);
+       fpswa_inf->fpswa = (void *) FW_HYPERCALL_FPSWA_ENTRY_PADDR + 
start_mpaddr;
 
        i = 0;
        if (d == dom0) {
@@ -990,17 +1022,24 @@ dom_fw_init (struct domain *d, const cha
                /* pass through the I/O port space */
                if (!running_on_sim) {
                        struct dom0_passthrough_arg arg;
+                       arg.md = &efi_memmap[i];
+                       arg.i = &i;
 #ifdef CONFIG_XEN_IA64_DOM0_VP
                        arg.d = d;
-#endif
-                       arg.md = &efi_memmap[i];
-                       arg.i = &i;
+                       arg.flags = ASSIGN_writable;
+#endif
                        //XXX Is this needed?
                        efi_memmap_walk_type(EFI_RUNTIME_SERVICES_CODE,
                                             dom_fw_dom0_passthrough, &arg);
                        // for ACPI table.
+#ifdef CONFIG_XEN_IA64_DOM0_VP
+                       arg.flags = ASSIGN_readonly;
+#endif
                        efi_memmap_walk_type(EFI_RUNTIME_SERVICES_DATA,
                                             dom_fw_dom0_passthrough, &arg);
+#ifdef CONFIG_XEN_IA64_DOM0_VP
+                       arg.flags = ASSIGN_writable;
+#endif
                        efi_memmap_walk_type(EFI_ACPI_RECLAIM_MEMORY,
                                             dom_fw_dom0_passthrough, &arg);
                        efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO,
@@ -1037,7 +1076,7 @@ dom_fw_init (struct domain *d, const cha
        bp->console_info.num_rows = 25;
        bp->console_info.orig_x = 0;
        bp->console_info.orig_y = 24;
-       bp->fpswa = 0;
+       bp->fpswa = dom_pa((unsigned long) fpswa_inf);
        if (d == dom0) {
                // XXX CONFIG_XEN_IA64_DOM0_VP
                // initrd_start address is hard coded in start_kernel()
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/domain.c        Fri Jun 02 12:31:48 2006 -0500
@@ -42,6 +42,7 @@
 
 #include <asm/vcpu.h>   /* for function declarations */
 #include <public/arch-ia64.h>
+#include <xen/domain.h>
 #include <asm/vmx.h>
 #include <asm/vmx_vcpu.h>
 #include <asm/vmx_vpd.h>
@@ -79,6 +80,31 @@ void build_physmap_table(struct domain *
 
 static void try_to_clear_PGC_allocate(struct domain* d,
                                       struct page_info* page);
+
+#ifdef CONFIG_XEN_IA64_DOM0_VP
+static struct domain *dom_xen, *dom_io;
+
+// followings are stolen from arch_init_memory() @ xen/arch/x86/mm.c
+void
+alloc_dom_xen_and_dom_io(void)
+{
+    /*
+     * Initialise our DOMID_XEN domain.
+     * Any Xen-heap pages that we will allow to be mapped will have
+     * their domain field set to dom_xen.
+     */
+    dom_xen = alloc_domain(DOMID_XEN);
+    BUG_ON(dom_xen == NULL);
+
+    /*
+     * Initialise our DOMID_IO domain.
+     * This domain owns I/O pages that are within the range of the page_info
+     * array. Mappings occur at the priv of the caller.
+     */
+    dom_io = alloc_domain(DOMID_IO);
+    BUG_ON(dom_io == NULL);
+}
+#endif
 
 /* this belongs in include/asm, but there doesn't seem to be a suitable place 
*/
 void arch_domain_destroy(struct domain *d)
@@ -612,6 +638,12 @@ share_xen_page_with_guest(struct page_in
     spin_unlock(&d->page_alloc_lock);
 }
 
+void
+share_xen_page_with_privileged_guests(struct page_info *page, int readonly)
+{
+    share_xen_page_with_guest(page, dom_xen, readonly);
+}
+
 //XXX !xxx_present() should be used instread of !xxx_none()?
 static pte_t*
 lookup_alloc_domain_pte(struct domain* d, unsigned long mpaddr)
@@ -793,17 +825,19 @@ assign_new_domain0_page(struct domain *d
 }
 
 /* map a physical address to the specified metaphysical addr */
+// flags: currently only ASSIGN_readonly
 void
 __assign_domain_page(struct domain *d,
-                     unsigned long mpaddr, unsigned long physaddr)
+                     unsigned long mpaddr, unsigned long physaddr,
+                     unsigned long flags)
 {
     pte_t *pte;
+    unsigned long arflags = (flags & ASSIGN_readonly)? _PAGE_AR_R: 
_PAGE_AR_RWX;
 
     pte = lookup_alloc_domain_pte(d, mpaddr);
     if (pte_none(*pte)) {
-        set_pte(pte,
-                pfn_pte(physaddr >> PAGE_SHIFT,
-                        __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
+        set_pte(pte, pfn_pte(physaddr >> PAGE_SHIFT,
+                             __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags)));
         mb ();
     } else
         printk("%s: mpaddr %lx already mapped!\n", __func__, mpaddr);
@@ -820,7 +854,7 @@ assign_domain_page(struct domain *d,
     BUG_ON((physaddr & GPFN_IO_MASK) != GPFN_MEM);
     ret = get_page(page, d);
     BUG_ON(ret == 0);
-    __assign_domain_page(d, mpaddr, physaddr);
+    __assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable);
 
     //XXX CONFIG_XEN_IA64_DOM0_VP
     //    TODO racy
@@ -830,12 +864,13 @@ assign_domain_page(struct domain *d,
 #ifdef CONFIG_XEN_IA64_DOM0_VP
 static void
 assign_domain_same_page(struct domain *d,
-                          unsigned long mpaddr, unsigned long size)
+                        unsigned long mpaddr, unsigned long size,
+                        unsigned long flags)
 {
     //XXX optimization
     unsigned long end = mpaddr + size;
     for (; mpaddr < end; mpaddr += PAGE_SIZE) {
-        __assign_domain_page(d, mpaddr, mpaddr);
+        __assign_domain_page(d, mpaddr, mpaddr, flags);
     }
 }
 
@@ -902,15 +937,16 @@ assign_domain_mmio_page(struct domain *d
                 __func__, __LINE__, d, mpaddr, size);
         return -EINVAL;
     }
-    assign_domain_same_page(d, mpaddr, size);
+    assign_domain_same_page(d, mpaddr, size, ASSIGN_writable);
     return mpaddr;
 }
 
 unsigned long
 assign_domain_mach_page(struct domain *d,
-                        unsigned long mpaddr, unsigned long size)
-{
-    assign_domain_same_page(d, mpaddr, size);
+                        unsigned long mpaddr, unsigned long size,
+                        unsigned long flags)
+{
+    assign_domain_same_page(d, mpaddr, size, flags);
     return mpaddr;
 }
 
@@ -1072,15 +1108,14 @@ unsigned long lookup_domain_mpa(struct d
                }
                pteval = pfn_pte(mpaddr >> PAGE_SHIFT,
                        __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
-               pte = &pteval;
-               return *(unsigned long *)pte;
+               return pte_val(pteval);
        }
 #endif
        pte = lookup_noalloc_domain_pte(d, mpaddr);
        if (pte != NULL) {
                if (pte_present(*pte)) {
 //printk("lookup_domain_page: found mapping for %lx, 
pte=%lx\n",mpaddr,pte_val(*pte));
-                       return *(unsigned long *)pte;
+                       return pte_val(*pte);
                } else if (VMX_DOMAIN(d->vcpu[0]))
                        return GPFN_INV_MASK;
        }
@@ -1094,7 +1129,10 @@ unsigned long lookup_domain_mpa(struct d
                printk("%s: bad mpa 0x%lx (=> 0x%lx)\n", __func__,
                       mpaddr, (unsigned long)d->max_pages << PAGE_SHIFT);
        mpafoo(mpaddr);
-       return 0;
+
+       //XXX This is a work around until the emulation memory access to a 
region
+       //    where memory or device are attached is implemented.
+       return pte_val(pfn_pte(0, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | 
_PAGE_AR_RWX)));
 }
 
 #ifdef CONFIG_XEN_IA64_DOM0_VP
@@ -1118,21 +1156,23 @@ out:
 
 // caller must get_page(mfn_to_page(mfn)) before
 // caller must call set_gpfn_from_mfn().
+// flags: currently only ASSIGN_readonly
 static void
 assign_domain_page_replace(struct domain *d, unsigned long mpaddr,
-                           unsigned long mfn, unsigned int flags)
+                           unsigned long mfn, unsigned long flags)
 {
     struct mm_struct *mm = &d->arch.mm;
     pte_t* pte;
     pte_t old_pte;
     pte_t npte;
+    unsigned long arflags = (flags & ASSIGN_readonly)? _PAGE_AR_R: 
_PAGE_AR_RWX;
 
     pte = lookup_alloc_domain_pte(d, mpaddr);
 
     // update pte
-    npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
+    npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags));
     old_pte = ptep_xchg(mm, mpaddr, pte, npte);
-    if (!pte_none(old_pte)) {
+    if (pte_mem(old_pte)) {
         unsigned long old_mfn;
         struct page_info* old_page;
 
@@ -1159,16 +1199,31 @@ assign_domain_page_replace(struct domain
 
 unsigned long
 dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn,
-                   unsigned int flags, domid_t domid)
+                   unsigned long flags, domid_t domid)
 {
     int error = 0;
-
     struct domain* rd;
+
     rd = find_domain_by_id(domid);
     if (unlikely(rd == NULL)) {
-        error = -EINVAL;
-        goto out0;
-    }
+        switch (domid) {
+        case DOMID_XEN:
+            rd = dom_xen;
+            break;
+        case DOMID_IO:
+            rd = dom_io;
+            break;
+        default:
+            DPRINTK("d 0x%p domid %d "
+                    "pgfn 0x%lx mfn 0x%lx flags 0x%lx domid %d\n",
+                    d, d->domain_id, gpfn, mfn, flags, domid);
+            error = -ESRCH;
+            goto out0;
+        }
+        BUG_ON(rd == NULL);
+        get_knownalive_domain(rd);
+    }
+
     if (unlikely(rd == d)) {
         error = -EINVAL;
         goto out1;
@@ -1178,7 +1233,7 @@ dom0vp_add_physmap(struct domain* d, uns
         goto out1;
     }
 
-    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* flags:XXX */);
+    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, flags);
     //don't update p2m table because this page belongs to rd, not d.
 out1:
     put_domain(rd);
@@ -1198,23 +1253,18 @@ create_grant_host_mapping(unsigned long 
     struct page_info* page;
     int ret;
 
-    if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) {
+    if (flags & (GNTMAP_device_map | 
+                 GNTMAP_application_map | GNTMAP_contains_pte)) {
         DPRINTK("%s: flags 0x%x\n", __func__, flags);
         return GNTST_general_error;
-    }
-    if (flags & GNTMAP_readonly) {
-#if 0
-        DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
-                __func__, flags);
-#endif
-        flags &= ~GNTMAP_readonly;
     }
 
     page = mfn_to_page(mfn);
     ret = get_page(page, page_get_owner(page));
     BUG_ON(ret == 0);
-    assign_domain_page_replace(d, gpaddr, mfn, flags);
-
+
+    assign_domain_page_replace(d, gpaddr, mfn, (flags & GNTMAP_readonly)?
+                                              ASSIGN_readonly: 
ASSIGN_writable);
     return GNTST_okay;
 }
 
@@ -1233,22 +1283,17 @@ destroy_grant_host_mapping(unsigned long
         DPRINTK("%s: flags 0x%x\n", __func__, flags);
         return GNTST_general_error;
     }
-    if (flags & GNTMAP_readonly) {
-#if 0
-        DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
-                __func__, flags);
-#endif
-        flags &= ~GNTMAP_readonly;
-    }
 
     pte = lookup_noalloc_domain_pte(d, gpaddr);
     if (pte == NULL || !pte_present(*pte) || pte_pfn(*pte) != mfn)
-        return GNTST_general_error;//XXX GNTST_bad_pseudo_phys_addr
+        return GNTST_general_error;
 
     // update pte
     old_pte = ptep_get_and_clear(&d->arch.mm, gpaddr, pte);
     if (pte_present(old_pte)) {
-        old_mfn = pte_pfn(old_pte);//XXX
+        old_mfn = pte_pfn(old_pte);
+    } else {
+        return GNTST_general_error;
     }
     domain_page_flush(d, gpaddr, old_mfn, INVALID_MFN);
 
@@ -1349,7 +1394,7 @@ guest_physmap_add_page(struct domain *d,
 
     ret = get_page(mfn_to_page(mfn), d);
     BUG_ON(ret == 0);
-    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* XXX */);
+    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, ASSIGN_writable);
     set_gpfn_from_mfn(mfn, gpfn);//XXX SMP
 
     //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> 
PAGE_SHIFT));
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/efi_emul.c
--- a/xen/arch/ia64/xen/efi_emul.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/efi_emul.c      Fri Jun 02 12:31:48 2006 -0500
@@ -21,6 +21,7 @@
 #include <asm/pgalloc.h>
 #include <asm/vcpu.h>
 #include <asm/dom_fw.h>
+#include <asm/fpswa.h>
 #include <public/sched.h>
 
 extern unsigned long translate_domain_mpaddr(unsigned long);
@@ -75,6 +76,7 @@ efi_emulate_set_virtual_address_map(
        unsigned long *vfn;
        struct domain *d = current->domain;
        efi_runtime_services_t *efi_runtime = d->arch.efi_runtime;
+       fpswa_interface_t *fpswa_inf = d->arch.fpswa_inf;
 
        if (descriptor_version != EFI_MEMDESC_VERSION) {
                printf ("efi_emulate_set_virtual_address_map: memory descriptor 
version unmatched\n");
@@ -119,6 +121,12 @@ efi_emulate_set_virtual_address_map(
                
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->set_variable,EFI_SET_VARIABLE);
                
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
                
EFI_HYPERCALL_PATCH_TO_VIRT(efi_runtime->reset_system,EFI_RESET_SYSTEM);
+
+               vfn = (unsigned long *) domain_mpa_to_imva(d, (unsigned long) 
fpswa_inf->fpswa);
+               *vfn++ = FW_HYPERCALL_FPSWA_PATCH_INDEX * 16UL + md->virt_addr;
+               *vfn   = 0;
+               fpswa_inf->fpswa = (void *) (FW_HYPERCALL_FPSWA_ENTRY_INDEX * 
16UL + md->virt_addr);
+               break;
        }
 
        /* The virtual address map has been applied. */
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/hypercall.c     Fri Jun 02 12:31:48 2006 -0500
@@ -14,6 +14,7 @@
 
 #include <linux/efi.h> /* FOR EFI_UNIMPLEMENTED */
 #include <asm/sal.h>   /* FOR struct ia64_sal_retval */
+#include <asm/fpswa.h> /* FOR struct fpswa_ret_t */
 
 #include <asm/vcpu.h>
 #include <asm/dom_fw.h>
@@ -25,9 +26,12 @@
 #include <asm/hw_irq.h>
 #include <public/physdev.h>
 #include <xen/domain.h>
+#include <public/callback.h>
+#include <xen/event.h>
 
 static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop);
 static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
+static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg);
 /* FIXME: where these declarations should be there ? */
 extern int dump_privop_counts_to_user(char *, int);
 extern int zero_privop_counts_to_user(char *, int);
@@ -67,7 +71,7 @@ hypercall_t ia64_hypercall_table[] =
        (hypercall_t)do_ni_hypercall,           /* do_acm_op */
        (hypercall_t)do_ni_hypercall,           /* do_nmi_op */
        (hypercall_t)do_sched_op,
-       (hypercall_t)do_ni_hypercall,           /*  */                          
/* 30 */
+       (hypercall_t)do_callback_op,            /*  */                  /* 30 */
        (hypercall_t)do_ni_hypercall,           /*  */
        (hypercall_t)do_event_channel_op,
        (hypercall_t)do_physdev_op,
@@ -178,12 +182,19 @@ fw_hypercall_ipi (struct pt_regs *regs)
        return;
 }
 
+static fpswa_ret_t
+fw_hypercall_fpswa (struct vcpu *v)
+{
+       return PSCBX(v, fpswa_ret);
+}
+
 static IA64FAULT
 fw_hypercall (struct pt_regs *regs)
 {
        struct vcpu *v = current;
        struct sal_ret_values x;
        efi_status_t efi_ret_value;
+       fpswa_ret_t fpswa_ret;
        IA64FAULT fault; 
        unsigned long index = regs->r2 & FW_HYPERCALL_NUM_MASK_HIGH;
 
@@ -200,11 +211,8 @@ fw_hypercall (struct pt_regs *regs)
                VCPU(v,pending_interruption) = 1;
 #endif
                if (regs->r28 == PAL_HALT_LIGHT) {
-                       int pi;
-#define SPURIOUS_VECTOR 15
-                       pi = vcpu_check_pending_interrupts(v);
-                       if (pi != SPURIOUS_VECTOR) {
-                               if (!VCPU(v,pending_interruption))
+                       if (vcpu_deliverable_interrupts(v) ||
+                               event_pending(v)) {
                                        idle_when_pending++;
                                vcpu_pend_unspecified_interrupt(v);
 //printf("idle w/int#%d pending!\n",pi);
@@ -253,6 +261,13 @@ fw_hypercall (struct pt_regs *regs)
            case FW_HYPERCALL_IPI:
                fw_hypercall_ipi (regs);
                break;
+           case FW_HYPERCALL_FPSWA:
+               fpswa_ret = fw_hypercall_fpswa (v);
+               regs->r8  = fpswa_ret.status;
+               regs->r9  = fpswa_ret.err0;
+               regs->r10 = fpswa_ret.err1;
+               regs->r11 = fpswa_ret.err2;
+               break;
            default:
                printf("unknown ia64 fw hypercall %lx\n", regs->r2);
                regs->r8 = do_ni_hypercall();
@@ -435,3 +450,75 @@ long do_event_channel_op_compat(XEN_GUES
 
     return do_event_channel_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
 }
+
+static long register_guest_callback(struct callback_register *reg)
+{
+    long ret = 0;
+    struct vcpu *v = current;
+
+    if (IS_VMM_ADDRESS(reg->address))
+        return -EINVAL;
+
+    switch ( reg->type )
+    {
+    case CALLBACKTYPE_event:
+        v->arch.event_callback_ip    = reg->address;
+        break;
+
+    case CALLBACKTYPE_failsafe:
+        v->arch.failsafe_callback_ip = reg->address;
+        break;
+
+    default:
+        ret = -EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+static long unregister_guest_callback(struct callback_unregister *unreg)
+{
+    return -EINVAL ;
+}
+
+/* First time to add callback to xen/ia64, so let's just stick to
+ * the newer callback interface.
+ */
+static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
+{
+    long ret;
+
+    switch ( cmd )
+    {
+    case CALLBACKOP_register:
+    {
+        struct callback_register reg;
+
+        ret = -EFAULT;
+        if ( copy_from_guest(&reg, arg, 1) )
+            break;
+
+        ret = register_guest_callback(&reg);
+    }
+    break;
+
+    case CALLBACKOP_unregister:
+    {
+        struct callback_unregister unreg;
+
+        ret = -EFAULT;
+        if ( copy_from_guest(&unreg, arg, 1) )
+            break;
+
+        ret = unregister_guest_callback(&unreg);
+    }
+    break;
+
+    default:
+        ret = -EINVAL;
+        break;
+    }
+
+    return ret;
+}
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/hyperprivop.S
--- a/xen/arch/ia64/xen/hyperprivop.S   Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/hyperprivop.S   Fri Jun 02 12:31:48 2006 -0500
@@ -106,6 +106,11 @@ GLOBAL_ENTRY(fast_hyperprivop)
        or r23=r23,r24; or r21=r21,r22;;
        or r20=r23,r21;;
 1:     // when we get to here r20=~=interrupts pending
+       // Check pending event indication
+(p7)   adds r20=XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS,r18;;
+(p7)   ld8 r20=[r20];;
+(p7)   adds r20=-1,r20;;
+(p7)   ld1 r20=[r20];;
 
        // HYPERPRIVOP_RFI?
        cmp.eq p7,p6=HYPERPRIVOP_RFI,r17
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/irq.c
--- a/xen/arch/ia64/xen/irq.c   Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/irq.c   Fri Jun 02 12:31:48 2006 -0500
@@ -70,11 +70,13 @@
  */
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
        [0 ... NR_IRQS-1] = {
-               .status = IRQ_DISABLED | IRQ_GUEST,
+               .status = IRQ_DISABLED,
                .handler = &no_irq_type,
                .lock = SPIN_LOCK_UNLOCKED
        }
 };
+
+void __do_IRQ_guest(int irq);
 
 /*
  * Special irq handlers.
@@ -167,9 +169,7 @@ fastcall unsigned int __do_IRQ(unsigned 
        spin_lock(&desc->lock);
 
        if (desc->status & IRQ_GUEST) {
-               /* __do_IRQ_guest(irq); */
-               vcpu_pend_interrupt(dom0->vcpu[0],irq);
-               vcpu_wake(dom0->vcpu[0]);
+               __do_IRQ_guest(irq);
                spin_unlock(&desc->lock);
                return 1;
        }
@@ -392,6 +392,9 @@ typedef struct {
     u8 nr_guests;
     u8 in_flight;
     u8 shareable;
+    u8 ack_type;
+#define ACKTYPE_NONE   0     /* No final acknowledgement is required */
+#define ACKTYPE_UNMASK 1     /* Unmask notification is required */
     struct domain *guest[IRQ_MAX_GUESTS];
 } irq_guest_action_t;
 
@@ -405,10 +408,24 @@ void __do_IRQ_guest(int irq)
     for ( i = 0; i < action->nr_guests; i++ )
     {
         d = action->guest[i];
-        if ( !test_and_set_bit(irq, &d->pirq_mask) )
+        if ( (action->ack_type != ACKTYPE_NONE) &&
+             !test_and_set_bit(irq, &d->pirq_mask) )
             action->in_flight++;
         send_guest_pirq(d, irq);
     }
+}
+
+int pirq_acktype(int irq)
+{
+    irq_desc_t *desc = &irq_desc[irq];
+
+    if (!strcmp(desc->handler->typename, "IO-SAPIC-level"))
+        return ACKTYPE_UNMASK;
+
+    if (!strcmp(desc->handler->typename, "IO-SAPIC-edge"))
+        return ACKTYPE_NONE;
+
+    return ACKTYPE_NONE;
 }
 
 int pirq_guest_eoi(struct domain *d, int irq)
@@ -422,7 +439,10 @@ int pirq_guest_eoi(struct domain *d, int
     spin_lock_irq(&desc->lock);
     if ( test_and_clear_bit(irq, &d->pirq_mask) &&
          (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
+    {
+        ASSERT(action->ack_type == ACKTYPE_UNMASK);
         desc->handler->end(irq);
+    }
     spin_unlock_irq(&desc->lock);
 
     return 0;
@@ -431,7 +451,6 @@ int pirq_guest_eoi(struct domain *d, int
 
 int pirq_guest_unmask(struct domain *d)
 {
-    irq_desc_t    *desc;
     int            irq;
     shared_info_t *s = d->shared_info;
 
@@ -439,13 +458,9 @@ int pirq_guest_unmask(struct domain *d)
           irq < NR_IRQS;
           irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) )
     {
-        desc = &irq_desc[irq];
-        spin_lock_irq(&desc->lock);
-        if ( !test_bit(d->pirq_to_evtchn[irq], &s->evtchn_mask[0]) &&
-             test_and_clear_bit(irq, &d->pirq_mask) &&
-             (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
-            desc->handler->end(irq);
-        spin_unlock_irq(&desc->lock);
+        if ( !test_bit(d->pirq_to_evtchn[irq], &s->evtchn_mask[0]) )
+            pirq_guest_eoi(d, irq);
+
     }
 
     return 0;
@@ -459,6 +474,11 @@ int pirq_guest_bind(struct vcpu *v, int 
     int                 rc = 0;
 
     spin_lock_irqsave(&desc->lock, flags);
+
+    if (desc->handler == &no_irq_type) {
+        spin_unlock_irqrestore(&desc->lock, flags);
+        return -ENOSYS;
+    }
 
     action = (irq_guest_action_t *)desc->action;
 
@@ -483,6 +503,7 @@ int pirq_guest_bind(struct vcpu *v, int 
         action->nr_guests = 0;
         action->in_flight = 0;
         action->shareable = will_share;
+        action->ack_type  = pirq_acktype(irq);
         
         desc->depth = 0;
         desc->status |= IRQ_GUEST;
@@ -529,26 +550,26 @@ int pirq_guest_unbind(struct domain *d, 
 
     action = (irq_guest_action_t *)desc->action;
 
-    if ( test_and_clear_bit(irq, &d->pirq_mask) &&
-         (--action->in_flight == 0) )
-        desc->handler->end(irq);
-
-    if ( action->nr_guests == 1 )
-    {
+    i = 0;
+    while ( action->guest[i] && (action->guest[i] != d) )
+        i++;
+    memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
+    action->nr_guests--;
+
+    if ( action->ack_type == ACKTYPE_UNMASK )
+        if ( test_and_clear_bit(irq, &d->pirq_mask) &&
+             (--action->in_flight == 0) )
+            desc->handler->end(irq);
+
+    if ( !action->nr_guests )
+    {
+        BUG_ON(action->in_flight != 0);
         desc->action = NULL;
         xfree(action);
         desc->depth   = 1;
         desc->status |= IRQ_DISABLED;
         desc->status &= ~IRQ_GUEST;
         desc->handler->shutdown(irq);
-    }
-    else
-    {
-        i = 0;
-        while ( action->guest[i] != d )
-            i++;
-        memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
-        action->nr_guests--;
     }
 
     spin_unlock_irqrestore(&desc->lock, flags);    
@@ -598,10 +619,9 @@ void process_soft_irq(void)
 
 // this is a temporary hack until real console input is implemented
 extern void domain_pend_keyboard_interrupt(int irq);
-irqreturn_t guest_forward_keyboard_input(int irq, void *nada, struct pt_regs 
*regs)
+void guest_forward_keyboard_input(int irq, void *nada, struct pt_regs *regs)
 {
        domain_pend_keyboard_interrupt(irq);
-       return 0;
 }
 
 void serial_input_init(void)
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/privop.c
--- a/xen/arch/ia64/xen/privop.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/privop.c        Fri Jun 02 12:31:48 2006 -0500
@@ -129,10 +129,10 @@ IA64FAULT priv_ptc_l(VCPU *vcpu, INST64 
 IA64FAULT priv_ptc_l(VCPU *vcpu, INST64 inst)
 {
        UINT64 vadr = vcpu_get_gr(vcpu,inst.M45.r3);
-       UINT64 addr_range;
-
-       addr_range = 1 << ((vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2);
-       return vcpu_ptc_l(vcpu,vadr,addr_range);
+       UINT64 log_range;
+
+       log_range = ((vcpu_get_gr(vcpu,inst.M45.r2) & 0xfc) >> 2);
+       return vcpu_ptc_l(vcpu,vadr,log_range);
 }
 
 IA64FAULT priv_ptc_e(VCPU *vcpu, INST64 inst)
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c       Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/process.c       Fri Jun 02 12:31:48 2006 -0500
@@ -33,6 +33,7 @@
 #include "hpsim_ssc.h"
 #include <xen/multicall.h>
 #include <asm/debugger.h>
+#include <asm/fpswa.h>
 
 extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
 /* FIXME: where these declarations shold be there ? */
@@ -85,6 +86,8 @@ u64 translate_domain_pte(u64 pteval, u64
        struct domain *d = current->domain;
        ia64_itir_t itir = {.itir = itir__};
        u64 mask, mpaddr, pteval2;
+       u64 arflags;
+       u64 arflags2;
 
        pteval &= ((1UL << 53) - 1);// ignore [63:53] bits
 
@@ -123,6 +126,20 @@ u64 translate_domain_pte(u64 pteval, u64
        }
 #endif
        pteval2 = lookup_domain_mpa(d,mpaddr);
+       arflags  = pteval  & _PAGE_AR_MASK;
+       arflags2 = pteval2 & _PAGE_AR_MASK;
+       if (arflags != _PAGE_AR_R && arflags2 == _PAGE_AR_R) {
+#if 0
+               DPRINTK("%s:%d "
+                       "pteval 0x%lx arflag 0x%lx address 0x%lx itir 0x%lx "
+                       "pteval2 0x%lx arflags2 0x%lx mpaddr 0x%lx\n",
+                       __func__, __LINE__,
+                       pteval, arflags, address, itir__,
+                       pteval2, arflags2, mpaddr);
+#endif
+               pteval = (pteval & ~_PAGE_AR_MASK) | _PAGE_AR_R;
+}
+
        pteval2 &= _PAGE_PPN_MASK; // ignore non-addr bits
        pteval2 |= (pteval & _PAGE_ED);
        pteval2 |= _PAGE_PL_2; // force PL0->2 (PL3 is unaffected)
@@ -246,6 +263,40 @@ printf("*#*#*#* about to deliver early t
        reflect_interruption(isr,regs,IA64_EXTINT_VECTOR);
 }
 
+void reflect_event(struct pt_regs *regs)
+{
+       unsigned long isr = regs->cr_ipsr & IA64_PSR_RI;
+       struct vcpu *v = current;
+
+       /* Sanity check */
+       if (is_idle_vcpu(v) || !user_mode(regs)) {
+               //printk("WARN: invocation to reflect_event in nested xen\n");
+               return;
+       }
+
+       if (!event_pending(v))
+               return;
+
+       if (!PSCB(v,interrupt_collection_enabled))
+               printf("psr.ic off, delivering event, 
ipsr=%lx,iip=%lx,isr=%lx,viip=0x%lx\n",
+                      regs->cr_ipsr, regs->cr_iip, isr, PSCB(v, iip));
+       PSCB(v,unat) = regs->ar_unat;  // not sure if this is really needed?
+       PSCB(v,precover_ifs) = regs->cr_ifs;
+       vcpu_bsw0(v);
+       PSCB(v,ipsr) = vcpu_get_ipsr_int_state(v,regs->cr_ipsr);
+       PSCB(v,isr) = isr;
+       PSCB(v,iip) = regs->cr_iip;
+       PSCB(v,ifs) = 0;
+       PSCB(v,incomplete_regframe) = 0;
+
+       regs->cr_iip = v->arch.event_callback_ip;
+       regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
+       regs->r31 = XSI_IPSR;
+
+       v->vcpu_info->evtchn_upcall_mask = 1;
+       PSCB(v,interrupt_collection_enabled) = 0;
+}
+
 // ONLY gets called from ia64_leave_kernel
 // ONLY call with interrupts disabled?? (else might miss one?)
 // NEVER successful if already reflecting a trap/fault because psr.i==0
@@ -255,7 +306,6 @@ void deliver_pending_interrupt(struct pt
        struct vcpu *v = current;
        // FIXME: Will this work properly if doing an RFI???
        if (!is_idle_domain(d) && user_mode(regs)) {
-               //vcpu_poke_timer(v);
                if (vcpu_deliverable_interrupts(v))
                        reflect_extint(regs);
                else if (PSCB(v,pending_interruption))
@@ -343,6 +393,98 @@ void ia64_do_page_fault (unsigned long a
        PSCB(current,iha) = iha;
        PSCB(current,ifa) = address;
        reflect_interruption(isr, regs, fault);
+}
+
+fpswa_interface_t *fpswa_interface = 0;
+
+void trap_init (void)
+{
+       if (ia64_boot_param->fpswa)
+               /* FPSWA fixup: make the interface pointer a virtual address: */
+               fpswa_interface = __va(ia64_boot_param->fpswa);
+       else
+               printk("No FPSWA supported.\n");
+}
+
+static fpswa_ret_t
+fp_emulate (int fp_fault, void *bundle, unsigned long *ipsr,
+           unsigned long *fpsr, unsigned long *isr, unsigned long *pr,
+           unsigned long *ifs, struct pt_regs *regs)
+{
+       fp_state_t fp_state;
+       fpswa_ret_t ret;
+
+       if (!fpswa_interface)
+               return ((fpswa_ret_t) {-1, 0, 0, 0});
+
+       memset(&fp_state, 0, sizeof(fp_state_t));
+
+       /*
+        * compute fp_state.  only FP registers f6 - f11 are used by the
+        * kernel, so set those bits in the mask and set the low volatile
+        * pointer to point to these registers.
+        */
+       fp_state.bitmask_low64 = 0xfc0;  /* bit6..bit11 */
+
+       fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) &regs->f6;
+       /*
+        * unsigned long (*EFI_FPSWA) (
+        *      unsigned long    trap_type,
+        *      void             *Bundle,
+        *      unsigned long    *pipsr,
+        *      unsigned long    *pfsr,
+        *      unsigned long    *pisr,
+        *      unsigned long    *ppreds,
+        *      unsigned long    *pifs,
+        *      void             *fp_state);
+        */
+       ret = (*fpswa_interface->fpswa)(fp_fault, bundle,
+                                       ipsr, fpsr, isr, pr, ifs, &fp_state);
+
+       return ret;
+}
+
+/*
+ * Handle floating-point assist faults and traps for domain.
+ */
+static unsigned long
+handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
+{
+       struct vcpu *v = current;
+       IA64_BUNDLE bundle;
+       IA64_BUNDLE __get_domain_bundle(UINT64);
+       unsigned long fault_ip;
+       fpswa_ret_t ret;
+
+       fault_ip = regs->cr_iip;
+       /*
+        * When the FP trap occurs, the trapping instruction is completed.
+        * If ipsr.ri == 0, there is the trapping instruction in previous 
bundle.
+        */
+       if (!fp_fault && (ia64_psr(regs)->ri == 0))
+               fault_ip -= 16;
+       bundle = __get_domain_bundle(fault_ip);
+       if (!bundle.i64[0] && !bundle.i64[1]) {
+               printk("%s: floating-point bundle at 0x%lx not mapped\n",
+                      __FUNCTION__, fault_ip);
+               return -1;
+       }
+
+       ret = fp_emulate(fp_fault, &bundle, &regs->cr_ipsr, &regs->ar_fpsr,
+                        &isr, &regs->pr, &regs->cr_ifs, regs);
+
+       if (ret.status) {
+               PSCBX(v, fpswa_ret) = ret;
+               printk("%s(%s): fp_emulate() returned %ld\n",
+                      __FUNCTION__, fp_fault?"fault":"trap", ret.status);
+       } else {
+               if (fp_fault) {
+                       /* emulation was successful */
+                       vcpu_increment_iip(v);
+               }
+       }
+
+       return ret.status;
 }
 
 void
@@ -709,29 +851,31 @@ ia64_handle_reflection (unsigned long if
                        vector = IA64_NAT_CONSUMPTION_VECTOR; break;
                }
 #endif
-printf("*** NaT fault... attempting to handle as privop\n");
-printf("isr=%016lx, ifa=%016lx, iip=%016lx, ipsr=%016lx\n",
-       isr, ifa, regs->cr_iip, psr);
+               printf("*** NaT fault... attempting to handle as privop\n");
+               printf("isr=%016lx, ifa=%016lx, iip=%016lx, ipsr=%016lx\n",
+                      isr, ifa, regs->cr_iip, psr);
                //regs->eml_unat = 0;  FIXME: DO WE NEED THIS???
                // certain NaT faults are higher priority than privop faults
                vector = priv_emulate(v,regs,isr);
                if (vector == IA64_NO_FAULT) {
-printf("*** Handled privop masquerading as NaT fault\n");
+                       printf("*** Handled privop masquerading as NaT 
fault\n");
                        return;
                }
                vector = IA64_NAT_CONSUMPTION_VECTOR; break;
            case 27:
-//printf("*** Handled speculation vector, itc=%lx!\n",ia64_get_itc());
+               //printf("*** Handled speculation vector, 
itc=%lx!\n",ia64_get_itc());
                PSCB(current,iim) = iim;
                vector = IA64_SPECULATION_VECTOR; break;
            case 30:
                // FIXME: Should we handle unaligned refs in Xen??
                vector = IA64_UNALIGNED_REF_VECTOR; break;
            case 32:
-               printf("ia64_handle_reflection: handling FP fault");
+               if (!(handle_fpu_swa(1, regs, isr))) return;
+               printf("ia64_handle_reflection: handling FP fault\n");
                vector = IA64_FP_FAULT_VECTOR; break;
            case 33:
-               printf("ia64_handle_reflection: handling FP trap");
+               if (!(handle_fpu_swa(0, regs, isr))) return;
+               printf("ia64_handle_reflection: handling FP trap\n");
                vector = IA64_FP_TRAP_VECTOR; break;
            case 34:
                printf("ia64_handle_reflection: handling lowerpriv trap");
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/vcpu.c  Fri Jun 02 12:31:48 2006 -0500
@@ -18,6 +18,7 @@
 #include <asm/vhpt.h>
 #include <asm/tlbflush.h>
 #include <xen/event.h>
+#include <asm/vmx_phy_mode.h>
 
 /* FIXME: where these declarations should be there ? */
 extern void getreg(unsigned long regnum, unsigned long *val, int *nat, struct 
pt_regs *regs);
@@ -649,16 +650,18 @@ void vcpu_pend_interrupt(VCPU *vcpu, UIN
                printf("vcpu_pend_interrupt: bad vector\n");
                return;
        }
-    if ( VMX_DOMAIN(vcpu) ) {
-           set_bit(vector,VCPU(vcpu,irr));
-    } else
-    {
-       if (test_bit(vector,PSCBX(vcpu,irr))) {
-//printf("vcpu_pend_interrupt: overrun\n");
-       }
-       set_bit(vector,PSCBX(vcpu,irr));
-       PSCB(vcpu,pending_interruption) = 1;
-    }
+
+       if (vcpu->arch.event_callback_ip) {
+               printf("Deprecated interface. Move to new event based 
solution\n");
+               return;
+       }
+               
+       if ( VMX_DOMAIN(vcpu) ) {
+               set_bit(vector,VCPU(vcpu,irr));
+       } else {
+               set_bit(vector,PSCBX(vcpu,irr));
+               PSCB(vcpu,pending_interruption) = 1;
+       }
 }
 
 #define        IA64_TPR_MMI    0x10000
@@ -673,6 +676,9 @@ UINT64 vcpu_check_pending_interrupts(VCP
 UINT64 vcpu_check_pending_interrupts(VCPU *vcpu)
 {
        UINT64 *p, *r, bits, bitnum, mask, i, vector;
+
+       if (vcpu->arch.event_callback_ip)
+               return SPURIOUS_VECTOR;
 
        /* Always check pending event, since guest may just ack the
         * event injection without handle. Later guest may throw out
@@ -1151,7 +1157,16 @@ void vcpu_pend_timer(VCPU *vcpu)
                // don't deliver another
                return;
        }
-       vcpu_pend_interrupt(vcpu, itv);
+       if (vcpu->arch.event_callback_ip) {
+               /* A small window may occur when injecting vIRQ while related
+                * handler has not been registered. Don't fire in such case.
+                */
+               if (vcpu->virq_to_evtchn[VIRQ_ITC]) {
+                       send_guest_vcpu_virq(vcpu, VIRQ_ITC);
+                       PSCBX(vcpu, domain_itm_last) = PSCBX(vcpu, domain_itm);
+               }
+       } else
+               vcpu_pend_interrupt(vcpu, itv);
 }
 
 // returns true if ready to deliver a timer interrupt too early
@@ -1834,12 +1849,17 @@ IA64FAULT vcpu_itc_i(VCPU *vcpu, UINT64 
        return IA64_NO_FAULT;
 }
 
-IA64FAULT vcpu_ptc_l(VCPU *vcpu, UINT64 vadr, UINT64 addr_range)
-{
-       printk("vcpu_ptc_l: called, not implemented yet\n");
-       return IA64_ILLOP_FAULT;
-}
-
+IA64FAULT vcpu_ptc_l(VCPU *vcpu, UINT64 vadr, UINT64 log_range)
+{
+       /* Purge TC  */
+       vcpu_purge_tr_entry(&PSCBX(vcpu,dtlb));
+       vcpu_purge_tr_entry(&PSCBX(vcpu,itlb));
+       
+       /*Purge all tlb and vhpt*/
+       vcpu_flush_tlb_vhpt_range (vadr, log_range);
+
+       return IA64_NO_FAULT;
+}
 // At privlvl=0, fc performs no access rights or protection key checks, while
 // at privlvl!=0, fc performs access rights checks as if it were a 1-byte
 // read but no protection key check.  Thus in order to avoid an unexpected
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/xensetup.c      Fri Jun 02 12:31:48 2006 -0500
@@ -35,8 +35,6 @@ char saved_command_line[COMMAND_LINE_SIZ
 char saved_command_line[COMMAND_LINE_SIZE];
 char dom0_command_line[COMMAND_LINE_SIZE];
 
-struct vcpu *idle_vcpu[NR_CPUS];
-
 cpumask_t cpu_present_map;
 
 extern unsigned long domain0_ready;
@@ -53,6 +51,7 @@ extern void setup_per_cpu_areas(void);
 extern void setup_per_cpu_areas(void);
 extern void mem_init(void);
 extern void init_IRQ(void);
+extern void trap_init(void);
 
 /* opt_nosmp: If true, secondary processors are ignored. */
 static int opt_nosmp = 0;
@@ -321,6 +320,8 @@ void start_kernel(void)
 
     init_frametable();
 
+    trap_init();
+
     alloc_dom0();
 
     end_boot_allocator();
@@ -337,6 +338,7 @@ printk("About to call scheduler_init()\n
     BUG_ON(idle_domain == NULL);
 
     late_setup_arch((char **) &cmdline);
+    alloc_dom_xen_and_dom_io();
     setup_per_cpu_areas();
     mem_init();
 
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/ia64/xen/xentime.c
--- a/xen/arch/ia64/xen/xentime.c       Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/ia64/xen/xentime.c       Fri Jun 02 12:31:48 2006 -0500
@@ -105,7 +105,7 @@ void do_settime(unsigned long secs, unsi
     return;
 }
 
-irqreturn_t
+void
 xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 {
        unsigned long new_itm, old_itc;
@@ -134,7 +134,7 @@ xen_timer_interrupt (int irq, void *dev_
        new_itm = local_cpu_data->itm_next;
 
        if (!VMX_DOMAIN(current) && !time_after(ia64_get_itc(), new_itm))
-               return IRQ_HANDLED;
+               return;
 
        while (1) {
                new_itm += local_cpu_data->itm_delta;
@@ -185,8 +185,6 @@ xen_timer_interrupt (int irq, void *dev_
                /* double check, in case we got hit by a (slow) PMI: */
        } while (time_after_eq(ia64_get_itc(), new_itm));
        raise_softirq(TIMER_SOFTIRQ);
-
-       return IRQ_HANDLED;
 }
 
 static struct irqaction xen_timer_irqaction = {
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/audit.c
--- a/xen/arch/x86/audit.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/audit.c      Fri Jun 02 12:31:48 2006 -0500
@@ -432,10 +432,10 @@ int audit_adjust_pgtables(struct domain 
 
         for_each_vcpu(d, v)
         {
-            if ( pagetable_get_paddr(v->arch.guest_table) )
+            if ( !pagetable_is_null(v->arch.guest_table) )
                 adjust(mfn_to_page(pagetable_get_pfn(v->arch.guest_table)),
                        !shadow_mode_refcounts(d));
-            if ( pagetable_get_paddr(v->arch.shadow_table) )
+            if ( !pagetable_is_null(v->arch.shadow_table) )
                 adjust(mfn_to_page(pagetable_get_pfn(v->arch.shadow_table)),
                        0);
             if ( v->arch.monitor_shadow_ref )
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/cpu/mtrr/main.c
--- a/xen/arch/x86/cpu/mtrr/main.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/cpu/mtrr/main.c      Fri Jun 02 12:31:48 2006 -0500
@@ -43,7 +43,7 @@
 #include "mtrr.h"
 
 /* No blocking mutexes in Xen. Spin instead. */
-#define DECLARE_MUTEX(_m) spinlock_t _m = SPIN_LOCK_UNLOCKED
+#define DECLARE_MUTEX(_m) DEFINE_SPINLOCK(_m)
 #define down(_m) spin_lock(_m)
 #define up(_m) spin_unlock(_m)
 #define lock_cpu_hotplug() ((void)0)
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/dom0_ops.c   Fri Jun 02 12:31:48 2006 -0500
@@ -467,7 +467,7 @@ void arch_getdomaininfo_ctxt(
     if ( hvm_guest(v) )
         c->flags |= VGCF_HVM_GUEST;
 
-    c->ctrlreg[3] = pagetable_get_paddr(v->arch.guest_table);
+    c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
 
     c->vm_assist = v->domain->vm_assist;
 }
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/domain.c     Fri Jun 02 12:31:48 2006 -0500
@@ -259,7 +259,7 @@ int arch_set_info_guest(
     struct vcpu *v, struct vcpu_guest_context *c)
 {
     struct domain *d = v->domain;
-    unsigned long phys_basetab = INVALID_MFN;
+    unsigned long cr3_pfn;
     int i, rc;
 
     if ( !(c->flags & VGCF_HVM_GUEST) )
@@ -322,12 +322,8 @@ int arch_set_info_guest(
 
     if ( !(c->flags & VGCF_HVM_GUEST) )
     {
-        phys_basetab = c->ctrlreg[3];
-        phys_basetab =
-            (gmfn_to_mfn(d, phys_basetab >> PAGE_SHIFT) << PAGE_SHIFT) |
-            (phys_basetab & ~PAGE_MASK);
-
-        v->arch.guest_table = mk_pagetable(phys_basetab);
+        cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3]));
+        v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
     }
 
     if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
@@ -335,14 +331,14 @@ int arch_set_info_guest(
 
     if ( c->flags & VGCF_HVM_GUEST )
     {
-        v->arch.guest_table = mk_pagetable(0);
+        v->arch.guest_table = pagetable_null();
 
         if ( !hvm_initialize_guest_resources(v) )
             return -EINVAL;
     }
     else if ( shadow_mode_refcounts(d) )
     {
-        if ( !get_page(mfn_to_page(phys_basetab>>PAGE_SHIFT), d) )
+        if ( !get_page(mfn_to_page(cr3_pfn), d) )
         {
             destroy_gdt(v);
             return -EINVAL;
@@ -350,7 +346,7 @@ int arch_set_info_guest(
     }
     else
     {
-        if ( !get_page_and_type(mfn_to_page(phys_basetab>>PAGE_SHIFT), d,
+        if ( !get_page_and_type(mfn_to_page(cr3_pfn), d,
                                 PGT_base_page_table) )
         {
             destroy_gdt(v);
@@ -935,7 +931,7 @@ void domain_relinquish_resources(struct 
                 put_page_type(mfn_to_page(pfn));
             put_page(mfn_to_page(pfn));
 
-            v->arch.guest_table = mk_pagetable(0);
+            v->arch.guest_table = pagetable_null();
         }
 
         if ( (pfn = pagetable_get_pfn(v->arch.guest_table_user)) != 0 )
@@ -944,7 +940,7 @@ void domain_relinquish_resources(struct 
                 put_page_type(mfn_to_page(pfn));
             put_page(mfn_to_page(pfn));
 
-            v->arch.guest_table_user = mk_pagetable(0);
+            v->arch.guest_table_user = pagetable_null();
         }
     }
 
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/domain_build.c       Fri Jun 02 12:31:48 2006 -0500
@@ -443,13 +443,13 @@ int construct_dom0(struct domain *d,
         l2tab[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT)+i] =
             l2e_from_paddr((u32)l2tab + i*PAGE_SIZE, __PAGE_HYPERVISOR);
     }
-    v->arch.guest_table = mk_pagetable((unsigned long)l3start);
+    v->arch.guest_table = pagetable_from_paddr((unsigned long)l3start);
 #else
     l2start = l2tab = (l2_pgentry_t *)mpt_alloc; mpt_alloc += PAGE_SIZE;
     memcpy(l2tab, idle_pg_table, PAGE_SIZE);
     l2tab[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
         l2e_from_paddr((unsigned long)l2start, __PAGE_HYPERVISOR);
-    v->arch.guest_table = mk_pagetable((unsigned long)l2start);
+    v->arch.guest_table = pagetable_from_paddr((unsigned long)l2start);
 #endif
 
     for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
@@ -577,7 +577,7 @@ int construct_dom0(struct domain *d,
         l4e_from_paddr(__pa(l4start), __PAGE_HYPERVISOR);
     l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] =
         l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR);
-    v->arch.guest_table = mk_pagetable(__pa(l4start));
+    v->arch.guest_table = pagetable_from_paddr(__pa(l4start));
 
     l4tab += l4_table_offset(dsi.v_start);
     mfn = alloc_spfn;
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/hvm/io.c     Fri Jun 02 12:31:48 2006 -0500
@@ -648,6 +648,16 @@ static void hvm_mmio_assist(struct vcpu 
             regs->eflags &= ~X86_EFLAGS_CF;
 
         break;
+
+    case INSTR_XCHG:
+       if (src & REGISTER) {
+               index = operand_index(src);
+               set_reg_value(size, index, 0, regs, p->u.data);
+       } else {
+               index = operand_index(dst);
+               set_reg_value(size, index, 0, regs, p->u.data);
+       }
+       break;
     }
 
     hvm_load_cpu_guest_regs(v, regs);
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/hvm/platform.c       Fri Jun 02 12:31:48 2006 -0500
@@ -954,10 +954,26 @@ void handle_mmio(unsigned long va, unsig
         mmio_opp->instr = mmio_inst.instr;
         mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */
         mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */
-
-        /* send the request and wait for the value */
-        send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
-                      mmio_inst.op_size, 0, IOREQ_WRITE, 0);
+       if (mmio_inst.operand[0] & REGISTER) {
+               long value;
+               unsigned long operand = mmio_inst.operand[0];
+               value = get_reg_value(operand_size(operand), 
+                                     operand_index(operand), 0,
+                                     mmio_opp->inst_decoder_regs);
+               /* send the request and wait for the value */
+               send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+                      mmio_inst.op_size, value, IOREQ_WRITE, 0);
+       } else {
+               /* the destination is a register */
+               long value;
+               unsigned long operand = mmio_inst.operand[1];
+               value = get_reg_value(operand_size(operand), 
+                                     operand_index(operand), 0,
+                                     mmio_opp->inst_decoder_regs);
+               /* send the request and wait for the value */
+               send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1,
+                      mmio_inst.op_size, value, IOREQ_WRITE, 0);
+       }
         break;
 
     default:
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Jun 02 12:31:48 2006 -0500
@@ -51,9 +51,6 @@
 
 #define SVM_EXTRA_DEBUG
 
-/* Useful define */
-#define MAX_INST_SIZE  15
-
 #define set_segment_register(name, value)  \
        __asm__ __volatile__ ( "movw %%ax ,%%" STR(name) "" : : "a" (value) )
 
@@ -74,6 +71,9 @@ void svm_dump_regs(const char *from, str
 void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
 
 static void svm_relinquish_guest_resources(struct domain *d);
+static int svm_do_vmmcall_reset_to_realmode(struct vcpu *v,
+        struct cpu_user_regs *regs);
+
 
 
 extern void set_hsa_to_guest( struct arch_svm_struct *arch_svm );
@@ -84,28 +84,26 @@ struct svm_percore_globals svm_globals[N
 /*
  * Initializes the POOL of ASID used by the guests per core.
  */
-void asidpool_init( int core )
+void asidpool_init(int core)
 {
     int i;
-    svm_globals[core].ASIDpool.asid_lock = SPIN_LOCK_UNLOCKED;
-    spin_lock(&svm_globals[core].ASIDpool.asid_lock);
+
+    spin_lock_init(&svm_globals[core].ASIDpool.asid_lock);
+
     /* Host ASID is always in use */
     svm_globals[core].ASIDpool.asid[INITIAL_ASID] = ASID_INUSE;
-    for( i=1; i<ASID_MAX; i++ )
-    {
+    for ( i = 1; i < ASID_MAX; i++ )
        svm_globals[core].ASIDpool.asid[i] = ASID_AVAILABLE;
-    }
-    spin_unlock(&svm_globals[core].ASIDpool.asid_lock);
 }
 
 
 /* internal function to get the next available ASID */
-static int asidpool_fetch_next( struct vmcb_struct *vmcb, int core )
+static int asidpool_fetch_next(struct vmcb_struct *vmcb, int core)
 {
     int i;   
-    for( i = 1; i < ASID_MAX; i++ )
-    {
-        if( svm_globals[core].ASIDpool.asid[i] == ASID_AVAILABLE )
+    for ( i = 1; i < ASID_MAX; i++ )
+    {
+        if ( svm_globals[core].ASIDpool.asid[i] == ASID_AVAILABLE )
         {
             vmcb->guest_asid = i;
             svm_globals[core].ASIDpool.asid[i] = ASID_INUSE;
@@ -438,6 +436,42 @@ unsigned long svm_get_ctrl_reg(struct vc
     return 0;                   /* dummy */
 }
 
+
+/* SVM-specific intitialization code for VCPU application processors */
+void svm_init_ap_context(struct vcpu_guest_context *ctxt, 
+        int vcpuid, int trampoline_vector)
+{
+    int i;
+    struct vcpu *v, *bsp = current;
+    struct domain *d = bsp->domain;
+    cpu_user_regs_t *regs;;
+
+  
+    if ((v = d->vcpu[vcpuid]) == NULL)
+    {
+        printk("vcpuid %d is invalid!  good-bye.\n", vcpuid);
+        domain_crash_synchronous();
+    }
+    regs = &v->arch.guest_context.user_regs;
+
+    memset(ctxt, 0, sizeof(*ctxt));
+    for (i = 0; i < 256; ++i)
+    {
+        ctxt->trap_ctxt[i].vector = i;
+        ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS;
+    }
+
+
+    /*
+     * We execute the trampoline code in real mode. The trampoline vector
+     * passed to us is page alligned and is the physicall frame number for
+     * the code. We will execute this code in real mode. 
+     */
+    ctxt->user_regs.eip = 0x0;
+    ctxt->user_regs.cs = (trampoline_vector << 8); 
+    ctxt->flags = VGCF_HVM_GUEST;
+}
+
 int start_svm(void)
 {
     u32 eax, ecx, edx;
@@ -484,6 +518,7 @@ int start_svm(void)
     hvm_funcs.paging_enabled = svm_paging_enabled;
     hvm_funcs.instruction_length = svm_instruction_length;
     hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
+    hvm_funcs.init_ap_context = svm_init_ap_context;
 
     hvm_enabled = 1;    
 
@@ -660,6 +695,20 @@ static void arch_svm_do_launch(struct vc
     if (svm_dbg_on)
         svm_dump_host_regs(__func__);
 #endif
+    if (v->vcpu_id != 0) 
+    {
+       u16     cs_sel = regs->cs;
+       /*
+        * This is the launch of an AP; set state so that we begin executing
+        * the trampoline code in real-mode.
+        */
+       svm_do_vmmcall_reset_to_realmode(v, regs);      
+       /* Adjust the state to execute the trampoline code.*/
+       v->arch.hvm_svm.vmcb->rip = 0;
+       v->arch.hvm_svm.vmcb->cs.sel= cs_sel;
+       v->arch.hvm_svm.vmcb->cs.base = (cs_sel << 4);
+    }
+       
     reset_stack_and_jump(svm_asm_do_launch);
 }
 
@@ -695,34 +744,34 @@ static void svm_ctxt_switch_to(struct vc
 
 void svm_final_setup_guest(struct vcpu *v)
 {
+    struct domain *d = v->domain;
+    struct vcpu *vc;
+
     v->arch.schedule_tail    = arch_svm_do_launch;
     v->arch.ctxt_switch_from = svm_ctxt_switch_from;
     v->arch.ctxt_switch_to   = svm_ctxt_switch_to;
 
-    if (v == v->domain->vcpu[0]) 
-    {
-       struct domain *d = v->domain;
-       struct vcpu *vc;
-
-       /* Initialize monitor page table */
-       for_each_vcpu(d, vc)
-           vc->arch.monitor_table = mk_pagetable(0);
-
-        /* 
-         * Required to do this once per domain
-         * TODO: add a seperate function to do these.
-         */
-        memset(&d->shared_info->evtchn_mask[0], 0xff, 
-               sizeof(d->shared_info->evtchn_mask));       
-
-        /* 
-         * Put the domain in shadow mode even though we're going to be using
-         * the shared 1:1 page table initially. It shouldn't hurt 
-         */
-        shadow_mode_enable(d, 
-                SHM_enable|SHM_refcounts|
-               SHM_translate|SHM_external|SHM_wr_pt_pte);
-    }
+    if ( v != d->vcpu[0] )
+        return;
+
+    /* Initialize monitor page table */
+    for_each_vcpu( d, vc )
+        vc->arch.monitor_table = pagetable_null();
+
+    /* 
+     * Required to do this once per domain
+     * TODO: add a seperate function to do these.
+     */
+    memset(&d->shared_info->evtchn_mask[0], 0xff, 
+           sizeof(d->shared_info->evtchn_mask));       
+
+    /* 
+     * Put the domain in shadow mode even though we're going to be using
+     * the shared 1:1 page table initially. It shouldn't hurt 
+     */
+    shadow_mode_enable(d,
+                       SHM_enable|SHM_refcounts|
+                       SHM_translate|SHM_external|SHM_wr_pt_pte);
 }
 
 
@@ -819,7 +868,7 @@ static int svm_do_page_fault(unsigned lo
     /* Use 1:1 page table to identify MMIO address space */
     if (mmio_space(gpa))
     {
-       /* No support for APIC */
+        /* No support for APIC */
         if (!hvm_apic_support(v->domain) && gpa >= 0xFEC00000)
         { 
             int inst_len;
@@ -896,8 +945,10 @@ static void svm_do_general_protection_fa
     svm_inject_exception(v, TRAP_gp_fault, 1, error_code);
 }
 
-/* Reserved bits: [31:14], [12:1] */
-#define SVM_VCPU_CPUID_L1_RESERVED 0xffffdffe
+/* Reserved bits ECX: [31:14], [12:4], [2:1]*/
+#define SVM_VCPU_CPUID_L1_ECX_RESERVED 0xffffdff6
+/* Reserved bits EDX: [31:29], [27], [22:20], [18], [10] */
+#define SVM_VCPU_CPUID_L1_EDX_RESERVED 0xe8740400
 
 static void svm_vmexit_do_cpuid(struct vmcb_struct *vmcb, unsigned long input, 
         struct cpu_user_regs *regs) 
@@ -920,20 +971,17 @@ static void svm_vmexit_do_cpuid(struct v
 
     cpuid(input, &eax, &ebx, &ecx, &edx);
 
-    if (input == 1)
+    if (input == 0x00000001)
     {
         if ( !hvm_apic_support(v->domain) ||
                 !vlapic_global_enabled((VLAPIC(v))) )
         {
-            clear_bit(X86_FEATURE_APIC, &edx);
-            /* Since the apic is disabled, avoid any confusion about SMP cpus 
being available */
-            clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
-            ebx &= 0xFF00FFFF;  /* set the logical processor count to 1 */
-            ebx |= 0x00010000;
-        }
-           
+            /* Since the apic is disabled, avoid any confusion 
+              about SMP cpus being available */
+           clear_bit(X86_FEATURE_APIC, &edx);
+        }
+
 #if CONFIG_PAGING_LEVELS < 3
-        clear_bit(X86_FEATURE_NX, &edx);
         clear_bit(X86_FEATURE_PAE, &edx);
         clear_bit(X86_FEATURE_PSE, &edx);
         clear_bit(X86_FEATURE_PSE36, &edx);
@@ -942,24 +990,90 @@ static void svm_vmexit_do_cpuid(struct v
         {
             if ( !v->domain->arch.hvm_domain.pae_enabled )
             {
-               clear_bit(X86_FEATURE_PAE, &edx);
-               clear_bit(X86_FEATURE_NX, &edx);
+               clear_bit(X86_FEATURE_PAE, &edx);
             }
             clear_bit(X86_FEATURE_PSE, &edx);
             clear_bit(X86_FEATURE_PSE36, &edx);
         }
 #endif 
         /* Clear out reserved bits. */
-        ecx &= ~SVM_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */
+        ecx &= ~SVM_VCPU_CPUID_L1_ECX_RESERVED;
+        edx &= ~SVM_VCPU_CPUID_L1_EDX_RESERVED;
+
         clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
-    }
+
+       /* Guest should only see one logical processor.
+        * See details on page 23 of AMD CPUID Specification. 
+       */
+       clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
+       ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
+       ebx |= 0x00010000;  /* set to 1 just for precaution */
+    }
+    else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) )
+    {
+       eax = ebx = ecx = edx = 0x0;
+    }
+    else if ( input == 0x80000001 )
+    {
+       /* We duplicate some CPUID_00000001 code because many bits of 
+          CPUID_80000001_EDX overlaps with CPUID_00000001_EDX. */
+
+        if ( !hvm_apic_support(v->domain) ||
+            !vlapic_global_enabled((VLAPIC(v))) )
+        {
+            /* Since the apic is disabled, avoid any confusion 
+              about SMP cpus being available */
+           clear_bit(X86_FEATURE_APIC, &edx);
+        }
+
+       /* Clear the Cmp_Legacy bit 
+        * This bit is supposed to be zero when HTT = 0.
+        * See details on page 23 of AMD CPUID Specification. 
+       */
+       clear_bit(X86_FEATURE_CMP_LEGACY & 31, &ecx);
+
 #ifdef __i386__
-    else if ( input == 0x80000001 )
-    {
         /* Mask feature for Intel ia32e or AMD long mode. */
+        clear_bit(X86_FEATURE_LAHF_LM & 31, &ecx);
+
         clear_bit(X86_FEATURE_LM & 31, &edx);
-    }
+        clear_bit(X86_FEATURE_SYSCALL & 31, &edx);
 #endif
+
+#if CONFIG_PAGING_LEVELS < 3
+       clear_bit(X86_FEATURE_NX & 31, &edx);
+        clear_bit(X86_FEATURE_PAE, &edx);
+        clear_bit(X86_FEATURE_PSE, &edx);
+        clear_bit(X86_FEATURE_PSE36, &edx);
+#else
+        if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
+        {
+            if ( !v->domain->arch.hvm_domain.pae_enabled )
+            {
+               clear_bit(X86_FEATURE_NX & 31, &edx);
+               clear_bit(X86_FEATURE_PAE, &edx);
+            }
+            clear_bit(X86_FEATURE_PSE, &edx);
+            clear_bit(X86_FEATURE_PSE36, &edx);
+        }
+#endif 
+
+        /* Make SVM feature invisible to the guest. */
+        clear_bit(X86_FEATURE_SVME & 31, &ecx);
+       
+       /* So far, we do not support 3DNow for the guest. */
+       clear_bit(X86_FEATURE_3DNOW & 31, &edx);
+       clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
+    }
+    else if ( ( input == 0x80000007 ) || ( input == 0x8000000A  ) )
+    {
+       /* Mask out features of power management and SVM extension. */
+       eax = ebx = ecx = edx = 0;
+    }
+    else if ( input == 0x80000008 )
+    {
+       ecx &= 0xFFFFFF00; /* Make sure Number of CPU core is 1 when HTT=0 */
+    }
 
     regs->eax = (unsigned long)eax;
     regs->ebx = (unsigned long)ebx;
@@ -1454,7 +1568,7 @@ static int svm_set_cr0(unsigned long val
         }
 
         /* Now arch.guest_table points to machine physical. */
-        v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+        v->arch.guest_table = pagetable_from_pfn(mfn);
         update_pagetables(v);
 
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
@@ -1474,7 +1588,7 @@ static int svm_set_cr0(unsigned long val
         if ( v->arch.hvm_svm.cpu_cr3 ) {
             put_page(mfn_to_page(get_mfn_from_gpfn(
                       v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT)));
-            v->arch.guest_table = mk_pagetable(0);
+            v->arch.guest_table = pagetable_null();
         }
 
     /*
@@ -1483,7 +1597,7 @@ static int svm_set_cr0(unsigned long val
      * created.
      */
     if ((value & X86_CR0_PE) == 0) {
-       if (value & X86_CR0_PG) {
+        if (value & X86_CR0_PG) {
             svm_inject_exception(v, TRAP_gp_fault, 1, 0);
             return 0;
         }
@@ -1624,7 +1738,7 @@ static int mov_to_cr(int gpreg, int cr, 
             }
 
             old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-            v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+            v->arch.guest_table = pagetable_from_pfn(mfn);
 
             if (old_base_mfn)
                 put_page(mfn_to_page(old_base_mfn));
@@ -1681,7 +1795,7 @@ static int mov_to_cr(int gpreg, int cr, 
                  * Now arch.guest_table points to machine physical.
                  */
 
-                v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+                v->arch.guest_table = pagetable_from_pfn(mfn);
                 update_pagetables(v);
 
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
@@ -2036,7 +2150,7 @@ void svm_handle_invlpg(const short invlp
 void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
 {
     struct vcpu *v = current;
-    u8 opcode[MAX_INST_SIZE], prefix, length = MAX_INST_SIZE;
+    u8 opcode[MAX_INST_LEN], prefix, length = MAX_INST_LEN;
     unsigned long g_vaddr;
     int inst_len;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Jun 02 12:31:48 2006 -0500
@@ -66,7 +66,7 @@ void vmx_final_setup_guest(struct vcpu *
 
         /* Initialize monitor page table */
         for_each_vcpu(d, vc)
-            vc->arch.monitor_table = mk_pagetable(0);
+            vc->arch.monitor_table = pagetable_null();
 
         /*
          * Required to do this once per domain
@@ -1223,7 +1223,7 @@ vmx_world_restore(struct vcpu *v, struct
         if(!get_page(mfn_to_page(mfn), v->domain))
                 return 0;
         old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-        v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+        v->arch.guest_table = pagetable_from_pfn(mfn);
         if (old_base_mfn)
              put_page(mfn_to_page(old_base_mfn));
         /*
@@ -1459,7 +1459,7 @@ static int vmx_set_cr0(unsigned long val
         /*
          * Now arch.guest_table points to machine physical.
          */
-        v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+        v->arch.guest_table = pagetable_from_pfn(mfn);
         update_pagetables(v);
 
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
@@ -1477,7 +1477,7 @@ static int vmx_set_cr0(unsigned long val
         if ( v->arch.hvm_vmx.cpu_cr3 ) {
             put_page(mfn_to_page(get_mfn_from_gpfn(
                       v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT)));
-            v->arch.guest_table = mk_pagetable(0);
+            v->arch.guest_table = pagetable_null();
         }
 
     /*
@@ -1635,7 +1635,7 @@ static int mov_to_cr(int gp, int cr, str
                 domain_crash_synchronous(); /* need to take a clean path */
             }
             old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-            v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+            v->arch.guest_table = pagetable_from_pfn(mfn);
             if (old_base_mfn)
                 put_page(mfn_to_page(old_base_mfn));
             /*
@@ -1690,7 +1690,7 @@ static int mov_to_cr(int gp, int cr, str
                  * Now arch.guest_table points to machine physical.
                  */
 
-                v->arch.guest_table = mk_pagetable((u64)mfn << PAGE_SHIFT);
+                v->arch.guest_table = pagetable_from_pfn(mfn);
                 update_pagetables(v);
 
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/i8259.c      Fri Jun 02 12:31:48 2006 -0500
@@ -102,7 +102,7 @@ BUILD_SMP_INTERRUPT(thermal_interrupt,TH
  * moves to arch independent land
  */
 
-spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(i8259A_lock);
 
 static void disable_8259A_vector(unsigned int vector)
 {
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/microcode.c
--- a/xen/arch/x86/microcode.c  Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/microcode.c  Fri Jun 02 12:31:48 2006 -0500
@@ -83,7 +83,7 @@
 #include <asm/processor.h>
 
 #define pr_debug(x...) ((void)0)
-#define DECLARE_MUTEX(_m) spinlock_t _m = SPIN_LOCK_UNLOCKED
+#define DECLARE_MUTEX(_m) DEFINE_SPINLOCK(_m)
 #define down(_m) spin_lock(_m)
 #define up(_m) spin_unlock(_m)
 #define vmalloc(_s) xmalloc_bytes(_s)
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/mm.c Fri Jun 02 12:31:48 2006 -0500
@@ -89,6 +89,7 @@
 #include <xen/kernel.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
+#include <xen/domain.h>
 #include <xen/sched.h>
 #include <xen/errno.h>
 #include <xen/perfc.h>
@@ -187,20 +188,16 @@ void arch_init_memory(void)
      * Any Xen-heap pages that we will allow to be mapped will have
      * their domain field set to dom_xen.
      */
-    dom_xen = alloc_domain();
-    spin_lock_init(&dom_xen->page_alloc_lock);
-    atomic_set(&dom_xen->refcnt, 1);
-    dom_xen->domain_id = DOMID_XEN;
+    dom_xen = alloc_domain(DOMID_XEN);
+    BUG_ON(dom_xen == NULL);
 
     /*
      * Initialise our DOMID_IO domain.
      * This domain owns I/O pages that are within the range of the page_info
      * array. Mappings occur at the priv of the caller.
      */
-    dom_io = alloc_domain();
-    spin_lock_init(&dom_io->page_alloc_lock);
-    atomic_set(&dom_io->refcnt, 1);
-    dom_io->domain_id = DOMID_IO;
+    dom_io = alloc_domain(DOMID_IO);
+    BUG_ON(dom_io == NULL);
 
     /* First 1MB of RAM is historically marked as I/O. */
     for ( i = 0; i < 0x100; i++ )
@@ -266,8 +263,15 @@ void share_xen_page_with_privileged_gues
 /* Only PDPTs above 4GB boundary need to be shadowed in low memory. */
 #define l3tab_needs_shadow(mfn) (mfn >= 0x100000)
 #else
-/* In debug builds we aggressively shadow PDPTs to exercise code paths. */
-#define l3tab_needs_shadow(mfn) ((mfn << PAGE_SHIFT) != __pa(idle_pg_table))
+/*
+ * In debug builds we aggressively shadow PDPTs to exercise code paths.
+ * We cannot safely shadow the idle page table, nor shadow-mode page tables
+ * (detected by lack of an owning domain). Always shadow PDPTs above 4GB.
+ */
+#define l3tab_needs_shadow(mfn)                         \
+    ((((mfn << PAGE_SHIFT) != __pa(idle_pg_table)) &&   \
+      (page_get_owner(mfn_to_page(mfn)) != NULL)) ||    \
+     (mfn >= 0x100000))
 #endif
 
 static l1_pgentry_t *fix_pae_highmem_pl1e;
@@ -1598,12 +1602,18 @@ int get_page_type(struct page_info *page
             {
                 if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
                 {
-                    if ( current->domain == page_get_owner(page) )
+                    if ( (current->domain == page_get_owner(page)) &&
+                         ((x & PGT_type_mask) == PGT_writable_page) )
                     {
                         /*
                          * This ensures functions like set_gdt() see up-to-date
                          * type info without needing to clean up writable p.t.
-                         * state on the fast path.
+                         * state on the fast path. We take this path only
+                         * when the current type is writable because:
+                         *  1. It's the only type that this path can decrement.
+                         *  2. If we take this path more liberally then we can
+                         *     enter a recursive loop via get_page_from_l1e()
+                         *     during pagetable revalidation.
                          */
                         LOCK_BIGLOCK(current->domain);
                         cleanup_writable_pagetable(current->domain);
@@ -1704,7 +1714,7 @@ int new_guest_cr3(unsigned long mfn)
         {
             /* Switch to idle pagetable: this VCPU has no active p.t. now. */
             old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-            v->arch.guest_table = mk_pagetable(0);
+            v->arch.guest_table = pagetable_null();
             update_pagetables(v);
             write_cr3(__pa(idle_pg_table));
             if ( old_base_mfn != 0 )
@@ -1726,7 +1736,7 @@ int new_guest_cr3(unsigned long mfn)
     invalidate_shadow_ldt(v);
 
     old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
-    v->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT);
+    v->arch.guest_table = pagetable_from_pfn(mfn);
     update_pagetables(v); /* update shadow_table and monitor_table */
 
     write_ptbase(v);
@@ -1993,7 +2003,7 @@ int do_mmuext_op(
             {
                 unsigned long old_mfn =
                     pagetable_get_pfn(v->arch.guest_table_user);
-                v->arch.guest_table_user = mk_pagetable(mfn << PAGE_SHIFT);
+                v->arch.guest_table_user = pagetable_from_pfn(mfn);
                 if ( old_mfn != 0 )
                     put_page_and_type(mfn_to_page(old_mfn));
             }
@@ -2200,99 +2210,88 @@ int do_mmu_update(
 
             switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
             {
-            case PGT_l1_page_table: 
-                ASSERT( !shadow_mode_refcounts(d) );
-                if ( likely(get_page_type(
+            case PGT_l1_page_table:
+            case PGT_l2_page_table:
+            case PGT_l3_page_table:
+            case PGT_l4_page_table:
+            {
+                ASSERT(!shadow_mode_refcounts(d));
+                if ( unlikely(!get_page_type(
                     page, type_info & (PGT_type_mask|PGT_va_mask))) )
+                    goto not_a_pt;
+
+                switch ( type_info & PGT_type_mask )
                 {
-                    l1_pgentry_t l1e;
-
-                    /* FIXME: doesn't work with PAE */
-                    l1e = l1e_from_intpte(req.val);
+                case PGT_l1_page_table:
+                {
+                    l1_pgentry_t l1e = l1e_from_intpte(req.val);
                     okay = mod_l1_entry(va, l1e);
                     if ( okay && unlikely(shadow_mode_enabled(d)) )
                         shadow_l1_normal_pt_update(
                             d, req.ptr, l1e, &sh_mapcache);
-                    put_page_type(page);
                 }
                 break;
-            case PGT_l2_page_table:
-                ASSERT( !shadow_mode_refcounts(d) );
-                if ( likely(get_page_type(
-                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
+                case PGT_l2_page_table:
                 {
-                    l2_pgentry_t l2e;
-
-                    /* FIXME: doesn't work with PAE */
-                    l2e = l2e_from_intpte(req.val);
+                    l2_pgentry_t l2e = l2e_from_intpte(req.val);
                     okay = mod_l2_entry(
                         (l2_pgentry_t *)va, l2e, mfn, type_info);
                     if ( okay && unlikely(shadow_mode_enabled(d)) )
                         shadow_l2_normal_pt_update(
                             d, req.ptr, l2e, &sh_mapcache);
-                    put_page_type(page);
                 }
                 break;
 #if CONFIG_PAGING_LEVELS >= 3
-            case PGT_l3_page_table:
-                ASSERT( !shadow_mode_refcounts(d) );
-                if ( likely(get_page_type(
-                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
+                case PGT_l3_page_table:
                 {
-                    l3_pgentry_t l3e;
-
-                    /* FIXME: doesn't work with PAE */
-                    l3e = l3e_from_intpte(req.val);
+                    l3_pgentry_t l3e = l3e_from_intpte(req.val);
                     okay = mod_l3_entry(va, l3e, mfn, type_info);
                     if ( okay && unlikely(shadow_mode_enabled(d)) )
                         shadow_l3_normal_pt_update(
                             d, req.ptr, l3e, &sh_mapcache);
-                    put_page_type(page);
                 }
                 break;
 #endif
 #if CONFIG_PAGING_LEVELS >= 4
-            case PGT_l4_page_table:
-                ASSERT( !shadow_mode_refcounts(d) );
-                if ( likely(get_page_type(
-                    page, type_info & (PGT_type_mask|PGT_va_mask))) )
+                case PGT_l4_page_table:
                 {
-                    l4_pgentry_t l4e;
-
-                    l4e = l4e_from_intpte(req.val);
+                    l4_pgentry_t l4e = l4e_from_intpte(req.val);
                     okay = mod_l4_entry(va, l4e, mfn, type_info);
                     if ( okay && unlikely(shadow_mode_enabled(d)) )
                         shadow_l4_normal_pt_update(
                             d, req.ptr, l4e, &sh_mapcache);
-                    put_page_type(page);
                 }
                 break;
 #endif
+                }
+
+                put_page_type(page);
+            }
+            break;
+
             default:
-                if ( likely(get_page_type(page, PGT_writable_page)) )
+            not_a_pt:
+            {
+                if ( unlikely(!get_page_type(page, PGT_writable_page)) )
+                    break;
+
+                if ( shadow_mode_enabled(d) )
                 {
-                    if ( shadow_mode_enabled(d) )
-                    {
-                        shadow_lock(d);
-
-                        __mark_dirty(d, mfn);
-
-                        if ( page_is_page_table(page) &&
-                             !page_out_of_sync(page) )
-                        {
-                            shadow_mark_mfn_out_of_sync(v, gmfn, mfn);
-                        }
-                    }
-
-                    *(intpte_t *)va = req.val;
-                    okay = 1;
-
-                    if ( shadow_mode_enabled(d) )
-                        shadow_unlock(d);
-
-                    put_page_type(page);
+                    shadow_lock(d);
+                    __mark_dirty(d, mfn);
+                    if ( page_is_page_table(page) && !page_out_of_sync(page) )
+                        shadow_mark_mfn_out_of_sync(v, gmfn, mfn);
                 }
-                break;
+
+                *(intpte_t *)va = req.val;
+                okay = 1;
+
+                if ( shadow_mode_enabled(d) )
+                    shadow_unlock(d);
+
+                put_page_type(page);
+            }
+            break;
             }
 
             unmap_domain_page_with_cache(va, &mapcache);
@@ -3696,7 +3695,7 @@ int map_pages_to_xen(
             {
                 local_flush_tlb_pge();
                 if ( !(l2e_get_flags(ol2e) & _PAGE_PSE) )
-                    free_xen_pagetable(l2e_get_page(*pl2e));
+                    free_xen_pagetable(l2e_get_page(ol2e));
             }
 
             virt    += 1UL << L2_PAGETABLE_SHIFT;
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/setup.c      Fri Jun 02 12:31:48 2006 -0500
@@ -85,8 +85,6 @@ extern void early_cpu_init(void);
 
 struct tss_struct init_tss[NR_CPUS];
 
-struct vcpu *idle_vcpu[NR_CPUS];
-
 extern unsigned long cpu0_stack[];
 
 struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c     Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/shadow.c     Fri Jun 02 12:31:48 2006 -0500
@@ -1724,7 +1724,8 @@ static int resync_all(struct domain *d, 
                         unshadow_l1 = 1;
                     else {
                         need_flush |= error;
-                        set_guest_back_ptr(d, *sl1e_p, smfn, i);
+                        if ( l1e_get_flags(*sl1e_p) & _PAGE_PRESENT )
+                            set_guest_back_ptr(d, *sl1e_p, smfn, i);
                     }
                     // can't update snapshots of linear page tables -- they
                     // are used multiple times...
@@ -2471,7 +2472,7 @@ static void shadow_update_pagetables(str
     if ( !get_shadow_ref(smfn) )
         BUG();
     old_smfn = pagetable_get_pfn(v->arch.shadow_table);
-    v->arch.shadow_table = mk_pagetable((u64)smfn << PAGE_SHIFT);
+    v->arch.shadow_table = pagetable_from_pfn(smfn);
     if ( old_smfn )
         put_shadow_ref(old_smfn);
 
@@ -3480,15 +3481,16 @@ static void shadow_set_l2e_64(unsigned l
 
     __shadow_get_l3e(v, va, &sl3e);
     if (!(l3e_get_flags(sl3e) & _PAGE_PRESENT)) {
-         if (create_l2_shadow) {
+        if (create_l2_shadow) {
             perfc_incrc(shadow_set_l2e_force_map);
             shadow_map_into_current(v, va, PAGING_L2, PAGING_L3);
             __shadow_get_l3e(v, va, &sl3e);
         } else {
             printk("For non HVM shadow, create_l1_shadow:%d\n", 
create_l2_shadow);
         }
-         shadow_update_min_max(l4e_get_pfn(sl4e), l3_table_offset(va));
-
+
+        if ( v->domain->arch.ops->guest_paging_levels == PAGING_L4 )
+            shadow_update_min_max(l4e_get_pfn(sl4e), l3_table_offset(va));
     }
 
     if ( put_ref_check ) {
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/shadow32.c   Fri Jun 02 12:31:48 2006 -0500
@@ -583,7 +583,7 @@ static void free_shadow_pages(struct dom
         if ( pagetable_get_paddr(v->arch.shadow_table) )
         {
             put_shadow_ref(pagetable_get_pfn(v->arch.shadow_table));
-            v->arch.shadow_table = mk_pagetable(0);
+            v->arch.shadow_table = pagetable_null();
 
             if ( shadow_mode_external(d) )
             {
@@ -765,7 +765,7 @@ static void alloc_monitor_pagetable(stru
     mpl2e[l2_table_offset(SH_LINEAR_PT_VIRT_START)] = l2e_empty();
     mpl2e[l2_table_offset(RO_MPT_VIRT_START)] = l2e_empty();
 
-    v->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT);
+    v->arch.monitor_table = pagetable_from_pfn(mmfn);
     v->arch.monitor_vtable = mpl2e;
 
     if ( v->vcpu_id == 0 )
@@ -830,7 +830,7 @@ void free_monitor_pagetable(struct vcpu 
     unmap_domain_page_global(v->arch.monitor_vtable);
     free_domheap_page(mfn_to_page(mfn));
 
-    v->arch.monitor_table = mk_pagetable(0);
+    v->arch.monitor_table = pagetable_null();
     v->arch.monitor_vtable = 0;
 }
 
@@ -992,7 +992,7 @@ alloc_p2m_table(struct domain *d)
 
         l1tab = map_domain_page(page_to_mfn(page));
         memset(l1tab, 0, PAGE_SIZE);
-        d->arch.phys_table = mk_pagetable(page_to_maddr(page));
+        d->arch.phys_table = pagetable_from_page(page);
     }
 
     list_ent = d->page_list.next;
@@ -1126,7 +1126,7 @@ int shadow_direct_map_init(struct domain
     memset(root, 0, PAGE_SIZE);
     unmap_domain_page(root);
 
-    d->arch.phys_table = mk_pagetable(page_to_maddr(page));
+    d->arch.phys_table = pagetable_from_page(page);
 
     return 1;
 }
@@ -1156,7 +1156,7 @@ void shadow_direct_map_clean(struct doma
 
     unmap_domain_page(l2e);
 
-    d->arch.phys_table = mk_pagetable(0);
+    d->arch.phys_table = pagetable_null();
 }
 
 int __shadow_mode_enable(struct domain *d, unsigned int mode)
@@ -2691,7 +2691,8 @@ static int resync_all(struct domain *d, 
                         unshadow_l1 = 1;
                     else {
                         need_flush |= error;
-                        set_guest_back_ptr(d, shadow1[i], smfn, i);
+                        if ( l1e_get_flags(shadow1[i]) & _PAGE_PRESENT )
+                            set_guest_back_ptr(d, shadow1[i], smfn, i);
                     }
 
                     // can't update snapshots of linear page tables -- they
@@ -3230,7 +3231,7 @@ void __update_pagetables(struct vcpu *v)
     if ( !get_shadow_ref(smfn) )
         BUG();
     old_smfn = pagetable_get_pfn(v->arch.shadow_table);
-    v->arch.shadow_table = mk_pagetable(smfn << PAGE_SHIFT);
+    v->arch.shadow_table = pagetable_from_pfn(smfn);
     if ( old_smfn )
         put_shadow_ref(old_smfn);
 
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/shadow_public.c      Fri Jun 02 12:31:48 2006 -0500
@@ -50,7 +50,7 @@ int shadow_direct_map_init(struct domain
     memset(root, 0, PAGE_SIZE);
     root[PAE_SHADOW_SELF_ENTRY] = l3e_from_page(page, __PAGE_HYPERVISOR);
 
-    d->arch.phys_table = mk_pagetable(page_to_maddr(page));
+    d->arch.phys_table = pagetable_from_page(page);
 
     unmap_domain_page(root);
     return 1;
@@ -92,7 +92,7 @@ void shadow_direct_map_clean(struct doma
 
     unmap_domain_page(l3e);
 
-    d->arch.phys_table = mk_pagetable(0);
+    d->arch.phys_table = pagetable_null();
 }
 
 /****************************************************************************/
@@ -338,7 +338,7 @@ static void alloc_monitor_pagetable(stru
 
     /* map the phys_to_machine map into the per domain Read-Only MPT space */
 
-    v->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT);
+    v->arch.monitor_table = pagetable_from_pfn(mmfn);
     v->arch.monitor_vtable = (l2_pgentry_t *) mpl4e;
     mpl4e[l4_table_offset(RO_MPT_VIRT_START)] = l4e_empty();
 
@@ -380,7 +380,7 @@ void free_monitor_pagetable(struct vcpu 
     unmap_domain_page_global(v->arch.monitor_vtable);
     free_domheap_page(mfn_to_page(mfn));
 
-    v->arch.monitor_table = mk_pagetable(0);
+    v->arch.monitor_table = pagetable_null();
     v->arch.monitor_vtable = 0;
 }
 #elif CONFIG_PAGING_LEVELS == 3
@@ -431,7 +431,7 @@ static void alloc_monitor_pagetable(stru
     for ( i = 0; i < (MACHPHYS_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
         mpl2e[l2_table_offset(RO_MPT_VIRT_START) + i] = l2e_empty();
 
-    v->arch.monitor_table = mk_pagetable(m3mfn << PAGE_SHIFT); /* < 4GB */
+    v->arch.monitor_table = pagetable_from_pfn(m3mfn);
     v->arch.monitor_vtable = (l2_pgentry_t *) mpl3e;
 
     if ( v->vcpu_id == 0 )
@@ -492,7 +492,7 @@ void free_monitor_pagetable(struct vcpu 
     unmap_domain_page_global(v->arch.monitor_vtable);
     free_domheap_page(mfn_to_page(m3mfn));
 
-    v->arch.monitor_table = mk_pagetable(0);
+    v->arch.monitor_table = pagetable_null();
     v->arch.monitor_vtable = 0;
 }
 #endif
@@ -924,7 +924,7 @@ void free_shadow_pages(struct domain *d)
         if ( pagetable_get_paddr(v->arch.shadow_table) )
         {
             put_shadow_ref(pagetable_get_pfn(v->arch.shadow_table));
-            v->arch.shadow_table = mk_pagetable(0);
+            v->arch.shadow_table = pagetable_null();
 
             if ( shadow_mode_external(d) )
             {
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/smp.c        Fri Jun 02 12:31:48 2006 -0500
@@ -161,7 +161,7 @@ void send_IPI_mask_phys(cpumask_t mask, 
     local_irq_restore(flags);
 }
 
-static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(flush_lock);
 static cpumask_t flush_cpumask;
 static unsigned long flush_va;
 
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/smpboot.c    Fri Jun 02 12:31:48 2006 -0500
@@ -37,6 +37,7 @@
 #include <xen/init.h>
 #include <xen/kernel.h>
 #include <xen/mm.h>
+#include <xen/domain.h>
 #include <xen/sched.h>
 #include <xen/irq.h>
 #include <xen/delay.h>
@@ -886,28 +887,16 @@ static int __devinit do_boot_cpu(int api
        int timeout;
        unsigned long start_eip;
        unsigned short nmi_high = 0, nmi_low = 0;
-       struct domain *d;
        struct vcpu *v;
-       int vcpu_id;
 
        ++cpucount;
 
        booting_cpu = cpu;
 
-       if ((vcpu_id = cpu % MAX_VIRT_CPUS) == 0) {
-               d = domain_create(IDLE_DOMAIN_ID, cpu);
-               BUG_ON(d == NULL);
-               v = d->vcpu[0];
-       } else {
-               d = idle_vcpu[cpu - vcpu_id]->domain;
-               BUG_ON(d == NULL);
-               v = alloc_vcpu(d, vcpu_id, cpu);
-       }
-
-       idle_vcpu[cpu] = v;
+       v = alloc_idle_vcpu(cpu);
        BUG_ON(v == NULL);
 
-       v->arch.monitor_table = mk_pagetable(__pa(idle_pg_table));
+       v->arch.monitor_table = pagetable_from_paddr(__pa(idle_pg_table));
 
        /* start_eip had better be page-aligned! */
        start_eip = setup_trampoline();
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/time.c       Fri Jun 02 12:31:48 2006 -0500
@@ -40,10 +40,10 @@ boolean_param("hpet_force", opt_hpet_for
 
 unsigned long cpu_khz;  /* CPU clock frequency in kHz. */
 unsigned long hpet_address;
-spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rtc_lock);
 unsigned long volatile jiffies;
 static u32 wc_sec, wc_nsec; /* UTC time at last 'time update'. */
-static spinlock_t wc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(wc_lock);
 
 struct time_scale {
     int shift;
@@ -67,7 +67,7 @@ static s_time_t stime_platform_stamp;
 static s_time_t stime_platform_stamp;
 static u64 platform_timer_stamp;
 static struct time_scale platform_timer_scale;
-static spinlock_t platform_timer_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(platform_timer_lock);
 static u64 (*read_platform_count)(void);
 
 /*
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/traps.c      Fri Jun 02 12:31:48 2006 -0500
@@ -876,7 +876,7 @@ static int emulate_privileged_op(struct 
                     PAGE_FAULT(regs->edi, USER_WRITE_FAULT);
                 break;
             }
-            regs->edi += (regs->eflags & EF_DF) ? -(int)op_bytes : op_bytes;
+            regs->edi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes);
             break;
 
         case 0x6e: /* OUTSB */
@@ -902,7 +902,7 @@ static int emulate_privileged_op(struct 
                 outl_user((u32)data, (u16)regs->edx, v, regs);
                 break;
             }
-            regs->esi += (regs->eflags & EF_DF) ? -(int)op_bytes : op_bytes;
+            regs->esi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes);
             break;
         }
 
@@ -1034,8 +1034,8 @@ static int emulate_privileged_op(struct 
             break;
             
         case 3: /* Read CR3 */
-            *reg = pfn_to_paddr(mfn_to_gmfn(v->domain,
-                                    pagetable_get_pfn(v->arch.guest_table)));
+            *reg = xen_pfn_to_cr3(mfn_to_gmfn(
+                v->domain, pagetable_get_pfn(v->arch.guest_table)));
             break;
 
         case 4: /* Read CR4 */
@@ -1085,7 +1085,7 @@ static int emulate_privileged_op(struct 
         case 3: /* Write CR3 */
             LOCK_BIGLOCK(v->domain);
             cleanup_writable_pagetable(v->domain);
-            (void)new_guest_cr3(gmfn_to_mfn(v->domain, paddr_to_pfn(*reg)));
+            (void)new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg)));
             UNLOCK_BIGLOCK(v->domain);
             break;
 
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/x86_32/domain_page.c
--- a/xen/arch/x86/x86_32/domain_page.c Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/x86_32/domain_page.c Fri Jun 02 12:31:48 2006 -0500
@@ -183,7 +183,7 @@ static unsigned long inuse[BITS_TO_LONGS
 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;
+static DEFINE_SPINLOCK(globalmap_lock);
 
 void *map_domain_page_global(unsigned long pfn)
 {
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/x86_32/mm.c  Fri Jun 02 12:31:48 2006 -0500
@@ -75,7 +75,8 @@ void __init paging_init(void)
     printk("PAE disabled.\n");
 #endif
 
-    idle_vcpu[0]->arch.monitor_table = mk_pagetable(__pa(idle_pg_table));
+    idle_vcpu[0]->arch.monitor_table =
+        pagetable_from_paddr(__pa(idle_pg_table));
 
     if ( cpu_has_pge )
     {
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/x86_64/mm.c  Fri Jun 02 12:31:48 2006 -0500
@@ -81,7 +81,8 @@ void __init paging_init(void)
     l2_pgentry_t *l2_ro_mpt;
     struct page_info *pg;
 
-    idle_vcpu[0]->arch.monitor_table = mk_pagetable(__pa(idle_pg_table));
+    idle_vcpu[0]->arch.monitor_table =
+        pagetable_from_paddr(__pa(idle_pg_table));
 
     /* Create user-accessible L2 directory to map the MPT for guests. */
     l3_ro_mpt = alloc_xenheap_page();
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/x86_64/traps.c       Fri Jun 02 12:31:48 2006 -0500
@@ -195,7 +195,7 @@ unsigned long do_iret(void)
     /* Returning to user mode? */
     if ( (iret_saved.cs & 3) == 3 )
     {
-        if ( unlikely(pagetable_get_paddr(v->arch.guest_table_user) == 0) )
+        if ( unlikely(pagetable_is_null(v->arch.guest_table_user)) )
         {
             DPRINTK("Guest switching to user mode with no user page tables\n");
             domain_crash_synchronous();
diff -r 29861ae27914 -r 91ee504ed40e xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/arch/x86/x86_emulate.c        Fri Jun 02 12:31:48 2006 -0500
@@ -380,11 +380,12 @@ do{ __asm__ __volatile__ (              
       ((reg) & ((1UL << (ad_bytes << 3)) - 1))))
 #define register_address_increment(reg, inc)                            \
 do {                                                                    \
+    int _inc = (inc); /* signed type ensures sign extension to long */  \
     if ( ad_bytes == sizeof(unsigned long) )                            \
-        (reg) += (inc);                                                 \
+        (reg) += _inc;                                                  \
     else                                                                \
         (reg) = ((reg) & ~((1UL << (ad_bytes << 3)) - 1)) |             \
-                (((reg) + (inc)) & ((1UL << (ad_bytes << 3)) - 1));     \
+                (((reg) + _inc) & ((1UL << (ad_bytes << 3)) - 1));      \
 } while (0)
 
 void *
@@ -858,7 +859,7 @@ x86_emulate_memop(
                                          &dst.val, 8, ctxt)) != 0 )
                     goto done;
             }
-            register_address_increment(_regs.esp, -(int)dst.bytes);
+            register_address_increment(_regs.esp, -dst.bytes);
             if ( (rc = ops->write_std(register_address(_regs.ss, _regs.esp),
                                       dst.val, dst.bytes, ctxt)) != 0 )
                 goto done;
@@ -942,9 +943,9 @@ x86_emulate_memop(
                 goto done;
         }
         register_address_increment(
-            _regs.esi, (_regs.eflags & EFLG_DF) ? -(int)dst.bytes : dst.bytes);
+            _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
         register_address_increment(
-            _regs.edi, (_regs.eflags & EFLG_DF) ? -(int)dst.bytes : dst.bytes);
+            _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
         break;
     case 0xa6 ... 0xa7: /* cmps */
         DPRINTF("Urk! I don't handle CMPS.\n");
@@ -955,7 +956,7 @@ x86_emulate_memop(
         dst.ptr   = (unsigned long *)cr2;
         dst.val   = _regs.eax;
         register_address_increment(
-            _regs.edi, (_regs.eflags & EFLG_DF) ? -(int)dst.bytes : dst.bytes);
+            _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
         break;
     case 0xac ... 0xad: /* lods */
         dst.type  = OP_REG;
@@ -964,7 +965,7 @@ x86_emulate_memop(
         if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0 )
             goto done;
         register_address_increment(
-            _regs.esi, (_regs.eflags & EFLG_DF) ? -(int)dst.bytes : dst.bytes);
+            _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
         break;
     case 0xae ... 0xaf: /* scas */
         DPRINTF("Urk! I don't handle SCAS.\n");
diff -r 29861ae27914 -r 91ee504ed40e xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/dom0_ops.c     Fri Jun 02 12:31:48 2006 -0500
@@ -95,7 +95,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op
     long ret = 0;
     struct dom0_op curop, *op = &curop;
     void *ssid = NULL; /* save security ptr between pre and post/fail hooks */
-    static spinlock_t dom0_lock = SPIN_LOCK_UNLOCKED;
+    static DEFINE_SPINLOCK(dom0_lock);
 
     if ( !IS_PRIV(current->domain) )
         return -EPERM;
diff -r 29861ae27914 -r 91ee504ed40e xen/common/domain.c
--- a/xen/common/domain.c       Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/domain.c       Fri Jun 02 12:31:48 2006 -0500
@@ -32,22 +32,111 @@ struct domain *domain_list;
 
 struct domain *dom0;
 
-struct domain *domain_create(domid_t dom_id, unsigned int cpu)
-{
-    struct domain *d, **pd;
-    struct vcpu *v;
-
-    if ( (d = alloc_domain()) == NULL )
+struct vcpu *idle_vcpu[NR_CPUS];
+
+struct domain *alloc_domain(domid_t domid)
+{
+    struct domain *d;
+
+    if ( (d = xmalloc(struct domain)) == NULL )
         return NULL;
 
-    d->domain_id = dom_id;
-
+    memset(d, 0, sizeof(*d));
+    d->domain_id = domid;
     atomic_set(&d->refcnt, 1);
-
     spin_lock_init(&d->big_lock);
     spin_lock_init(&d->page_alloc_lock);
     INIT_LIST_HEAD(&d->page_list);
     INIT_LIST_HEAD(&d->xenpage_list);
+
+    return d;
+}
+
+
+void free_domain(struct domain *d)
+{
+    struct vcpu *v;
+    int i;
+
+    sched_destroy_domain(d);
+
+    for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- )
+        if ( (v = d->vcpu[i]) != NULL )
+            free_vcpu_struct(v);
+
+    xfree(d);
+}
+
+
+struct vcpu *alloc_vcpu(
+    struct domain *d, unsigned int vcpu_id, unsigned int cpu_id)
+{
+    struct vcpu *v;
+
+    BUG_ON(d->vcpu[vcpu_id] != NULL);
+
+    if ( (v = alloc_vcpu_struct(d, vcpu_id)) == NULL )
+        return NULL;
+
+    v->domain = d;
+    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;
+
+    v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
+    v->runstate.state_entry_time = NOW();
+
+    if ( (vcpu_id != 0) && !is_idle_domain(d) )
+        set_bit(_VCPUF_down, &v->vcpu_flags);
+
+    if ( sched_init_vcpu(v) < 0 )
+    {
+        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;
+
+    return v;
+}
+
+struct vcpu *alloc_idle_vcpu(unsigned int cpu_id)
+{
+    struct domain *d;
+    struct vcpu *v;
+    unsigned int vcpu_id;
+
+    if ((vcpu_id = cpu_id % MAX_VIRT_CPUS) == 0)
+    {
+        d = domain_create(IDLE_DOMAIN_ID, cpu_id);
+        BUG_ON(d == NULL);
+        v = d->vcpu[0];
+    }
+    else
+    {
+        d = idle_vcpu[cpu_id - vcpu_id]->domain;
+        BUG_ON(d == NULL);
+        v = alloc_vcpu(d, vcpu_id, cpu_id);
+    }
+
+    idle_vcpu[cpu_id] = v;
+
+    return v;
+}
+
+struct domain *domain_create(domid_t domid, unsigned int cpu)
+{
+    struct domain *d, **pd;
+    struct vcpu *v;
+
+    if ( (d = alloc_domain(domid)) == NULL )
+        return NULL;
 
     rangeset_domain_initialise(d);
 
@@ -74,14 +163,14 @@ struct domain *domain_create(domid_t dom
     if ( !is_idle_domain(d) )
     {
         write_lock(&domlist_lock);
-        pd = &domain_list; /* NB. domain_list maintained in order of dom_id. */
+        pd = &domain_list; /* NB. domain_list maintained in order of domid. */
         for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list )
             if ( (*pd)->domain_id > d->domain_id )
                 break;
         d->next_in_list = *pd;
         *pd = d;
-        d->next_in_hashbucket = domain_hash[DOMAIN_HASH(dom_id)];
-        domain_hash[DOMAIN_HASH(dom_id)] = d;
+        d->next_in_hashbucket = domain_hash[DOMAIN_HASH(domid)];
+        domain_hash[DOMAIN_HASH(domid)] = d;
         write_unlock(&domlist_lock);
     }
 
@@ -126,19 +215,16 @@ struct domain *find_domain_by_id(domid_t
 
 void domain_kill(struct domain *d)
 {
-    struct vcpu *v;
-
     domain_pause(d);
-    if ( !test_and_set_bit(_DOMF_dying, &d->domain_flags) )
-    {
-        for_each_vcpu(d, v)
-            sched_rem_domain(v);
-        gnttab_release_mappings(d);
-        domain_relinquish_resources(d);
-        put_domain(d);
-
-        send_guest_global_virq(dom0, VIRQ_DOM_EXC);
-    }
+
+    if ( test_and_set_bit(_DOMF_dying, &d->domain_flags) )
+        return;
+
+    gnttab_release_mappings(d);
+    domain_relinquish_resources(d);
+    put_domain(d);
+
+    send_guest_global_virq(dom0, VIRQ_DOM_EXC);
 }
 
 
diff -r 29861ae27914 -r 91ee504ed40e xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/page_alloc.c   Fri Jun 02 12:31:48 2006 -0500
@@ -59,7 +59,7 @@ custom_param("lowmem_emergency_pool", pa
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 
-static spinlock_t page_scrub_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(page_scrub_lock);
 LIST_HEAD(page_scrub_list);
 
 /*********************
@@ -250,7 +250,7 @@ static struct list_head heap[NR_ZONES][M
 
 static unsigned long avail[NR_ZONES];
 
-static spinlock_t heap_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(heap_lock);
 
 void end_boot_allocator(void)
 {
diff -r 29861ae27914 -r 91ee504ed40e xen/common/perfc.c
--- a/xen/common/perfc.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/perfc.c        Fri Jun 02 12:31:48 2006 -0500
@@ -209,7 +209,7 @@ static int perfc_copy_info(XEN_GUEST_HAN
 /* Dom0 control of perf counters */
 int perfc_control(dom0_perfccontrol_t *pc)
 {
-    static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+    static DEFINE_SPINLOCK(lock);
     u32 op = pc->op;
     int rc;
 
diff -r 29861ae27914 -r 91ee504ed40e xen/common/sched_bvt.c
--- a/xen/common/sched_bvt.c    Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/sched_bvt.c    Fri Jun 02 12:31:48 2006 -0500
@@ -160,15 +160,14 @@ static inline u32 calc_evt(struct vcpu *
 }
 
 /**
- * bvt_alloc_task - allocate BVT private structures for a task
- * @p:              task to allocate private structures for
- *
+ * bvt_init_vcpu - allocate BVT private structures for a VCPU.
  * Returns non-zero on failure.
  */
-static int bvt_alloc_task(struct vcpu *v)
+static int bvt_init_vcpu(struct vcpu *v)
 {
     struct domain *d = v->domain;
     struct bvt_dom_info *inf;
+    struct bvt_vcpu_info *einf;
 
     if ( (d->sched_priv == NULL) )
     {
@@ -199,15 +198,7 @@ static int bvt_alloc_task(struct vcpu *v
         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);
+    einf = EBVT_INFO(v);
 
     /* Allocate per-CPU context if this is the first domain to be added. */
     if ( CPU_INFO(v->processor) == NULL )
@@ -223,13 +214,15 @@ static void bvt_add_task(struct vcpu *v)
         einf->avt = einf->evt = ~0U;
         BUG_ON(__task_on_runqueue(v));
         __add_to_runqueue_head(v);
-    } 
+    }
     else 
     {
         /* Set avt and evt to system virtual time. */
         einf->avt = CPU_SVT(v->processor);
         einf->evt = CPU_SVT(v->processor);
     }
+
+    return 0;
 }
 
 static void bvt_wake(struct vcpu *v)
@@ -298,10 +291,9 @@ static int bvt_set_affinity(struct vcpu 
 
 
 /**
- * bvt_free_task - free BVT private structures for a task
- * @d:             task
- */
-static void bvt_free_task(struct domain *d)
+ * bvt_destroy_domain - free BVT private structures for a domain.
+ */
+static void bvt_destroy_domain(struct domain *d)
 {
     struct bvt_dom_info *inf = BVT_INFO(d);
 
@@ -568,10 +560,10 @@ struct scheduler sched_bvt_def = {
     .name     = "Borrowed Virtual Time",
     .opt_name = "bvt",
     .sched_id = SCHED_BVT,
-    
-    .alloc_task     = bvt_alloc_task,
-    .add_task       = bvt_add_task,
-    .free_task      = bvt_free_task,
+
+    .init_vcpu      = bvt_init_vcpu,
+    .destroy_domain = bvt_destroy_domain,
+
     .do_schedule    = bvt_do_schedule,
     .control        = bvt_ctl,
     .adjdom         = bvt_adjdom,
diff -r 29861ae27914 -r 91ee504ed40e xen/common/sched_credit.c
--- a/xen/common/sched_credit.c Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/sched_credit.c Fri Jun 02 12:31:48 2006 -0500
@@ -75,14 +75,13 @@
     } while ( 0 );
 
 #define CSCHED_STATS_EXPAND_SCHED(_MACRO)   \
-    _MACRO(vcpu_alloc)                      \
-    _MACRO(vcpu_add)                        \
+    _MACRO(vcpu_init)                       \
     _MACRO(vcpu_sleep)                      \
     _MACRO(vcpu_wake_running)               \
     _MACRO(vcpu_wake_onrunq)                \
     _MACRO(vcpu_wake_runnable)              \
     _MACRO(vcpu_wake_not_runnable)          \
-    _MACRO(dom_free)                        \
+    _MACRO(dom_destroy)                     \
     _MACRO(schedule)                        \
     _MACRO(tickle_local_idler)              \
     _MACRO(tickle_local_over)               \
@@ -429,14 +428,14 @@ __csched_vcpu_acct_idle_locked(struct cs
 }
 
 static int
-csched_vcpu_alloc(struct vcpu *vc)
+csched_vcpu_init(struct vcpu *vc)
 {
     struct domain * const dom = vc->domain;
     struct csched_dom *sdom;
     struct csched_vcpu *svc;
     int16_t pri;
 
-    CSCHED_STAT_CRANK(vcpu_alloc);
+    CSCHED_STAT_CRANK(vcpu_init);
 
     /* Allocate, if appropriate, per-domain info */
     if ( is_idle_vcpu(vc) )
@@ -489,19 +488,13 @@ csched_vcpu_alloc(struct vcpu *vc)
     if ( likely(sdom != NULL) )
         csched_vcpu_acct(svc, 0);
 
-    return 0;
-}
-
-static void
-csched_vcpu_add(struct vcpu *vc) 
-{
-    CSCHED_STAT_CRANK(vcpu_add);
-
     /* Allocate per-PCPU info */
     if ( unlikely(!CSCHED_PCPU(vc->processor)) )
         csched_pcpu_init(vc->processor);
 
     CSCHED_VCPU_CHECK(vc);
+
+    return 0;
 }
 
 static void
@@ -644,12 +637,12 @@ csched_dom_cntl(
 }
 
 static void
-csched_dom_free(struct domain *dom)
+csched_dom_destroy(struct domain *dom)
 {
     struct csched_dom * const sdom = CSCHED_DOM(dom);
     int i;
 
-    CSCHED_STAT_CRANK(dom_free);
+    CSCHED_STAT_CRANK(dom_destroy);
 
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
     {
@@ -1215,14 +1208,15 @@ struct scheduler sched_credit_def = {
     .opt_name       = "credit",
     .sched_id       = SCHED_CREDIT,
 
-    .alloc_task     = csched_vcpu_alloc,
-    .add_task       = csched_vcpu_add,
+    .init_vcpu      = csched_vcpu_init,
+    .destroy_domain = csched_dom_destroy,
+
     .sleep          = csched_vcpu_sleep,
     .wake           = csched_vcpu_wake,
+
     .set_affinity   = csched_vcpu_set_affinity,
 
     .adjdom         = csched_dom_cntl,
-    .free_task      = csched_dom_free,
 
     .tick           = csched_tick,
     .do_schedule    = csched_schedule,
diff -r 29861ae27914 -r 91ee504ed40e xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/sched_sedf.c   Fri Jun 02 12:31:48 2006 -0500
@@ -328,11 +328,9 @@ static inline void __add_to_runqueue_sor
 }
 
 
-/* Allocates memory for per domain private scheduling data*/
-static int sedf_alloc_task(struct vcpu *v)
-{
-    PRINT(2, "sedf_alloc_task was called, domain-id %i.%i\n",
-          v->domain->domain_id, v->vcpu_id);
+static int sedf_init_vcpu(struct vcpu *v)
+{
+    struct sedf_vcpu_info *inf;
 
     if ( v->domain->sched_priv == NULL )
     {
@@ -344,23 +342,11 @@ static int sedf_alloc_task(struct vcpu *
 
     if ( (v->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL )
         return -1;
-
     memset(v->sched_priv, 0, sizeof(struct sedf_vcpu_info));
 
-    return 0;
-}
-
-
-/* Setup the sedf_dom_info */
-static void sedf_add_task(struct vcpu *v)
-{
-    struct sedf_vcpu_info *inf = EDOM_INFO(v);
-
+    inf = EDOM_INFO(v);
     inf->vcpu = v;
  
-    PRINT(2,"sedf_add_task was called, domain-id %i.%i\n",
-          v->domain->domain_id, v->vcpu_id);
-
     /* Allocate per-CPU context if this is the first domain to be added. */
     if ( unlikely(schedule_data[v->processor].sched_priv == NULL) )
     {
@@ -408,14 +394,13 @@ static void sedf_add_task(struct vcpu *v
         EDOM_INFO(v)->deadl_abs = 0;
         EDOM_INFO(v)->status &= ~SEDF_ASLEEP;
     }
-}
-
-/* Frees memory used by domain info */
-static void sedf_free_task(struct domain *d)
+
+    return 0;
+}
+
+static void sedf_destroy_domain(struct domain *d)
 {
     int i;
-
-    PRINT(2,"sedf_free_task was called, domain-id %i\n",d->domain_id);
 
     xfree(d->sched_priv);
  
@@ -1452,9 +1437,9 @@ struct scheduler sched_sedf_def = {
     .opt_name = "sedf",
     .sched_id = SCHED_SEDF,
     
-    .alloc_task     = sedf_alloc_task,
-    .add_task       = sedf_add_task,
-    .free_task      = sedf_free_task,
+    .init_vcpu      = sedf_init_vcpu,
+    .destroy_domain = sedf_destroy_domain,
+
     .do_schedule    = sedf_do_schedule,
     .dump_cpu_state = sedf_dump_cpu_state,
     .sleep          = sedf_sleep,
diff -r 29861ae27914 -r 91ee504ed40e xen/common/schedule.c
--- a/xen/common/schedule.c     Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/schedule.c     Fri Jun 02 12:31:48 2006 -0500
@@ -99,74 +99,7 @@ void vcpu_runstate_get(struct vcpu *v, s
     }
 }
 
-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 ( (v = d->vcpu[i]) != NULL )
-            free_vcpu_struct(v);
-
-    xfree(d);
-}
-
-struct vcpu *alloc_vcpu(
-    struct domain *d, unsigned int vcpu_id, unsigned int cpu_id)
-{
-    struct vcpu *v;
-
-    BUG_ON(d->vcpu[vcpu_id] != NULL);
-
-    if ( (v = alloc_vcpu_struct(d, vcpu_id)) == NULL )
-        return NULL;
-
-    v->domain = d;
-    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;
-
-    v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
-    v->runstate.state_entry_time = NOW();
-
-    if ( (vcpu_id != 0) && !is_idle_domain(d) )
-        set_bit(_VCPUF_down, &v->vcpu_flags);
-
-    if ( SCHED_OP(alloc_task, v) < 0 )
-    {
-        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);
-
-    return v;
-}
-
-void sched_add_domain(struct vcpu *v) 
+int sched_init_vcpu(struct vcpu *v) 
 {
     /* Initialise the per-domain timers. */
     init_timer(&v->timer, vcpu_timer_fn, v, v->processor);
@@ -179,17 +112,23 @@ void sched_add_domain(struct vcpu *v)
         set_bit(_VCPUF_running, &v->vcpu_flags);
     }
 
-    SCHED_OP(add_task, v);
     TRACE_2D(TRC_SCHED_DOM_ADD, v->domain->domain_id, v->vcpu_id);
-}
-
-void sched_rem_domain(struct vcpu *v) 
-{
-    kill_timer(&v->timer);
-    kill_timer(&v->poll_timer);
-
-    SCHED_OP(rem_task, v);
-    TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id);
+
+    return SCHED_OP(init_vcpu, v);
+}
+
+void sched_destroy_domain(struct domain *d)
+{
+    struct vcpu *v;
+
+    for_each_vcpu ( d, v )
+    {
+        kill_timer(&v->timer);
+        kill_timer(&v->poll_timer);
+        TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id);
+    }
+
+    SCHED_OP(destroy_domain, d);
 }
 
 void vcpu_sleep_nosync(struct vcpu *v)
@@ -663,7 +602,7 @@ static void poll_timer_fn(void *data)
 /* Initialise the data structures. */
 void __init scheduler_init(void)
 {
-    int i, rc;
+    int i;
 
     open_softirq(SCHEDULE_SOFTIRQ, __enter_scheduler);
 
@@ -686,17 +625,6 @@ void __init scheduler_init(void)
 
     printk("Using scheduler: %s (%s)\n", ops.name, ops.opt_name);
     SCHED_OP(init);
-
-    if ( idle_vcpu[0] != NULL )
-    {
-        schedule_data[0].curr = idle_vcpu[0];
-        schedule_data[0].idle = idle_vcpu[0];
-
-        rc = SCHED_OP(alloc_task, idle_vcpu[0]);
-        BUG_ON(rc < 0);
-
-        sched_add_domain(idle_vcpu[0]);
-    }
 }
 
 /*
diff -r 29861ae27914 -r 91ee504ed40e xen/common/trace.c
--- a/xen/common/trace.c        Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/trace.c        Fri Jun 02 12:31:48 2006 -0500
@@ -173,25 +173,17 @@ void init_trace_bufs(void)
  */
 int tb_control(dom0_tbufcontrol_t *tbc)
 {
-    static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+    static DEFINE_SPINLOCK(lock);
     int rc = 0;
 
     spin_lock(&lock);
-
-    if ( !tb_init_done &&
-         (tbc->op != DOM0_TBUF_SET_SIZE) &&
-         (tbc->op != DOM0_TBUF_ENABLE) )
-    {
-        spin_unlock(&lock);
-        return -EINVAL;
-    }
 
     switch ( tbc->op )
     {
     case DOM0_TBUF_GET_INFO:
         tbc->cpu_mask   = tb_cpu_mask;
         tbc->evt_mask   = tb_event_mask;
-        tbc->buffer_mfn = __pa(t_bufs[0]) >> PAGE_SHIFT;
+        tbc->buffer_mfn = opt_tbuf_size ? virt_to_mfn(t_bufs[0]) : 0UL;
         tbc->size       = opt_tbuf_size * PAGE_SIZE;
         break;
     case DOM0_TBUF_SET_CPU_MASK:
diff -r 29861ae27914 -r 91ee504ed40e xen/common/xmalloc.c
--- a/xen/common/xmalloc.c      Tue May 30 15:24:31 2006 -0500
+++ b/xen/common/xmalloc.c      Fri Jun 02 12:31:48 2006 -0500
@@ -35,7 +35,7 @@
 #include <xen/prefetch.h>
 
 static LIST_HEAD(freelist);

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


 


Rackspace

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