WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 13 Apr 2007 10:50:36 -0700
Delivery-date: Fri, 13 Apr 2007 11:47:50 -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 Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1176476868 -3600
# Node ID 039daabebad5d3c69fb9497693e8e3fd4fee00c9
# Parent  c42ae7839750d685e0330f76351af8b02deabadc
# Parent  0ab8f81019a5df4250893f1aae2d64969b4d1c18
Merge with xen-ia64-unstable.hg
---
 .hgignore                                            |    2 
 README                                               |    4 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c |   26 +-
 tools/libxc/xc_domain_restore.c                      |   41 +--
 tools/libxc/xc_domain_save.c                         |   64 +----
 tools/libxc/xg_private.c                             |   12 -
 tools/pygrub/src/pygrub                              |   18 -
 tools/python/xen/xend/XendAPI.py                     |   17 +
 tools/python/xen/xend/XendNode.py                    |    6 
 tools/python/xen/xm/migrate.py                       |   17 +
 tools/python/xen/xm/xenapi_create.py                 |   22 +
 xen/arch/powerpc/0opt.c                              |    6 
 xen/arch/powerpc/domain_build.c                      |    2 
 xen/arch/powerpc/ofd_fixup.c                         |    5 
 xen/arch/x86/domain.c                                |    4 
 xen/arch/x86/hvm/hvm.c                               |  222 +++++++++++++++----
 xen/arch/x86/hvm/intercept.c                         |   46 +--
 xen/arch/x86/hvm/io.c                                |    2 
 xen/arch/x86/hvm/platform.c                          |   46 +++
 xen/arch/x86/hvm/svm/svm.c                           |   33 ++
 xen/arch/x86/hvm/vmx/vmx.c                           |   21 +
 xen/arch/x86/mm.c                                    |   22 +
 xen/common/domain.c                                  |    3 
 xen/include/asm-powerpc/system.h                     |    6 
 xen/include/asm-x86/hvm/domain.h                     |   12 -
 xen/include/asm-x86/hvm/hvm.h                        |    1 
 xen/include/asm-x86/hvm/support.h                    |   15 -
 xen/include/public/hvm/save.h                        |   35 ++
 xen/include/xen/domain_page.h                        |    4 
 29 files changed, 473 insertions(+), 241 deletions(-)

diff -r c42ae7839750 -r 039daabebad5 .hgignore
--- a/.hgignore Fri Apr 13 08:33:21 2007 -0600
+++ b/.hgignore Fri Apr 13 16:07:48 2007 +0100
@@ -22,7 +22,7 @@
 ^\.pc
 ^TAGS$
 ^tags$
-^build.*$
+^build-.*$
 ^dist/.*$
 ^docs/.*\.aux$
 ^docs/.*\.dvi$
diff -r c42ae7839750 -r 039daabebad5 README
--- a/README    Fri Apr 13 08:33:21 2007 -0600
+++ b/README    Fri Apr 13 16:07:48 2007 +0100
@@ -199,3 +199,7 @@ Xend (the Xen daemon) has the following 
     * For optional PAM support, PyPAM:
           URL:    http://www.pangalactic.org/PyPAM/
           Debian: python-pam
