Xen 
 
Home About Xen.org Xen Xen Summit Wiki Mailing List Bug Tracker Xen Downloads
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Merge with xenppc-unstable-merge.hg.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Merge with xenppc-unstable-merge.hg.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 30 Aug 2006 23:40:45 +0000
Delivery-date: Wed, 30 Aug 2006 16:44:44 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 50aea0ec406bd03dad9da31255857e4a41f7efcc
# Parent  e01441c9a607d3364dc092f186e0d925a3d4d8d4
# Parent  74db626d2fcfde3e61f1f43934eddd034d64a4a9
Merge with xenppc-unstable-merge.hg.
---
 linux-2.6-xen-sparse/arch/ia64/dig/setup.c           |    2 
 linux-2.6-xen-sparse/arch/ia64/kernel/setup.c        |    2 
 linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c      |   27 
 linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c  |    6 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c |   60 -
 linux-2.6-xen-sparse/include/asm-ia64/agp.h          |   12 
 linux-2.6-xen-sparse/include/asm-ia64/dma-mapping.h  |   20 
 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h    |  165 ---
 linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h   |   38 
 linux-2.6-xen-sparse/include/asm-ia64/io.h           |    6 
 linux-2.6-xen-sparse/include/asm-ia64/machvec.h      |    2 
 linux-2.6-xen-sparse/include/asm-ia64/maddr.h        |   88 +
 linux-2.6-xen-sparse/include/asm-ia64/page.h         |   69 -
 linux-2.6-xen-sparse/include/asm-ia64/pgalloc.h      |    4 
 tools/debugger/gdb/gdbbuild                          |    4 
 tools/examples/xmexample.vti                         |   32 
 tools/libxc/ia64/xc_ia64_hvm_build.c                 |   13 
 tools/libxc/ia64/xc_ia64_linux_save.c                |    2 
 tools/libxc/ia64/xc_ia64_stubs.c                     |   16 
 xen/arch/ia64/asm-offsets.c                          |    1 
 xen/arch/ia64/linux-xen/efi.c                        |   22 
 xen/arch/ia64/linux-xen/iosapic.c                    |    2 
 xen/arch/ia64/linux-xen/irq_ia64.c                   |   10 
 xen/arch/ia64/linux-xen/mca.c                        |    1 
 xen/arch/ia64/linux-xen/process-linux-xen.c          |    5 
 xen/arch/ia64/linux-xen/smp.c                        |    4 
 xen/arch/ia64/linux-xen/unwind.c                     |    3 
 xen/arch/ia64/vmx/Makefile                           |    2 
 xen/arch/ia64/vmx/mmio.c                             |   17 
 xen/arch/ia64/vmx/vmmu.c                             |    1 
 xen/arch/ia64/vmx/vmx_hypercall.c                    |   12 
 xen/arch/ia64/vmx/vmx_init.c                         |   47 
 xen/arch/ia64/vmx/vmx_phy_mode.c                     |    3 
 xen/arch/ia64/vmx/vmx_process.c                      |    8 
 xen/arch/ia64/vmx/vmx_support.c                      |  136 +-
 xen/arch/ia64/vmx/vtlb.c                             |  101 -
 xen/arch/ia64/xen/acpi.c                             |    3 
 xen/arch/ia64/xen/dom0_ops.c                         |    5 
 xen/arch/ia64/xen/dom_fw.c                           |  967 ++++++++---------
 xen/arch/ia64/xen/domain.c                           |   49 
 xen/arch/ia64/xen/faults.c                           |    7 
 xen/arch/ia64/xen/flushd.S                           |   11 
 xen/arch/ia64/xen/fw_emul.c                          |  165 ++-
 xen/arch/ia64/xen/hypercall.c                        |  130 +-
 xen/arch/ia64/xen/hyperprivop.S                      |   81 -
 xen/arch/ia64/xen/irq.c                              |    4 
 xen/arch/ia64/xen/ivt.S                              | 1035 ++++++++++---------
 xen/arch/ia64/xen/mm.c                               |    7 
 xen/arch/ia64/xen/pcdp.c                             |    1 
 xen/arch/ia64/xen/privop.c                           |    4 
 xen/arch/ia64/xen/privop_stat.c                      |  113 +-
 xen/arch/ia64/xen/vcpu.c                             |   31 
 xen/arch/ia64/xen/vhpt.c                             |   18 
 xen/arch/ia64/xen/xen.lds.S                          |    8 
 xen/arch/ia64/xen/xenasm.S                           |   22 
 xen/arch/ia64/xen/xensetup.c                         |   12 
 xen/arch/ia64/xen/xentime.c                          |    4 
 xen/arch/x86/physdev.c                               |    5 
 xen/include/asm-ia64/config.h                        |    6 
 xen/include/asm-ia64/dom_fw.h                        |   56 -
 xen/include/asm-ia64/domain.h                        |   14 
 xen/include/asm-ia64/grant_table.h                   |    2 
 xen/include/asm-ia64/linux-xen/asm/processor.h       |    8 
 xen/include/asm-ia64/linux-xen/linux/efi.h           |    4 
 xen/include/asm-ia64/multicall.h                     |    8 
 xen/include/asm-ia64/perfc.h                         |   12 
 xen/include/asm-ia64/perfc_defn.h                    |   17 
 xen/include/asm-ia64/privop_stat.h                   |   43 
 xen/include/asm-ia64/uaccess.h                       |   18 
 xen/include/asm-ia64/vcpu.h                          |   17 
 xen/include/asm-ia64/vhpt.h                          |    2 
 xen/include/asm-ia64/vmx.h                           |    8 
 xen/include/asm-ia64/vmx_vcpu.h                      |    7 
 xen/include/asm-ia64/vmx_vpd.h                       |   10 
 xen/include/public/domctl.h                          |    7 
 xen/include/public/xen.h                             |    1 
 76 files changed, 2182 insertions(+), 1683 deletions(-)

diff -r e01441c9a607 -r 50aea0ec406b linux-2.6-xen-sparse/arch/ia64/dig/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/dig/setup.c        Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/dig/setup.c        Wed Aug 30 22:36:18 
2006 +0100
@@ -69,7 +69,7 @@ dig_setup (char **cmdline_p)
        screen_info.orig_video_isVGA = 1;       /* XXX fake */
        screen_info.orig_video_ega_bx = 3;      /* XXX fake */
 #ifdef CONFIG_XEN
-       if (!is_running_on_xen())
+       if (!is_running_on_xen() || !is_initial_xendomain())
                return;
 
        if (xen_start_info->console.dom0.info_size >=
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c     Wed Aug 30 22:36:18 
2006 +0100
@@ -560,7 +560,9 @@ setup_arch (char **cmdline_p)
 
        platform_setup(cmdline_p);
        paging_init();
+#ifdef CONFIG_XEN
        contiguous_bitmap_init(max_pfn);
+#endif
 }
 
 /*
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Wed Aug 30 22:36:18 
2006 +0100
@@ -371,6 +371,8 @@ int
 int
 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
 {
+       __u64 va1, va2, pa1, pa2;
+
        if (cmd == GNTTABOP_map_grant_ref) {
                unsigned int i;
                for (i = 0; i < count; i++) {
@@ -378,8 +380,29 @@ HYPERVISOR_grant_table_op(unsigned int c
                                (struct gnttab_map_grant_ref*)uop + i);
                }
        }
-
-       return ____HYPERVISOR_grant_table_op(cmd, uop, count);
+       va1 = (__u64)uop & PAGE_MASK;
+       pa1 = pa2 = 0;
+       if ((REGION_NUMBER(va1) == 5) &&
+           ((va1 - KERNEL_START) >= KERNEL_TR_PAGE_SIZE)) {
+               pa1 = ia64_tpa(va1);
+               if (cmd <= GNTTABOP_transfer) {
+                       static uint32_t uop_size[GNTTABOP_transfer + 1] = {
+                               sizeof(struct gnttab_map_grant_ref),
+                               sizeof(struct gnttab_unmap_grant_ref),
+                               sizeof(struct gnttab_setup_table),
+                               sizeof(struct gnttab_dump_table),
+                               sizeof(struct gnttab_transfer),
+                       };
+                       va2 = (__u64)uop + (uop_size[cmd] * count) - 1;
+                       va2 &= PAGE_MASK;
+                       if (va1 != va2) {
+                               /* maximum size of uop is 2pages */
+                               BUG_ON(va2 > va1 + PAGE_SIZE);
+                               pa2 = ia64_tpa(va2);
+                       }
+               }
+       }
+       return ____HYPERVISOR_grant_table_op(cmd, uop, count, pa1, pa2);
 }
 EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
 
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Wed Aug 30 
14:09:31 2006 -0500
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Wed Aug 30 
22:36:18 2006 +0100
@@ -846,7 +846,7 @@ void __init setup_arch(char **cmdline_p)
 
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* Make sure we have a large enough P->M table. */
-                       phys_to_machine_mapping = alloc_bootmem(
+                       phys_to_machine_mapping = alloc_bootmem_pages(
                                end_pfn * sizeof(unsigned long));
                        memset(phys_to_machine_mapping, ~0,
                               end_pfn * sizeof(unsigned long));
@@ -863,7 +863,7 @@ void __init setup_arch(char **cmdline_p)
                         * list of frames that make up the p2m table. Used by
                          * save/restore.
                         */
-                       pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE);
+                       pfn_to_mfn_frame_list_list = 
alloc_bootmem_pages(PAGE_SIZE);
                        HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list 
=
                                virt_to_mfn(pfn_to_mfn_frame_list_list);
 
@@ -873,7 +873,7 @@ void __init setup_arch(char **cmdline_p)
                                        k++;
                                        BUG_ON(k>=fpp);
                                        pfn_to_mfn_frame_list[k] =
-                                               alloc_bootmem(PAGE_SIZE);
+                                               alloc_bootmem_pages(PAGE_SIZE);
                                        pfn_to_mfn_frame_list_list[k] =
                                                
