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, 09 Feb 2007 09:40:58 -0800
Delivery-date: Fri, 09 Feb 2007 10:37:03 -0800
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 kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1170955650 0
# Node ID f9277e2548b5ffcaaffb39ae269c13915084ca59
# Parent  fbc233a1dc53dd0928fb8c0062d6582ef210950d
# Parent  5a1abfefe892c27ddee13eb2537dbe1a5089accb
Merge with xen-ia64-unstable.hg.
---
 linux-2.6-xen-sparse/include/asm-i386/a.out.h     |   26 ----
 xen/include/asm-ia64/kexec.h                      |   25 ----
 xen/include/asm-powerpc/kexec.h                   |   25 ----
 xen/include/asm-x86/kexec.h                       |   20 ---
 xen/include/asm-x86/x86_32/kexec.h                |   39 ------
 xen/include/asm-x86/x86_64/kexec.h                |   38 ------
 .hgignore                                         |    1 
 linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c |  103 ++++++++++++-----
 linux-2.6-xen-sparse/net/core/skbuff.c            |   46 ++++----
 tools/examples/vif-bridge                         |    7 +
 tools/examples/xen-hotplug-common.sh              |    5 
 tools/ioemu/hw/cirrus_vga.c                       |    4 
 tools/ioemu/hw/ide.c                              |    4 
 tools/ioemu/hw/rtl8139.c                          |    6 -
 tools/ioemu/xenstore.c                            |   60 ++++++++++
 tools/libxc/xc_hvm_restore.c                      |    5 
 tools/libxc/xc_hvm_save.c                         |   70 ++++--------
 tools/libxc/xenguest.h                            |    3 
 tools/libxc/xg_private.c                          |    3 
 tools/misc/Makefile                               |    4 
 tools/misc/xen-detect.c                           |  108 ++++++++++++++++++
 tools/python/xen/xend/XendCheckpoint.py           |    7 -
 tools/python/xen/xend/XendConfig.py               |   41 +++++++
 tools/python/xen/xend/XendDomain.py               |   20 ++-
 tools/python/xen/xend/XendDomainInfo.py           |   58 +++++++++-
 tools/python/xen/xend/server/BlktapController.py  |   62 ++++++++++
 tools/python/xen/xend/server/DevController.py     |   52 +++++----
 tools/xcutils/xc_restore.c                        |    5 
 tools/xenfb/vncfb.c                               |   10 +
 xen/arch/powerpc/machine_kexec.c                  |    5 
 xen/arch/x86/crash.c                              |    1 
 xen/arch/x86/hvm/hvm.c                            |    2 
 xen/arch/x86/hvm/pmtimer.c                        |   75 +++++++------
 xen/arch/x86/machine_kexec.c                      |   53 ++++++++-
 xen/arch/x86/x86_64/Makefile                      |    1 
 xen/arch/x86/x86_64/compat_kexec.S                |  126 ++++++++++++++++++++++
 xen/common/kexec.c                                |    1 
 xen/common/memory.c                               |   10 +
 xen/drivers/char/console.c                        |    2 
 xen/include/asm-x86/config.h                      |    4 
 xen/include/asm-x86/hvm/vpt.h                     |   14 --
 xen/include/asm-x86/shadow.h                      |    5 
 xen/include/public/hvm/save.h                     |   12 +-
 xen/include/xen/kexec.h                           |    1 
 44 files changed, 791 insertions(+), 378 deletions(-)

diff -r fbc233a1dc53 -r f9277e2548b5 .hgignore
--- a/.hgignore Wed Feb 07 10:46:18 2007 -0700
+++ b/.hgignore Thu Feb 08 17:27:30 2007 +0000
@@ -138,6 +138,7 @@
 ^tools/misc/miniterm/miniterm$
 ^tools/misc/xc_shadow$
 ^tools/misc/xen_cpuperf$
+^tools/misc/xen-detect$
 ^tools/misc/xenperf$
 ^tools/pygrub/build/.*$
 ^tools/python/build/.*$
diff -r fbc233a1dc53 -r f9277e2548b5 
linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c Wed Feb 07 10:46:18 
2007 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c Thu Feb 08 17:27:30 
2007 +0000
@@ -29,10 +29,12 @@
 
 struct xenkbd_info
 {
-       struct input_dev *dev;
+       struct input_dev *kbd;
+       struct input_dev *ptr;
        struct xenkbd_page *page;
        int irq;
        struct xenbus_device *xbdev;
+       char phys[32];
 };
 
 static int xenkbd_remove(struct xenbus_device *);
@@ -56,23 +58,36 @@ static irqreturn_t input_handler(int rq,
        rmb();                  /* ensure we see ring contents up to prod */
        for (cons = page->in_cons; cons != prod; cons++) {
                union xenkbd_in_event *event;
+               struct input_dev *dev;
                event = &XENKBD_IN_RING_REF(page, cons);
 
+               dev = info->ptr;
                switch (event->type) {
                case XENKBD_TYPE_MOTION:
-                       input_report_rel(info->dev, REL_X, event->motion.rel_x);
-                       input_report_rel(info->dev, REL_Y, event->motion.rel_y);
+                       input_report_rel(dev, REL_X, event->motion.rel_x);
+                       input_report_rel(dev, REL_Y, event->motion.rel_y);
                        break;
                case XENKBD_TYPE_KEY:
-                       input_report_key(info->dev, event->key.keycode, 
event->key.pressed);
+                       dev = NULL;
+                       if (test_bit(event->key.keycode, info->kbd->keybit))
+                               dev = info->kbd;
+                       if (test_bit(event->key.keycode, info->ptr->keybit))
+                               dev = info->ptr;
+                       if (dev)
+                               input_report_key(dev, event->key.keycode,
+                                                event->key.pressed);
+                       else
+                               printk("xenkbd: unhandled keycode 0x%x\n",
+                                      event->key.keycode);
                        break;
                case XENKBD_TYPE_POS:
-                       input_report_abs(info->dev, ABS_X, event->pos.abs_x);
-                       input_report_abs(info->dev, ABS_Y, event->pos.abs_y);
+                       input_report_abs(dev, ABS_X, event->pos.abs_x);
+                       input_report_abs(dev, ABS_Y, event->pos.abs_y);
                        break;
                }
-       }
-       input_sync(info->dev);
+               if (dev)
+                       input_sync(dev);
+       }
        mb();                   /* ensure we got ring contents */
        page->in_cons = cons;
        notify_remote_via_irq(info->irq);