+
+    * For optional XenAPI support in XM, PyXML:
+          URL:    http://pyxml.sourceforge.net
+          YUM:    PyXML
diff -r c42ae7839750 -r 039daabebad5 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Apr 13 
08:33:21 2007 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Fri Apr 13 
16:07:48 2007 +0100
@@ -622,14 +622,14 @@ static int network_open(struct net_devic
 
        memset(&np->stats, 0, sizeof(np->stats));
 
-       spin_lock(&np->rx_lock);
+       spin_lock_bh(&np->rx_lock);
        if (netfront_carrier_ok(np)) {
                network_alloc_rx_buffers(dev);
                np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
                if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
                        netif_rx_schedule(dev);
        }
-       spin_unlock(&np->rx_lock);
+       spin_unlock_bh(&np->rx_lock);
 
        network_maybe_wake_tx(dev);
 
@@ -1307,7 +1307,7 @@ static int netif_poll(struct net_device 
        int pages_flipped = 0;
        int err;
 
-       spin_lock(&np->rx_lock);
+       spin_lock(&np->rx_lock); /* no need for spin_lock_bh() in ->poll() */
 
        if (unlikely(!netfront_carrier_ok(np))) {
                spin_unlock(&np->rx_lock);
@@ -1520,7 +1520,7 @@ static void netif_release_rx_bufs(struct
 
        skb_queue_head_init(&free_list);
 
-       spin_lock(&np->rx_lock);
+       spin_lock_bh(&np->rx_lock);
 
        for (id = 0; id < NET_RX_RING_SIZE; id++) {
                if ((ref = np->grant_rx_ref[id]) == GRANT_INVALID_REF) {
@@ -1588,7 +1588,7 @@ static void netif_release_rx_bufs(struct
        while ((skb = __skb_dequeue(&free_list)) != NULL)
                dev_kfree_skb(skb);
 
-       spin_unlock(&np->rx_lock);
+       spin_unlock_bh(&np->rx_lock);
 }
 
 static int network_close(struct net_device *dev)
@@ -1708,8 +1708,8 @@ static int network_connect(struct net_de
        IPRINTK("device %s has %sing receive path.\n",
                dev->name, np->copying_receiver ? "copy" : "flipp");
 
+       spin_lock_bh(&np->rx_lock);
        spin_lock_irq(&np->tx_lock);
-       spin_lock(&np->rx_lock);
 
        /*
         * Recovery procedure:
@@ -1761,8 +1761,8 @@ static int network_connect(struct net_de
        network_tx_buf_gc(dev);
        network_alloc_rx_buffers(dev);
 
-       spin_unlock(&np->rx_lock);
        spin_unlock_irq(&np->tx_lock);
+       spin_unlock_bh(&np->rx_lock);
 
        return 0;
 }
@@ -1818,7 +1818,7 @@ static ssize_t store_rxbuf_min(struct cl
        if (target > RX_MAX_TARGET)
                target = RX_MAX_TARGET;
 
-       spin_lock(&np->rx_lock);
+       spin_lock_bh(&np->rx_lock);
        if (target > np->rx_max_target)
                np->rx_max_target = target;
        np->rx_min_target = target;
@@ -1827,7 +1827,7 @@ static ssize_t store_rxbuf_min(struct cl
 
        network_alloc_rx_buffers(netdev);
 
-       spin_unlock(&np->rx_lock);
+       spin_unlock_bh(&np->rx_lock);
        return len;
 }
 
@@ -1861,7 +1861,7 @@ static ssize_t store_rxbuf_max(struct cl
        if (target > RX_MAX_TARGET)
                target = RX_MAX_TARGET;
 
-       spin_lock(&np->rx_lock);
+       spin_lock_bh(&np->rx_lock);
        if (target < np->rx_min_target)
                np->rx_min_target = target;
        np->rx_max_target = target;
@@ -1870,7 +1870,7 @@ static ssize_t store_rxbuf_max(struct cl
 
        network_alloc_rx_buffers(netdev);
 
-       spin_unlock(&np->rx_lock);
+       spin_unlock_bh(&np->rx_lock);
        return len;
 }
 
@@ -2033,11 +2033,11 @@ static void netif_disconnect_backend(str
 static void netif_disconnect_backend(struct netfront_info *info)
 {
        /* Stop old i/f to prevent errors whilst we rebuild the state. */
+       spin_lock_bh(&info->rx_lock);
        spin_lock_irq(&info->tx_lock);
-       spin_lock(&info->rx_lock);
        netfront_carrier_off(info);
-       spin_unlock(&info->rx_lock);
        spin_unlock_irq(&info->tx_lock);
+       spin_unlock_bh(&info->rx_lock);
 
        if (info->irq)
                unbind_from_irqhandler(info->irq, info->netdev);
diff -r c42ae7839750 -r 039daabebad5 tools/libxc/xc_domain_restore.c
--- a/tools/libxc/xc_domain_restore.c   Fri Apr 13 08:33:21 2007 -0600
+++ b/tools/libxc/xc_domain_restore.c   Fri Apr 13 16:07:48 2007 +0100
@@ -688,33 +688,22 @@ int xc_domain_restore(int xc_handle, int
             ERROR("error zeroing magic pages");
             goto out;
         }
-        
-        xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, magic_pfns[0]);
-        xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, 
magic_pfns[1]);
-        xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, magic_pfns[2]);
-        xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
-        xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
+                
+        if ( (rc = xc_set_hvm_param(xc_handle, dom, 
+                                    HVM_PARAM_IOREQ_PFN, magic_pfns[0]))
+             || (rc = xc_set_hvm_param(xc_handle, dom, 
+                                       HVM_PARAM_BUFIOREQ_PFN, magic_pfns[1]))
+             || (rc = xc_set_hvm_param(xc_handle, dom, 
+                                       HVM_PARAM_STORE_PFN, magic_pfns[2]))
+             || (rc = xc_set_hvm_param(xc_handle, dom, 
+                                       HVM_PARAM_PAE_ENABLED, pae))
+             || (rc = xc_set_hvm_param(xc_handle, dom, 
+                                       HVM_PARAM_STORE_EVTCHN, store_evtchn)) )
+        {
+            ERROR("error setting HVM params: %i", rc);
+            goto out;
+        }
         *store_mfn = magic_pfns[2];
-
-        /* Read vcpu contexts */
-        for ( i = 0; i <= max_vcpu_id; i++ )
-        {
-            if ( !(vcpumap & (1ULL << i)) )
-                continue;
-
-            if ( !read_exact(io_fd, &(ctxt), sizeof(ctxt)) )
-            {
-                ERROR("error read vcpu context.\n");
-                goto out;
-            }
-            
-            if ( (rc = xc_vcpu_setcontext(xc_handle, dom, i, &ctxt)) )
-            {
-                ERROR("Could not set vcpu context, rc=%d", rc);
-                goto out;
-            }
-            rc = 1;
-        }
 
         /* Read HVM context */
         if ( !read_exact(io_fd, &rec_len, sizeof(uint32_t)) )
diff -r c42ae7839750 -r 039daabebad5 tools/libxc/xc_domain_save.c
--- a/tools/libxc/xc_domain_save.c      Fri Apr 13 08:33:21 2007 -0600
+++ b/tools/libxc/xc_domain_save.c      Fri Apr 13 16:07:48 2007 +0100
@@ -378,8 +378,7 @@ static int analysis_phase(int xc_handle,
 
 
 static int suspend_and_state(int (*suspend)(int), int xc_handle, int io_fd,
-                             int dom, xc_dominfo_t *info,
-                             vcpu_guest_context_t *ctxt)
+                             int dom, xc_dominfo_t *info)
 {
     int i = 0;
 
@@ -396,10 +395,6 @@ static int suspend_and_state(int (*suspe
         ERROR("Could not get domain info");
         return -1;
     }
-
-    if ( xc_vcpu_getcontext(xc_handle, dom, 0, ctxt) )
-        ERROR("Could not get vcpu context");
-
 
     if ( info->dying )
     {
@@ -663,10 +658,11 @@ static xen_pfn_t *map_and_save_p2m_table
 static xen_pfn_t *map_and_save_p2m_table(int xc_handle, 
                                          int io_fd, 
                                          uint32_t dom,
-                                         vcpu_guest_context_t *ctxt,
                                          unsigned long p2m_size,
                                          shared_info_t *live_shinfo)
 {
+    vcpu_guest_context_t ctxt;
+
     /* Double and single indirect references to the live P2M table */
     xen_pfn_t *live_p2m_frame_list_list = NULL;
     xen_pfn_t *live_p2m_frame_list = NULL;
@@ -728,6 +724,12 @@ static xen_pfn_t *map_and_save_p2m_table
                   (uint64_t)p2m_frame_list[i/fpp]);
             goto out;
         }
+    }
+
+    if ( xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt) )
+    {
+        ERROR("Could not get vcpu context");
+        goto out;
     }
 
     /*
@@ -736,7 +738,7 @@ static xen_pfn_t *map_and_save_p2m_table
      * slow paths in the restore code.
      */
     if ( (pt_levels == 3) &&
-         (ctxt->vm_assist & (1UL << VMASST_TYPE_pae_extended_cr3)) )
+         (ctxt.vm_assist & (1UL << VMASST_TYPE_pae_extended_cr3)) )
     {
         unsigned long signature = ~0UL;
         uint32_t tot_sz   = sizeof(struct vcpu_guest_context) + 8;
@@ -746,7 +748,7 @@ static xen_pfn_t *map_and_save_p2m_table
              !write_exact(io_fd, &tot_sz,    sizeof(tot_sz)) ||
              !write_exact(io_fd, &chunk_sig, 4) ||
              !write_exact(io_fd, &chunk_sz,  sizeof(chunk_sz)) ||
-             !write_exact(io_fd, ctxt,       sizeof(*ctxt)) )
+             !write_exact(io_fd, &ctxt,      sizeof(ctxt)) )
         {
             ERROR("write: extended info");
             goto out;
@@ -853,11 +855,6 @@ int xc_domain_save(int xc_handle, int io
         return 1;
     }
 
-    if ( xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt) )
-    {
-        ERROR("Could not get vcpu context");
-        goto out;
-    }
     shared_info_frame = info.shared_info_frame;
 
     /* Map the shared info frame */
@@ -900,7 +897,7 @@ int xc_domain_save(int xc_handle, int io
     else
     {
         /* This is a non-live suspend. Suspend the domain .*/
-        if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info, &ctxt) )
+        if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info) )
         {
             ERROR("Domain appears not to have suspended");
             goto out;
@@ -999,7 +996,7 @@ int xc_domain_save(int xc_handle, int io
 
         /* Map the P2M table, and write the list of P2M frames */
         live_p2m = map_and_save_p2m_table(xc_handle, io_fd, dom, 
-                                          &ctxt, p2m_size, live_shinfo);
+                                          p2m_size, live_shinfo);
         if ( live_p2m == NULL )
         {
             ERROR("Failed to map/save the p2m frame list");
@@ -1304,17 +1301,13 @@ int xc_domain_save(int xc_handle, int io
                 DPRINTF("Start last iteration\n");
                 last_iter = 1;
 
-                if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info,
-                                       &ctxt) )
+                if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info) )
                 {
                     ERROR("Domain appears not to have suspended");
                     goto out;
                 }
 
-                DPRINTF("SUSPEND shinfo %08lx eip %08lx edx %08lx\n",
-                        info.shared_info_frame,
-                        (unsigned long)ctxt.user_regs.eip,
-                        (unsigned long)ctxt.user_regs.edx);
+                DPRINTF("SUSPEND shinfo %08lx\n", info.shared_info_frame);
             }
 
             if ( xc_shadow_control(xc_handle, dom, 
@@ -1410,27 +1403,6 @@ int xc_domain_save(int xc_handle, int io
             goto out;
         }
 
-        /* Save vcpu contexts */
-
-        for ( i = 0; i <= info.max_vcpu_id; i++ )
-        {
-            if ( !(vcpumap & (1ULL << i)) )
-                continue;
-            
-            if ( xc_vcpu_getcontext(xc_handle, dom, i, &ctxt) )
-            {
-                ERROR("HVM:Could not get vcpu context");
-                goto out;
-            }
-            
-            DPRINTF("write vcpu %d context.\n", i); 
-            if ( !write_exact(io_fd, &(ctxt), sizeof(ctxt)) )
-            {
-                ERROR("write vcpu context failed!\n");
-                goto out;
-            }
-        }
-
         /* Get HVM context from Xen and save it too */
         if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, 
                                                   hvm_buf_size)) == -1 )