virt_to_mfn(pfn_to_mfn_frame_list[k]);
                                        j=0;
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Aug 30 
14:09:31 2006 -0500
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Aug 30 
22:36:18 2006 +0100
@@ -193,6 +193,7 @@ static void netfront_closing(struct xenb
 
 static void end_access(int, void *);
 static void netif_disconnect_backend(struct netfront_info *);
+static int open_netdev(struct netfront_info *);
 static void close_netdev(struct netfront_info *);
 static void netif_free(struct netfront_info *);
 
@@ -263,15 +264,22 @@ static int __devinit netfront_probe(stru
        dev->dev.driver_data = info;
 
        err = talk_to_backend(dev, info);
-       if (err) {
-               xennet_sysfs_delif(info->netdev);
-               unregister_netdev(netdev);
-               free_netdev(netdev);
-               dev->dev.driver_data = NULL;
-               return err;
-       }
+       if (err)
+               goto fail_backend;
+
+       err = open_netdev(info);
+       if (err)
+               goto fail_open;
 
        return 0;
+
+ fail_open:
+       xennet_sysfs_delif(info->netdev);
+       unregister_netdev(netdev);
+ fail_backend:
+       free_netdev(netdev);
+       dev->dev.driver_data = NULL;
+       return err;
 }
 
 
@@ -1887,27 +1895,9 @@ create_netdev(int handle, int copying_re
        SET_MODULE_OWNER(netdev);
        SET_NETDEV_DEV(netdev, &dev->dev);
 
-       err = register_netdev(netdev);
-       if (err) {
-               printk(KERN_WARNING "%s> register_netdev err=%d\n",
-                      __FUNCTION__, err);
-               goto exit_free_rx;
-       }
-
-       err = xennet_sysfs_addif(netdev);
-       if (err) {
-               /* This can be non-fatal: it only means no tuning parameters */
-               printk(KERN_WARNING "%s> add sysfs failed err=%d\n",
-                      __FUNCTION__, err);
-       }
-
        np->netdev = netdev;
-
        return netdev;
 
-
- exit_free_rx:
-       gnttab_free_grant_references(np->gref_rx_head);
  exit_free_tx:
        gnttab_free_grant_references(np->gref_tx_head);
  exit:
@@ -1966,6 +1956,26 @@ static int __devexit netfront_remove(str
        return 0;
 }
 
+
+static int open_netdev(struct netfront_info *info)
+{
+       int err;
+       
+       err = register_netdev(info->netdev);
+       if (err) {
+               printk(KERN_WARNING "%s: register_netdev err=%d\n",
+                      __FUNCTION__, err);
+               return err;
+       }
+
+       err = xennet_sysfs_addif(info->netdev);
+       if (err) {
+               /* This can be non-fatal: it only means no tuning parameters */
+               printk(KERN_WARNING "%s: add sysfs failed err=%d\n",
+                      __FUNCTION__, err);
+       }
+       return 0;
+}
 
 static void close_netdev(struct netfront_info *info)
 {
diff -r e01441c9a607 -r 50aea0ec406b linux-2.6-xen-sparse/include/asm-ia64/agp.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/agp.h       Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/agp.h       Wed Aug 30 22:36:18 
2006 +0100
@@ -19,10 +19,21 @@
 #define flush_agp_cache()              mb()
 
 /* Convert a physical address to an address suitable for the GART. */
+#ifndef CONFIG_XEN
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+#else
 #define phys_to_gart(x) phys_to_machine_for_dma(x)
 #define gart_to_phys(x) machine_to_phys_for_dma(x)
+#endif
 
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#ifndef CONFIG_XEN
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+#else
 #include <asm/hypervisor.h>
 static inline char*
 alloc_gatt_pages(unsigned int order)
@@ -46,5 +57,6 @@ free_gatt_pages(void* table, unsigned in
        xen_destroy_contiguous_region((unsigned long)table, order);
        free_pages((unsigned long)table, order);
 }
+#endif /* CONFIG_XEN */
 
 #endif /* _ASM_IA64_AGP_H */
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/include/asm-ia64/dma-mapping.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/dma-mapping.h       Wed Aug 30 
14:09:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/dma-mapping.h       Wed Aug 30 
22:36:18 2006 +0100
@@ -7,11 +7,28 @@
  */
 #include <linux/config.h>
 #include <asm/machvec.h>
+#ifdef CONFIG_XEN
 /* Needed for arch/i386/kernel/swiotlb.c and arch/i386/kernel/pci-dma-xen.c */
 #include <asm/hypervisor.h>
 /* Needed for arch/i386/kernel/swiotlb.c */
 #include <asm-i386/mach-xen/asm/swiotlb.h>
+#endif
 
+#ifndef CONFIG_XEN
+#define dma_alloc_coherent     platform_dma_alloc_coherent
+#define dma_alloc_noncoherent  platform_dma_alloc_coherent     /* coherent 
mem. is cheap */
+#define dma_free_coherent      platform_dma_free_coherent
+#define dma_free_noncoherent   platform_dma_free_coherent
+#define dma_map_single         platform_dma_map_single
+#define dma_map_sg             platform_dma_map_sg
+#define dma_unmap_single       platform_dma_unmap_single
+#define dma_unmap_sg           platform_dma_unmap_sg
+#define dma_sync_single_for_cpu        platform_dma_sync_single_for_cpu
+#define dma_sync_sg_for_cpu    platform_dma_sync_sg_for_cpu
+#define dma_sync_single_for_device platform_dma_sync_single_for_device
+#define dma_sync_sg_for_device platform_dma_sync_sg_for_device
+#define dma_mapping_error      platform_dma_mapping_error
+#else
 int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
                enum dma_data_direction direction);
 void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
@@ -50,6 +67,7 @@ dma_sync_sg_for_device(struct device *de
                swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
        flush_write_buffers();
 }
+#endif
 
 #define dma_map_page(dev, pg, off, size, dir)                          \
        dma_map_single(dev, page_address(pg) + (off), (size), (dir))
@@ -91,6 +109,7 @@ dma_cache_sync (void *vaddr, size_t size
 
 #define dma_is_consistent(dma_handle)  (1)     /* all we do is coherent 
memory... */
 
+#ifdef CONFIG_XEN
 /* arch/i386/kernel/swiotlb.o requires */
 void contiguous_bitmap_init(unsigned long end_pfn);
 
@@ -111,5 +130,6 @@ range_straddles_page_boundary(void *p, s
        return (((((unsigned long)p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
                !test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap));
 }
+#endif
 
 #endif /* _ASM_IA64_DMA_MAPPING_H */
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed Aug 30 22:36:18 
2006 +0100
@@ -51,7 +51,7 @@
                              "break 0x1000 ;;\n"               \
                              "mov %0=r8 ;;\n"                  \
                              : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name)       \
+                             : "J" (__HYPERVISOR_##name)       \
                              : "r2","r8",                      \
                                "memory" );                     \
        (type)__res;                                            \
@@ -66,8 +66,8 @@
                              "break 0x1000 ;;\n"               \
                              "mov %0=r8 ;;\n"                  \
                              : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "r" ((unsigned long)(a1))       \
+                             : "J" (__HYPERVISOR_##name),      \
+                               "rI" ((unsigned long)(a1))      \
                              : "r14","r2","r8",                \
                                "memory" );                     \
        (type)__res;                                            \
@@ -83,9 +83,9 @@
                              "break 0x1000 ;;\n"               \
                              "mov %0=r8 ;;\n"                  \
                              : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "r" ((unsigned long)(a1)),      \
-                               "r" ((unsigned long)(a2))       \
+                             : "J" (__HYPERVISOR_##name),      \
+                               "rI" ((unsigned long)(a1)),     \
+                               "rI" ((unsigned long)(a2))      \
                              : "r14","r15","r2","r8",          \
                                "memory" );                     \
        (type)__res;                                            \
@@ -102,10 +102,10 @@
                              "break 0x1000 ;;\n"               \
                              "mov %0=r8 ;;\n"                  \
                              : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "r" ((unsigned long)(a1)),      \
-                               "r" ((unsigned long)(a2)),      \
-                               "r" ((unsigned long)(a3))       \
+                             : "J" (__HYPERVISOR_##name),      \
+                               "rI" ((unsigned long)(a1)),     \
+                               "rI" ((unsigned long)(a2)),     \
+                               "rI" ((unsigned long)(a3))      \
                              : "r14","r15","r16","r2","r8",    \
                                "memory" );                     \
        (type)__res;                                            \
@@ -123,11 +123,11 @@
                              "break 0x1000 ;;\n"               \
                              "mov %0=r8 ;;\n"                  \
                              : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "r" ((unsigned long)(a1)),      \
-                               "r" ((unsigned long)(a2)),      \
-                               "r" ((unsigned long)(a3)),      \
-                               "r" ((unsigned long)(a4))       \
+                             : "J" (__HYPERVISOR_##name),      \
+                               "rI" ((unsigned long)(a1)),     \
+                               "rI" ((unsigned long)(a2)),     \
+                               "rI" ((unsigned long)(a3)),     \
+                               "rI" ((unsigned long)(a4))      \
                              : "r14","r15","r16","r2","r8",    \
                                "r17","memory" );               \
        (type)__res;                                            \
@@ -146,12 +146,12 @@
                              "break 0x1000 ;;\n"               \
                              "mov %0=r8 ;;\n"                  \
                              : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "r" ((unsigned long)(a1)),      \
-                               "r" ((unsigned long)(a2)),      \
-                               "r" ((unsigned long)(a3)),      \
-                               "r" ((unsigned long)(a4)),      \
-                               "r" ((unsigned long)(a5))       \
+                             : "J" (__HYPERVISOR_##name),      \
+                               "rI" ((unsigned long)(a1)),     \
+                               "rI" ((unsigned long)(a2)),     \
+                               "rI" ((unsigned long)(a3)),     \
+                               "rI" ((unsigned long)(a4)),     \
+                               "rI" ((unsigned long)(a5))      \
                              : "r14","r15","r16","r2","r8",    \
                                "r17","r18","memory" );         \
        (type)__res;                                            \
@@ -275,9 +275,10 @@ HYPERVISOR_physdev_op(
 //XXX __HYPERVISOR_grant_table_op is used for this hypercall constant.
 static inline int
 ____HYPERVISOR_grant_table_op(
-    unsigned int cmd, void *uop, unsigned int count)
-{
-    return _hypercall3(int, grant_table_op, cmd, uop, count);
+    unsigned int cmd, void *uop, unsigned int count,
+    unsigned long pa1, unsigned long pa2)
+{
+    return _hypercall5(int, grant_table_op, cmd, uop, count, pa1, pa2);
 }
 
 int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
@@ -290,6 +291,13 @@ HYPERVISOR_vcpu_op(
 }
 
 extern int HYPERVISOR_suspend(unsigned long srec);
+
+static inline unsigned long
+HYPERVISOR_hvm_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(unsigned long, hvm_op, cmd, arg);
+}
 
 static inline int
 HYPERVISOR_callback_op(
@@ -307,99 +315,15 @@ static inline void exit_idle(void) {}
 })
 
 #include <linux/err.h>
+#ifdef CONFIG_XEN
 #include <asm/xen/privop.h>
-
-#define _hypercall_imm1(type, name, imm, a1)                   \
-({                                                             \
-       long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r15=%3\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "i" (imm),                      \
-                               "r" ((unsigned long)(a1))       \
-                             : "r14","r15","r2","r8",          \
-                               "memory" );                     \
-       (type)__res;                                            \
-})
-
-#define _hypercall_imm2(type, name, imm, a1, a2)               \
-({                                                             \
-       long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r15=%3\n"                    \
-                             "mov r16=%4\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "i" (imm),                      \
-                               "r" ((unsigned long)(a1)),      \
-                               "r" ((unsigned long)(a2))       \
-                             : "r14","r15","r16","r2","r8",    \
-                               "memory" );                     \
-       (type)__res;                                            \
-})
-
-#define _hypercall_imm3(type, name, imm, a1, a2, a3)           \
-({                                                             \
-       long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r15=%3\n"                    \
-                             "mov r16=%4\n"                    \
-                             "mov r17=%5\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "i" (imm),                      \
-                               "r" ((unsigned long)(a1)),      \
-                               "r" ((unsigned long)(a2)),      \
-                               "r" ((unsigned long)(a3))       \
-                             : "r14","r15","r16","r17",        \
-                               "r2","r8",                      \
-                               "memory" );                     \
-       (type)__res;                                            \
-})
-
-#define _hypercall_imm4(type, name, imm, a1, a2, a3, a4)       \
-({                                                             \
-       long __res;                                             \
-       __asm__ __volatile__ (";;\n"                            \
-                             "mov r14=%2\n"                    \
-                             "mov r15=%3\n"                    \
-                             "mov r16=%4\n"                    \
-                             "mov r17=%5\n"                    \
-                             "mov r18=%6\n"                    \
-                             "mov r2=%1\n"                     \
-                             "break 0x1000 ;;\n"               \
-                             "mov %0=r8 ;;\n"                  \
-                             : "=r" (__res)                    \
-                             : "i" (__HYPERVISOR_##name),      \
-                               "i" (imm),                      \
-                               "r" ((unsigned long)(a1)),      \
-                               "r" ((unsigned long)(a2)),      \
-                               "r" ((unsigned long)(a3)),      \
-                               "r" ((unsigned long)(a4))       \
-                             : "r14","r15","r16","r17","r18",  \
-                               "r2","r8",                      \
-                               "memory" );                     \
-       (type)__res;                                            \
-})
+#endif /* CONFIG_XEN */
 
 static inline unsigned long
 __HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
 {
-       return _hypercall_imm2(unsigned long, ia64_dom0vp_op,
-                              IA64_DOM0VP_ioremap, ioaddr, size);
+       return _hypercall3(unsigned long, ia64_dom0vp_op,
+                          IA64_DOM0VP_ioremap, ioaddr, size);
 }
 
 static inline unsigned long
@@ -421,8 +345,8 @@ static inline unsigned long
 static inline unsigned long
 __HYPERVISOR_phystomach(unsigned long gpfn)
 {
-       return _hypercall_imm1(unsigned long, ia64_dom0vp_op,
-                              IA64_DOM0VP_phystomach, gpfn);
+       return _hypercall2(unsigned long, ia64_dom0vp_op,
+                          IA64_DOM0VP_phystomach, gpfn);
 }
 
 static inline unsigned long
@@ -438,8 +362,8 @@ static inline unsigned long
 static inline unsigned long
 __HYPERVISOR_machtophys(unsigned long mfn)
 {
-       return _hypercall_imm1(unsigned long, ia64_dom0vp_op,
-                              IA64_DOM0VP_machtophys, mfn);
+       return _hypercall2(unsigned long, ia64_dom0vp_op,
+                          IA64_DOM0VP_machtophys, mfn);
 }
 
 static inline unsigned long
@@ -455,8 +379,8 @@ static inline unsigned long
 static inline unsigned long
 __HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
 {
-       return _hypercall_imm2(unsigned long, ia64_dom0vp_op,
-                              IA64_DOM0VP_zap_physmap, gpfn, extent_order);
+       return _hypercall3(unsigned long, ia64_dom0vp_op,
+                          IA64_DOM0VP_zap_physmap, gpfn, extent_order);
 }
 
 static inline unsigned long
@@ -473,9 +397,8 @@ __HYPERVISOR_add_physmap(unsigned long g
 __HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
                         unsigned long flags, domid_t domid)
 {
-       return _hypercall_imm4(unsigned long, ia64_dom0vp_op,
-                              IA64_DOM0VP_add_physmap, gpfn, mfn, flags,
-                              domid);
+       return _hypercall5(unsigned long, ia64_dom0vp_op,
+                          IA64_DOM0VP_add_physmap, gpfn, mfn, flags, domid);
 }
 
 static inline unsigned long
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Wed Aug 30 
14:09:31 2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h        Wed Aug 30 
22:36:18 2006 +0100
@@ -33,7 +33,7 @@
 #ifndef __HYPERVISOR_H__
 #define __HYPERVISOR_H__
 
-#ifndef CONFIG_XEN
+#if !defined(CONFIG_XEN) && !defined(CONFIG_VMX_GUEST)
 #define is_running_on_xen()                    (0)
 #define HYPERVISOR_ioremap(offset, size)       (offset)
 #else
@@ -41,7 +41,7 @@ extern int running_on_xen;
 #define is_running_on_xen()                    (running_on_xen)
 #endif
 
-#ifdef CONFIG_XEN
+#if defined(CONFIG_XEN) || defined(CONFIG_VMX_GUEST)
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -59,10 +59,9 @@ extern shared_info_t *HYPERVISOR_shared_
 extern shared_info_t *HYPERVISOR_shared_info;
 extern start_info_t *xen_start_info;
 
-#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
-
 void force_evtchn_callback(void);
 
+#ifndef CONFIG_VMX_GUEST
 /* Turn jiffies into Xen system time. XXX Implement me. */
 #define jiffies_to_st(j)       0
 
@@ -145,10 +144,14 @@ int privcmd_mmap(struct file * file, str
 #define scrub_pages(_p,_n) ((void)0)
 #endif
 #define        pte_mfn(_x)     pte_pfn(_x)
-#define __pte_ma(_x)   ((pte_t) {(_x)})
 #define phys_to_machine_mapping_valid(_x)      (1)
-#define pfn_pte_ma(_x,_y)      __pte_ma(0)
-
+
+#endif /* !CONFIG_VMX_GUEST */
+
+#define __pte_ma(_x)   ((pte_t) {(_x)})        /* unmodified use */
+#define pfn_pte_ma(_x,_y)      __pte_ma(0)     /* unmodified use */
+
+#ifndef CONFIG_VMX_GUEST
 int __xen_create_contiguous_region(unsigned long vstart, unsigned int order, 
unsigned int address_bits);
 static inline int
 xen_create_contiguous_region(unsigned long vstart,
@@ -170,6 +173,8 @@ xen_destroy_contiguous_region(unsigned l
                __xen_destroy_contiguous_region(vstart, order);
 }
 
+#endif /* !CONFIG_VMX_GUEST */
+
 // for netfront.c, netback.c
 #define MULTI_UVMFLAGS_INDEX 0 //XXX any value
 
@@ -180,12 +185,29 @@ MULTI_update_va_mapping(
 {
        mcl->op = __HYPERVISOR_update_va_mapping;
        mcl->result = 0;
+}
+
+static inline void
+MULTI_grant_table_op(multicall_entry_t *mcl, unsigned int cmd,
+       void *uop, unsigned int count)
+{
+       mcl->op = __HYPERVISOR_grant_table_op;
+       mcl->args[0] = cmd;
+       mcl->args[1] = (unsigned long)uop;
+       mcl->args[2] = count;
 }
 
 // for debug
 asmlinkage int xprintk(const char *fmt, ...);
 #define xprintd(fmt, ...)      xprintk("%s:%d " fmt, __func__, __LINE__, \
                                        ##__VA_ARGS__)
-#endif /* CONFIG_XEN */
+
+#endif /* CONFIG_XEN || CONFIG_VMX_GUEST */
+
+#ifdef CONFIG_XEN_PRIVILEGED_GUEST
+#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
+#else
+#define is_initial_xendomain() 0
+#endif
 
 #endif /* __HYPERVISOR_H__ */
diff -r e01441c9a607 -r 50aea0ec406b linux-2.6-xen-sparse/include/asm-ia64/io.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/io.h        Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/io.h        Wed Aug 30 22:36:18 
2006 +0100
@@ -97,6 +97,11 @@ extern int valid_mmap_phys_addr_range (u
  * The following two macros are deprecated and scheduled for removal.
  * Please use the PCI-DMA interface defined in <asm/pci.h> instead.
  */
+#ifndef CONFIG_XEN
+#define bus_to_virt    phys_to_virt
+#define virt_to_bus    virt_to_phys
+#define page_to_bus    page_to_phys
+#else
 #define bus_to_virt(bus)       \
        phys_to_virt(machine_to_phys_for_dma(bus))
 #define virt_to_bus(virt)      \
@@ -124,6 +129,7 @@ extern int valid_mmap_phys_addr_range (u
        (((bvec_to_bus((vec1)) + (vec1)->bv_len) == bvec_to_bus((vec2))) && \
         ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) ==              \
          bvec_to_pseudophys((vec2))))
+#endif /* CONFIG_XEN */
 
 # endif /* KERNEL */
 
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/include/asm-ia64/machvec.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/machvec.h   Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/machvec.h   Wed Aug 30 22:36:18 
2006 +0100
@@ -247,6 +247,7 @@ extern void machvec_init (const char *na
 #  error Unknown configuration.  Update asm-ia64/machvec.h.
 # endif /* CONFIG_IA64_GENERIC */
 
+#ifdef CONFIG_XEN
 # define platform_dma_map_sg           dma_map_sg
 # define platform_dma_unmap_sg         dma_unmap_sg
 # define platform_dma_mapping_error    dma_mapping_error
@@ -259,6 +260,7 @@ extern void machvec_init (const char *na
                                        dma_sync_single_for_cpu
 # define platform_dma_sync_single_for_device \
                                        dma_sync_single_for_device
+#endif
 
 /*
  * Declare default routines which aren't declared anywhere else:
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/include/asm-ia64/page.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/page.h      Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/page.h      Wed Aug 30 22:36:18 
2006 +0100
@@ -117,6 +117,9 @@ extern unsigned long max_low_pfn;
 # define pfn_to_page(pfn)      (vmem_map + (pfn))
 #endif
 
+#ifndef CONFIG_XEN
+#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
+#endif
 #define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 
@@ -221,12 +224,9 @@ get_order (unsigned long size)
 #ifndef __ASSEMBLY__
 #ifdef CONFIG_XEN
 
-#define INVALID_P2M_ENTRY      (~0UL)
-
 #include <linux/kernel.h>
 #include <asm/hypervisor.h>
 #include <xen/features.h>      // to compile netback, netfront
-typedef unsigned long maddr_t; // to compile netback, netfront
 
 /*
  * XXX hack!
@@ -265,68 +265,7 @@ extern struct address_space xen_ia64_for
 })
 #define HAVE_ARCH_FREE_PAGE
 
-/* XXX xen page size != page size */
-
-static inline unsigned long
-pfn_to_mfn_for_dma(unsigned long pfn)
-{
-       unsigned long mfn;
-       mfn = HYPERVISOR_phystomach(pfn);
-       BUG_ON(mfn == 0); // XXX
-       BUG_ON(mfn == INVALID_P2M_ENTRY); // XXX
-       BUG_ON(mfn == INVALID_MFN);
-       return mfn;
-}
-
-static inline unsigned long
-phys_to_machine_for_dma(unsigned long phys)
-{
-       unsigned long machine =
-                     pfn_to_mfn_for_dma(phys >> PAGE_SHIFT) << PAGE_SHIFT;
-       machine |= (phys & ~PAGE_MASK);
-       return machine;
-}
-
-static inline unsigned long
-mfn_to_pfn_for_dma(unsigned long mfn)
-{
-       unsigned long pfn;
-       pfn = HYPERVISOR_machtophys(mfn);
-       BUG_ON(pfn == 0);
-       //BUG_ON(pfn == INVALID_M2P_ENTRY);
-       return pfn;
-}
-
-static inline unsigned long
-machine_to_phys_for_dma(unsigned long machine)
-{
-       unsigned long phys =
-                     mfn_to_pfn_for_dma(machine >> PAGE_SHIFT) << PAGE_SHIFT;
-       phys |= (machine & ~PAGE_MASK);
-       return phys;
-}
-
-#define set_phys_to_machine(pfn, mfn) do { } while (0)
-#define xen_machphys_update(mfn, pfn) do { } while (0)
-
-/* XXX to compile set_phys_to_machine(vaddr, FOREIGN_FRAME(m)) */
-#define FOREIGN_FRAME(m)        (INVALID_P2M_ENTRY)
-
-#define mfn_to_pfn(mfn)                        (mfn)
-#define mfn_to_virt(mfn)               (__va((mfn) << PAGE_SHIFT))
-#define pfn_to_mfn(pfn)                        (pfn)
-#define virt_to_mfn(virt)              (__pa(virt) >> PAGE_SHIFT)
-#define virt_to_machine(virt)          __pa(virt) // for tpmfront.c
-
-static inline unsigned long
-mfn_to_local_pfn(unsigned long mfn)
-{
-       extern unsigned long max_mapnr;
-       unsigned long pfn = mfn_to_pfn_for_dma(mfn);
-       if (!pfn_valid(pfn))
-               return INVALID_P2M_ENTRY;
-       return pfn;
-}
+#include <asm/maddr.h>
 
 #endif /* CONFIG_XEN */
 #endif /* __ASSEMBLY__ */
diff -r e01441c9a607 -r 50aea0ec406b 
linux-2.6-xen-sparse/include/asm-ia64/pgalloc.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/pgalloc.h   Wed Aug 30 14:09:31 
2006 -0500
+++ b/linux-2.6-xen-sparse/include/asm-ia64/pgalloc.h   Wed Aug 30 22:36:18 
2006 +0100
@@ -126,7 +126,11 @@ static inline void
 static inline void
 pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, struct page *pte)
 {
+#ifndef CONFIG_XEN
+       pmd_val(*pmd_entry) = page_to_phys(pte);
+#else
        pmd_val(*pmd_entry) = page_to_pseudophys(pte);
+#endif
 }
 
 static inline void
diff -r e01441c9a607 -r 50aea0ec406b tools/debugger/gdb/gdbbuild
--- a/tools/debugger/gdb/gdbbuild       Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/debugger/gdb/gdbbuild       Wed Aug 30 22:36:18 2006 +0100
@@ -18,7 +18,7 @@ if [ "$MAKE" ]; then
 if [ "$MAKE" ]; then
     $MAKE
 elif which gmake ; then
-    gmake -j4
+    gmake -j4 CFLAGS=-D__XEN_TOOLS__
 else
-    make -j4
+    make -j4 CFLAGS=-D__XEN_TOOLS__
 fi
diff -r e01441c9a607 -r 50aea0ec406b tools/examples/xmexample.vti
--- a/tools/examples/xmexample.vti      Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/examples/xmexample.vti      Wed Aug 30 22:36:18 2006 +0100
@@ -37,11 +37,9 @@ name = "ExampleVTIDomain"
 
 # Optionally define mac and/or bridge for the network interfaces.
 # Random MACs are assigned if not given.
-#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
+#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
 # type=ioemu specify the NIC is an ioemu device not netfront
 vif = [ 'type=ioemu, bridge=xenbr0' ]
-# for multiple NICs in device model, 3 in this example
-#vif = [ 'type=ioemu, bridge=xenbr0', 'type=ioemu', 'type=ioemu']
 
 #----------------------------------------------------------------------------
 # Define the disk devices you want the domain to have access to, and
@@ -51,7 +49,7 @@ vif = [ 'type=ioemu, bridge=xenbr0' ]
 # and MODE is r for read-only, w for read-write.
 
 #disk = [ 'phy:hda1,hda1,r' ]
-disk = [ 'file:/var/images/xenia64.img,ioemu:hda,w' ]
+disk = [ 'file:/var/images/xenia64.img,hda,w', ',hdc:cdrom,r' ]
 
 #----------------------------------------------------------------------------
 # Set according to whether you want the domain restarted when it exits.
@@ -65,13 +63,6 @@ disk = [ 'file:/var/images/xenia64.img,i
 
 # New stuff
 device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
-
-# Advanced users only. Don't touch if you don't know what you're doing
-memmap = '/usr/lib/xen/boot/mem-map.sxp'
-
-#-----------------------------------------------------------------------------
-# Disk image for 
-#cdrom=
 
 #-----------------------------------------------------------------------------
 # boot on floppy (a), hard disk (c) or CD-ROM (d) 
@@ -91,8 +82,17 @@ vnc=0
 vnc=0
 
 #----------------------------------------------------------------------------
-# enable spawning vncviewer(only valid when vnc=1), default = 1
-vncviewer=0
+# set VNC display number, default = domid
+#vncdisplay=1
+
+#----------------------------------------------------------------------------
+# try to find an unused port for the VNC server, default = 1
+#vncunused=1
+
+#----------------------------------------------------------------------------
+# enable spawning vncviewer for domain's console
+# (only valid when vnc=1), default = 0
+#vncconsole=0
 
 #----------------------------------------------------------------------------
 # no graphics, use serial port
@@ -108,14 +108,12 @@ serial='pty'
 serial='pty'
 
 #-----------------------------------------------------------------------------
-#   enable audio support
-#enable-audio=1
-
+#   enable sound card support, [sb16|es1370|all|..,..], default none
+#soundhw='sb16'
 
 #-----------------------------------------------------------------------------
 #    set the real time clock to local time [default=0 i.e. set to utc]
 #localtime=1
-
 
 #-----------------------------------------------------------------------------
 #    start in full screen
diff -r e01441c9a607 -r 50aea0ec406b tools/libxc/ia64/xc_ia64_hvm_build.c
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c      Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c      Wed Aug 30 22:36:18 2006 +0100
@@ -553,7 +553,6 @@ setup_guest(int xc_handle, uint32_t dom,
 {
     unsigned long page_array[2];
     shared_iopage_t *sp;
-    int i;
     unsigned long dom_memsize = (memsize << 20);
     DECLARE_DOMCTL;
 
@@ -604,18 +603,6 @@ setup_guest(int xc_handle, uint32_t dom,
         goto error_out;
 
     memset(sp, 0, PAGE_SIZE);
-
-    for (i = 0; i < vcpus; i++) {
-        uint32_t vp_eport;
-
-        vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
-        if (vp_eport < 0) {
-            DPRINTF("Couldn't get unbound port from VMX guest.\n");
-            goto error_out;
-        }
-        sp->vcpu_iodata[i].vp_eport = vp_eport;
-    }
-
     munmap(sp, PAGE_SIZE);
 
     return 0;
diff -r e01441c9a607 -r 50aea0ec406b tools/libxc/ia64/xc_ia64_linux_save.c
--- a/tools/libxc/ia64/xc_ia64_linux_save.c     Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/libxc/ia64/xc_ia64_linux_save.c     Wed Aug 30 22:36:18 2006 +0100
@@ -79,7 +79,7 @@ static int xc_ia64_shadow_control(int xc
     }
 
     return xc_shadow_control(xc_handle, domid, sop,
-                             dirty_bitmap, pages, stats);
+                             dirty_bitmap, pages, NULL, 0, stats);
 }
 
 static inline ssize_t
diff -r e01441c9a607 -r 50aea0ec406b tools/libxc/ia64/xc_ia64_stubs.c
--- a/tools/libxc/ia64/xc_ia64_stubs.c  Wed Aug 30 14:09:31 2006 -0500
+++ b/tools/libxc/ia64/xc_ia64_stubs.c  Wed Aug 30 22:36:18 2006 +0100
@@ -36,7 +36,6 @@ xc_ia64_get_pfn_list(int xc_handle, uint
     struct xen_domctl domctl;
     int num_pfns,ret;
     unsigned int __start_page, __nr_pages;
-    unsigned long max_pfns;
     xen_pfn_t *__pfn_buf;
 
     __start_page = start_page;
@@ -44,27 +43,22 @@ xc_ia64_get_pfn_list(int xc_handle, uint
     __pfn_buf = pfn_buf;
   
     while (__nr_pages) {
-        max_pfns = ((unsigned long)__start_page << 32) | __nr_pages;
         domctl.cmd = XEN_DOMCTL_getmemlist;
-        domctl.domain   = (domid_t)domid;
-        domctl.u.getmemlist.max_pfns = max_pfns;
+        domctl.domain = (domid_t)domid;
+        domctl.u.getmemlist.max_pfns = __nr_pages;
+        domctl.u.getmemlist.start_pfn =__start_page;
         domctl.u.getmemlist.num_pfns = 0;
         set_xen_guest_handle(domctl.u.getmemlist.buffer, __pfn_buf);
 
-        if ((max_pfns != -1UL)
-            && mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0) {
+        if (mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0) {
             PERROR("Could not lock pfn list buffer");
             return -1;
         }
 
         ret = do_domctl(xc_handle, &domctl);
 
-        if (max_pfns != -1UL)
-            (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t));
+        (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t));
 
-        if (max_pfns == -1UL)
-            return 0;
-        
         num_pfns = domctl.u.getmemlist.num_pfns;
         __start_page += num_pfns;
         __nr_pages -= num_pfns;
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/asm-offsets.c
--- a/xen/arch/ia64/asm-offsets.c       Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/asm-offsets.c       Wed Aug 30 22:36:18 2006 +0100
@@ -31,7 +31,6 @@ void foo(void)
        DEFINE(IA64_SWITCH_STACK_SIZE, sizeof (struct switch_stack));
        DEFINE(IA64_CPU_SIZE, sizeof (struct cpuinfo_ia64));
        DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));
-       DEFINE(SHARED_INFO_SIZE, sizeof (struct shared_info));
        DEFINE(MAPPED_REGS_T_SIZE, sizeof (mapped_regs_t));
 
        BLANK();
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/efi.c
--- a/xen/arch/ia64/linux-xen/efi.c     Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/efi.c     Wed Aug 30 22:36:18 2006 +0100
@@ -291,28 +291,6 @@ efi_memmap_walk_uc (efi_freemem_callback
 {
        walk(callback, arg, EFI_MEMORY_UC);
 }
-
-#ifdef XEN
-void
-efi_memmap_walk_type(u32 type, efi_walk_type_callback_t callback, void *arg)
-{
-       void *efi_map_start, *efi_map_end, *p;
-       efi_memory_desc_t *md;
-       u64 efi_desc_size;
-
-       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;
-
-       for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
-               md = p;
-               if (md->type == type) {
-                       if ((*callback)(md, arg) < 0)
-                               return;
-               }
-       }
-}
-#endif
 
 /*
  * Look for the PAL_CODE region reported by EFI and maps it using an
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/iosapic.c
--- a/xen/arch/ia64/linux-xen/iosapic.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/iosapic.c Wed Aug 30 22:36:18 2006 +0100
@@ -77,6 +77,8 @@
 #include <linux/list.h>
 #ifndef XEN
 #include <linux/pci.h>
+#else
+#include <xen/errno.h>
 #endif
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/irq_ia64.c
--- a/xen/arch/ia64/linux-xen/irq_ia64.c        Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/irq_ia64.c        Wed Aug 30 22:36:18 2006 +0100
@@ -40,6 +40,10 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
+#ifdef XEN
+#include <xen/perfc.h>
+#endif
+
 #ifdef CONFIG_PERFMON
 # include <asm/perfmon.h>
 #endif
@@ -108,6 +112,9 @@ ia64_handle_irq (ia64_vector vector, str
 {
        unsigned long saved_tpr;
 
+#ifdef XEN
+       perfc_incrc(irqs);
+#endif
 #if IRQ_DEBUG
 #ifdef XEN
        xen_debug_irq(vector, regs);
@@ -290,8 +297,5 @@ ia64_send_ipi (int cpu, int vector, int 
        ipi_data = (delivery_mode << 8) | (vector & 0xff);
        ipi_addr = ipi_base_addr + ((phys_cpu_id << 4) | ((redirect & 1) << 3));
 
-#ifdef XEN
-       //printf ("send_ipi to %d (%x)\n", cpu, phys_cpu_id);
-#endif
        writeq(ipi_data, ipi_addr);
 }
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c     Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/mca.c     Wed Aug 30 22:36:18 2006 +0100
@@ -79,6 +79,7 @@
 
 #ifdef XEN
 #include <xen/symbols.h>
+#include <xen/mm.h>
 #endif
 
 #if defined(IA64_MCA_DEBUG_INFO)
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/process-linux-xen.c
--- a/xen/arch/ia64/linux-xen/process-linux-xen.c       Wed Aug 30 14:09:31 
2006 -0500
+++ b/xen/arch/ia64/linux-xen/process-linux-xen.c       Wed Aug 30 22:36:18 
2006 +0100
@@ -10,6 +10,7 @@
 #include <xen/lib.h>
 #include <xen/symbols.h>
 #include <xen/smp.h>
+#include <xen/sched.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
@@ -166,6 +167,7 @@ show_regs (struct pt_regs *regs)
        printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, 
regs->r27, regs->r28);
        printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, 
regs->r30, regs->r31);
 
+#ifndef XEN
        if (user_mode(regs)) {
                /* print the stacked registers */
                unsigned long val, *bsp, ndirty;
@@ -180,6 +182,7 @@ show_regs (struct pt_regs *regs)
                               ((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
                }
        } else
+#endif
                show_stack(NULL, NULL);
 }
 
@@ -807,6 +810,7 @@ get_wchan (struct task_struct *p)
        } while (count++ < 16);
        return 0;
 }
+#endif // !XEN
 
 void
 cpu_halt (void)
@@ -831,6 +835,7 @@ cpu_halt (void)
                ia64_pal_halt(min_power_state);
 }
 
+#ifndef XEN
 void
 machine_restart (char *restart_cmd)
 {
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/smp.c
--- a/xen/arch/ia64/linux-xen/smp.c     Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/smp.c     Wed Aug 30 22:36:18 2006 +0100
@@ -48,6 +48,7 @@
 #include <asm/unistd.h>
 #include <asm/mca.h>
 #ifdef XEN
+#include <xen/errno.h>
 #include <asm/vhpt.h>
 #include <asm/hw_irq.h>
 #endif
@@ -146,6 +147,9 @@ handle_IPI (int irq, void *dev_id, struc
        unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
        unsigned long ops;
 
+#ifdef XEN
+       perfc_incrc(ipis);
+#endif
        mb();   /* Order interrupt and bit testing. */
        while ((ops = xchg(pending_ipis, 0)) != 0) {
                mb();   /* Order bit clearing and data access. */
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/linux-xen/unwind.c
--- a/xen/arch/ia64/linux-xen/unwind.c  Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/linux-xen/unwind.c  Wed Aug 30 22:36:18 2006 +0100
@@ -33,6 +33,7 @@
 #include <xen/sched.h>
 #include <xen/xmalloc.h>
 #include <xen/spinlock.h>
+#include <xen/errno.h>
 
 // work around
 #ifdef CONFIG_SMP
@@ -2315,6 +2316,7 @@ unw_init (void)
                          __start_unwind, __end_unwind);
 }
 
+#ifndef XEN
 /*
  * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
  *
@@ -2353,3 +2355,4 @@ sys_getunwind (void __user *buf, size_t 
                        return -EFAULT;
        return unw.gate_table_size;
 }
+#endif
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/Makefile
--- a/xen/arch/ia64/vmx/Makefile        Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/Makefile        Wed Aug 30 22:36:18 2006 +0100
@@ -1,5 +1,5 @@ obj-y += hvm_vioapic.o
 obj-y += hvm_vioapic.o
-obj-y += mm.o
+#obj-y += mm.o
 obj-y += mmio.o
 obj-y += pal_emul.o
 obj-y += vlsapic.o
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/mmio.c
--- a/xen/arch/ia64/vmx/mmio.c  Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/mmio.c  Wed Aug 30 22:36:18 2006 +0100
@@ -22,6 +22,7 @@
  */
 
 #include <linux/sched.h>
+#include <xen/mm.h>
 #include <asm/tlb.h>
 #include <asm/vmx_mm_def.h>
 #include <asm/gcc_intrin.h>
@@ -30,7 +31,6 @@
 #include <asm/bundle.h>
 #include <asm/types.h>
 #include <public/hvm/ioreq.h>
-#include <asm/mm.h>
 #include <asm/vmx.h>
 #include <public/event_channel.h>
 #include <public/xen.h>
@@ -155,10 +155,9 @@ static void low_mmio_access(VCPU *vcpu, 
     p->type = 1;
     p->df = 0;
 
-    set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
-    p->state = STATE_IOREQ_READY;
-    evtchn_send(iopacket_port(v));
-    vmx_wait_io();
+    p->io_count++;
+
+    vmx_send_assist_req(v);
     if(dir==IOREQ_READ){ //read
         *val=p->u.data;
     }
@@ -187,11 +186,9 @@ static void legacy_io_access(VCPU *vcpu,
     p->type = 0;
     p->df = 0;
 
-    set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
-    p->state = STATE_IOREQ_READY;
-    evtchn_send(iopacket_port(v));
-
-    vmx_wait_io();
+    p->io_count++;
+
+    vmx_send_assist_req(v);
     if(dir==IOREQ_READ){ //read
         *val=p->u.data;
     }
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c  Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmmu.c  Wed Aug 30 22:36:18 2006 +0100
@@ -33,6 +33,7 @@
 #include <asm/kregs.h>
 #include <asm/vcpu.h>
 #include <xen/irq.h>
+#include <xen/errno.h>
 
 /*
  * Get the machine page frame number in 16KB unit
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_hypercall.c
--- a/xen/arch/ia64/vmx/vmx_hypercall.c Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_hypercall.c Wed Aug 30 22:36:18 2006 +0100
@@ -59,21 +59,23 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA
         }
         else if (IS_PRIV(current->domain)) {
             d = find_domain_by_id(a.domid);
-            if (!d)
+            if (d == NULL)
                 return -ESRCH;
         }
         else
             return -EPERM;
 
         if (op == HVMOP_set_param) {
+            d->arch.hvm_domain.params[a.index] = a.value;
             rc = 0;
-            d->arch.hvm_domain.params[a.index] = a.value;
         }
-        else
-            rc = d->arch.hvm_domain.params[a.index];
+        else {
+            a.value = d->arch.hvm_domain.params[a.index];
+            rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
+        }
 
         put_domain(d);
-        return rc;
+        break;
     }
 
     default:
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c      Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_init.c      Wed Aug 30 22:36:18 2006 +0100
@@ -206,7 +206,7 @@ vmx_create_vp(struct vcpu *v)
        u64 ret;
        vpd_t *vpd = (vpd_t *)v->arch.privregs;
        u64 ivt_base;
-    extern char vmx_ia64_ivt;
+       extern char vmx_ia64_ivt;
        /* ia64_ivt is function pointer, so need this tranlation */
        ivt_base = (u64) &vmx_ia64_ivt;
        printk("ivt_base: 0x%lx\n", ivt_base);
@@ -265,6 +265,29 @@ vmx_load_state(struct vcpu *v)
         * anchored in vcpu */
 }
 
+static void vmx_create_event_channels(struct vcpu *v)
+{
+       vcpu_iodata_t *p;
+       struct vcpu *o;
+
+       if (v->vcpu_id == 0) {
+               /* Ugly: create event channels for every vcpu when vcpu 0
+                  starts, so that they're available for ioemu to bind to. */
+               for_each_vcpu(v->domain, o) {
+                       p = get_vio(v->domain, o->vcpu_id);
+                       o->arch.arch_vmx.xen_port = p->vp_eport =
+                                       alloc_unbound_xen_event_channel(o, 0);
+                       DPRINTK("Allocated port %d for hvm.\n",
+                               o->arch.arch_vmx.xen_port);
+               }
+       }
+}
+
+static void vmx_release_assist_channel(struct vcpu *v)
+{
+       free_xen_event_channel(v, v->arch.arch_vmx.xen_port);
+}
+
 /*
  * Initialize VMX envirenment for guest. Only the 1st vp/vcpu
  * is registered here.
@@ -286,6 +309,8 @@ vmx_final_setup_guest(struct vcpu *v)
 #ifndef HASH_VHPT     
         init_domain_tlb(v);
 #endif
+       vmx_create_event_channels(v);
+
        /* v->arch.schedule_tail = arch_vmx_do_launch; */
        vmx_create_vp(v);
 
@@ -301,6 +326,15 @@ vmx_final_setup_guest(struct vcpu *v)
        set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags);
        /* Set up guest 's indicator for VTi domain*/
        set_bit(ARCH_VMX_DOMAIN, &v->arch.arch_vmx.flags);
+}
+
+void
+vmx_relinquish_guest_resources(struct domain *d)
+{
+       struct vcpu *v;
+
+       for_each_vcpu(d, v)
+               vmx_release_assist_channel(v);
 }
 
 void
@@ -411,6 +445,9 @@ void vmx_setup_platform(struct domain *d
        memset(&d->shared_info->evtchn_mask[0], 0xff,
            sizeof(d->shared_info->evtchn_mask));
 
+       /* initiate spinlock for pass virq */
+       spin_lock_init(&d->arch.arch_vmx.virq_assist_lock);
+
        /* Initialize the virtual interrupt lines */
        vmx_virq_line_init(d);
 
@@ -420,13 +457,5 @@ void vmx_setup_platform(struct domain *d
 
 void vmx_do_launch(struct vcpu *v)
 {
-       if (evtchn_bind_vcpu(iopacket_port(v), v->vcpu_id) < 0) {
-           printk("VMX domain bind port %d to vcpu %d failed!\n",
-               iopacket_port(v), v->vcpu_id);
-           domain_crash_synchronous();
-       }
-
-       clear_bit(iopacket_port(v), &v->domain->shared_info->evtchn_mask[0]);
-
        vmx_load_all_rr(v);
 }
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_phy_mode.c
--- a/xen/arch/ia64/vmx/vmx_phy_mode.c  Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_phy_mode.c  Wed Aug 30 22:36:18 2006 +0100
@@ -195,7 +195,8 @@ vmx_load_all_rr(VCPU *vcpu)
                        (void *)vcpu->domain->shared_info,
                        (void *)vcpu->arch.privregs,
                        (void *)vcpu->arch.vhpt.hash, pal_vaddr );
-       ia64_set_pta(vcpu->arch.arch_vmx.mpta);
+       ia64_set_pta(VMX(vcpu, mpta));
+       ia64_set_dcr(VMX(vcpu, mdcr));
 
        ia64_srlz_d();
        ia64_set_psr(psr);
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_process.c   Wed Aug 30 22:36:18 2006 +0100
@@ -186,6 +186,7 @@ void leave_hypervisor_tail(struct pt_reg
 {
     struct domain *d = current->domain;
     struct vcpu *v = current;
+    int callback_irq;
     // FIXME: Will this work properly if doing an RFI???
     if (!is_idle_domain(d) ) { // always comes from guest
 //        struct pt_regs *user_regs = vcpu_regs(current);
@@ -212,6 +213,13 @@ void leave_hypervisor_tail(struct pt_reg
 //           VCPU(v, irr[0]) |= 1UL << 0x10;
 //           v->arch.irq_new_pending = 1;
 //       }
+
+        callback_irq = d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
+        if (callback_irq != 0 && local_events_need_delivery()) {
+            /*inject para-device call back irq*/
+            v->vcpu_info->evtchn_upcall_mask = 1;
+            vmx_vcpu_pend_interrupt(v, callback_irq);
+        }
 
         if ( v->arch.irq_new_pending ) {
             v->arch.irq_new_pending = 0;
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vmx_support.c
--- a/xen/arch/ia64/vmx/vmx_support.c   Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vmx_support.c   Wed Aug 30 22:36:18 2006 +0100
@@ -1,4 +1,3 @@
-
 /* -*-  Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
 /*
  * vmx_support.c: vmx specific support interface.
@@ -22,45 +21,11 @@
 #include <xen/config.h>
 #include <xen/sched.h>
 #include <xen/hypercall.h>
+#include <xen/event.h>
 #include <public/sched.h>
 #include <public/hvm/ioreq.h>
 #include <asm/vmx.h>
 #include <asm/vmx_vcpu.h>
-
-/*
- * I/O emulation should be atomic from domain point of view. However,
- * when emulation code is waiting for I/O completion by blocking,
- * other events like DM interrupt, VBD, etc. may come and unblock
- * current exection flow. So we have to prepare for re-block if unblocked
- * by non I/O completion event. After io emulation is done, re-enable
- * pending indicaion if other ports are pending
- */
-void vmx_wait_io(void)
-{
-    struct vcpu *v = current;
-    struct domain *d = v->domain;
-    int port = iopacket_port(v);
-
-    for (;;) {
-        if (test_and_clear_bit(0, &v->vcpu_info->evtchn_upcall_pending) &&
-            test_and_clear_bit(port / BITS_PER_LONG,
-                                     &v->vcpu_info->evtchn_pending_sel) &&
-            test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]))
-            vmx_io_assist(v);
-
-        if (!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
-            break;
-
-        do_sched_op_compat(SCHEDOP_block, 0);
-    }
-
-    /* re-enable indication if other pending events */
-    if (d->shared_info->evtchn_pending[port / BITS_PER_LONG])
-        set_bit(port / BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-
-    if (v->vcpu_info->evtchn_pending_sel)
-        set_bit(0, &v->vcpu_info->evtchn_upcall_pending);
-}
 
 /*
  * Only place to call vmx_io_assist is mmio/legacy_io emulation.
@@ -83,17 +48,15 @@ void vmx_io_assist(struct vcpu *v)
 
     p = &vio->vp_ioreq;
 
-    if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
-       if (p->state != STATE_IORESP_READY) {
-           /* Can't block here, for the same reason as other places to
-            * use vmx_wait_io. Simple return is safe since vmx_wait_io will
-            * try to block again
-            */
-           return; 
-       } else
-           p->state = STATE_INVALID;
-
-       clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
+    if (p->state == STATE_IORESP_READY) {
+        p->state = STATE_INVALID;
+    }
+    else {
+        /* Can't block here, for the same reason as other places to
+         * use vmx_wait_io. Simple return is safe since vmx_wait_io will
+         * try to block again
+         */
+        return;
     }
 }
 
@@ -108,35 +71,62 @@ void vmx_io_assist(struct vcpu *v)
  */
 void vmx_intr_assist(struct vcpu *v)
 {
-    vcpu_iodata_t *vio;
-    struct domain *d = v->domain;
-    extern void vmx_vcpu_pend_batch_interrupt(VCPU *vcpu,
-                                       unsigned long *pend_irr);
-    int port = iopacket_port(v);
-
-    if (test_bit(port, &d->shared_info->evtchn_pending[0]) ||
-       test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
-       vmx_wait_io();
-
-    /* I/O emulation is atomic, so it's impossible to see execution flow
-     * out of vmx_wait_io, when guest is still waiting for response.
-     */
-    if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
-       panic_domain(vcpu_regs(v),"!!!Bad resume to guest before I/O emulation 
is done.\n");
-
-    /* Even without event pending, we still need to sync pending bits
-     * between DM and vlsapic. The reason is that interrupt delivery
-     * shares same event channel as I/O emulation, with corresponding
-     * indicator possibly cleared when vmx_wait_io().
-     */
-    vio = get_vio(v->domain, v->vcpu_id);
-    if (!vio)
-       panic_domain(vcpu_regs(v),"Corruption: bad shared page: %lx\n", 
(unsigned long)vio);
-
 #ifdef V_IOSAPIC_READY
     /* Confirm virtual interrupt line signals, and set pending bits in vpd */
-    if(v->vcpu_id==0)
+    if (spin_trylock(&v->domain->arch.arch_vmx.virq_assist_lock)) {
         vmx_virq_line_assist(v);
+        spin_unlock(&v->domain->arch.arch_vmx.virq_assist_lock);
+    }
 #endif
     return;
 }
+
+void vmx_send_assist_req(struct vcpu *v)
+{
+    ioreq_t *p;
+
+    p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+    if (unlikely(p->state != STATE_INVALID)) {
+        /* This indicates a bug in the device model.  Crash the
+           domain. */
+        printk("Device model set bad IO state %d.\n", p->state);
+        domain_crash(v->domain);
+        return;
+    }
+    wmb();
+    p->state = STATE_IOREQ_READY;
+    notify_via_xen_event_channel(v->arch.arch_vmx.xen_port);
+
+    /*
+     * Waiting for MMIO completion
+     *   like the wait_on_xen_event_channel() macro like...
+     *   but, we can't call do_softirq() at this point..
+     */
+    for (;;) {
+        if (p->state != STATE_IOREQ_READY &&
+            p->state != STATE_IOREQ_INPROCESS)
+            break;
+
+        set_bit(_VCPUF_blocked_in_xen, &current->vcpu_flags);
+        mb(); /* set blocked status /then/ re-evaluate condition */
+        if (p->state != STATE_IOREQ_READY &&
+            p->state != STATE_IOREQ_INPROCESS)
+        {
+            clear_bit(_VCPUF_blocked_in_xen, &current->vcpu_flags);
+            break;
+        }
+
+        /* I want to call __enter_scheduler() only */
+        do_sched_op_compat(SCHEDOP_yield, 0);
+        mb();
+    }
+
+    /* the code under this line is completer phase... */
+    vmx_io_assist(v);
+}
+
+/* Wake up a vcpu whihc is waiting for interrupts to come in */
+void vmx_prod_vcpu(struct vcpu *v)
+{
+    vcpu_unblock(v);
+}
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c  Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/vmx/vtlb.c  Wed Aug 30 22:36:18 2006 +0100
@@ -23,7 +23,7 @@
 
 #include <linux/sched.h>
 #include <asm/tlb.h>
-#include <asm/mm.h>
+#include <xen/mm.h>
 #include <asm/vmx_mm_def.h>
 #include <asm/gcc_intrin.h>
 #include <linux/interrupt.h>
@@ -148,13 +148,17 @@ static void vmx_vhpt_insert(thash_cb_t *
     rr.rrval = ia64_get_rr(ifa);
     head = (thash_data_t *)ia64_thash(ifa);
     tag = ia64_ttag(ifa);
-    if( INVALID_VHPT(head) ) {
-        len = head->len;
-        head->page_flags = pte;
-        head->len = len;
-        head->itir = rr.ps << 2;
-        head->etag = tag;
-        return;
+    cch = head;
+    while (cch) {    
+        if (INVALID_VHPT(cch)) {
+            len = cch->len;
+            cch->page_flags = pte;
+            cch->len = len;
+            cch->itir = rr.ps << 2;
+            cch->etag = tag;
+            return;
+        }
+        cch = cch->next;
     }
 
     if(head->len>=MAX_CCN_DEPTH){
@@ -214,12 +218,22 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
 {
     u64 ret;
     thash_data_t * data;
+    PTA vpta;
+
     data = vhpt_lookup(iha);
     if (data == NULL) {
         data = vtlb_lookup(current, iha, DSIDE_TLB);
         if (data != NULL)
             thash_vhpt_insert(current, data->page_flags, data->itir ,iha);
     }
+
+    /* VHPT long format is not read.  */
+    vmx_vcpu_get_pta(current, &vpta.val);
+    if (vpta.vf == 1) {
+        *pte = 0;
+        return 0;
+    }
+
     asm volatile ("rsm psr.ic|psr.i;;"
                   "srlz.d;;"
                   "ld8.s r9=[%1];;"
@@ -231,11 +245,10 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
                   "ssm psr.ic;;"
                   "srlz.d;;"
                   "ssm psr.i;;"
-             : "=r"(ret) : "r"(iha), "r"(pte):"memory");
+                  : "=r"(ret) : "r"(iha), "r"(pte):"memory");
     return ret;
 }
 
-
 /*
  *  purge software guest tlb
  */
@@ -243,28 +256,29 @@ void vtlb_purge(VCPU *v, u64 va, u64 ps)
 void vtlb_purge(VCPU *v, u64 va, u64 ps)
 {
     thash_data_t *cur;
-    u64 start, end, curadr, size, psbits, tag, def_size;
+    u64 start, curadr, size, psbits, tag, rr_ps, num;
     ia64_rr vrr;
     thash_cb_t *hcb = &v->arch.vtlb;
+
     vcpu_get_rr(v, va, &vrr.rrval);
     psbits = VMX(v, psbits[(va >> 61)]);
-    size = PSIZE(ps);
-    start = va & (-size);
-    end = start + size;
+    start = va & ~((1UL << ps) - 1);
     while (psbits) {
         curadr = start;
-        ps = __ffs(psbits);
-        psbits &= ~(1UL << ps);
-        def_size = PSIZE(ps);
-        vrr.ps = ps;
-        while (curadr < end) {
+        rr_ps = __ffs(psbits);
+        psbits &= ~(1UL << rr_ps);
+        num = 1UL << ((ps < rr_ps) ? 0 : (ps - rr_ps));
+        size = PSIZE(rr_ps);
+        vrr.ps = rr_ps;
+        while (num) {
             cur = vsa_thash(hcb->pta, curadr, vrr.rrval, &tag);
             while (cur) {
-                if (cur->etag == tag && cur->ps == ps)
+                if (cur->etag == tag && cur->ps == rr_ps)
                     cur->etag = 1UL << 63;
                 cur = cur->next;
             }
-            curadr += def_size;
+            curadr += size;
+            num--;
         }
     }
 }
@@ -277,14 +291,14 @@ static void vhpt_purge(VCPU *v, u64 va, 
 {
     //thash_cb_t *hcb = &v->arch.vhpt;
     thash_data_t *cur;
-    u64 start, end, size, tag;
+    u64 start, size, tag, num;
     ia64_rr rr;
-    size = PSIZE(ps);
-    start = va & (-size);
-    end = start + size;
-    rr.rrval = ia64_get_rr(va);
-    size = PSIZE(rr.ps);    
-    while(start < end){
+    
+    start = va & ~((1UL << ps) - 1);
+    rr.rrval = ia64_get_rr(va);  
+    size = PSIZE(rr.ps);
+    num = 1UL << ((ps < rr.ps) ? 0 : (ps - rr.ps));
+    while (num) {
         cur = (thash_data_t *)ia64_thash(start);
         tag = ia64_ttag(start);
         while (cur) {
@@ -293,6 +307,7 @@ static void vhpt_purge(VCPU *v, u64 va, 
             cur = cur->next;
         }
         start += size;
+        num--;
     }
     machine_tlb_purge(va, ps);
 }
@@ -347,24 +362,20 @@ void vtlb_insert(VCPU *v, u64 pte, u64 i
     u64 tag, len;
     thash_cb_t *hcb = &v->arch.vtlb;
     vcpu_get_rr(v, va, &vrr.rrval);
-#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, itir_ps(itir));
-        return;
-    }
-#endif
     vrr.ps = itir_ps(itir);
     VMX(v, psbits[va >> 61]) |= (1UL << vrr.ps);
     hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
-    if( INVALID_TLB(hash_table) ) {
-        len = hash_table->len;
-        hash_table->page_flags = pte;
-        hash_table->len = len;
-        hash_table->itir=itir;
-        hash_table->etag=tag;
-        return;
+    cch = hash_table;
+    while (cch) {
+        if (INVALID_TLB(cch)) {
+            len = cch->len;
+            cch->page_flags = pte;
+            cch->len = len;
+            cch->itir=itir;
+            cch->etag=tag;
+            return;
+        }
+        cch = cch->next;
     }
     if (hash_table->len>=MAX_CCN_DEPTH){
         thash_recycle_cch(hcb, hash_table);
@@ -458,10 +469,6 @@ void thash_purge_and_insert(VCPU *v, u64
     ps = itir_ps(itir);
     vcpu_get_rr(current, ifa, &vrr.rrval);
     mrr.rrval = ia64_get_rr(ifa);
-//    if (vrr.ps != itir_ps(itir)) {
-//        printf("not preferred ps with va: 0x%lx vrr.ps=%d ps=%ld\n",
-//               ifa, vrr.ps, itir_ps(itir));
-//    }
     if(VMX_DOMAIN(v)){
         /* Ensure WB attribute if pte is related to a normal mem page,
          * which is required by vga acceleration since qemu maps shared
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/xen/acpi.c
--- a/xen/arch/ia64/xen/acpi.c  Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/xen/acpi.c  Wed Aug 30 22:36:18 2006 +0100
@@ -51,6 +51,9 @@
 #include <asm/numa.h>
 #include <asm/sal.h>
 #include <asm/hw_irq.h>
+#ifdef XEN
+#include <xen/errno.h>
+#endif
 
 #define BAD_MADT_ENTRY(entry, end) (                                        \
                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/xen/dom0_ops.c      Wed Aug 30 22:36:18 2006 +0100
@@ -21,6 +21,7 @@
 #include <asm/vmx.h>
 #include <asm/dom_fw.h>
 #include <xen/iocap.h>
+#include <xen/errno.h>
 
 void build_physmap_table(struct domain *d);
 
@@ -39,8 +40,8 @@ long arch_do_domctl(xen_domctl_t *op, XE
     {
         unsigned long i;
         struct domain *d = find_domain_by_id(op->domain);
-        unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
-        unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
+        unsigned long start_page = op->u.getmemlist.start_pfn;
+        unsigned long nr_pages = op->u.getmemlist.max_pfns;
         unsigned long mfn;
 
         if ( d == NULL ) {
diff -r e01441c9a607 -r 50aea0ec406b xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c        Wed Aug 30 14:09:31 2006 -0500
+++ b/xen/arch/ia64/xen/dom_fw.c        Wed Aug 30 22:36:18 2006 +0100
@@ -21,28 +21,23 @@
 #include <asm/fpswa.h>
 #include <xen/version.h>
 #include <xen/acpi.h>
+#include <xen/errno.h>
 
 #include <asm/dom_fw.h>
 #include <asm/bundle.h>
 
-static void dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char 
*fw_mem, int fw_mem_size, unsigned long maxmem);
-
-extern struct domain *dom0;
+#define ONE_MB (1UL << 20)
 
 extern unsigned long running_on_sim;
 
-/* Note: two domains cannot be created simulteanously!  */
-static unsigned long dom_fw_base_mpa = -1;
-static unsigned long imva_fw_base = -1;
-
 #define FW_VENDOR 
"X\0e\0n\0/\0i\0a\0\066\0\064\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 
-#define MAKE_MD(typ, attr, start, end, abs)                            \
+#define MAKE_MD(typ, attr, start, end)                                         
\
        do {                                                            \
-               md = efi_memmap + i++;                                  \
+               md = tables->efi_memmap + i++;                          \
                md->type = typ;                                         \
                md->pad = 0;                                            \
-               md->phys_addr = abs ? start : start_mpaddr + start;     \
+               md->phys_addr = start;                                  \
                md->virt_addr = 0;                                      \
                md->num_pages = (end - start) >> EFI_PAGE_SHIFT;        \
                md->attribute = attr;                                   \
@@ -51,44 +46,31 @@ static unsigned long imva_fw_base = -1;
 #define EFI_HYPERCALL_PATCH(tgt, call)                                 \
        do {                                                            \
                dom_efi_hypercall_patch(d, FW_HYPERCALL_##call##_PADDR, \
-                                       FW_HYPERCALL_##call);           \
-               tgt = dom_pa((unsigned long) pfn);                      \
-               *pfn++ = FW_HYPERCALL_##call##_PADDR + start_mpaddr;    \
-               *pfn++ = 0;                                             \
+                                FW_HYPERCALL_##call, hypercalls_imva); \
+               /* Descriptor address.  */                              \
+               tables->efi_runtime.tgt =                               \
+                                   FW_FIELD_MPA(func_ptrs) + 8 * pfn;  \
+               /* Descriptor.  */                                      \
+               tables->func_ptrs[pfn++] = FW_HYPERCALL_##call##_PADDR; \
+               tables->func_ptrs[pfn++] = 0;                           \
        } while (0)
-
-// return domain (meta)physical address for a given imva
-// this function is a call-back from dom_fw_init
-static unsigned long
-dom_pa(unsigned long imva)
-{
-       if (dom_fw_base_mpa == -1 || imva_fw_base == -1) {
-               printf("dom_pa: uninitialized! (spinning...)\n");
-               while(1);
-       }
-       if (imva - imva_fw_base > PAGE_SIZE) {
-               printf("dom_pa: bad offset! imva=0x%lx, imva_fw_base=0x%lx 
(spinning...)\n",
-                       imva, imva_fw_base);
-               while(1);
-       }
-       return dom_fw_base_mpa + (imva - imva_fw_base);
-}
 
 // allocate a page for fw
 // build_physmap_table() which is called by new_thread()
 // does for domU.
-#define ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, mpaddr)   \
-    do {                                            \
-        if ((d) == dom0) {                          \
-            assign_new_domain0_page((d), (mpaddr)); \
-        }                                           \
-    } while (0)
+static inline void
+assign_new_domain_page_if_dom0(struct domain *d, unsigned long mpaddr)
+{
+        if (d == dom0)
+            assign_new_domain0_page(d, mpaddr);
+}
 
 /**************************************************************************
 Hypercall bundle creation
 **************************************************************************/
 
-static void build_hypercall_bundle(UINT64 *imva, UINT64 brkimm, UINT64 hypnum, 
UINT64 ret)
+static void
+build_hypercall_bundle(u64 *imva, u64 brkimm, u64 hypnum, u64 ret)
 {
        INST64_A5 slot0;
        INST64_I19 slot1;
@@ -104,8 +86,8 @@ static void build_hypercall_bundle(UINT6
        slot1.inst = 0;
        slot1.qp = 0; slot1.x6 = 0; slot1.x3 = 0; slot1.major = 0x0;
        slot1.imm20 = brkimm; slot1.i = brkimm >> 20;
-       // if ret slot2: br.ret.sptk.many rp
-       // else slot2: br.cond.sptk.many rp
+       // if ret slot2:  br.ret.sptk.many rp
+       // else   slot2:  br.cond.sptk.many rp
        slot2.inst = 0; slot2.qp = 0; slot2.p = 1; slot2.b2 = 0;
        slot2.wh = 0; slot2.d = 0; slot2.major = 0x0;
        if (ret) {
@@ -125,7 +107,8 @@ static void build_hypercall_bundle(UINT6
        ia64_fc(imva + 1);
 }
 
-static void build_pal_hypercall_bundles(UINT64 *imva, UINT64 brkimm, UINT64 
hypnum)
+static void
+build_pal_hypercall_bundles(u64 *imva, u64 brkimm, u64 hypnum)
 {
        extern unsigned long pal_call_stub[];
        IA64_BUNDLE bundle;
@@ -162,76 +145,68 @@ static void build_pal_hypercall_bundles(
 }
 
 // builds a hypercall bundle at domain physical address
-static void dom_fpswa_hypercall_patch(struct domain *d)
+static void
+dom_fpswa_hypercall_patch(struct domain *d, unsigned long imva)
 {
        unsigned long *entry_imva, *patch_imva;
-       unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
-       unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
-
-       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, entry_paddr);
-       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, patch_paddr);
-       entry_imva = domain_mpa_to_imva(d, entry_paddr);
-       patch_imva = domain_mpa_to_imva(d, patch_paddr);
-
+       const unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
+       const unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
+
+       entry_imva = (unsigned long *)(imva + entry_paddr -
+                                      FW_HYPERCALL_BASE_PADDR);
+       patch_imva = (unsigned long *)(imva + patch_paddr -
+                                      FW_HYPERCALL_BASE_PADDR);
+
+       /* Descriptor.  */
        *entry_imva++ = patch_paddr;
        *entry_imva   = 0;
-       build_hypercall_bundle(patch_imva, d->arch.breakimm, 
FW_HYPERCALL_FPSWA, 1);
+
+       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;
-
-       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
-       imva = domain_mpa_to_imva(d, paddr);
-       build_hypercall_bundle(imva, d->arch.breakimm, hypercall, 1);
+static void
+dom_efi_hypercall_patch(struct domain *d, unsigned long paddr,
+                        unsigned long hypercall, unsigned long imva)
+{
+       build_hypercall_bundle((u64 *)(imva + paddr - FW_HYPERCALL_BASE_PADDR),
+                              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)
-{
-       unsigned long *imva;
-
-       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
-       imva = domain_mpa_to_imva(d, paddr);
-       build_hypercall_bundle(imva, d->arch.breakimm, hypercall, ret);
-}
-
-static void dom_fw_pal_hypercall_patch(struct domain *d, unsigned long paddr)
-{
-       unsigned long *imva;
-
-       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
-       imva = domain_mpa_to_imva(d, paddr);
-       build_pal_hypercall_bundles(imva, d->arch.breakimm, 
FW_HYPERCALL_PAL_CALL);
-}
-
-
-void dom_fw_setup(struct domain *d, unsigned long bp_mpa, unsigned long maxmem)
-{
-       struct ia64_boot_param *bp;
-
-       dom_fw_base_mpa = 0;
-       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, dom_fw_base_mpa);
-       imva_fw_base = (unsigned long) domain_mpa_to_imva(d, dom_fw_base_mpa);
-       ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, bp_mpa);
-       bp = domain_mpa_to_imva(d, bp_mpa);
-       dom_fw_init(d, bp, (char *) imva_fw_base, PAGE_SIZE, maxmem);
-}
-
-
-/* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */
-
-#define NFUNCPTRS 20
+static void
+dom_fw_hypercall_patch(struct domain *d, unsigned long paddr,
+                       unsigned long hypercall,unsigned long ret,
+                       unsigned long imva)
+{
+       build_hypercall_bundle((u64 *)(imva + paddr - FW_HYPERCALL_BASE_PADDR),
+                              d->arch.breakimm, hypercall, ret);
+}
+
+static void
+dom_fw_pal_hypercall_patch(struct domain *d, unsigned long paddr,
+                           unsigned long imva)
+{
+       build_pal_hypercall_bundles((u64*)(imva + paddr -
+                                   FW_HYPERCALL_BASE_PADDR),
+                                   d->arch.breakimm, FW_HYPERCALL_PAL_CALL);
+}
 
 static inline void
 print_md(efi_memory_desc_t *md)
 {
-       printk("domain mem: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) 
(%luMB)\n",
-               md->type, md->attribute, md->phys_addr,
-               md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
-               md->num_pages >> (20 - EFI_PAGE_SHIFT));
+       u64 size;
+       
+       printk("dom mem: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) ",
+              md->type, md->attribute, md->phys_addr,
+              md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
+
+       size = md->num_pages << EFI_PAGE_SHIFT;
+       if (size > ONE_MB)
+               printf ("(%luMB)\n", size >> 20);
+       else
+               printf ("(%luKB)\n", size >> 10);
 }
 
 static u32 lsapic_nbr;
@@ -316,6 +291,8 @@ struct fake_acpi_tables {
        u8 pm1a_cnt_blk[1];
        u8 pm_tmr_blk[4];
 };
+#define ACPI_TABLE_MPA(field) \
+  FW_ACPI_BASE_PADDR + offsetof(struct fake_acpi_tables, field);
 
 /* Create enough of an ACPI structure to make the guest OS ACPI happy. */
 static void
@@ -345,8 +322,8 @@ dom_fw_fake_acpi(struct domain *d, struc
        xsdt->asl_compiler_revision = (xen_major_version() << 16) |
                xen_minor_version();
 
-       xsdt->table_offset_entry[0] = dom_pa((unsigned long) fadt);
-       tables->madt_ptr = dom_pa((unsigned long) madt);
+       xsdt->table_offset_entry[0] = ACPI_TABLE_MPA(fadt);
+       tables->madt_ptr = ACPI_TABLE_MPA(madt);
 
        xsdt->checksum = generate_acpi_checksum(xsdt, xsdt->length);
 
@@ -364,8 +341,8 @@ dom_fw_fake_acpi(struct domain *d, struc
        facs->version = 1;
        facs->length = sizeof(struct facs_descriptor_rev2);
 
-       fadt->xfirmware_ctrl = dom_pa((unsigned long) facs);
-       fadt->Xdsdt = dom_pa((unsigned long) dsdt);
+       fadt->xfirmware_ctrl = ACPI_TABLE_MPA(facs);
+       fadt->Xdsdt = ACPI_TABLE_MPA(dsdt);
 
        /*
         * All of the below FADT entries are filled it to prevent warnings
@@ -375,15 +352,15 @@ dom_fw_fake_acpi(struct domain *d, struc
        fadt->pm1_evt_len = 4;
        fadt->xpm1a_evt_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
        fadt->xpm1a_evt_blk.register_bit_width = 8;
-       fadt->xpm1a_evt_blk.address = dom_pa((unsigned long) 
&tables->pm1a_evt_blk);
+       fadt->xpm1a_evt_blk.address = ACPI_TABLE_MPA(pm1a_evt_blk);
        fadt->pm1_cnt_len = 1;
        fadt->xpm1a_cnt_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
        fadt->xpm1a_cnt_blk.register_bit_width = 8;
-       fadt->xpm1a_cnt_blk.address = dom_pa((unsigned long) 
&tables->pm1a_cnt_blk);
+       fadt->xpm1a_cnt_blk.address = ACPI_TABLE_MPA(pm1a_cnt_blk);
        fadt->pm_tm_len = 4;
        fadt->xpm_tmr_blk.address_space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
        fadt->xpm_tmr_blk.register_bit_width = 8;
-       fadt->xpm_tmr_blk.address = dom_pa((unsigned long) &tables->pm_tmr_blk);
+       fadt->xpm_tmr_blk.address = ACPI_TABLE_MPA(pm_tmr_blk);
 
        fadt->checksum = generate_acpi_checksum(fadt, fadt->length);
 
@@ -392,7 +369,7 @@ dom_fw_fake_acpi(struct domain *d, struc
        strcpy(rsdp->oem_id, "XEN");
        rsdp->revision = 2; /* ACPI 2.0 includes XSDT */
        rsdp->length = sizeof(struct acpi20_table_rsdp);
-       rsdp->xsdt_address = dom_pa((unsigned long) xsdt);
+       rsdp->xsdt_address = ACPI_TABLE_MPA(xsdt);
 
        rsdp->checksum = generate_acpi_checksum(rsdp,
                                                ACPI_RSDP_CHECKSUM_LENGTH);
@@ -467,115 +444,6 @@ dom_fw_fake_acpi(struct domain *d, struc
        return;
 }
 
-#define NUM_EFI_SYS_TABLES 6
-#define NUM_MEM_DESCS  64 //large enough
-
-struct dom0_passthrough_arg {
-    struct domain*      d;
-    int                 flags;
-    efi_memory_desc_t *md;
-    int*                i;
-};
-
-static int
-dom_fw_dom0_passthrough(efi_memory_desc_t *md, void *arg__)
-{
-    struct dom0_passthrough_arg* arg = (struct dom0_passthrough_arg*)arg__;
-    unsigned long paddr;
-    struct domain* d = arg->d;
-    u64 start = md->phys_addr;
-    u64 size = md->num_pages << EFI_PAGE_SHIFT;
-
-    if (md->type == EFI_MEMORY_MAPPED_IO ||
-        md->type == EFI_MEMORY_MAPPED_IO_PORT_SPACE) {
-
-        //XXX some machine has large mmio area whose size is about several TB.
-        //    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 && (size > 0x100000000UL))
-            return 0;
-
-        paddr = assign_domain_mmio_page(d, start, size);
-    } else
-        paddr = assign_domain_mach_page(d, start, size, arg->flags);
-
-    BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
-           md->type != EFI_RUNTIME_SERVICES_DATA &&
-           md->type != EFI_ACPI_RECLAIM_MEMORY &&
-           md->type != EFI_ACPI_MEMORY_NVS &&
-           md->type != EFI_RESERVED_TYPE &&
-           md->type != EFI_MEMORY_MAPPED_IO &&
-           md->type != EFI_MEMORY_MAPPED_IO_PORT_SPACE);
-
-    arg->md->type = md->type;
-    arg->md->pad = 0;
-    arg->md->phys_addr = paddr;
-    arg->md->virt_addr = 0;
-    arg->md->num_pages = md->num_pages;
-    arg->md->attribute = md->attribute;
-
-    (*arg->i)++;
-    arg->md++;
-    return 0;
-}
-
-/*
- * Create dom0 MDT entries for conventional memory below 1MB.  Without
- * this Linux will assume VGA is present because 0xA0000 will always
- * be either a hole in the MDT or an I/O region via the passthrough.
- */
-static int
-dom_fw_dom0_lowmem(efi_memory_desc_t *md, void *arg__)
-{
-    struct dom0_passthrough_arg* arg = (struct dom0_passthrough_arg*)arg__;
-    u64 end = min(HYPERCALL_START,
-                  md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
-
-    BUG_ON(md->type != EFI_CONVENTIONAL_MEMORY);
-
-    /* avoid hypercall area */
-    if (md->phys_addr >= HYPERCALL_START)
-        return 0;
-
-    /* avoid firmware base area */
-    if (md->phys_addr < dom_pa(imva_fw_base))
-        end = min(end, dom_pa(imva_fw_base));
-    else if (md->phys_addr < dom_pa(imva_fw_base + PAGE_SIZE)) {
-        if (end < dom_pa(imva_fw_base + PAGE_SIZE))
-            return 0;
-        md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
-    }
-
-    arg->md->type = md->type;
-    arg->md->pad = 0;
-    arg->md->phys_addr = md->phys_addr;
-    arg->md->virt_addr = 0;
-    arg->md->num_pages = (end - md->phys_addr) >> EFI_PAGE_SHIFT;
-    arg->md->attribute = md->attribute;
-
-    (*arg->i)++;
-    arg->md++;
-
-    /* if firmware area spliced the md, add the upper part here */
-    if (end == dom_pa(imva_fw_base)) {
-        end = min(HYPERCALL_START,
-                  md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
-       if (end > dom_pa(imva_fw_base + PAGE_SIZE)) {
-            arg->md->type = md->type;
-            arg->md->pad = 0;
-            arg->md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
-            arg->md->virt_addr = 0;
-            arg->md->num_pages = (end - arg->md->phys_addr) >> EFI_PAGE_SHIFT;
-            arg->md->attribute = md->attribute;
-
-            (*arg->i)++;
-            arg->md++;
-        }
-    }
-    return 0;
-}
-
 static int
 efi_mdt_cmp(const void *a, const void *b)
 {
@@ -595,279 +463,403 @@ efi_mdt_cmp(const void *a, const void *b
        return 0;
 }
 
+#define NFUNCPTRS 16
+#define NUM_EFI_SYS_TABLES 6
+#define NUM_MEM_DESCS 64 //large enough
+
+struct fw_tables {
+       efi_system_table_t efi_systab;
+       efi_runtime_services_t efi_runtime;
+       efi_config_table_t efi_tables[NUM_EFI_SYS_TABLES];
+
+       struct ia64_sal_systab sal_systab;
+       struct ia64_sal_desc_entry_point sal_ed;
+       struct ia64_sal_desc_ap_wakeup sal_wakeup;
+       /* End of SAL descriptors.  Do not forget to update checkum bound.  */
+
+       fpswa_interface_t fpswa_inf;
+       efi_memory_desc_t efi_memmap[NUM_MEM_DESCS];
+       unsigned long func_ptrs[2*NFUNCPTRS];
+       struct xen_sal_data sal_data;
+       unsigned char fw_vendor[sizeof(FW_VENDOR)];
+};
+#define FW_FIELD_MPA(field) \
+   FW_TABLES_BASE_PADDR + offsetof(struct fw_tables, field)
+
+/* Complete the dom0 memmap.  */
+static int
+complete_dom0_memmap(struct domain *d,
+                     struct fw_tables *tables,
+                     unsigned long maxmem,
+                     int num_mds)
+{
+       efi_memory_desc_t *md;
+       u64 addr;
+       int j;
+       void *efi_map_start, *efi_map_end, *p;
+       u64 efi_desc_size;
+       int i;
+
+       /* Walk through all MDT entries.
+          Copy all interesting entries.  */
+       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;
+
+       for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+               const efi_memory_desc_t *md = p;
+               efi_memory_desc_t *dom_md = &tables->efi_memmap[num_mds];
+               u64 start = md->phys_addr;
+               u64 size = md->num_pages << EFI_PAGE_SHIFT;
+               u64 end = start + size;
+
+               switch (md->type) {
+               case EFI_RUNTIME_SERVICES_CODE:
+               case EFI_RUNTIME_SERVICES_DATA:
+               case EFI_ACPI_RECLAIM_MEMORY:
+               case EFI_ACPI_MEMORY_NVS:
+               case EFI_RESERVED_TYPE:
+                       /* Map into dom0 - All these are writable.  */
+                       assign_domain_mach_page(d, start, size,
+                                               ASSIGN_writable);
+                       /* Fall-through.  */
+               case EFI_MEMORY_MAPPED_IO:
+                       /* Will be mapped with ioremap.  */
+                       /* Copy descriptor.  */
+                       *dom_md = *md;
+                       dom_md->virt_addr = 0;
+                       num_mds++;
+                       break;
+
+               case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+                       /* Map into dom0.  */
+                       assign_domain_mmio_page(d, start, size);
+                       /* Copy descriptor.  */
+                       *dom_md = *md;
+                       dom_md->virt_addr = 0;
+                       num_mds++;
+                       break;
+
+               case EFI_CONVENTIONAL_MEMORY:
+               case EFI_LOADER_CODE:
+               case EFI_LOADER_DATA:
+               case EFI_BOOT_SERVICES_CODE:
+               case EFI_BOOT_SERVICES_DATA:
+                       /* Create dom0 MDT entries for conventional memory
+                          below 1MB.  Without this Linux will assume VGA is
+                          present because 0xA0000 will always be either a hole
+                          in the MDT or an I/O region via the passthrough.  */
+
+                       end = min(ONE_MB, end);
+
+                       /* Avoid firmware and hypercall area.
+                          We know they are 0-based.  */
+                       if (end < FW_END_PADDR || start >= ONE_MB)
+                               break;
+                       if (start < FW_END_PADDR)
+                               start = FW_END_PADDR;
+                       
+                       dom_md->type = EFI_CONVENTIONAL_MEMORY;
+                       dom_md->phys_addr = start;
+                       dom_md->virt_addr = 0;
+                       dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
+                       dom_md->attribute = md->attribute;
+                       num_mds++;
+                       break;
+
+               case EFI_UNUSABLE_MEMORY:
+               case EFI_PAL_CODE:
+                       /* Discard.  */
+                       break;
+
+               default:
+                       /* Print a warning but continue.  */
+                       printf("complete_dom0_memmap: warning: "
+                              "unhandled MDT entry type %u\n", md->type);
+               }
+       }
+       BUG_ON(num_mds > NUM_MEM_DESCS);
+       
+       sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
+            efi_mdt_cmp, NULL);
+
+       /* find gaps and fill them with conventional memory */
+       i = num_mds;
+       for (j = 0; j < num_mds; j++) {
+               unsigned long end;
+               unsigned long next_start;
+               
+               md = &tables->efi_memmap[j];
+               end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+               
+               if (j + 1 < num_mds) {
+                       efi_memory_desc_t* next_md;
+                       next_md = &tables->efi_memmap[j + 1];
+                       next_start = next_md->phys_addr;
+                       
+                       /* Have just been sorted.  */
+                       BUG_ON(end > next_start);
+                       
+                       /* No room for memory!  */
+                       if (end == next_start)
+                               continue;
+                       
+                       if (next_start > maxmem)
+                               next_start = maxmem;
+               }
+               else
+                       next_start = maxmem;
+               
+               /* Avoid "legacy" low memory addresses 
+                  and the HYPERCALL area.  */
+               if (end < ONE_MB)
+                       end = ONE_MB;
+                                                     
+               // clip the range and align to PAGE_SIZE
+               next_start = next_start & PAGE_MASK;
+               end = PAGE_ALIGN(end);
+               
+               /* No room for memory.  */
+               if (end >= next_start)
+                       continue;
+               
+               MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+                       end, next_start);
+
+               if (next_start >= maxmem)
+                       break;
+       }
+       num_mds = i;
+       BUG_ON(num_mds > NUM_MEM_DESCS);
+       sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
+            efi_mdt_cmp, NULL);
+
+       // dom0 doesn't need build_physmap_table()
+       // see arch_set_info_guest()
+       // instead we allocate pages manually.
+       for (i = 0; i < num_mds; i++) {
+               md = &tables->efi_memmap[i];
+               if (md->phys_addr > maxmem)
+                       break;
+               
+               if (md->type == EFI_LOADER_DATA ||
+                   md->type == EFI_PAL_CODE ||
+                   md->type == EFI_CONVENTIONAL_MEMORY) {
+                       unsigned long start = md->phys_addr & PAGE_MASK;
+                       unsigned long end = md->phys_addr +
+                               (md->num_pages << EFI_PAGE_SHIFT);
+
+                       if (end == start) {
+                               /* md->num_pages = 0 is allowed. */
+                               continue;
+                       }
+                       if (end > (max_page << PAGE_SHIFT))
+                               end = (max_page << PAGE_SHIFT);
+                       
+                       for (addr = start; addr < end; addr += PAGE_SIZE)
+                               assign_new_domain0_page(d, addr);
+               }
+       }
+       // Map low-memory holes & unmapped MMIO for legacy drivers
+       for (addr = 0; addr < ONE_MB; addr += PAGE_SIZE) {
+               if (domain_page_mapped(d, addr))
+                       continue;
+               
+               if (efi_mmio(addr, PAGE_SIZE))
+                       assign_domain_mmio_page(d, addr, PAGE_SIZE);
+       }
+       return num_mds;
+}
+       
 static void
-dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char *fw_mem, int 
fw_mem_size, unsigned long maxmem)
-{
-       efi_system_table_t *efi_systab;
-       efi_runtime_services_t *efi_runtime;
-       efi_config_table_t *efi_tables;
-       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 xen_sal_data *sal_data;
-       unsigned long *pfn;
-       unsigned char checksum = 0;
-       char *cp, *fw_vendor;
-       int num_mds, j, i = 0;
-       const unsigned long start_mpaddr = 0;
-
-/* FIXME: should check size but for now we have a whole MB to play with.
-   And if stealing code from fw-emu.c, watch out for new fw_vendor on the end!
-       if (fw_mem_size < sizeof(fw_mem_proto)) {
-               printf("sys_fw_init: insufficient space for fw_mem\n");
-               return 0;
-       }
-*/
-       memset(fw_mem, 0, fw_mem_size);
-
-       cp = fw_mem;
-       efi_systab  = (void *) cp; cp += sizeof(*efi_systab);
-       efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
-       efi_tables  = (void *) cp; cp += NUM_EFI_SYS_TABLES * 
sizeof(*efi_tables);
-       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);
-       pfn         = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
-       sal_data    = (void *) cp; cp += sizeof(*sal_data);
+dom_fw_init(struct domain *d,
+            struct ia64_boot_param *bp,
+            struct fw_tables *tables,
+            unsigned long hypercalls_imva,
+            unsigned long maxmem)
+{
+       efi_memory_desc_t *md;
+       unsigned long pfn;
+       unsigned char checksum;
+       char *cp;
+       int num_mds, i;
+
+       memset(tables, 0, sizeof(struct fw_tables));
 
        /* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
-       d->arch.efi_runtime = efi_runtime;
-       d->arch.fpswa_inf   = fpswa_inf;
-       d->arch.sal_data    = sal_data;
-
-       memset(efi_systab, 0, sizeof(efi_systab));
-       efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
-       efi_systab->hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
-       efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
-       fw_vendor = cp;
-       cp += sizeof(FW_VENDOR) + (8-((unsigned long)cp & 7)); // round to 
64-bit boundary
-
-       memcpy(fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
-       efi_systab->fw_vendor = dom_pa((unsigned long) fw_vendor);
-       efi_systab->fw_revision = 1;
-       efi_systab->runtime = (void *) dom_pa((unsigned long) efi_runtime);
-       efi_systab->nr_tables = NUM_EFI_SYS_TABLES;
-       efi_systab->tables = dom_pa((unsigned long) efi_tables);
-
-       efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
-       efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
-       efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
-
-       EFI_HYPERCALL_PATCH(efi_runtime->get_time,EFI_GET_TIME);
-       EFI_HYPERCALL_PATCH(efi_runtime->set_time,EFI_SET_TIME);
-       EFI_HYPERCALL_PATCH(efi_runtime->get_wakeup_time,EFI_GET_WAKEUP_TIME);
-       EFI_HYPERCALL_PATCH(efi_runtime->set_wakeup_time,EFI_SET_WAKEUP_TIME);
-       
EFI_HYPERCALL_PATCH(efi_runtime->set_virtual_address_map,EFI_SET_VIRTUAL_ADDRESS_MAP);
-       EFI_HYPERCALL_PATCH(efi_runtime->get_variable,EFI_GET_VARIABLE);
-       
EFI_HYPERCALL_PATCH(efi_runtime->get_next_variable,EFI_GET_NEXT_VARIABLE);
-       EFI_HYPERCALL_PATCH(efi_runtime->set_variable,EFI_SET_VARIABLE);
-       
EFI_HYPERCALL_PATCH(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
-       EFI_HYPERCALL_PATCH(efi_runtime->reset_system,EFI_RESET_SYSTEM);
-
-       efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
-       efi_tables[0].table = dom_pa((unsigned long) sal_systab);
+       d->arch.efi_runtime = &tables->efi_runtime;
+       d->arch.fpswa_inf   = &tables->fpswa_inf;
+       d->arch.sal_data    = &tables->sal_data;
+
+       /* EFI systab.  */
+       tables->efi_systab.hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
+       tables->efi_systab.hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
+       tables->efi_systab.hdr.headersize = sizeof(tables->efi_systab.hdr);
+
+       memcpy(tables->fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
+       tables->efi_systab.fw_vendor = FW_FIELD_MPA(fw_vendor);
+       tables->efi_systab.fw_revision = 1;
+       tables->efi_systab.runtime = (void *)FW_FIELD_MPA(efi_runtime);
+       tables->efi_systab.nr_tables = NUM_EFI_SYS_TABLES;
+       tables->efi_systab.tables = FW_FIELD_MPA(efi_tables);
+
+       /* EFI runtime.  */
+       tables->efi_runtime.hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
+       tables->efi_runtime.hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
+       tables->efi_runtime.hdr.headersize = sizeof(tables->efi_runtime.hdr);
+
+       pfn = 0;
+       EFI_HYPERCALL_PATCH(get_time,EFI_GET_TIME);
+       EFI_HYPERCALL_PATCH(set_time,EFI_SET_TIME);
+       EFI_HYPERCALL_PATCH(get_wakeup_time,EFI_GET_WAKEUP_TIME);
+       EFI_HYPERCALL_PATCH(set_wakeup_time,EFI_SET_WAKEUP_TIME);
+       EFI_HYPERCALL_PATCH(set_virtual_address_map,
+                           EFI_SET_VIRTUAL_ADDRESS_MAP);
+       EFI_HYPERCALL_PATCH(get_variable,EFI_GET_VARIABLE);
+       EFI_HYPERCALL_PATCH(get_next_variable,EFI_GET_NEXT_VARIABLE);
+       EFI_HYPERCALL_PATCH(set_variable,EFI_SET_VARIABLE);
+       EFI_HYPERCALL_PATCH(get_next_high_mono_count,
+                           EFI_GET_NEXT_HIGH_MONO_COUNT);
+       EFI_HYPERCALL_PATCH(reset_system,EFI_RESET_SYSTEM);
+
+       /* System tables.  */
+       tables->efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
+       tables->efi_tables[0].table = FW_FIELD_MPA(sal_systab);
        for (i = 1; i < NUM_EFI_SYS_TABLES; i++) {
-               efi_tables[i].guid = NULL_GUID;
-               efi_tables[i].table = 0;
-       }
+               tables->efi_tables[i].guid = NULL_GUID;
+               tables->efi_tables[i].table = 0;
+       }
+       i = 1;
        if (d == dom0) {
+               /* Write messages to the console.  */
+               touch_acpi_table();
+
                printf("Domain0 EFI passthrough:");
-               i = 1;
                if (efi.mps) {
-                       efi_tables[i].guid = MPS_TABLE_GUID;
-                       efi_tables[i].table = __pa(efi.mps);
-                       printf(" MPS=0x%lx",efi_tables[i].table);
+                       tables->efi_tables[i].guid = MPS_TABLE_GUID;
+                       tables->efi_tables[i].table = __pa(efi.mps);
+                       printf(" MPS=0x%lx",tables->efi_tables[i].table);
                        i++;
                }
 
-               touch_acpi_table();
-
                if (efi.acpi20) {
-                       efi_tables[i].guid = ACPI_20_TABLE_GUID;
-                       efi_tables[i].table = __pa(efi.acpi20);
-                       printf(" ACPI 2.0=0x%lx",efi_tables[i].table);
+                       tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
+                       tables->efi_tables[i].table = __pa(efi.acpi20);
+                       printf(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
                        i++;
                }
                if (efi.acpi) {
-                       efi_tables[i].guid = ACPI_TABLE_GUID;
-                       efi_tables[i].table = __pa(efi.acpi);
-                       printf(" ACPI=0x%lx",efi_tables[i].table);
+                       tables->efi_tables[i].guid = ACPI_TABLE_GUID;
+                       tables->efi_tables[i].table = __pa(efi.acpi);
+                       printf(" ACPI=0x%lx",tables->efi_tables[i].table);
                        i++;
                }
                if (efi.smbios) {
-                       efi_tables[i].guid = SMBIOS_TABLE_GUID;
-                       efi_tables[i].table = __pa(efi.smbios);
-                       printf(" SMBIOS=0x%lx",efi_tables[i].table);
+                       tables->efi_tables[i].guid = SMBIOS_TABLE_GUID;
+                       tables->efi_tables[i].table = __pa(efi.smbios);
+                       printf(" SMBIOS=0x%lx",tables->efi_tables[i].table);
                        i++;
                }
                if (efi.hcdp) {
-                       efi_tables[i].guid = HCDP_TABLE_GUID;
-                       efi_tables[i].table = __pa(efi.hcdp);
-                       printf(" HCDP=0x%lx",efi_tables[i].table);
+                       tables->efi_tables[i].guid = HCDP_TABLE_GUID;
+                       tables->efi_tables[i].table = __pa(efi.hcdp);
+                       printf(" HCDP=0x%lx",tables->efi_tables[i].table);
                        i++;
                }
                printf("\n");
        } else {
                printf("DomainU EFI build up:");
-               i = 1;
-
-               if ((unsigned long)fw_mem + fw_mem_size - (unsigned long)cp >=
-                   sizeof(struct fake_acpi_tables)) {
-                       struct fake_acpi_tables *acpi_tables;
-
-                       acpi_tables = (void *)cp;
-                       cp += sizeof(struct fake_acpi_tables);
-                       dom_fw_fake_acpi(d, acpi_tables);
-
-                       efi_tables[i].guid = ACPI_20_TABLE_GUID;
-                       efi_tables[i].table = dom_pa((unsigned long) 
acpi_tables);
-                       printf(" ACPI 2.0=0x%lx",efi_tables[i].table);
-                       i++;
-               }
+
+               tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
+               tables->efi_tables[i].table = FW_ACPI_BASE_PADDR;
+               printf(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
+               i++;
                printf("\n");
        }
 
        /* fill in the SAL system table: */
-       memcpy(sal_systab->signature, "SST_", 4);
-       sal_systab->size = sizeof(*sal_systab);
-       sal_systab->sal_rev_minor = 1;
-       sal_systab->sal_rev_major = 0;
-       sal_systab->entry_count = 2;
-
-       strcpy((char *)sal_systab->oem_id, "Xen/ia64");
-       strcpy((char *)sal_systab->product_id, "Xen/ia64");
-
-       /* fill in an entry point: */
-       sal_ed->type = SAL_DESC_ENTRY_POINT;
-       sal_ed->pal_proc = FW_HYPERCALL_PAL_CALL_PADDR + start_mpaddr;
-       dom_fw_pal_hypercall_patch (d, sal_ed->pal_proc);
-       sal_ed->sal_proc = FW_HYPERCALL_SAL_CALL_PADDR + start_mpaddr;
-       dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1);
-       sal_ed->gp = 0;  // will be ignored
+       memcpy(tables->sal_systab.signature, "SST_", 4);
+       tables->sal_systab.size = sizeof(tables->sal_systab);
+       tables->sal_systab.sal_rev_minor = 1;
+       tables->sal_systab.sal_rev_major = 0;
+       tables->sal_systab.entry_count = 2;
+
+       strcpy((char *)tables->sal_systab.oem_id, "Xen/ia64");
+       strcpy((char *)tables->sal_systab.product_id, "Xen/ia64");
+
+       /* PAL entry point: */
+       tables->sal_ed.type = SAL_DESC_ENTRY_POINT;
+       tables->sal_ed.pal_proc = FW_HYPERCALL_PAL_CALL_PADDR;
+       dom_fw_pal_hypercall_patch(d, tables->sal_ed.pal_proc, 
+                                  hypercalls_imva);
+       /* SAL entry point.  */
+       tables->sal_ed.sal_proc = FW_HYPERCALL_SAL_CALL_PADDR;
+       dom_fw_hypercall_patch(d, tables->sal_ed.sal_proc,
+                              FW_HYPERCALL_SAL_CALL, 1, hypercalls_imva);
+       tables->sal_ed.gp = 0;  /* will be ignored */
 
        /* Fill an AP wakeup descriptor.  */
-       sal_wakeup->type = SAL_DESC_AP_WAKEUP;
-       sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT;
-       sal_wakeup->vector = XEN_SAL_BOOT_RENDEZ_VEC;
+       tables->sal_wakeup.type = SAL_DESC_AP_WAKEUP;
+       tables->sal_wakeup.mechanism = IA64_SAL_AP_EXTERNAL_INT;
+       tables->sal_wakeup.vector = XEN_SAL_BOOT_RENDEZ_VEC;
 
        /* Compute checksum.  */
-       for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
+       checksum = 0;
+       for (cp = (char *)&tables->sal_systab;
+            cp < (char *)&tables->fpswa_inf;
+            ++cp)
                checksum += *cp;
-       sal_systab->checksum = -checksum;
+       tables->sal_systab.checksum = -checksum;
 
        /* SAL return point.  */
-       d->arch.sal_return_addr = FW_HYPERCALL_SAL_RETURN_PADDR + start_mpaddr;
-       dom_fw_hypercall_patch (d, d->arch.sal_return_addr,
-                               FW_HYPERCALL_SAL_RETURN, 0);
+       dom_fw_hypercall_patch(d, FW_HYPERCALL_SAL_RETURN_PADDR,
+                              FW_HYPERCALL_SAL_RETURN, 0, hypercalls_imva);
 
        /* 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;
+       tables->fpswa_inf.revision = fpswa_interface->revision;
+       dom_fpswa_hypercall_patch(d, hypercalls_imva);
+       tables->fpswa_inf.fpswa = (void *)FW_HYPERCALL_FPSWA_ENTRY_PADDR;
 
        i = 0; /* Used by MAKE_MD */
 
-       /* Create dom0/domu md entry for fw_mem area */
-       MAKE_MD(EFI_ACPI_RECLAIM_MEMORY, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
-               dom_pa((unsigned long)fw_mem),
-               dom_pa((unsigned long)fw_mem + fw_mem_size), 1);
-
-       if (d == dom0) {
-               /* hypercall patches live here, masquerade as reserved PAL 
memory */
-               
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END,
 0);
-
-               /* pass through the I/O port space */
-               if (!running_on_sim) {
-                       struct dom0_passthrough_arg arg;
-                       arg.md = &efi_memmap[i];
-                       arg.i = &i;
-                       arg.d = d;
-                       arg.flags = ASSIGN_writable;
-                       //XXX Is this needed?
-                       efi_memmap_walk_type(EFI_RUNTIME_SERVICES_CODE,
-                                            dom_fw_dom0_passthrough, &arg);
-                       // for ACPI table.
-                       arg.flags = ASSIGN_readonly;
-                       efi_memmap_walk_type(EFI_RUNTIME_SERVICES_DATA,
-                                            dom_fw_dom0_passthrough, &arg);
-                       arg.flags = ASSIGN_writable;
-                       efi_memmap_walk_type(EFI_ACPI_RECLAIM_MEMORY,
-                                            dom_fw_dom0_passthrough, &arg);
-                       efi_memmap_walk_type(EFI_ACPI_MEMORY_NVS,
-                                            dom_fw_dom0_passthrough, &arg);
-                       efi_memmap_walk_type(EFI_RESERVED_TYPE,
-                                            dom_fw_dom0_passthrough, &arg);
-                       efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO,
-                                            dom_fw_dom0_passthrough, &arg);
-                       efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO_PORT_SPACE,
-                                            dom_fw_dom0_passthrough, &arg);
-                       efi_memmap_walk_type(EFI_CONVENTIONAL_MEMORY,
-                                            dom_fw_dom0_lowmem, &arg);
-               }
-               else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
-       } else {
-               /* hypercall patches live here, masquerade as reserved
-                  PAL memory */
-               MAKE_MD(EFI_PAL_CODE, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
-                       HYPERCALL_START, HYPERCALL_END, 1);
+       /* hypercall patches live here, masquerade as reserved PAL memory */
+       MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,
+               FW_HYPERCALL_BASE_PADDR, FW_HYPERCALL_END_PADDR);
+
+       /* Create dom0/domu md entry for fw and cpi tables area.  */
+       MAKE_MD(EFI_ACPI_MEMORY_NVS, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
+               FW_ACPI_BASE_PADDR, FW_ACPI_END_PADDR);
+       MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
+               FW_TABLES_BASE_PADDR, FW_TABLES_END_PADDR);
+
+       if (d != dom0 || running_on_sim) {
+               /* DomU (or hp-ski).
+                  Create a continuous memory area.  */
+               /* Memory.  */
+               MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+                       FW_END_PADDR, maxmem);
+               
                /* Create an entry for IO ports.  */
                MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
-                       IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE, 1);
-               MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
-       }
-
-       // simple
-       // MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
-       //         HYPERCALL_END, maxmem, 0);
-       // is not good. Check overlap.
-       sort(efi_memmap, i, sizeof(efi_memory_desc_t),
-            efi_mdt_cmp, NULL);
-
-       // find gap and fill it with conventional memory
-       num_mds = i;
-       for (j = 0; j < num_mds; j++) {
-               unsigned long end;
-               unsigned long next_start;
-
-               md = &efi_memmap[j];
-               end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
-
-               next_start = maxmem;
-               if (j + 1 < num_mds) {
-                       efi_memory_desc_t* next_md = &efi_memmap[j + 1];
-                       next_start = next_md->phys_addr;
-                       BUG_ON(end > next_start);
-                       if (end == next_md->phys_addr)
-                               continue;
-               }
-
-               // clip the range and align to PAGE_SIZE
-               // Avoid "legacy" low memory addresses and the
-               // HYPERCALL patch area.      
-               if (end < HYPERCALL_END)
-                       end = HYPERCALL_END;
-               if (next_start > maxmem)
-                       next_start = maxmem;
-               end = PAGE_ALIGN(end);
-               next_start = next_start & PAGE_MASK;
-               if (end >= next_start)
-                       continue;
-
-               MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
-                       end, next_start, 0);
-               if (next_start >= maxmem)
-