@@ -85,7 +100,7 @@ int __devinit xenkbd_probe(struct xenbus
 {
        int ret, i;
        struct xenkbd_info *info;
-       struct input_dev *input_dev;
+       struct input_dev *kbd, *ptr;
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info) {
@@ -94,6 +109,7 @@ int __devinit xenkbd_probe(struct xenbus
        }
        dev->dev.driver_data = info;
        info->xbdev = dev;
+       snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename);
 
        info->page = (void *)__get_free_page(GFP_KERNEL);
        if (!info->page)
@@ -101,32 +117,52 @@ int __devinit xenkbd_probe(struct xenbus
        info->page->in_cons = info->page->in_prod = 0;
        info->page->out_cons = info->page->out_prod = 0;
 
-       input_dev = input_allocate_device();
-       if (!input_dev)
+       /* keyboard */
+       kbd = input_allocate_device();
+       if (!kbd)
                goto error_nomem;
-
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_MOUSE)]
-               = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-       /* TODO additional buttons */
-       input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-
-       /* FIXME not sure this is quite right */
-       for (i = 0; i < 256; i++)
-               set_bit(i, input_dev->keybit);
-
-       input_dev->name = "Xen Virtual Keyboard/Mouse";
-
-       input_set_abs_params(input_dev, ABS_X, 0, XENFB_WIDTH, 0, 0);
-       input_set_abs_params(input_dev, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
-
-       ret = input_register_device(input_dev);
-       if (ret) {
-               input_free_device(input_dev);
-               xenbus_dev_fatal(dev, ret, "input_register_device");
+       kbd->name = "Xen Virtual Keyboard";
+       kbd->phys = info->phys;
+       kbd->id.bustype = BUS_PCI;
+       kbd->id.vendor = 0x5853;
+       kbd->id.product = 0xffff;
+       kbd->evbit[0] = BIT(EV_KEY);
+       for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
+               set_bit(i, kbd->keybit);
+       for (i = KEY_OK; i < KEY_MAX; i++)
+               set_bit(i, kbd->keybit);
+
+       ret = input_register_device(kbd);
+       if (ret) {
+               input_free_device(kbd);
+               xenbus_dev_fatal(dev, ret, "input_register_device(kbd)");
                goto error;
        }
-       info->dev = input_dev;
+       info->kbd = kbd;
+
+       /* pointing device */
+       ptr = input_allocate_device();
+       if (!ptr)
+               goto error_nomem;
+       ptr->name = "Xen Virtual Pointer";
+       ptr->phys = info->phys;
+       ptr->id.bustype = BUS_PCI;
+       ptr->id.vendor = 0x5853;
+       ptr->id.product = 0xfffe;
+       ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
+       for (i = BTN_LEFT; i <= BTN_TASK; i++)
+               set_bit(i, ptr->keybit);
+       ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+       input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
+       input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
+
+       ret = input_register_device(ptr);
+       if (ret) {
+               input_free_device(ptr);
+               xenbus_dev_fatal(dev, ret, "input_register_device(ptr)");
+               goto error;
+       }
+       info->ptr = ptr;
 
        ret = xenkbd_connect_backend(dev, info);
        if (ret < 0)
@@ -155,7 +191,8 @@ static int xenkbd_remove(struct xenbus_d
        struct xenkbd_info *info = dev->dev.driver_data;
 
        xenkbd_disconnect_backend(info);
-       input_unregister_device(info->dev);
+       input_unregister_device(info->kbd);
+       input_unregister_device(info->ptr);
        free_page((unsigned long)info->page);
        kfree(info);
        return 0;
diff -r fbc233a1dc53 -r f9277e2548b5 
linux-2.6-xen-sparse/include/asm-i386/a.out.h
--- a/linux-2.6-xen-sparse/include/asm-i386/a.out.h     Wed Feb 07 10:46:18 
2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#ifndef __I386_A_OUT_H__
-#define __I386_A_OUT_H__
-
-struct exec
-{
-  unsigned long a_info;                /* Use macros N_MAGIC, etc for access */
-  unsigned a_text;             /* length of text, in bytes */
-  unsigned a_data;             /* length of data, in bytes */
-  unsigned a_bss;              /* length of uninitialized data area for file, 
in bytes */
-  unsigned a_syms;             /* length of symbol table data in file, in 
bytes */
-  unsigned a_entry;            /* start address */
-  unsigned a_trsize;           /* length of relocation info for text, in bytes 
*/
-  unsigned a_drsize;           /* length of relocation info for data, in bytes 
*/
-};
-
-#define N_TRSIZE(a)    ((a).a_trsize)
-#define N_DRSIZE(a)    ((a).a_drsize)
-#define N_SYMSIZE(a)   ((a).a_syms)
-
-#ifdef __KERNEL__
-
-#define STACK_TOP      (TASK_SIZE - 3*PAGE_SIZE)
-
-#endif
-
-#endif /* __A_OUT_GNU_H__ */
diff -r fbc233a1dc53 -r f9277e2548b5 linux-2.6-xen-sparse/net/core/skbuff.c
--- a/linux-2.6-xen-sparse/net/core/skbuff.c    Wed Feb 07 10:46:18 2007 -0700
+++ b/linux-2.6-xen-sparse/net/core/skbuff.c    Thu Feb 08 17:27:30 2007 +0000
@@ -1897,6 +1897,29 @@ int skb_append_datato_frags(struct sock 
 }
 
 /**
+ *     skb_pull_rcsum - pull skb and update receive checksum
+ *     @skb: buffer to update
+ *     @start: start of data before pull
+ *     @len: length of data pulled
+ *
+ *     This function performs an skb_pull on the packet and updates
+ *     update the CHECKSUM_HW checksum.  It should be used on receive
+ *     path processing instead of skb_pull unless you know that the
+ *     checksum difference is zero (e.g., a valid IP header) or you
+ *     are setting ip_summed to CHECKSUM_NONE.
+ */
+unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
+{
+       BUG_ON(len > skb->len);
+       skb->len -= len;
+       BUG_ON(skb->len < skb->data_len);
+       skb_postpull_rcsum(skb, skb->data, len);
+       return skb->data += len;
+}
+
+EXPORT_SYMBOL_GPL(skb_pull_rcsum);
+
+/**
  *     skb_segment - Perform protocol segmentation on skb.
  *     @skb: buffer to segment
  *     @features: features for the output path (see dev->features)
@@ -2021,29 +2044,6 @@ err:
 }
 
 EXPORT_SYMBOL_GPL(skb_segment);
-
-/**
- *     skb_pull_rcsum - pull skb and update receive checksum
- *     @skb: buffer to update
- *     @start: start of data before pull
- *     @len: length of data pulled
- *
- *     This function performs an skb_pull on the packet and updates
- *     update the CHECKSUM_HW checksum.  It should be used on receive
- *     path processing instead of skb_pull unless you know that the
- *     checksum difference is zero (e.g., a valid IP header) or you
- *     are setting ip_summed to CHECKSUM_NONE.
- */
-unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
-{
-       BUG_ON(len > skb->len);
-       skb->len -= len;
-       BUG_ON(skb->len < skb->data_len);
-       skb_postpull_rcsum(skb, skb->data, len);
-       return skb->data += len;
-}
-
-EXPORT_SYMBOL_GPL(skb_pull_rcsum);
 
 void __init skb_init(void)
 {
diff -r fbc233a1dc53 -r f9277e2548b5 tools/examples/vif-bridge
--- a/tools/examples/vif-bridge Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/examples/vif-bridge Thu Feb 08 17:27:30 2007 +0000
@@ -46,6 +46,13 @@ then
   fi
 fi
 
+RET=0
+ip link show $bridge 1>/dev/null 2>&1 || RET=1
+if [ "$RET" -eq 1 ]
+then
+    fatal "Could not find bridge device $bridge"
+fi
+
 case "$command" in
     online)
        setup_bridge_port "$vif"
diff -r fbc233a1dc53 -r f9277e2548b5 tools/examples/xen-hotplug-common.sh
--- a/tools/examples/xen-hotplug-common.sh      Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/examples/xen-hotplug-common.sh      Thu Feb 08 17:27:30 2007 +0000
@@ -28,14 +28,15 @@ unset $(set | grep ^LC_ | cut -d= -f1)
 unset $(set | grep ^LC_ | cut -d= -f1)
 
 fatal() {
-  xenstore_write "$XENBUS_PATH"/hotplug-status error
+  xenstore_write "$XENBUS_PATH/hotplug-error" "$*" \
+                 "$XENBUS_PATH/hotplug-status" error
   log err "$@"
   exit 1
 }
 
 success() {
   # Tell DevController that backend is "connected"
-  xenstore_write "$XENBUS_PATH"/hotplug-status connected
+  xenstore_write "$XENBUS_PATH/hotplug-status" connected
 }
 
 do_or_die() {
diff -r fbc233a1dc53 -r f9277e2548b5 tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c       Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/ioemu/hw/cirrus_vga.c       Thu Feb 08 17:27:30 2007 +0000
@@ -3339,6 +3339,10 @@ void pci_cirrus_vga_init(PCIBus *bus, Di
     pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
     pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
     pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
+    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
+    pci_conf[0x2d] = 0x58;
+    pci_conf[0x2e] = 0x01; /* subsystem device */
+    pci_conf[0x2f] = 0x00;
 
     /* setup VGA */
     s = &d->cirrus_vga;
diff -r fbc233a1dc53 -r f9277e2548b5 tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c      Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/ioemu/hw/ide.c      Thu Feb 08 17:27:30 2007 +0000
@@ -2502,6 +2502,10 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
     pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
     pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
     pci_conf[0x0e] = 0x00; // header_type
+    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
+    pci_conf[0x2d] = 0x58;
+    pci_conf[0x2e] = 0x01; /* subsystem device */
+    pci_conf[0x2f] = 0x00;
 
     pci_register_io_region((PCIDevice *)d, 4, 0x10, 
                            PCI_ADDRESS_SPACE_IO, bmdma_map);
diff -r fbc233a1dc53 -r f9277e2548b5 tools/ioemu/hw/rtl8139.c
--- a/tools/ioemu/hw/rtl8139.c  Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/ioemu/hw/rtl8139.c  Thu Feb 08 17:27:30 2007 +0000
@@ -3423,8 +3423,10 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
     pci_conf[0x0e] = 0x00; /* header_type */
     pci_conf[0x3d] = 1;    /* interrupt pin 0 */
     pci_conf[0x34] = 0xdc;
-    pci_conf[0x2c] = pci_conf[0x00]; // same as Vendor ID
-    pci_conf[0x2d] = pci_conf[0x01];
+    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
+    pci_conf[0x2d] = 0x58;
+    pci_conf[0x2e] = 0x01; /* subsystem device */
+    pci_conf[0x2f] = 0x00;
 
     s = &d->rtl8139;
 
diff -r fbc233a1dc53 -r f9277e2548b5 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c    Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/ioemu/xenstore.c    Thu Feb 08 17:27:30 2007 +0000
@@ -10,6 +10,7 @@
 
 #include "vl.h"
 #include "block_int.h"
+#include <unistd.h>
 
 static struct xs_handle *xsh = NULL;
 static char *hd_filename[MAX_DISKS];
@@ -52,11 +53,40 @@ void xenstore_check_new_media_present(in
     qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout);
 }
 
+static int waitForDevice(char *path, char *field, char *desired)
+{ 
+    char *buf = NULL, *stat = NULL;
+    unsigned int len;
+    int val = 1;
+
+    /* loop until we find a value in xenstore, return 
+     * if it was what we wanted, or not
+     */
+    while (1) {
+        if (pasprintf(&buf, "%s/%s", path, field) == -1)
+            goto done;
+        free(stat);
+        stat = xs_read(xsh, XBT_NULL, buf, &len);
+        if (stat == NULL) {
+            usleep(100000); /* 1/10th second, no path found */
+        } else {
+            val = strcmp(stat, desired);
+            goto done;
+        }
+    }
+
+done:
+    free(stat);
+    free(buf);
+    return val;
+}
+
 void xenstore_parse_domain_config(int domid)
 {
     char **e = NULL;
     char *buf = NULL, *path;
-    char *bpath = NULL, *dev = NULL, *params = NULL, *type = NULL;
+    char *fpath = NULL, *bpath = NULL,
+         *dev = NULL, *params = NULL, *type = NULL;
     int i;
     unsigned int len, num, hd_index;
 
@@ -120,7 +150,35 @@ void xenstore_parse_domain_config(int do
            hd_filename[hd_index] = params;     /* strdup() */
            params = NULL;              /* don't free params on re-use */
        }
+        /* 
+         * check if device has a phantom vbd; the phantom is hooked
+         * to the frontend device (for ease of cleanup), so lookup 
+         * the frontend device, and see if there is a phantom_vbd
+         * if there is, we will use resolution as the filename
+         */
+       if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
+           continue;
+       free(fpath);
+        fpath = xs_read(xsh, XBT_NULL, buf, &len);
+       if (fpath != NULL) {
+
+            if (waitForDevice(fpath, "hotplug-status", "connected")) {
+               continue;
+            }
+
+           if (pasprintf(&buf, "%s/dev", fpath) == -1)
+               continue;
+            params = xs_read(xsh, XBT_NULL, buf , &len);
+           if (params != NULL) {
+                free(hd_filename[hd_index]);
+                hd_filename[hd_index] = params;
+                params = NULL;              /* don't free params on re-use */
+            }
+        }
        bs_table[hd_index] = bdrv_new(dev);
+        /* re-establish buf */
+       if (pasprintf(&buf, "%s/params", bpath) == -1)
+           continue;
        /* check if it is a cdrom */
        if (type && !strcmp(type, "cdrom")) {
            bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
diff -r fbc233a1dc53 -r f9277e2548b5 tools/libxc/xc_hvm_restore.c
--- a/tools/libxc/xc_hvm_restore.c      Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/libxc/xc_hvm_restore.c      Thu Feb 08 17:27:30 2007 +0000
@@ -69,7 +69,6 @@ int xc_hvm_restore(int xc_handle, int io
 int xc_hvm_restore(int xc_handle, int io_fd,
                      uint32_t dom, unsigned long nr_pfns,
                      unsigned int store_evtchn, unsigned long *store_mfn,
-                     unsigned int console_evtchn, unsigned long *console_mfn,
                      unsigned int pae, unsigned int apic)
 {
     DECLARE_DOMCTL;
@@ -104,8 +103,8 @@ int xc_hvm_restore(int xc_handle, int io
     memsize = (unsigned long long)*store_mfn;
     v_end = memsize << 20;
 
-    DPRINTF("xc_hvm_restore:dom=%d, nr_pfns=0x%lx, store_evtchn=%d, 
*store_mfn=%ld, console_evtchn=%d, *console_mfn=%ld, pae=%u, apic=%u.\n", 
-            dom, nr_pfns, store_evtchn, *store_mfn, console_evtchn, 
*console_mfn, pae, apic);
+    DPRINTF("xc_hvm_restore:dom=%d, nr_pfns=0x%lx, store_evtchn=%d, 
*store_mfn=%ld, pae=%u, apic=%u.\n", 
+            dom, nr_pfns, store_evtchn, *store_mfn, pae, apic);
 
     max_pfn = nr_pfns;
 
diff -r fbc233a1dc53 -r f9277e2548b5 tools/libxc/xc_hvm_save.c
--- a/tools/libxc/xc_hvm_save.c Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/libxc/xc_hvm_save.c Thu Feb 08 17:27:30 2007 +0000
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/time.h>
+#include <xen/hvm/e820.h>
 
 #include "xc_private.h"
 #include "xg_private.h"
@@ -275,9 +276,8 @@ int xc_hvm_save(int xc_handle, int io_fd
     /* A copy of the CPU context of the guest. */
     vcpu_guest_context_t ctxt;
 
-    /* A table containg the type of each PFN (/not/ MFN!). */
-    unsigned long *pfn_type = NULL;
-    unsigned long *pfn_batch = NULL;
+    /* A table containg the PFNs (/not/ MFN!) to map. */
+    xen_pfn_t *pfn_batch = NULL;
 
     /* A copy of hvm domain context buffer*/
     uint32_t hvm_buf_size;
@@ -290,7 +290,6 @@ int xc_hvm_save(int xc_handle, int io_fd
     unsigned char *region_base = NULL;
 
     uint32_t nr_pfns, rec_size, nr_vcpus;
-    unsigned long *page_array = NULL;
 
     /* power of 2 order of max_pfn */
     int order_nr;
@@ -361,18 +360,12 @@ int xc_hvm_save(int xc_handle, int io_fd
         goto out;
     }
 
-    max_pfn = live_shinfo->arch.max_pfn;
-
     DPRINTF("saved hvm domain info:max_memkb=0x%lx, max_mfn=0x%lx, 
nr_pages=0x%lx\n", info.max_memkb, max_mfn, info.nr_pages); 
 
-    /* nr_pfns: total pages excluding vga acc mem
-     * max_pfn: nr_pfns + 0x20 vga hole(0xa0~0xc0)
-     * getdomaininfo.tot_pages: all the allocated pages for this domain
-     */
     if (live) {
         ERROR("hvm domain doesn't support live migration now.\n");
         goto out;
-
+        
         if (xc_shadow_control(xc_handle, dom,
                               XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
                               NULL, 0, NULL, 0, NULL) < 0) {
@@ -381,6 +374,7 @@ int xc_hvm_save(int xc_handle, int io_fd
         }
 
         /* excludes vga acc mem */
+        /* XXX will need to check whether acceleration is enabled here! */
         nr_pfns = info.nr_pages - 0x800;
 
         last_iter = 0;
@@ -396,8 +390,8 @@ int xc_hvm_save(int xc_handle, int io_fd
             ERROR("HVM Domain appears not to have suspended");
             goto out;
         }
-        nr_pfns = info.nr_pages;
-        DPRINTF("after suspend hvm domain nr_pages=0x%x.\n", nr_pfns);
+
+        nr_pfns = info.nr_pages; 
     }
 
     DPRINTF("after 1st handle hvm domain nr_pfns=0x%x, nr_pages=0x%lx, 
max_memkb=0x%lx, live=%d.\n",
@@ -406,10 +400,15 @@ int xc_hvm_save(int xc_handle, int io_fd
             info.max_memkb,
             live);
 
-    nr_pfns = info.nr_pages;
-
-    /*XXX: caculate the VGA hole*/
-    max_pfn = nr_pfns + 0x20;
+    /* Calculate the highest PFN of "normal" memory:
+     * HVM memory is sequential except for the VGA and MMIO holes, and
+     * we have nr_pfns of it (which now excludes the cirrus video RAM) */
+    max_pfn = nr_pfns; 
+    /* Skip the VGA hole from 0xa0000 to 0xc0000 */
+    max_pfn += 0x20;   
+    /* Skip the MMIO hole: 256MB just below 4GB */
+    if ( max_pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) )
+        max_pfn += (HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT); 
 
     skip_this_iter = 0;/*XXX*/
     /* pretend we sent all the pages last iteration */
@@ -424,7 +423,6 @@ int xc_hvm_save(int xc_handle, int io_fd
     to_send = malloc(BITMAP_SIZE);
     to_skip = malloc(BITMAP_SIZE);
 
-    page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn);
 
     hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0);
     if ( hvm_buf_size == -1 )
@@ -434,7 +432,7 @@ int xc_hvm_save(int xc_handle, int io_fd
     }
     hvm_buf = malloc(hvm_buf_size);
 
-    if (!to_send ||!to_skip ||!page_array ||!hvm_buf) {
+    if (!to_send ||!to_skip ||!hvm_buf) {
         ERROR("Couldn't allocate memory");
         goto out;
     }
@@ -454,23 +452,13 @@ int xc_hvm_save(int xc_handle, int io_fd
 
     analysis_phase(xc_handle, dom, max_pfn, to_skip, 0);
 
-    /* get all the HVM domain pfns */
-    for ( i = 0; i < max_pfn; i++)
-        page_array[i] = i;
-
 
     /* We want zeroed memory so use calloc rather than malloc. */
-    pfn_type  = calloc(MAX_BATCH_SIZE, sizeof(*pfn_type));
     pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(*pfn_batch));
 
-    if ((pfn_type == NULL) || (pfn_batch == NULL)) {
-        ERROR("failed to alloc memory for pfn_type and/or pfn_batch arrays");
+    if (pfn_batch == NULL) {
+        ERROR("failed to alloc memory for pfn_batch array");
         errno = ENOMEM;
-        goto out;
-    }
-
-    if (lock_pages(pfn_type, MAX_BATCH_SIZE * sizeof(*pfn_type))) {
-        ERROR("Unable to lock");
         goto out;
     }
 
@@ -511,16 +499,15 @@ int xc_hvm_save(int xc_handle, int io_fd
             }
 
 
-            /* load pfn_type[] with the mfn of all the pages we're doing in
+            /* load pfn_batch[] with the mfn of all the pages we're doing in
                this batch. */
             for (batch = 0; batch < MAX_BATCH_SIZE && N < max_pfn ; N++) {
 
                 int n = permute(N, max_pfn, order_nr);
 
                 if (debug) {
-                    DPRINTF("%d pfn= %08lx mfn= %08lx %d \n",
-                            iter, (unsigned long)n, page_array[n],
-                            test_bit(n, to_send));
+                    DPRINTF("%d pfn= %08lx %d \n",
+                            iter, (unsigned long)n, test_bit(n, to_send));
                 }
 
                 if (!last_iter && test_bit(n, to_send)&& test_bit(n, to_skip))
@@ -530,10 +517,12 @@ int xc_hvm_save(int xc_handle, int io_fd
                       (test_bit(n, to_send) && last_iter)))
                     continue;
 
-                if (n >= 0xa0 && n < 0xc0) {
-/*                    DPRINTF("get a vga hole pfn= %x.\n", n);*/
+                /* Skip PFNs that aren't really there */
+                if ((n >= 0xa0 && n < 0xc0) /* VGA hole */
+                    || (n >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT)
+                        && n < (1ULL << 32) >> PAGE_SHIFT)) /* 4G MMIO hole */
                     continue;
-                }
+
                 /*
                 ** we get here if:
                 **  1. page is marked to_send & hasn't already been re-dirtied
@@ -541,7 +530,6 @@ int xc_hvm_save(int xc_handle, int io_fd
                 */
 
                 pfn_batch[batch] = n;
-                pfn_type[batch]  = page_array[n];
 
                 batch++;
             }
@@ -573,7 +561,6 @@ int xc_hvm_save(int xc_handle, int io_fd
                 goto out;
             }
 
-
             sent_this_iter += batch;
 
             munmap(region_base, batch*PAGE_SIZE);
@@ -723,9 +710,6 @@ int xc_hvm_save(int xc_handle, int io_fd
     }
 
     free(hvm_buf);
-    free(page_array);
-
-    free(pfn_type);
     free(pfn_batch);
     free(to_send);
     free(to_skip);
diff -r fbc233a1dc53 -r f9277e2548b5 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h    Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/libxc/xenguest.h    Thu Feb 08 17:27:30 2007 +0000
@@ -58,8 +58,7 @@ int xc_linux_restore(int xc_handle, int 
  */
 int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom,
                       unsigned long nr_pfns, unsigned int store_evtchn,
-                      unsigned long *store_mfn, unsigned int console_evtchn,
-                      unsigned long *console_mfn,
+                      unsigned long *store_mfn, 
                       unsigned int pae, unsigned int apic);
 
 /**
diff -r fbc233a1dc53 -r f9277e2548b5 tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c  Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/libxc/xg_private.c  Thu Feb 08 17:27:30 2007 +0000
@@ -210,8 +210,7 @@ __attribute__((weak))
 __attribute__((weak)) 
 int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom,
                    unsigned long nr_pfns, unsigned int store_evtchn,
-                   unsigned long *store_mfn, unsigned int console_evtchn,
-                   unsigned long *console_mfn,
+                   unsigned long *store_mfn,
                    unsigned int pae, unsigned int apic)
 {
     errno = ENOSYS;
diff -r fbc233a1dc53 -r f9277e2548b5 tools/misc/Makefile
--- a/tools/misc/Makefile       Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/misc/Makefile       Thu Feb 08 17:27:30 2007 +0000
@@ -9,7 +9,7 @@ CFLAGS   += $(INCLUDES)
 
 HDRS     = $(wildcard *.h)
 
-TARGETS  = xenperf xc_shadow
+TARGETS  = xenperf xc_shadow xen-detect
 
 INSTALL_BIN  = $(TARGETS) xencons
 INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf
@@ -41,5 +41,5 @@ clean:
 %.o: %.c $(HDRS) Makefile
        $(CC) -c $(CFLAGS) -o $@ $<
 
-$(TARGETS): %: %.o Makefile
+xenperf xc_shadow: %: %.o Makefile
        $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
diff -r fbc233a1dc53 -r f9277e2548b5 tools/misc/xen-detect.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/misc/xen-detect.c   Thu Feb 08 17:27:30 2007 +0000
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * xen_detect.c
+ * 
+ * Simple GNU C / POSIX application to detect execution on Xen VMM platform.
+ * 
+ * Copyright (c) 2007, XenSource Inc.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static int pv_context;
+
+static void cpuid(uint32_t idx,
+                  uint32_t *eax,
+                  uint32_t *ebx,
+                  uint32_t *ecx,
+                  uint32_t *edx)
+{
+    asm volatile (
+        "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid"
+        : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+        : "0" (idx), "1" (pv_context) );
+}
+
+static int check_for_xen(void)
+{
+    uint32_t eax, ebx, ecx, edx;
+    char signature[13];
+
+    cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
+    *(uint32_t *)(signature + 0) = ebx;
+    *(uint32_t *)(signature + 4) = ecx;
+    *(uint32_t *)(signature + 8) = edx;
+    signature[12] = '\0';
+
+    if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
+        return 0;
+
+    cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
+    printf("Running in %s context on Xen v%d.%d.\n",
+           pv_context ? "PV" : "HVM", (uint16_t)(eax >> 16), (uint16_t)eax);
+    return 1;
+}
+
+int main(void)
+{
+    pid_t pid;
+    int status;
+    uint32_t dummy;
+
+    /* Check for execution in HVM context. */
+    if ( check_for_xen() )
+        return 0;
+
+    /* Now we check for execution in PV context. */
+    pv_context = 1;
+
+    /*
+     * Fork a child to test the paravirtualised CPUID instruction.
+     * If executed outside Xen PV context, the extended opcode will fault.
+     */
+    pid = fork();
+    switch ( pid )
+    {
+    case 0:
+        /* Child: test paravirtualised CPUID opcode and then exit cleanly. */
+        cpuid(0x40000000, &dummy, &dummy, &dummy, &dummy);
+        exit(0);
+    case -1:
+        fprintf(stderr, "Fork failed.\n");
+        return 0;
+    }
+
+    /*
+     * Parent waits for child to terminate and checks for clean exit.
+     * Only if the exit is clean is it safe for us to try the extended CPUID.
+     */
+    waitpid(pid, &status, 0);
+    if ( WIFEXITED(status) && check_for_xen() )
+        return 0;
+
+    printf("Not running on Xen.\n");
+    return 0;
+}
diff -r fbc233a1dc53 -r f9277e2548b5 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/python/xen/xend/XendCheckpoint.py   Thu Feb 08 17:27:30 2007 +0000
@@ -239,8 +239,11 @@ def restore(xd, fd, dominfo = None, paus
 
         forkHelper(cmd, fd, handler.handler, True)
 
-        if handler.store_mfn is None or handler.console_mfn is None:
-            raise XendError('Could not read store/console MFN')
+        if handler.store_mfn is None:
+            raise XendError('Could not read store MFN')
+
+        if not is_hvm and handler.console_mfn is None:
+            raise XendError('Could not read console MFN')        
 
         dominfo.waitForDevices() # Wait for backends to set up
         if not paused:
diff -r fbc233a1dc53 -r f9277e2548b5 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/python/xen/xend/XendConfig.py       Thu Feb 08 17:27:30 2007 +0000
@@ -1148,6 +1148,47 @@ class XendConfig(dict):
         # no valid device to add
         return ''
 
+    def phantom_device_add(self, dev_type, cfg_xenapi = None,
+                   target = None):
+        """Add a phantom tap device configuration in XenAPI struct format.
+        """
+
+        if target == None:
+            target = self
+        
+        if dev_type not in XendDevices.valid_devices() and \
+           dev_type not in XendDevices.pseudo_devices():        
+            raise XendConfigError("XendConfig: %s not a valid device type" %
+                            dev_type)
+
+        if cfg_xenapi == None:
+            raise XendConfigError("XendConfig: device_add requires some "
+                                  "config.")
+
+        if cfg_xenapi:
+            log.debug("XendConfig.phantom_device_add: %s" % str(cfg_xenapi))
+ 
+        if cfg_xenapi:
+            dev_info = {}            
+            if dev_type in ('vbd', 'tap'):
+                if dev_type == 'vbd':
+                    dev_info['uname'] = cfg_xenapi.get('image', '')
+                    dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
+                elif dev_type == 'tap':
+                    if cfg_xenapi.get('image').find('tap:') == -1:
+                        dev_info['uname'] = 'tap:qcow:%s' % 
cfg_xenapi.get('image')
+                    dev_info['dev'] =  '/dev/%s' % cfg_xenapi.get('device')
+                    dev_info['uname'] = cfg_xenapi.get('image')
+                dev_info['mode'] = cfg_xenapi.get('mode')
+                dev_info['backend'] = '0'
+                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+                dev_info['uuid'] = dev_uuid
+                self['devices'][dev_uuid] = (dev_type, dev_info)
+                self['vbd_refs'].append(dev_uuid)
+                return dev_uuid
+
+        return ''
+
     def console_add(self, protocol, location, other_config = {}):
         dev_uuid = uuid.createString()
         if protocol == 'vt100':
diff -r fbc233a1dc53 -r f9277e2548b5 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/python/xen/xend/XendDomain.py       Thu Feb 08 17:27:30 2007 +0000
@@ -800,7 +800,10 @@ class XendDomain:
                                 "support.")
 
             path = self._managed_check_point_path(dom_uuid)
-            fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
+            oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
+            if hasattr(os, "O_LARGEFILE"):
+                oflags |= os.O_LARGEFILE
+            fd = os.open(path, oflags)
             try:
                 # For now we don't support 'live checkpoint' 
                 XendCheckpoint.save(fd, dominfo, False, False, path)
@@ -840,8 +843,11 @@ class XendDomain:
                 # Restore that replaces the existing XendDomainInfo
                 try:
                     log.debug('Current DomainInfo state: %d' % dominfo.state)
+                    oflags = os.O_RDONLY
+                    if hasattr(os, "O_LARGEFILE"):
+                        oflags |= os.O_LARGEFILE
                     XendCheckpoint.restore(self,
-                                           os.open(chkpath, os.O_RDONLY),
+                                           os.open(chkpath, oflags),
                                            dominfo,
                                            paused = start_paused)
                     os.unlink(chkpath)
@@ -1009,7 +1015,10 @@ class XendDomain:
         @raise XendError: Failure to restore domain
         """
         try:
-            fd = os.open(src, os.O_RDONLY)
+            oflags = os.O_RDONLY
+            if hasattr(os, "O_LARGEFILE"):
+                oflags |= os.O_LARGEFILE
+            fd = os.open(src, oflags)
             try:
                 return self.domain_restore_fd(fd, paused=paused)
             finally:
@@ -1193,7 +1202,10 @@ class XendDomain:
             if dominfo.getDomid() == DOM0_ID:
                 raise XendError("Cannot save privileged domain %i" % domid)
 
-            fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
+            oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
+            if hasattr(os, "O_LARGEFILE"):
+                oflags |= os.O_LARGEFILE
+            fd = os.open(dst, oflags)
             try:
                 # For now we don't support 'live checkpoint' 
                 XendCheckpoint.save(fd, dominfo, False, False, dst)
diff -r fbc233a1dc53 -r f9277e2548b5 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Feb 08 17:27:30 2007 +0000
@@ -1416,7 +1416,7 @@ class XendDomainInfo:
                                       self.info['image'],
                                       self.info['devices'])
 
-            localtime = self.info.get('localtime', False)
+            localtime = self.info.get('platform_localtime', False)
             if localtime:
                 xc.domain_set_time_offset(self.domid)
 
@@ -1565,18 +1565,53 @@ class XendDomainInfo:
     # VM Destroy
     # 
 
+    def _prepare_phantom_paths(self):
+        # get associated devices to destroy
+        # build list of phantom devices to be removed after normal devices
+        plist = []
+        from xen.xend.xenstore.xstransact import xstransact
+        t = xstransact("%s/device/vbd" % GetDomainPath(self.domid))
+        for dev in t.list():
+            backend_phantom_vbd = 
xstransact.Read("%s/device/vbd/%s/phantom_vbd" \
+                                  % (self.dompath, dev))
+            if backend_phantom_vbd is not None:
+                frontend_phantom_vbd =  xstransact.Read("%s/frontend" \
+                                  % backend_phantom_vbd)
+                plist.append(backend_phantom_vbd)
+                plist.append(frontend_phantom_vbd)
+        return plist
+
+    def _cleanup_phantom_devs(self, plist):
+        # remove phantom devices
+        if not plist == []:
+            time.sleep(2)
+        for paths in plist:
+            if paths.find('backend') != -1:
+                from xen.xend.server import DevController
+                # Modify online status /before/ updating state (latter is 
watched by
+                # drivers, so this ordering avoids a race).
+                xstransact.Write(paths, 'online', "0")
+                xstransact.Write(paths, 'state', 
str(DevController.xenbusState['Closing']))
+            # force
+            xstransact.Remove(paths)
+
     def destroy(self):
         """Cleanup VM and destroy domain.  Nothrow guarantee."""
 
         log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
+
+        paths = self._prepare_phantom_paths()
 
         self._cleanupVm()
         if self.dompath is not None:
             self.destroyDomain()
 
+        self._cleanup_phantom_devs(paths)
 
     def destroyDomain(self):
         log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
+
+        paths = self._prepare_phantom_paths()
 
         try:
             if self.domid is not None:
@@ -1591,7 +1626,7 @@ class XendDomainInfo:
         XendDomain.instance().remove_domain(self)
 
         self.cleanupDomain()
-
+        self._cleanup_phantom_devs(paths)
 
     def resumeDomain(self):
         log.debug("XendDomainInfo.resumeDomain(%s)", str(self.domid))
@@ -2211,6 +2246,25 @@ class XendDomainInfo:
 
         return dev_uuid
 
+    def create_phantom_vbd_with_vdi(self, xenapi_vbd, vdi_image_path):
+        """Create a VBD using a VDI from XendStorageRepository.
+
+        @param xenapi_vbd: vbd struct from the Xen API
+        @param vdi_image_path: VDI UUID
+        @rtype: string
+        @return: uuid of the device
+        """
+        xenapi_vbd['image'] = vdi_image_path
+        dev_uuid = self.info.phantom_device_add('tap', cfg_xenapi = xenapi_vbd)
+        if not dev_uuid:
+            raise XendError('Failed to create device')
+
+        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+            _, config = self.info['devices'][dev_uuid]
+            config['devid'] = 
self.getDeviceController('tap').createDevice(config)
+
+        return config['devid']
+
     def create_vif(self, xenapi_vif):
         """Create VIF device from the passed struct in Xen API format.
 
diff -r fbc233a1dc53 -r f9277e2548b5 
tools/python/xen/xend/server/BlktapController.py
--- a/tools/python/xen/xend/server/BlktapController.py  Wed Feb 07 10:46:18 
2007 -0700
+++ b/tools/python/xen/xend/server/BlktapController.py  Thu Feb 08 17:27:30 
2007 +0000
@@ -2,7 +2,10 @@
 
 
 from xen.xend.server.blkif import BlkifController
+from xen.xend.XendLogging import log
 
+phantomDev = 0;
+phantomId = 0;
 
 class BlktapController(BlkifController):
     def __init__(self, vm):
@@ -12,3 +15,62 @@ class BlktapController(BlkifController):
         """@see DevController#frontendRoot"""
         
         return "%s/device/vbd" % self.vm.getDomainPath()
+
+    def getDeviceDetails(self, config):
+        (devid, back, front) = BlkifController.getDeviceDetails(self, config)
+
+        phantomDevid = 0
+        wrapped = False
+
+        try:
+            imagetype = self.vm.info['image']['type']
+        except:
+            imagetype = ""
+
+        if imagetype == 'hvm':
+            tdevname = back['dev']
+            index = ['c', 'd', 'e', 'f', 'g', 'h', 'i', \
+                     'j', 'l', 'm', 'n', 'o', 'p']
+            while True:
+                global phantomDev
+                global phantomId
+                import os, stat
+
+                phantomId = phantomId + 1
+                if phantomId == 16:
+                    if index[phantomDev] == index[-1]:
+                        if wrapped:
+                            raise VmError(" No loopback block \
+                                       devices are available. ")
+                        wrapped = True
+                        phantomDev = 0
+                    else:
+                        phantomDev = phantomDev + 1
+                    phantomId = 1
+                devname = 'xvd%s%d' % (index[phantomDev], phantomId)
+                try:
+                    info = os.stat('/dev/%s' % devname)
+                except:
+                    break
+
+            vbd = { 'mode': 'w', 'device': devname }
+            fn = 'tap:%s' % back['params']
+
+            # recurse ... by creating the vbd, then fallthrough
+            # and finish creating the original device
+
+            from xen.xend import XendDomain
+            dom0 = XendDomain.instance().privilegedDomain()
+            phantomDevid = dom0.create_phantom_vbd_with_vdi(vbd, fn)
+            # we need to wait for this device at a higher level
+            # the vbd that gets created will have a link to us
+            # and will let them do it there
+
+        # add a hook to point to the phantom device,
+        # root path is always the same (dom0 tap)
+        if phantomDevid != 0:
+            front['phantom_vbd'] = '/local/domain/0/backend/tap/0/%s' \
+                                   % str(phantomDevid)
+
+        return (devid, back, front)
+
diff -r fbc233a1dc53 -r f9277e2548b5 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Wed Feb 07 10:46:18 
2007 -0700
+++ b/tools/python/xen/xend/server/DevController.py     Thu Feb 08 17:27:30 
2007 +0000
@@ -153,9 +153,9 @@ class DevController:
         log.debug("Waiting for %s.", devid)
 
         if not self.hotplug:
-            return 
-        
-        status = self.waitForBackend(devid)
+            return
+
+        (status, err) = self.waitForBackend(devid)
 
         if status == Timeout:
             self.destroyDevice(devid, False)
@@ -165,25 +165,22 @@ class DevController:
 
         elif status == Error:
             self.destroyDevice(devid, False)
-            raise VmError("Device %s (%s) could not be connected. "
-                          "Backend device not found." %
-                          (devid, self.deviceClass))
-
+            if err is None:
+                raise VmError("Device %s (%s) could not be connected. "
+                              "Backend device not found." %
+                              (devid, self.deviceClass))
+            else:
+                raise VmError("Device %s (%s) could not be connected. "
+                              "%s" % (devid, self.deviceClass, err))
         elif status == Missing:
             # Don't try to destroy the device; it's already gone away.
             raise VmError("Device %s (%s) could not be connected. "
                           "Device not found." % (devid, self.deviceClass))
 
         elif status == Busy:
-            err = None
-            frontpath = self.frontendPath(devid)
-            backpath = xstransact.Read(frontpath, "backend")
-            if backpath:
-                err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
-            if not err:
+            self.destroyDevice(devid, False)
+            if err is None:
                 err = "Busy."
-                
-            self.destroyDevice(devid, False)
             raise VmError("Device %s (%s) could not be connected.\n%s" %
                           (devid, self.deviceClass, err))
 
@@ -476,19 +473,36 @@ class DevController:
     def waitForBackend(self, devid):
 
         frontpath = self.frontendPath(devid)
+        # lookup a phantom 
+        phantomPath = xstransact.Read(frontpath, 'phantom_vbd')
+        if phantomPath is not None:
+            log.debug("Waiting for %s's phantom %s.", devid, phantomPath)
+            statusPath = phantomPath + '/' + HOTPLUG_STATUS_NODE
+            ev = Event()
+            result = { 'status': Timeout }
+            xswatch(statusPath, hotplugStatusCallback, ev, result)
+            ev.wait(DEVICE_CREATE_TIMEOUT)
+            err = xstransact.Read(statusPath, HOTPLUG_ERROR_NODE)
+            if result['status'] != 'Connected':
+                return (result['status'], err)
+            
         backpath = xstransact.Read(frontpath, "backend")
+
 
         if backpath:
             statusPath = backpath + '/' + HOTPLUG_STATUS_NODE
             ev = Event()
             result = { 'status': Timeout }
-            
+
             xswatch(statusPath, hotplugStatusCallback, ev, result)
 
             ev.wait(DEVICE_CREATE_TIMEOUT)
-            return result['status']
-        else:
-            return Missing
+
+            err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
+
+            return (result['status'], err)
+        else:
+            return (Missing, None)
 
 
     def backendPath(self, backdom, devid):
diff -r fbc233a1dc53 -r f9277e2548b5 tools/xcutils/xc_restore.c
--- a/tools/xcutils/xc_restore.c        Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/xcutils/xc_restore.c        Thu Feb 08 17:27:30 2007 +0000
@@ -45,14 +45,15 @@ main(int argc, char **argv)
          /* pass the memsize to xc_hvm_restore to find the store_mfn */
         store_mfn = hvm;
         ret = xc_hvm_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn,
-                &store_mfn, console_evtchn, &console_mfn, pae, apic);
+                &store_mfn, pae, apic);
     } else 
         ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn,
                 &store_mfn, console_evtchn, &console_mfn);
 
     if (ret == 0) {
        printf("store-mfn %li\n", store_mfn);
-       printf("console-mfn %li\n", console_mfn);
+        if (!hvm)
+            printf("console-mfn %li\n", console_mfn);
        fflush(stdout);
     }
 
diff -r fbc233a1dc53 -r f9277e2548b5 tools/xenfb/vncfb.c
--- a/tools/xenfb/vncfb.c       Wed Feb 07 10:46:18 2007 -0700
+++ b/tools/xenfb/vncfb.c       Thu Feb 08 17:27:30 2007 +0000
@@ -57,7 +57,8 @@ static void *kbd_layout;
 static void *kbd_layout;
 
 static int btnmap[] = {
-       BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_FORWARD, BTN_BACK
+       BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE,
+       BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK
 };
 
 static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
@@ -73,11 +74,12 @@ static void on_kbd_event(rfbBool down, r
         */
        rfbScreenInfoPtr server = cl->screen;
        struct xenfb *xenfb = server->screenData;
-
-       if( keycode >= 'A' && keycode <= 'Z' )
+       int scancode;
+
+       if (keycode >= 'A' && keycode <= 'Z')
                keycode += 'a' - 'A';
 
-       int scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
+       scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
        if (scancode == 0)
                return;
        if (xenfb_send_key(xenfb, down, scancode) < 0)
diff -r fbc233a1dc53 -r f9277e2548b5 xen/arch/powerpc/machine_kexec.c
--- a/xen/arch/powerpc/machine_kexec.c  Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/arch/powerpc/machine_kexec.c  Thu Feb 08 17:27:30 2007 +0000
@@ -19,6 +19,11 @@ void machine_reboot_kexec(xen_kexec_imag
     printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
 }
 
+void machine_kexec(xen_kexec_image_t *image)
+{
+    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+}
+
 /*
  * Local variables:
  * mode: C
diff -r fbc233a1dc53 -r f9277e2548b5 xen/arch/x86/crash.c
--- a/xen/arch/x86/crash.c      Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/arch/x86/crash.c      Thu Feb 08 17:27:30 2007 +0000
@@ -11,7 +11,6 @@
 #include <asm/atomic.h>
 #include <asm/elf.h>
 #include <asm/percpu.h>
-#include <asm/kexec.h>
 #include <xen/types.h>
 #include <xen/irq.h>
 #include <asm/ipi.h>
diff -r fbc233a1dc53 -r f9277e2548b5 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/arch/x86/hvm/hvm.c    Thu Feb 08 17:27:30 2007 +0000
@@ -106,7 +106,6 @@ void hvm_migrate_timers(struct vcpu *v)
     pit_migrate_timers(v);
     rtc_migrate_timers(v);
     hpet_migrate_timers(v);
-    pmtimer_migrate_timers(v);
     if ( vcpu_vlapic(v)->pt.enabled )
         migrate_timer(&vcpu_vlapic(v)->pt.timer, v->processor);
 }
@@ -170,7 +169,6 @@ void hvm_domain_destroy(struct domain *d
 {
     pit_deinit(d);
     rtc_deinit(d);
-    pmtimer_deinit(d);
     hpet_deinit(d);
 
     if ( d->arch.hvm_domain.shared_page_va )
diff -r fbc233a1dc53 -r f9277e2548b5 xen/arch/x86/hvm/pmtimer.c
--- a/xen/arch/x86/hvm/pmtimer.c        Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/arch/x86/hvm/pmtimer.c        Thu Feb 08 17:27:30 2007 +0000
@@ -1,17 +1,6 @@
 #include <asm/hvm/vpt.h>
 #include <asm/hvm/io.h>
 #include <asm/hvm/support.h>
-
-#define TMR_STS (1 << 0)
-static void pmt_update_status(void *opaque)
-{
-   PMTState *s = opaque;
-   s->pm1_status |= TMR_STS;
-
-   /* TODO: When TMR_EN == 1, generate a SCI event */
-
-   set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
-}
 
 static int handle_pmt_io(ioreq_t *p)
 {
@@ -30,42 +19,62 @@ static int handle_pmt_io(ioreq_t *p)
         /* PM_TMR_BLK is read-only */
         return 1;
     } else if (p->dir == 1) { /* read */
+        /* Set the correct value in the timer, accounting for time
+         * elapsed since the last time we did that. */
         curr_gtime = hvm_get_guest_time(s->vcpu);
-        s->pm1_timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
-        p->data = s->pm1_timer;
+        s->pm.timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
+        p->data = s->pm.timer;
         s->last_gtime = curr_gtime;
         return 1;
     }
     return 0;
 }
 
+static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
+{
+    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+    uint32_t x;
+
+    /* Update the counter to the guest's current time.  We always save
+     * with the domain paused, so the saved time should be after the
+     * last_gtime, but just in case, make sure we only go forwards */
+    x = ((s->vcpu->arch.hvm_vcpu.guest_time - s->last_gtime) * s->scale) >> 32;
+    if ( x < 1UL<<31 )
+        s->pm.timer += x;
+    return hvm_save_entry(PMTIMER, 0, h, &s->pm);
+}
+
+static int pmtimer_load(struct domain *d, hvm_domain_context_t *h)
+{
+    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+
+    /* Reload the counter */
+    if ( hvm_load_entry(PMTIMER, h, &s->pm) )
+        return -EINVAL;
+
+    /* Calculate future counter values from now. */
+    s->last_gtime = hvm_get_guest_time(s->vcpu);
+    
+    return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(PMTIMER, pmtimer_save, pmtimer_load, 
+                          1, HVMSR_PER_DOM);
+
+
 void pmtimer_init(struct vcpu *v, int base)
 {
     PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
 
-    s->pm1_timer = 0;
-    s->pm1_status = 0;
+    s->pm.timer = 0;
     s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
     s->vcpu = v;
 
-    init_timer(&s->timer, pmt_update_status, s, v->processor);
-    /* ACPI supports a 32-bit power management timer */
-    set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
-    
+    /* Not implemented: we should set TMR_STS (bit 0 of PM1a_STS) every
+     * time the timer's top bit flips, and generate an SCI if TMR_EN
+     * (bit 0 of PM1a_EN) is set.  For now, those registers are in
+     * qemu-dm, and we just calculate the timer's value on demand. */  
+
     register_portio_handler(v->domain, base, 4, handle_pmt_io);
 }
 
-void pmtimer_migrate_timers(struct vcpu *v)
-{
-    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
-
-    if (vpmt->vcpu == v)
-        migrate_timer(&vpmt->timer, v->processor);
-}
-
-void pmtimer_deinit(struct domain *d)
-{
-    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
-
-    kill_timer(&s->timer);
-}
diff -r fbc233a1dc53 -r f9277e2548b5 xen/arch/x86/machine_kexec.c
--- a/xen/arch/x86/machine_kexec.c      Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/arch/x86/machine_kexec.c      Thu Feb 08 17:27:30 2007 +0000
@@ -15,10 +15,14 @@
 #include <xen/types.h>
 #include <xen/console.h>
 #include <xen/kexec.h>
-#include <asm/kexec.h>
 #include <xen/domain_page.h>
 #include <asm/fixmap.h>
 #include <asm/hvm/hvm.h>
+
+typedef void (*relocate_new_kernel_t)(
+                unsigned long indirection_page,
+                unsigned long *page_list,
+                unsigned long start_address);
 
 int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
 {
@@ -40,8 +44,26 @@ int machine_kexec_load(int type, int slo
         else
         {
             /* Odd pages: va for previous ma. */
-            set_fixmap(fix_base + (k >> 1), prev_ma);
-            image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
+            if ( IS_COMPAT(dom0) )
+            {
+
+                /*
+                 * The compatability bounce code sets up a page table
+                 * with a 1-1 mapping of the first 1G of memory so
+                 * VA==PA here.
+                 *
+                 * This Linux purgatory code still sets up separate
+                 * high and low mappings on the control page (entries
+                 * 0 and 1) but it is harmless if they are equal since
+                 * that PT is not live at the time.
+                 */
+                image->page_list[k] = prev_ma;
+            }
+            else
+            {
+                set_fixmap(fix_base + (k >> 1), prev_ma);
+                image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
+            }
         }
     }
 
@@ -94,6 +116,31 @@ void machine_reboot_kexec(xen_kexec_imag
     BUG();
 }
 
+void machine_kexec(xen_kexec_image_t *image)
+{
+#ifdef CONFIG_COMPAT
+    if ( IS_COMPAT(dom0) )
+    {
+        extern void compat_machine_kexec(unsigned long rnk,
+                                         unsigned long indirection_page,
+                                         unsigned long *page_list,
+                                         unsigned long start_address);
+        compat_machine_kexec(image->page_list[1],
+                             image->indirection_page,
+                             image->page_list,
+                             image->start_address);
+    }
+    else
+#endif
+    {
+        relocate_new_kernel_t rnk;
+
+        rnk = (relocate_new_kernel_t) image->page_list[1];
+        (*rnk)(image->indirection_page, image->page_list,
+               image->start_address);
+    }
+}
+
 /*
  * Local variables:
  * mode: C
diff -r fbc233a1dc53 -r f9277e2548b5 xen/arch/x86/x86_64/Makefile
--- a/xen/arch/x86/x86_64/Makefile      Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/arch/x86/x86_64/Makefile      Thu Feb 08 17:27:30 2007 +0000
@@ -1,4 +1,5 @@ obj-y += entry.o
 obj-y += entry.o
+obj-y += compat_kexec.o
 obj-y += gpr_switch.o
 obj-y += mm.o
 obj-y += traps.o
diff -r fbc233a1dc53 -r f9277e2548b5 xen/arch/x86/x86_64/compat_kexec.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/x86_64/compat_kexec.S        Thu Feb 08 17:27:30 2007 +0000
@@ -0,0 +1,126 @@
+/*
+ * Compatibility kexec handler.
+ */
+
+#include <xen/config.h>
+
+#include <asm/asm_defns.h>
+#include <asm/msr.h>
+#include <asm/page.h>
+
+.text
+
+        .code64
+
+ENTRY(compat_machine_kexec)
+        /* x86/64                        x86/32  */
+        /* %rdi - relocate_new_kernel_t  CALL    */
+        /* %rsi - indirection page       4(%esp) */
+        /* %rdx - page_list              8(%esp) */
+        /* %rcx - start address         12(%esp) */
+        /*        cpu has pae           16(%esp) */
+
+        /* Shim the 64 bit page_list into a 32 bit page_list. */
+        mov $12,%r9
+        lea compat_page_list(%rip), %rbx
+1:      dec %r9
+        movl (%rdx,%r9,8),%eax
+        movl %eax,(%rbx,%r9,4)
+        test %r9,%r9
+        jnz 1b
+
+        movq %rbx,%rdx
+        mov $__PAGE_OFFSET,%rbx
+        sub %rbx, %rdx
+
+        /*
+         * Setup an identity mapped region in PML4[0] of idle page
+         * table.
+         */
+        lea idle_pg_table_l3(%rip),%rax
+        sub %rbx,%rax
+        or  $0x63,%rax
+        mov %rax, idle_pg_table(%rip)
+
+        /* Switch to idle page table. */
+        movq $(idle_pg_table - __PAGE_OFFSET), %rax
+        movq %rax, %cr3
+
+        /* Jump to low identity mapping in compatibility mode. */
+        ljmp *compatibility_mode_far(%rip)
+        ud2
+
+compatibility_mode_far:
+        .long compatibility_mode - __PAGE_OFFSET
+        .long __HYPERVISOR_CS32
+
+        .code32
+
+compatibility_mode:
+        /* Setup some sane segments. */
+        movl $__HYPERVISOR_DS32, %eax
+        movl %eax, %ds
+        movl %eax, %es
+        movl %eax, %fs
+        movl %eax, %gs
+        movl %eax, %ss
+
+        /* Push arguments onto stack. */
+        pushl $1   /* 16(%esp) - cpu has pae */
+        pushl %ecx /* 12(%esp) - start address */
+        pushl %edx /*  8(%esp) - page list */
+        pushl %esi /*  4(%esp) - indirection page */
+        pushl %edi /*  0(%esp) - CALL */
+
+        /* Disable paging and therefore leave 64 bit mode. */
+        movl %cr0, %eax
+        andl $~X86_CR0_PG, %eax
+        movl %eax, %cr0
+
+        /* Switch to 32 bit page table. */
+        movl  $compat_pg_table - __PAGE_OFFSET, %eax
+        movl  %eax, %cr3
+
+        /* Clear MSR_EFER[LME], disabling long mode */
+        movl    $MSR_EFER,%ecx
+        rdmsr
+        btcl    $_EFER_LME,%eax
+        wrmsr
+
+        /* Re-enable paging, but only 32 bit mode now. */
+        movl %cr0, %eax
+        orl $X86_CR0_PG, %eax
+        movl %eax, %cr0
+
+        popl %eax
+        call *%eax
+        ud2
+
+compat_page_list:
+        .fill 12,4,0
+
+        .align 32,0
+
+        /*
+         * These compat page tables contain an identity mapping of the
+         * first 1G of the physical address space.
+         */
+compat_pg_table:
+        .long compat_pg_table_l2 + 0*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
+        .long 0, 0
+        .long 0, 0
+        .long 0, 0
+
+        .align 4096,0
+
+compat_pg_table_l2:
+        .macro identmap from=0, count=512
+        .if \count-1
+        identmap "(\from+0)","(\count/2)"
+        identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
+        .else
+        .quad 0x00000000000000e3 + \from
+        .endif
+        .endm
+
+        identmap
diff -r fbc233a1dc53 -r f9277e2548b5 xen/common/kexec.c
--- a/xen/common/kexec.c        Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/common/kexec.c        Thu Feb 08 17:27:30 2007 +0000
@@ -6,7 +6,6 @@
  * - Magnus Damm <magnus@xxxxxxxxxxxxx>
  */
 
-#include <asm/kexec.h>
 #include <xen/lib.h>
 #include <xen/ctype.h>
 #include <xen/errno.h>
diff -r fbc233a1dc53 -r f9277e2548b5 xen/common/memory.c
--- a/xen/common/memory.c       Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/common/memory.c       Thu Feb 08 17:27:30 2007 +0000
@@ -175,11 +175,13 @@ int guest_remove_page(struct domain *d, 
 
     if ( unlikely(!page_is_removable(page)) )
     {
+        shadow_drop_references(d, page);
         /* We'll make this a guest-visible error in future, so take heed! */
-        gdprintk(XENLOG_INFO, "Dom%d freeing in-use page %lx (pseudophys %lx):"
-                " count=%lx type=%lx\n",
-                d->domain_id, mfn, get_gpfn_from_mfn(mfn),
-                (unsigned long)page->count_info, page->u.inuse.type_info);
+        if ( !page_is_removable(page) )
+            gdprintk(XENLOG_INFO, "Dom%d freeing in-use page %lx "
+                     "(pseudophys %lx): count=%lx type=%lx\n",
+                     d->domain_id, mfn, get_gpfn_from_mfn(mfn),
+                     (unsigned long)page->count_info, page->u.inuse.type_info);
     }
 
     guest_physmap_remove_page(d, gmfn, mfn);
diff -r fbc233a1dc53 -r f9277e2548b5 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/drivers/char/console.c        Thu Feb 08 17:27:30 2007 +0000
@@ -223,7 +223,7 @@ int console_steal(int handle, void (*fn)
     if ( (handle == -1) || (handle != sercon_handle) )
         return 0;
 
-    if ( serial_steal_fn == NULL )
+    if ( serial_steal_fn != NULL )
         return -EBUSY;
 
     serial_steal_fn = fn;
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/asm-ia64/kexec.h
--- a/xen/include/asm-ia64/kexec.h      Wed Feb 07 10:46:18 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#ifndef __IA64_KEXEC_H__
-#define __IA64_KEXEC_H__
-
-#include <xen/lib.h>       /* for printk() used in stub */
-#include <xen/types.h>
-#include <public/xen.h>
-#include <xen/kexec.h>
-
-static inline void machine_kexec(xen_kexec_image_t *image)
-{
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-}
-
-#endif /* __IA64_KEXEC_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/asm-powerpc/kexec.h
--- a/xen/include/asm-powerpc/kexec.h   Wed Feb 07 10:46:18 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#ifndef _ASM_KEXEC_H__
-#define _ASM_KEXEC_H__
-
-#include <xen/lib.h>       /* for printk() used in stub */
-#include <xen/types.h>
-#include <public/xen.h>
-#include <xen/kexec.h>
-
-static inline void machine_kexec(xen_kexec_image_t *image)
-{
-    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-}
-
-#endif /* _ASM_KEXEC_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h      Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/include/asm-x86/config.h      Thu Feb 08 17:27:30 2007 +0000
@@ -145,9 +145,9 @@
  * Compatibility guest area layout:
  *  0x0000000000000000 - 0x00000000f57fffff [3928MB,            PML4:0]
  *    Guest-defined use.
- *  0x0000000f58000000 - 0x00000000ffffffff [168MB,             PML4:0]
+ *  0x00000000f5800000 - 0x00000000ffffffff [168MB,             PML4:0]
  *    Read-only machine-to-phys translation table (GUEST ACCESSIBLE).
- *  0x0000000000000000 - 0x00000000ffffffff [508GB,             PML4:0]
+ *  0x0000000100000000 - 0x0000007fffffffff [508GB,             PML4:0]
  *    Unused.
  *  0x0000008000000000 - 0x000000ffffffffff [512GB, 2^39 bytes, PML4:1]
  *    Hypercall argument translation area.
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/include/asm-x86/hvm/vpt.h     Thu Feb 08 17:27:30 2007 +0000
@@ -94,14 +94,12 @@ typedef struct RTCState {
     struct periodic_time pt;
 } RTCState;
 
-#define FREQUENCE_PMTIMER  3579545
+#define FREQUENCE_PMTIMER  3579545  /* Timer should run at 3.579545 MHz */
 typedef struct PMTState {
-    uint32_t pm1_timer;
-    uint32_t pm1_status;
-    uint64_t last_gtime;
-    struct timer timer;
-    uint64_t scale;
-    struct vcpu *vcpu;
+    struct hvm_hw_pmtimer pm;   /* 32bit timer value */
+    struct vcpu *vcpu;          /* Keeps sync with this vcpu's guest-time */
+    uint64_t last_gtime;        /* Last (guest) time we updated the timer */
+    uint64_t scale;             /* Multiplier to get from tsc to timer ticks */
 } PMTState;
 
 struct pl_time {    /* platform time */
@@ -134,8 +132,6 @@ void rtc_deinit(struct domain *d);
 void rtc_deinit(struct domain *d);
 int is_rtc_periodic_irq(void *opaque);
 void pmtimer_init(struct vcpu *v, int base);
-void pmtimer_migrate_timers(struct vcpu *v);
-void pmtimer_deinit(struct domain *d);
 
 void hpet_migrate_timers(struct vcpu *v);
 void hpet_init(struct vcpu *v);
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/asm-x86/kexec.h
--- a/xen/include/asm-x86/kexec.h       Wed Feb 07 10:46:18 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#ifndef __X86_KEXEC_H__
-#define __X86_KEXEC_H__
-
-#ifdef __x86_64__
-#include <asm/x86_64/kexec.h>
-#else
-#include <asm/x86_32/kexec.h>
-#endif
-
-#endif /* __X86_KEXEC_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/include/asm-x86/shadow.h      Thu Feb 08 17:27:30 2007 +0000
@@ -355,8 +355,9 @@ static inline void
 static inline void 
 shadow_drop_references(struct domain *d, struct page_info *p)
 {
-    /* See the comment about locking in sh_remove_all_mappings */
-    sh_remove_all_mappings(d->vcpu[0], _mfn(page_to_mfn(p)));
+    if ( unlikely(shadow_mode_enabled(d)) )
+        /* See the comment about locking in sh_remove_all_mappings */
+        sh_remove_all_mappings(d->vcpu[0], _mfn(page_to_mfn(p)));
 }
 
 /* Remove all shadows of the guest mfn. */
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/asm-x86/x86_32/kexec.h
--- a/xen/include/asm-x86/x86_32/kexec.h        Wed Feb 07 10:46:18 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/******************************************************************************
- * kexec.h
- * 
- * Based heavily on machine_kexec.c and kexec.h from Linux 2.6.19-rc1
- *
- */
-  
-#ifndef __X86_KEXEC_X86_32_H__
-#define __X86_KEXEC_X86_32_H__
-
-#include <xen/types.h>
-#include <xen/kexec.h>
-
-typedef asmlinkage void (*relocate_new_kernel_t)(
-               unsigned long indirection_page,
-               unsigned long page_list,
-               unsigned long start_address,
-               unsigned int has_pae);
-
-static inline void machine_kexec(xen_kexec_image_t *image)
-{
-    relocate_new_kernel_t rnk;
-
-    rnk = (relocate_new_kernel_t) image->page_list[1];
-    (*rnk)(image->indirection_page, (unsigned long)image->page_list, 
-           image->start_address, (unsigned long)cpu_has_pae);
-}
-
-#endif /* __X86_KEXEC_X86_32_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/asm-x86/x86_64/kexec.h
--- a/xen/include/asm-x86/x86_64/kexec.h        Wed Feb 07 10:46:18 2007 -0700
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/******************************************************************************
- * kexec.h
- * 
- * Based heavily on machine_kexec.c and kexec.h from Linux 2.6.19-rc1
- *
- */
-
-#ifndef __X86_64_KEXEC_H__
-#define __X86_64_KEXEC_H__
-  
-#include <xen/types.h>
-#include <xen/kexec.h>
-
-typedef void (*relocate_new_kernel_t)(
-                unsigned long indirection_page,
-                unsigned long page_list,
-                unsigned long start_address);
-
-static inline void machine_kexec(xen_kexec_image_t *image)
-{
-    relocate_new_kernel_t rnk;
-
-    rnk = (relocate_new_kernel_t) image->page_list[1];
-    (*rnk)(image->indirection_page, (unsigned long)image->page_list, 
-           image->start_address);
-}
-
-#endif /* __X86_64_KEXEC_H__ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/include/public/hvm/save.h     Thu Feb 08 17:27:30 2007 +0000
@@ -382,10 +382,20 @@ DECLARE_HVM_SAVE_TYPE(HPET, 12, struct h
 DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
 
 
+/*
+ * PM timer
+ */
+
+struct hvm_hw_pmtimer {
+    uint32_t timer;
+};
+
+DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
+
 /* 
  * Largest type-code in use
  */
-#define HVM_SAVE_CODE_MAX 12
+#define HVM_SAVE_CODE_MAX 13
 
 
 /* 
diff -r fbc233a1dc53 -r f9277e2548b5 xen/include/xen/kexec.h
--- a/xen/include/xen/kexec.h   Wed Feb 07 10:46:18 2007 -0700
+++ b/xen/include/xen/kexec.h   Thu Feb 08 17:27:30 2007 +0000
@@ -25,6 +25,7 @@ void machine_kexec_unload(int type, int 
 void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image);
 void machine_kexec_reserved(xen_kexec_reserve_t *reservation);
 void machine_reboot_kexec(xen_kexec_image_t *image);
+void machine_kexec(xen_kexec_image_t *image);
 void kexec_crash(void);
 void kexec_crash_save_cpu(void);
 crash_xen_info_t *kexec_crash_save_info(void);

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

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