@@ -1492,6 +1464,12 @@ int xc_domain_save(int xc_handle, int io
                 j = 0;
             }
         }
+    }
+
+    if ( xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt) )
+    {
+        ERROR("Could not get vcpu context");
+        goto out;
     }
 
     /* Canonicalise the suspend-record frame number. */
diff -r c42ae7839750 -r 039daabebad5 tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c  Fri Apr 13 08:33:21 2007 -0600
+++ b/tools/libxc/xg_private.c  Fri Apr 13 16:07:48 2007 +0100
@@ -196,18 +196,6 @@ __attribute__((weak))
 {
     errno = ENOSYS;
     return -1;
-}
-
-__attribute__((weak)) int xc_get_hvm_param(
-    int handle, domid_t dom, int param, unsigned long *value)
-{
-    return -ENOSYS;
-}
-
-__attribute__((weak)) int xc_set_hvm_param(
-    int handle, domid_t dom, int param, unsigned long value)
-{
-    return -ENOSYS;
 }
 
 /*
diff -r c42ae7839750 -r 039daabebad5 tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Fri Apr 13 08:33:21 2007 -0600
+++ b/tools/pygrub/src/pygrub   Fri Apr 13 16:07:48 2007 +0100
@@ -61,13 +61,6 @@ def get_active_partition(file):
         if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
             return buf[poff:poff+16]
 
-        # type=0xee: GUID partition table
-        # XXX assume the first partition is active
-        if struct.unpack("<c", buf[poff+4:poff+5]) == ('\xee',):
-            os.lseek(fd, 0x400, 0)
-            buf = os.read(fd, 512)
-            return buf[24:40] # XXX buf[32:40]
-
     # if there's not a partition marked as active, fall back to
     # the first partition
     return buf[446:446+16]
@@ -97,8 +90,16 @@ def get_solaris_slice(file, offset):
 
     raise RuntimeError, "No root slice found"      
 
+def get_fs_offset_gpt(file):
+    fd = os.open(file, os.O_RDONLY)
+    # assume the first partition is an EFI system partition.
+    os.lseek(fd, SECTOR_SIZE * 2, 0)
+    buf = os.read(fd, 512)
+    return struct.unpack("<Q", buf[32:40])[0] * SECTOR_SIZE
+
 FDISK_PART_SOLARIS=0xbf
 FDISK_PART_SOLARIS_OLD=0x82
+FDISK_PART_GPT=0xee
 
 def get_fs_offset(file):
     if not is_disk_image(file):
@@ -115,6 +116,9 @@ def get_fs_offset(file):
     if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
         offset += get_solaris_slice(file, offset)
 
+    if type == FDISK_PART_GPT:
+        offset = get_fs_offset_gpt(file)
+    
     return offset
 
 class GrubLineEditor(curses.textpad.Textbox):
diff -r c42ae7839750 -r 039daabebad5 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Fri Apr 13 08:33:21 2007 -0600
+++ b/tools/python/xen/xend/XendAPI.py  Fri Apr 13 16:07:48 2007 +0100
@@ -96,7 +96,10 @@ def datetime(when = None):
     @param when The time in question, given as seconds since the epoch, UTC.
                 May be None, in which case the current time is used.
     """
-    return xmlrpclib.DateTime(time.gmtime(when))
+    if when is None:
+        return xmlrpclib.DateTime(time.gmtime())
+    else:
+        return xmlrpclib.DateTime(time.gmtime(when))
 
 
 # ---------------------------------------------------
@@ -1304,6 +1307,7 @@ class XendAPI(object):
                   ('set_memory_dynamic_max_live', None),
                   ('set_memory_dynamic_min_live', None),
                   ('send_trigger', None),
+                  ('migrate', None),
                   ('destroy', None)]
     
     VM_funcs  = [('create', 'VM'),
@@ -1823,6 +1827,17 @@ class XendAPI(object):
         xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu)
         return xen_api_success_void()
 
+    def VM_migrate(self, _, vm_ref, destination_url, live, other_config):
+        xendom = XendDomain.instance()
+        xeninfo = xendom.get_vm_by_uuid(vm_ref)
+
+        resource = other_config.get("resource", 0)
+        port = other_config.get("port", 0)
+        
+        xendom.domain_migrate(xeninfo.getDomid(), destination_url,
+                              bool(live), resource, port)
+        return xen_api_success_void()
+
     def VM_save(self, _, vm_ref, dest, checkpoint):
         xendom = XendDomain.instance()
         xeninfo = xendom.get_vm_by_uuid(vm_ref)
diff -r c42ae7839750 -r 039daabebad5 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Fri Apr 13 08:33:21 2007 -0600
+++ b/tools/python/xen/xend/XendNode.py Fri Apr 13 16:07:48 2007 +0100
@@ -150,8 +150,10 @@ class XendNode:
                 
         # Get a mapping from interface to bridge
 
-        if_to_br = dict(reduce(lambda ls,(b,ifs):[(i,b) for i in ifs] + ls,
-                               Brctl.get_state().items(), []))
+        if_to_br = dict([(i,b)
+                         for (b,ifs) in Brctl.get_state().items()
+                         for i in ifs])
+
         # initialise PIFs
         saved_pifs = self.state_store.load_state('pif')
         if saved_pifs:
diff -r c42ae7839750 -r 039daabebad5 tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py    Fri Apr 13 08:33:21 2007 -0600
+++ b/tools/python/xen/xm/migrate.py    Fri Apr 13 16:07:48 2007 +0100
@@ -23,7 +23,7 @@ import sys
 
 from xen.xm.opts import *
 
-from main import server
+from main import server, serverType, get_single_vm, SERVER_XEN_API
 
 gopts = Opts(use="""[options] DOM HOST
 
@@ -60,5 +60,16 @@ def main(argv):
 
     dom = args[0]
     dst = args[1]
-    server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource,
-                               opts.vals.port)
+
+    if serverType == SERVER_XEN_API:
+        vm_ref = get_single_vm(dom)
+        other_config = {
+            "port":     opts.vals.port,
+            "resource": opts.vals.resource
+            }
+        server.xenapi.VM.migrate(vm_ref, dst, bool(opts.vals.live),
+                                 other_config)
+    else:
+        server.xend.domain.migrate(dom, dst, opts.vals.live,
+                                   opts.vals.resource,
+                                   opts.vals.port)
diff -r c42ae7839750 -r 039daabebad5 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Fri Apr 13 08:33:21 2007 -0600
+++ b/tools/python/xen/xm/xenapi_create.py      Fri Apr 13 16:07:48 2007 +0100
@@ -48,7 +48,7 @@ def get_name_description(node):
 
 def get_text_in_child_node(node, child):
     tag_node = node.getElementsByTagName(child)[0]
-    return tag_node.nodeValue
+    return " ".join([child.nodeValue for child in tag_node.childNodes])
 
 def get_child_node_attribute(node, child, attribute):
     tag_node = node.getElementsByTagName(child)[0]
@@ -264,7 +264,23 @@ class xenapi_create:
             "platform":
                 get_child_nodes_as_dict(vm, "platform", "key", "value"),
             "other_config":
-                get_child_nodes_as_dict(vm, "other_config", "key", "value")
+                get_child_nodes_as_dict(vm, "other_config", "key", "value"),
+            "PV_bootloader":
+                "",
+            "PV_kernel":
+                "",
+            "PV_ramdisk":
+                "",
+            "PV_args":
+                "",
+            "PV_bootloader_args":
+                "",
+            "HVM_boot_policy":
+                "",
+            "HVM_boot_params":
+                {},
+            "PCI_bus":
+               ""
             }
 
         if len(vm.getElementsByTagName("pv")) > 0:
@@ -494,7 +510,7 @@ class sxp2xml:
         # Make version tag
 
         version = document.createElement("version")
-        version.appendChild(document.createTextNode("1.0"))
+        version.appendChild(document.createTextNode("0"))
         vm.appendChild(version)
         
         # Make pv or hvm tag
diff -r c42ae7839750 -r 039daabebad5 xen/arch/powerpc/0opt.c
--- a/xen/arch/powerpc/0opt.c   Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/powerpc/0opt.c   Fri Apr 13 16:07:48 2007 +0100
@@ -21,6 +21,12 @@
 #include <xen/config.h>
 #include <xen/lib.h>
 
+extern void __xchg_called_with_bad_pointer(void);
+void __xchg_called_with_bad_pointer(void)
+{
+    BUG();
+}
+
 extern void __cmpxchg_called_with_bad_pointer(void);
 void __cmpxchg_called_with_bad_pointer(void)
 {
diff -r c42ae7839750 -r 039daabebad5 xen/arch/powerpc/domain_build.c
--- a/xen/arch/powerpc/domain_build.c   Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/powerpc/domain_build.c   Fri Apr 13 16:07:48 2007 +0100
@@ -229,7 +229,7 @@ int construct_dom0(struct domain *d,
     /* Load the dom0 kernel. */
     elf.dest = (void *)dst;
     elf_load_binary(&elf);
-    v->arch.ctxt.pc = dst - rma;
+    v->arch.ctxt.pc = dst - rma + (parms.virt_entry - parms.virt_kstart);
     dst = ALIGN_UP(dst + parms.virt_kend, PAGE_SIZE);
 
     /* Load the initrd. */
diff -r c42ae7839750 -r 039daabebad5 xen/arch/powerpc/ofd_fixup.c
--- a/xen/arch/powerpc/ofd_fixup.c      Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/powerpc/ofd_fixup.c      Fri Apr 13 16:07:48 2007 +0100
@@ -264,7 +264,7 @@ static ofdn_t ofd_chosen_props(void *m, 
     ofdn_t n;
     ofdn_t p;
     static const char path[] = "/chosen";
-    char bootargs[256];
+    char bootargs[256] = { 0, };
     int bsz;
     int sz;
     int rm;
@@ -276,7 +276,8 @@ static ofdn_t ofd_chosen_props(void *m, 
                      &path[1], sizeof (path) - 1);
     }
 
-    strlcpy(bootargs, cmdline, sizeof(bootargs));
+    if (cmdline)
+        strlcpy(bootargs, cmdline, sizeof(bootargs));
     bsz = strlen(bootargs) + 1;
     rm = sizeof (bootargs) - bsz;
 
diff -r c42ae7839750 -r 039daabebad5 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/x86/domain.c     Fri Apr 13 16:07:48 2007 +0100
@@ -1540,8 +1540,10 @@ void domain_relinquish_resources(struct 
     relinquish_memory(d, &d->xenpage_list, PGT_l2_page_table);
     relinquish_memory(d, &d->page_list, PGT_l2_page_table);
 
-    /* Free page used by xen oprofile buffer */
+    /* Free page used by xen oprofile buffer. */
     free_xenoprof_pages(d);
+
+    hvm_domain_relinquish_resources(d);
 }
 
 void arch_dump_domain_info(struct domain *d)
diff -r c42ae7839750 -r 039daabebad5 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/x86/hvm/hvm.c    Fri Apr 13 16:07:48 2007 +0100
@@ -101,7 +101,7 @@ void hvm_set_guest_time(struct vcpu *v, 
 
 u64 hvm_get_guest_time(struct vcpu *v)
 {
-    u64    host_tsc;
+    u64 host_tsc;
 
     rdtscll(host_tsc);
     return host_tsc + v->arch.hvm_vcpu.cache_tsc_offset;
@@ -125,7 +125,7 @@ void hvm_do_resume(struct vcpu *v)
     pt_thaw_time(v);
 
     /* NB. Optimised for common case (p->state == STATE_IOREQ_NONE). */
-    p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+    p = &get_ioreq(v)->vp_ioreq;
     while ( p->state != STATE_IOREQ_NONE )
     {
         switch ( p->state )
@@ -146,6 +146,73 @@ void hvm_do_resume(struct vcpu *v)
     }
 }
 
+static void hvm_init_ioreq_page(
+    struct domain *d, struct hvm_ioreq_page *iorp)
+{
+    memset(iorp, 0, sizeof(*iorp));
+    spin_lock_init(&iorp->lock);
+    domain_pause(d);
+}
+
+static void hvm_destroy_ioreq_page(
+    struct domain *d, struct hvm_ioreq_page *iorp)
+{
+    spin_lock(&iorp->lock);
+
+    ASSERT(d->is_dying);
+
+    if ( iorp->va != NULL )
+    {
+        unmap_domain_page_global(iorp->va);
+        put_page_and_type(iorp->page);
+        iorp->va = NULL;
+    }
+
+    spin_unlock(&iorp->lock);
+}
+
+static int hvm_set_ioreq_page(
+    struct domain *d, struct hvm_ioreq_page *iorp, unsigned long gmfn)
+{
+    struct page_info *page;
+    unsigned long mfn;
+    void *va;
+
+    mfn = gmfn_to_mfn(d, gmfn);
+    if ( !mfn_valid(mfn) )
+        return -EINVAL;
+
+    page = mfn_to_page(mfn);
+    if ( !get_page_and_type(page, d, PGT_writable_page) )
+        return -EINVAL;
+
+    va = map_domain_page_global(mfn);
+    if ( va == NULL )
+    {
+        put_page_and_type(page);
+        return -ENOMEM;
+    }
+
+    spin_lock(&iorp->lock);
+
+    if ( (iorp->va != NULL) || d->is_dying )
+    {
+        spin_unlock(&iorp->lock);
+        unmap_domain_page_global(va);
+        put_page_and_type(mfn_to_page(mfn));
+        return -EINVAL;
+    }
+
+    iorp->va = va;
+    iorp->page = page;
+
+    spin_unlock(&iorp->lock);
+
+    domain_unpause(d);
+
+    return 0;
+}
+
 int hvm_domain_initialise(struct domain *d)
 {
     int rc;
@@ -158,10 +225,8 @@ int hvm_domain_initialise(struct domain 
     }
 
     spin_lock_init(&d->arch.hvm_domain.pbuf_lock);
-    spin_lock_init(&d->arch.hvm_domain.buffered_io_lock);
     spin_lock_init(&d->arch.hvm_domain.irq_lock);
 
-    /* paging support will be determined inside paging.c */
     rc = paging_enable(d, PG_refcounts|PG_translate|PG_external);
     if ( rc != 0 )
         return rc;
@@ -169,7 +234,16 @@ int hvm_domain_initialise(struct domain 
     vpic_init(d);
     vioapic_init(d);
 
+    hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
+    hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
+
     return 0;
+}
+
+void hvm_domain_relinquish_resources(struct domain *d)
+{
+    hvm_destroy_ioreq_page(d, &d->arch.hvm_domain.ioreq);
+    hvm_destroy_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
 }
 
 void hvm_domain_destroy(struct domain *d)
@@ -178,19 +252,13 @@ void hvm_domain_destroy(struct domain *d
     rtc_deinit(d);
     pmtimer_deinit(d);
     hpet_deinit(d);
-
-    if ( d->arch.hvm_domain.shared_page_va )
-        unmap_domain_page_global(
-            (void *)d->arch.hvm_domain.shared_page_va);
-
-    if ( d->arch.hvm_domain.buffered_io_va )
-        unmap_domain_page_global((void *)d->arch.hvm_domain.buffered_io_va);
 }
 
 static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
 {
     struct vcpu *v;
     struct hvm_hw_cpu ctxt;
+    struct vcpu_guest_context *vc;
 
     for_each_vcpu(d, v)
     {
@@ -199,7 +267,40 @@ static int hvm_save_cpu_ctxt(struct doma
         if ( test_bit(_VPF_down, &v->pause_flags) ) 
             continue;
 
+        /* Architecture-specific vmcs/vmcb bits */
         hvm_funcs.save_cpu_ctxt(v, &ctxt);
+
+        /* Other vcpu register state */
+        vc = &v->arch.guest_context;
+        if ( vc->flags & VGCF_i387_valid )
+            memcpy(ctxt.fpu_regs, &vc->fpu_ctxt, sizeof(ctxt.fpu_regs));
+        else 
+            memset(ctxt.fpu_regs, 0, sizeof(ctxt.fpu_regs));
+        ctxt.rax = vc->user_regs.eax;
+        ctxt.rbx = vc->user_regs.ebx;
+        ctxt.rcx = vc->user_regs.ecx;
+        ctxt.rdx = vc->user_regs.edx;
+        ctxt.rbp = vc->user_regs.ebp;
+        ctxt.rsi = vc->user_regs.esi;
+        ctxt.rdi = vc->user_regs.edi;
+        /* %rsp handled by arch-specific call above */
+#ifdef __x86_64__        
+        ctxt.r8  = vc->user_regs.r8;
+        ctxt.r9  = vc->user_regs.r9;
+        ctxt.r10 = vc->user_regs.r10;
+        ctxt.r11 = vc->user_regs.r11;
+        ctxt.r12 = vc->user_regs.r12;
+        ctxt.r13 = vc->user_regs.r13;
+        ctxt.r14 = vc->user_regs.r14;
+        ctxt.r15 = vc->user_regs.r15;
+#endif
+        ctxt.dr0 = vc->debugreg[0];
+        ctxt.dr1 = vc->debugreg[1];
+        ctxt.dr2 = vc->debugreg[2];
+        ctxt.dr3 = vc->debugreg[3];
+        ctxt.dr6 = vc->debugreg[6];
+        ctxt.dr7 = vc->debugreg[7];
+
         if ( hvm_save_entry(CPU, v->vcpu_id, h, &ctxt) != 0 )
             return 1; 
     }
@@ -208,9 +309,10 @@ static int hvm_save_cpu_ctxt(struct doma
 
 static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
 {
-    int vcpuid;
+    int vcpuid, rc;
     struct vcpu *v;
     struct hvm_hw_cpu ctxt;
+    struct vcpu_guest_context *vc;
 
     /* Which vcpu is this? */
     vcpuid = hvm_load_instance(h);
@@ -219,12 +321,51 @@ static int hvm_load_cpu_ctxt(struct doma
         gdprintk(XENLOG_ERR, "HVM restore: domain has no vcpu %u\n", vcpuid);
         return -EINVAL;
     }
+    vc = &v->arch.guest_context;
+
+    /* Need to init this vcpu before loading its contents */
+    LOCK_BIGLOCK(d);
+    if ( !v->is_initialised )
+        if ( (rc = boot_vcpu(d, vcpuid, vc)) != 0 )
+            return rc;
+    UNLOCK_BIGLOCK(d);
 
     if ( hvm_load_entry(CPU, h, &ctxt) != 0 ) 
         return -EINVAL;
 
+    /* Architecture-specific vmcs/vmcb bits */
     if ( hvm_funcs.load_cpu_ctxt(v, &ctxt) < 0 )
         return -EINVAL;
+
+    /* Other vcpu register state */
+    memcpy(&vc->fpu_ctxt, ctxt.fpu_regs, sizeof(ctxt.fpu_regs));
+    vc->user_regs.eax = ctxt.rax;
+    vc->user_regs.ebx = ctxt.rbx;
+    vc->user_regs.ecx = ctxt.rcx;
+    vc->user_regs.edx = ctxt.rdx;
+    vc->user_regs.ebp = ctxt.rbp;
+    vc->user_regs.esi = ctxt.rsi;
+    vc->user_regs.edi = ctxt.rdi;
+    vc->user_regs.esp = ctxt.rsp;
+#ifdef __x86_64__
+    vc->user_regs.r8  = ctxt.r8; 
+    vc->user_regs.r9  = ctxt.r9; 
+    vc->user_regs.r10 = ctxt.r10;
+    vc->user_regs.r11 = ctxt.r11;
+    vc->user_regs.r12 = ctxt.r12;
+    vc->user_regs.r13 = ctxt.r13;
+    vc->user_regs.r14 = ctxt.r14;
+    vc->user_regs.r15 = ctxt.r15;
+#endif
+    vc->debugreg[0] = ctxt.dr0;
+    vc->debugreg[1] = ctxt.dr1;
+    vc->debugreg[2] = ctxt.dr2;
+    vc->debugreg[3] = ctxt.dr3;
+    vc->debugreg[6] = ctxt.dr6;
+    vc->debugreg[7] = ctxt.dr7;
+
+    vc->flags = VGCF_i387_valid | VGCF_online;
+    v->fpu_initialised = 1;
 
     /* Auxiliary processors should be woken immediately. */
     if ( test_and_clear_bit(_VPF_down, &v->pause_flags) )
@@ -250,10 +391,20 @@ int hvm_vcpu_initialise(struct vcpu *v)
     }
 
     /* Create ioreq event channel. */
-    v->arch.hvm_vcpu.xen_port = alloc_unbound_xen_event_channel(v, 0);
-    if ( get_sp(v->domain) && get_vio(v->domain, v->vcpu_id) )
-        get_vio(v->domain, v->vcpu_id)->vp_eport =
-            v->arch.hvm_vcpu.xen_port;
+    rc = alloc_unbound_xen_event_channel(v, 0);
+    if ( rc < 0 )
+    {
+        hvm_funcs.vcpu_destroy(v);
+        vlapic_destroy(v);
+        return rc;
+    }
+
+    /* Register ioreq event channel. */
+    v->arch.hvm_vcpu.xen_port = rc;
+    spin_lock(&v->domain->arch.hvm_domain.ioreq.lock);
+    if ( v->domain->arch.hvm_domain.ioreq.va != NULL )
+        get_ioreq(v)->vp_eport = v->arch.hvm_vcpu.xen_port;
+    spin_unlock(&v->domain->arch.hvm_domain.ioreq.lock);
 
     INIT_LIST_HEAD(&v->arch.hvm_vcpu.tm_list);
 
@@ -334,7 +485,7 @@ void hvm_send_assist_req(struct vcpu *v)
     if ( unlikely(!vcpu_start_shutdown_deferral(v)) )
         return; /* implicitly bins the i/o operation */
 
-    p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
+    p = &get_ioreq(v)->vp_ioreq;
     if ( unlikely(p->state != STATE_IOREQ_NONE) )
     {
         /* This indicates a bug in the device model.  Crash the domain. */
@@ -852,10 +1003,9 @@ long do_hvm_op(unsigned long op, XEN_GUE
     case HVMOP_get_param:
     {
         struct xen_hvm_param a;
+        struct hvm_ioreq_page *iorp;
         struct domain *d;
         struct vcpu *v;
-        unsigned long mfn;
-        void *p;
 
         if ( copy_from_guest(&a, arg, 1) )
             return -EFAULT;
@@ -882,30 +1032,18 @@ long do_hvm_op(unsigned long op, XEN_GUE
             switch ( a.index )
             {
             case HVM_PARAM_IOREQ_PFN:
-                if ( d->arch.hvm_domain.shared_page_va )
-                    goto param_fail;
-                mfn = gmfn_to_mfn(d, a.value);
-                if ( mfn == INVALID_MFN )
-                    goto param_fail;
-                p = map_domain_page_global(mfn);
-                if ( p == NULL )
-                    goto param_fail;
-                d->arch.hvm_domain.shared_page_va = (unsigned long)p;
-                /* Initialise evtchn port info if VCPUs already created. */
-                for_each_vcpu ( d, v )
-                    get_vio(d, v->vcpu_id)->vp_eport =
-                    v->arch.hvm_vcpu.xen_port;
+                iorp = &d->arch.hvm_domain.ioreq;
+                rc = hvm_set_ioreq_page(d, iorp, a.value);
+                spin_lock(&iorp->lock);
+                if ( (rc == 0) && (iorp->va != NULL) )
+                    /* Initialise evtchn port info if VCPUs already created. */
+                    for_each_vcpu ( d, v )
+                        get_ioreq(v)->vp_eport = v->arch.hvm_vcpu.xen_port;
+                spin_unlock(&iorp->lock);
                 break;
-            case HVM_PARAM_BUFIOREQ_PFN:
-                if ( d->arch.hvm_domain.buffered_io_va )
-                    goto param_fail;
-                mfn = gmfn_to_mfn(d, a.value);
-                if ( mfn == INVALID_MFN )
-                    goto param_fail;
-                p = map_domain_page_global(mfn);
-                if ( p == NULL )
-                    goto param_fail;
-                d->arch.hvm_domain.buffered_io_va = (unsigned long)p;
+            case HVM_PARAM_BUFIOREQ_PFN: 
+                iorp = &d->arch.hvm_domain.buf_ioreq;
+                rc = hvm_set_ioreq_page(d, iorp, a.value);
                 break;
             case HVM_PARAM_CALLBACK_IRQ:
                 hvm_set_callback_via(d, a.value);
diff -r c42ae7839750 -r 039daabebad5 xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c      Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/x86/hvm/intercept.c      Fri Apr 13 16:07:48 2007 +0100
@@ -158,34 +158,26 @@ int hvm_buffered_io_send(ioreq_t *p)
 int hvm_buffered_io_send(ioreq_t *p)
 {
     struct vcpu *v = current;
-    spinlock_t  *buffered_io_lock;
-    buffered_iopage_t *buffered_iopage =
-        (buffered_iopage_t *)(v->domain->arch.hvm_domain.buffered_io_va);
-    unsigned long tmp_write_pointer = 0;
-
-    buffered_io_lock = &v->domain->arch.hvm_domain.buffered_io_lock;
-    spin_lock(buffered_io_lock);
-
-    if ( buffered_iopage->write_pointer - buffered_iopage->read_pointer ==
-         (unsigned int)IOREQ_BUFFER_SLOT_NUM ) {
-        /* the queue is full.
-         * send the iopacket through the normal path.
-         * NOTE: The arithimetic operation could handle the situation for
-         * write_pointer overflow.
-         */
-        spin_unlock(buffered_io_lock);
-        return 0;
-    }
-
-    tmp_write_pointer = buffered_iopage->write_pointer % IOREQ_BUFFER_SLOT_NUM;
-
-    memcpy(&buffered_iopage->ioreq[tmp_write_pointer], p, sizeof(ioreq_t));
-
-    /*make the ioreq_t visible before write_pointer*/
+    struct hvm_ioreq_page *iorp = &v->domain->arch.hvm_domain.buf_ioreq;
+    buffered_iopage_t *pg = iorp->va;
+
+    spin_lock(&iorp->lock);
+
+    if ( (pg->write_pointer - pg->read_pointer) == IOREQ_BUFFER_SLOT_NUM )
+    {
+        /* The queue is full: send the iopacket through the normal path. */
+        spin_unlock(&iorp->lock);
+        return 0;
+    }
+
+    memcpy(&pg->ioreq[pg->write_pointer % IOREQ_BUFFER_SLOT_NUM],
+           p, sizeof(ioreq_t));
+
+    /* Make the ioreq_t visible /before/ write_pointer. */
     wmb();
-    buffered_iopage->write_pointer++;
-
-    spin_unlock(buffered_io_lock);
+    pg->write_pointer++;
+
+    spin_unlock(&iorp->lock);
 
     return 1;
 }
diff -r c42ae7839750 -r 039daabebad5 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/x86/hvm/io.c     Fri Apr 13 16:07:48 2007 +0100
@@ -832,7 +832,7 @@ void hvm_io_assist(void)
 
     io_opp = &v->arch.hvm_vcpu.io_op;
     regs   = &io_opp->io_context;
-    vio    = get_vio(d, v->vcpu_id);
+    vio    = get_ioreq(v);
 
     p = &vio->vp_ioreq;
     if ( p->state != STATE_IORESP_READY )
diff -r c42ae7839750 -r 039daabebad5 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/x86/hvm/platform.c       Fri Apr 13 16:07:48 2007 +0100
@@ -221,7 +221,6 @@ static inline unsigned long get_immediat
 
     inst++; //skip ModR/M byte
     if ( ad_size != WORD && mod != 3 && rm == 4 ) {
-        rm = *inst & 7;
         inst++; //skip SIB byte
     }
 
@@ -255,6 +254,33 @@ static inline unsigned long get_immediat
     }
 
     return val;
+}
+
+/* Some instructions, like "add $imm8, r/m16"/"MOV $imm32, r/m64" require
+ * the src immediate operand be sign-extented befere the op is executed. Here
+ * we always sign-extend the operand to a "unsigned long" variable.
+ *
+ * Note: to simplify the logic here, the sign-extension here may be performed
+ * redundantly against some instructions, like "MOV $imm16, r/m16" -- however
+ * this is harmless, since we always remember the operand's size.
+ */
+static inline unsigned long get_immediate_sign_ext(int ad_size,
+                                                   const unsigned char *inst,
+                                                   int op_size)
+{
+    unsigned long result = get_immediate(ad_size, inst, op_size);
+
+    if ( op_size == QUAD )
+        op_size = LONG;
+
+    ASSERT( op_size == BYTE || op_size == WORD || op_size == LONG );
+
+    if ( result & (1UL << ((8*op_size) - 1)) )
+    {
+        unsigned long mask = ~0UL >> (8 * (sizeof(mask) - op_size));
+        result = ~mask | (result & mask);
+    }
+    return result;
 }
 
 static inline int get_index(const unsigned char *inst, unsigned char rex)
@@ -394,7 +420,9 @@ static int mmio_decode(int address_bytes
     case 8:
         if ( *op_size == 0 )
             *op_size = rex & 0x8 ? QUAD : LONG;
-        if ( *ad_size == 0 )
+        if ( *ad_size == WORD )
+            *ad_size = LONG;
+        else if ( *ad_size == 0 )
             *ad_size = QUAD;
         break;
 #endif
@@ -520,10 +548,10 @@ static int mmio_decode(int address_bytes
         /* opcode 0x83 always has a single byte operand */
         if ( opcode[0] == 0x83 )
             mmio_op->immediate =
-                (signed char)get_immediate(*ad_size, opcode + 1, BYTE);
+                get_immediate_sign_ext(*ad_size, opcode + 1, BYTE);
         else
             mmio_op->immediate =
-                get_immediate(*ad_size, opcode + 1, *op_size);
+                get_immediate_sign_ext(*ad_size, opcode + 1, *op_size);
 
         mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
         mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
@@ -677,7 +705,7 @@ static int mmio_decode(int address_bytes
 
             mmio_op->operand[0] = mk_operand(*op_size, 0, 0, IMMEDIATE);
             mmio_op->immediate =
-                    get_immediate(*ad_size, opcode + 1, *op_size);
+                    get_immediate_sign_ext(*ad_size, opcode + 1, *op_size);
             mmio_op->operand[1] = mk_operand(*op_size, 0, 0, MEMORY);
 
             return DECODE_success;
@@ -699,7 +727,7 @@ static int mmio_decode(int address_bytes
 
             mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
             mmio_op->immediate =
-                    get_immediate(*ad_size, opcode + 1, *op_size);
+                    get_immediate_sign_ext(*ad_size, opcode + 1, *op_size);
             mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
 
             return DECODE_success;
@@ -838,7 +866,7 @@ void send_pio_req(unsigned long port, un
                port, count, size, value, dir, value_is_ptr);
     }
 
-    vio = get_vio(v->domain, v->vcpu_id);
+    vio = get_ioreq(v);
     if ( vio == NULL ) {
         printk("bad shared page: %lx\n", (unsigned long) vio);
         domain_crash_synchronous();
@@ -887,7 +915,7 @@ static void send_mmio_req(unsigned char 
                type, gpa, count, size, value, dir, value_is_ptr);
     }
 
-    vio = get_vio(v->domain, v->vcpu_id);
+    vio = get_ioreq(v);
     if (vio == NULL) {
         printk("bad shared page\n");
         domain_crash_synchronous();
@@ -948,7 +976,7 @@ void send_invalidate_req(void)
     vcpu_iodata_t *vio;
     ioreq_t *p;
 
-    vio = get_vio(v->domain, v->vcpu_id);
+    vio = get_ioreq(v);
     if ( vio == NULL )
     {
         printk("bad shared page: %lx\n", (unsigned long) vio);
diff -r c42ae7839750 -r 039daabebad5 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Apr 13 16:07:48 2007 +0100
@@ -233,7 +233,7 @@ int svm_vmcb_save(struct vcpu *v, struct
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
-    c->eip = vmcb->rip;
+    c->rip = vmcb->rip;
 
 #ifdef HVM_DEBUG_SUSPEND
     printk("%s: eip=0x%"PRIx64".\n", 
@@ -241,10 +241,11 @@ int svm_vmcb_save(struct vcpu *v, struct
            inst_len, c->eip);
 #endif
 
-    c->esp = vmcb->rsp;
-    c->eflags = vmcb->rflags;
+    c->rsp = vmcb->rsp;
+    c->rflags = vmcb->rflags;
 
     c->cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
+    c->cr2 = v->arch.hvm_svm.cpu_cr2;
     c->cr3 = v->arch.hvm_svm.cpu_cr3;
     c->cr4 = v->arch.hvm_svm.cpu_shadow_cr4;
 
@@ -315,14 +316,14 @@ int svm_vmcb_restore(struct vcpu *v, str
     unsigned long mfn, old_base_mfn;
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
-    vmcb->rip    = c->eip;
-    vmcb->rsp    = c->esp;
-    vmcb->rflags = c->eflags;
+    vmcb->rip    = c->rip;
+    vmcb->rsp    = c->rsp;
+    vmcb->rflags = c->rflags;
 
     v->arch.hvm_svm.cpu_shadow_cr0 = c->cr0;
-    vmcb->cr0 = c->cr0 | X86_CR0_WP | X86_CR0_ET;
-    if ( !paging_mode_hap(v->domain) ) 
-        vmcb->cr0 |= X86_CR0_PG;
+    vmcb->cr0 = c->cr0 | X86_CR0_WP | X86_CR0_ET | X86_CR0_PG;
+
+    v->arch.hvm_svm.cpu_cr2 = c->cr2;
 
 #ifdef HVM_DEBUG_SUSPEND
     printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n",
@@ -421,6 +422,19 @@ int svm_vmcb_restore(struct vcpu *v, str
     vmcb->sysenter_esp = c->sysenter_esp;
     vmcb->sysenter_eip = c->sysenter_eip;
 
+    /* update VMCB for nested paging restore */
+    if ( paging_mode_hap(v->domain) ) {
+        vmcb->cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
+        vmcb->cr4 = v->arch.hvm_svm.cpu_shadow_cr4;
+        vmcb->cr3 = c->cr3;
+        vmcb->np_enable = 1;
+        vmcb->g_pat = 0x0007040600070406ULL; /* guest PAT */
+        vmcb->h_cr3 = pagetable_get_paddr(v->domain->arch.phys_table);
+    }
+
+    vmcb->dr6 = c->dr6;
+    vmcb->dr7 = c->dr7;
+
     paging_update_paging_modes(v);
     return 0;
  
@@ -440,6 +454,7 @@ void svm_save_cpu_state(struct vcpu *v, 
     data->msr_cstar        = vmcb->cstar;
     data->msr_syscall_mask = vmcb->sfmask;
     data->msr_efer         = v->arch.hvm_svm.cpu_shadow_efer;
+    data->msr_flags        = -1ULL;
 
     data->tsc = hvm_get_guest_time(v);
 }
diff -r c42ae7839750 -r 039daabebad5 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Apr 13 16:07:48 2007 +0100
@@ -370,11 +370,12 @@ static inline void __restore_debug_regis
 
 int vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c)
 {    
-    c->eip = __vmread(GUEST_RIP);
-    c->esp = __vmread(GUEST_RSP);
-    c->eflags = __vmread(GUEST_RFLAGS);
+    c->rip = __vmread(GUEST_RIP);
+    c->rsp = __vmread(GUEST_RSP);
+    c->rflags = __vmread(GUEST_RFLAGS);
 
     c->cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
+    c->cr2 = v->arch.hvm_vmx.cpu_cr2;
     c->cr3 = v->arch.hvm_vmx.cpu_cr3;
     c->cr4 = v->arch.hvm_vmx.cpu_shadow_cr4;
 
@@ -444,12 +445,14 @@ int vmx_vmcs_restore(struct vcpu *v, str
 
     vmx_vmcs_enter(v);
 
-    __vmwrite(GUEST_RIP, c->eip);
-    __vmwrite(GUEST_RSP, c->esp);
-    __vmwrite(GUEST_RFLAGS, c->eflags);
+    __vmwrite(GUEST_RIP, c->rip);
+    __vmwrite(GUEST_RSP, c->rsp);
+    __vmwrite(GUEST_RFLAGS, c->rflags);
 
     v->arch.hvm_vmx.cpu_shadow_cr0 = c->cr0;
     __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
+
+    v->arch.hvm_vmx.cpu_cr2 = c->cr2;
 
 #ifdef HVM_DEBUG_SUSPEND
     printk("vmx_vmcs_restore: cr3=0x%"PRIx64", cr0=0x%"PRIx64", 
cr4=0x%"PRIx64".\n",
@@ -555,6 +558,8 @@ int vmx_vmcs_restore(struct vcpu *v, str
     __vmwrite(GUEST_SYSENTER_ESP, c->sysenter_esp);
     __vmwrite(GUEST_SYSENTER_EIP, c->sysenter_eip);
 
+    __vmwrite(GUEST_DR7, c->dr7);
+
     vmx_vmcs_exit(v);
 
     paging_update_paging_modes(v);
@@ -590,7 +595,7 @@ void vmx_save_cpu_state(struct vcpu *v, 
     data->shadow_gs = guest_state->shadow_gs;
 
     /* save msrs */
-    data->flags = guest_flags;
+    data->msr_flags        = guest_flags;
     data->msr_lstar        = guest_state->msrs[VMX_INDEX_MSR_LSTAR];
     data->msr_star         = guest_state->msrs[VMX_INDEX_MSR_STAR];
     data->msr_cstar        = guest_state->msrs[VMX_INDEX_MSR_CSTAR];
@@ -607,7 +612,7 @@ void vmx_load_cpu_state(struct vcpu *v, 
     struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
 
     /* restore msrs */
-    guest_state->flags = data->flags;
+    guest_state->flags = data->msr_flags;
     guest_state->msrs[VMX_INDEX_MSR_LSTAR]        = data->msr_lstar;
     guest_state->msrs[VMX_INDEX_MSR_STAR]         = data->msr_star;
     guest_state->msrs[VMX_INDEX_MSR_CSTAR]        = data->msr_cstar;
diff -r c42ae7839750 -r 039daabebad5 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/arch/x86/mm.c Fri Apr 13 16:07:48 2007 +0100
@@ -2041,7 +2041,7 @@ int do_mmuext_op(
                 MEM_LOG("Error while pinning mfn %lx", mfn);
                 break;
             }
-            
+
             if ( unlikely(test_and_set_bit(_PGT_pinned,
                                            &page->u.inuse.type_info)) )
             {
@@ -2054,14 +2054,18 @@ int do_mmuext_op(
             /* A page is dirtied when its pin status is set. */
             mark_dirty(d, mfn);
            
-            /*
-             * We can race domain destruction (domain_relinquish_resources).
-             * NB. The dying-flag test must happen /after/ setting PGT_pinned.
-             */
-            if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) &&
-                 this_cpu(percpu_mm_info).foreign->is_dying &&
-                 test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
-                put_page_and_type(page);
+            /* We can race domain destruction (domain_relinquish_resources). */
+            if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) )
+            {
+                int drop_ref;
+                spin_lock(&FOREIGNDOM->page_alloc_lock);
+                drop_ref = (FOREIGNDOM->is_dying &&
+                            test_and_clear_bit(_PGT_pinned,
+                                               &page->u.inuse.type_info));
+                spin_unlock(&FOREIGNDOM->page_alloc_lock);
+                if ( drop_ref )
+                    put_page_and_type(page);
+            }
 
             break;
 
diff -r c42ae7839750 -r 039daabebad5 xen/common/domain.c
--- a/xen/common/domain.c       Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/common/domain.c       Fri Apr 13 16:07:48 2007 +0100
@@ -313,9 +313,6 @@ void domain_kill(struct domain *d)
         return;
     }
 
-    /* Tear down state /after/ setting the dying flag. */
-    smp_wmb();
-
     gnttab_release_mappings(d);
     domain_relinquish_resources(d);
     put_domain(d);
diff -r c42ae7839750 -r 039daabebad5 xen/include/asm-powerpc/system.h
--- a/xen/include/asm-powerpc/system.h  Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/include/asm-powerpc/system.h  Fri Apr 13 16:07:48 2007 +0100
@@ -28,7 +28,11 @@
 #include <asm/processor.h>
 #include <asm/msr.h>
 
-#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned 
long)(v),(ptr),sizeof(*(ptr))))
+#define xchg(ptr,x)                                                           \
+({                                                                            \
+       __typeof__(*(ptr)) _x_ = (x);                                          \
+       (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); 
\
+})
 
 static __inline__ unsigned long
 __xchg_u32(volatile int *m, unsigned long val)
diff -r c42ae7839750 -r 039daabebad5 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h  Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/include/asm-x86/hvm/domain.h  Fri Apr 13 16:07:48 2007 +0100
@@ -28,10 +28,16 @@
 #include <public/hvm/params.h>
 #include <public/hvm/save.h>
 
+struct hvm_ioreq_page {
+    spinlock_t lock;
+    struct page_info *page;
+    void *va;
+};
+
 struct hvm_domain {
-    unsigned long          shared_page_va;
-    unsigned long          buffered_io_va;
-    spinlock_t             buffered_io_lock;
+    struct hvm_ioreq_page  ioreq;
+    struct hvm_ioreq_page  buf_ioreq;
+
     s64                    tsc_frequency;
     struct pl_time         pl_time;
 
diff -r c42ae7839750 -r 039daabebad5 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/include/asm-x86/hvm/hvm.h     Fri Apr 13 16:07:48 2007 +0100
@@ -145,6 +145,7 @@ extern struct hvm_function_table hvm_fun
 extern struct hvm_function_table hvm_funcs;
 
 int hvm_domain_initialise(struct domain *d);
+void hvm_domain_relinquish_resources(struct domain *d);
 void hvm_domain_destroy(struct domain *d);
 
 int hvm_vcpu_initialise(struct vcpu *v);
diff -r c42ae7839750 -r 039daabebad5 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/include/asm-x86/hvm/support.h Fri Apr 13 16:07:48 2007 +0100
@@ -32,14 +32,13 @@
 #define HVM_DEBUG 1
 #endif
 
-static inline shared_iopage_t *get_sp(struct domain *d)
-{
-    return (shared_iopage_t *) d->arch.hvm_domain.shared_page_va;
-}
-
-static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu)
-{
-    return &get_sp(d)->vcpu_iodata[cpu];
+static inline vcpu_iodata_t *get_ioreq(struct vcpu *v)
+{
+    struct domain *d = v->domain;
+    shared_iopage_t *p = d->arch.hvm_domain.ioreq.va;
+    ASSERT((v == current) || spin_is_locked(&d->arch.hvm_domain.ioreq.lock));
+    ASSERT(d->arch.hvm_domain.ioreq.va != NULL);
+    return &p->vcpu_iodata[v->vcpu_id];
 }
 
 /* XXX these are really VMX specific */
diff -r c42ae7839750 -r 039daabebad5 xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/include/public/hvm/save.h     Fri Apr 13 16:07:48 2007 +0100
@@ -87,12 +87,39 @@ DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct 
  */
 
 struct hvm_hw_cpu {
-    uint64_t eip;
-    uint64_t esp;
-    uint64_t eflags;
+    uint8_t  fpu_regs[512];
+
+    uint64_t rax;
+    uint64_t rbx;
+    uint64_t rcx;
+    uint64_t rdx;
+    uint64_t rbp;
+    uint64_t rsi;
+    uint64_t rdi;
+    uint64_t rsp;
+    uint64_t r8;
+    uint64_t r9;
+    uint64_t r10;
+    uint64_t r11;
+    uint64_t r12;
+    uint64_t r13;
+    uint64_t r14;
+    uint64_t r15;
+
+    uint64_t rip;
+    uint64_t rflags;
+
     uint64_t cr0;
+    uint64_t cr2;
     uint64_t cr3;
     uint64_t cr4;
+
+    uint64_t dr0;
+    uint64_t dr1;
+    uint64_t dr2;
+    uint64_t dr3;
+    uint64_t dr6;
+    uint64_t dr7;    
 
     uint32_t cs_sel;
     uint32_t ds_sel;
@@ -142,9 +169,9 @@ struct hvm_hw_cpu {
 
     /* msr for em64t */
     uint64_t shadow_gs;
-    uint64_t flags;
 
     /* msr content saved/restored. */
+    uint64_t msr_flags;
     uint64_t msr_lstar;
     uint64_t msr_star;
     uint64_t msr_cstar;
diff -r c42ae7839750 -r 039daabebad5 xen/include/xen/domain_page.h
--- a/xen/include/xen/domain_page.h     Fri Apr 13 08:33:21 2007 -0600
+++ b/xen/include/xen/domain_page.h     Fri Apr 13 16:07:48 2007 +0100
@@ -96,10 +96,10 @@ domain_mmap_cache_destroy(struct domain_
 
 #else /* !CONFIG_DOMAIN_PAGE */
 
-#define map_domain_page(mfn)                maddr_to_virt((mfn)<<PAGE_SHIFT)
+#define map_domain_page(mfn)                mfn_to_virt(mfn)
 #define unmap_domain_page(va)               ((void)(va))
 
-#define map_domain_page_global(mfn)         maddr_to_virt((mfn)<<PAGE_SHIFT)
+#define map_domain_page_global(mfn)         mfn_to_virt(mfn)
 #define unmap_domain_page_global(va)        ((void)(va))
 
 struct domain_mmap_cache { 

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

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