ia64/xen-unstable

changeset 13888:f9277e2548b5

Merge with xen-ia64-unstable.hg.
author kfraser@localhost.localdomain
date Thu Feb 08 17:27:30 2007 +0000 (2007-02-08)
parents fbc233a1dc53 5a1abfefe892
children a68a3c6cac5f
files linux-2.6-xen-sparse/include/asm-i386/a.out.h xen/include/asm-ia64/kexec.h xen/include/asm-powerpc/kexec.h xen/include/asm-x86/kexec.h xen/include/asm-x86/x86_32/kexec.h xen/include/asm-x86/x86_64/kexec.h
line diff
     1.1 --- a/.hgignore	Wed Feb 07 10:46:18 2007 -0700
     1.2 +++ b/.hgignore	Thu Feb 08 17:27:30 2007 +0000
     1.3 @@ -138,6 +138,7 @@
     1.4  ^tools/misc/miniterm/miniterm$
     1.5  ^tools/misc/xc_shadow$
     1.6  ^tools/misc/xen_cpuperf$
     1.7 +^tools/misc/xen-detect$
     1.8  ^tools/misc/xenperf$
     1.9  ^tools/pygrub/build/.*$
    1.10  ^tools/python/build/.*$
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c	Wed Feb 07 10:46:18 2007 -0700
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c	Thu Feb 08 17:27:30 2007 +0000
     2.3 @@ -29,10 +29,12 @@
     2.4  
     2.5  struct xenkbd_info
     2.6  {
     2.7 -	struct input_dev *dev;
     2.8 +	struct input_dev *kbd;
     2.9 +	struct input_dev *ptr;
    2.10  	struct xenkbd_page *page;
    2.11  	int irq;
    2.12  	struct xenbus_device *xbdev;
    2.13 +	char phys[32];
    2.14  };
    2.15  
    2.16  static int xenkbd_remove(struct xenbus_device *);
    2.17 @@ -56,23 +58,36 @@ static irqreturn_t input_handler(int rq,
    2.18  	rmb();			/* ensure we see ring contents up to prod */
    2.19  	for (cons = page->in_cons; cons != prod; cons++) {
    2.20  		union xenkbd_in_event *event;
    2.21 +		struct input_dev *dev;
    2.22  		event = &XENKBD_IN_RING_REF(page, cons);
    2.23  
    2.24 +		dev = info->ptr;
    2.25  		switch (event->type) {
    2.26  		case XENKBD_TYPE_MOTION:
    2.27 -			input_report_rel(info->dev, REL_X, event->motion.rel_x);
    2.28 -			input_report_rel(info->dev, REL_Y, event->motion.rel_y);
    2.29 +			input_report_rel(dev, REL_X, event->motion.rel_x);
    2.30 +			input_report_rel(dev, REL_Y, event->motion.rel_y);
    2.31  			break;
    2.32  		case XENKBD_TYPE_KEY:
    2.33 -			input_report_key(info->dev, event->key.keycode, event->key.pressed);
    2.34 +			dev = NULL;
    2.35 +			if (test_bit(event->key.keycode, info->kbd->keybit))
    2.36 +				dev = info->kbd;
    2.37 +			if (test_bit(event->key.keycode, info->ptr->keybit))
    2.38 +				dev = info->ptr;
    2.39 +			if (dev)
    2.40 +				input_report_key(dev, event->key.keycode,
    2.41 +						 event->key.pressed);
    2.42 +			else
    2.43 +				printk("xenkbd: unhandled keycode 0x%x\n",
    2.44 +				       event->key.keycode);
    2.45  			break;
    2.46  		case XENKBD_TYPE_POS:
    2.47 -			input_report_abs(info->dev, ABS_X, event->pos.abs_x);
    2.48 -			input_report_abs(info->dev, ABS_Y, event->pos.abs_y);
    2.49 +			input_report_abs(dev, ABS_X, event->pos.abs_x);
    2.50 +			input_report_abs(dev, ABS_Y, event->pos.abs_y);
    2.51  			break;
    2.52  		}
    2.53 +		if (dev)
    2.54 +			input_sync(dev);
    2.55  	}
    2.56 -	input_sync(info->dev);
    2.57  	mb();			/* ensure we got ring contents */
    2.58  	page->in_cons = cons;
    2.59  	notify_remote_via_irq(info->irq);
    2.60 @@ -85,7 +100,7 @@ int __devinit xenkbd_probe(struct xenbus
    2.61  {
    2.62  	int ret, i;
    2.63  	struct xenkbd_info *info;
    2.64 -	struct input_dev *input_dev;
    2.65 +	struct input_dev *kbd, *ptr;
    2.66  
    2.67  	info = kzalloc(sizeof(*info), GFP_KERNEL);
    2.68  	if (!info) {
    2.69 @@ -94,6 +109,7 @@ int __devinit xenkbd_probe(struct xenbus
    2.70  	}
    2.71  	dev->dev.driver_data = info;
    2.72  	info->xbdev = dev;
    2.73 +	snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename);
    2.74  
    2.75  	info->page = (void *)__get_free_page(GFP_KERNEL);
    2.76  	if (!info->page)
    2.77 @@ -101,32 +117,52 @@ int __devinit xenkbd_probe(struct xenbus
    2.78  	info->page->in_cons = info->page->in_prod = 0;
    2.79  	info->page->out_cons = info->page->out_prod = 0;
    2.80  
    2.81 -	input_dev = input_allocate_device();
    2.82 -	if (!input_dev)
    2.83 +	/* keyboard */
    2.84 +	kbd = input_allocate_device();
    2.85 +	if (!kbd)
    2.86  		goto error_nomem;
    2.87 -
    2.88 -	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
    2.89 -	input_dev->keybit[LONG(BTN_MOUSE)]
    2.90 -		= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
    2.91 -	/* TODO additional buttons */
    2.92 -	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
    2.93 +	kbd->name = "Xen Virtual Keyboard";
    2.94 +	kbd->phys = info->phys;
    2.95 +	kbd->id.bustype = BUS_PCI;
    2.96 +	kbd->id.vendor = 0x5853;
    2.97 +	kbd->id.product = 0xffff;
    2.98 +	kbd->evbit[0] = BIT(EV_KEY);
    2.99 +	for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
   2.100 +		set_bit(i, kbd->keybit);
   2.101 +	for (i = KEY_OK; i < KEY_MAX; i++)
   2.102 +		set_bit(i, kbd->keybit);
   2.103  
   2.104 -	/* FIXME not sure this is quite right */
   2.105 -	for (i = 0; i < 256; i++)
   2.106 -		set_bit(i, input_dev->keybit);
   2.107 -
   2.108 -	input_dev->name = "Xen Virtual Keyboard/Mouse";
   2.109 -
   2.110 -	input_set_abs_params(input_dev, ABS_X, 0, XENFB_WIDTH, 0, 0);
   2.111 -	input_set_abs_params(input_dev, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
   2.112 -
   2.113 -	ret = input_register_device(input_dev);
   2.114 +	ret = input_register_device(kbd);
   2.115  	if (ret) {
   2.116 -		input_free_device(input_dev);
   2.117 -		xenbus_dev_fatal(dev, ret, "input_register_device");
   2.118 +		input_free_device(kbd);
   2.119 +		xenbus_dev_fatal(dev, ret, "input_register_device(kbd)");
   2.120  		goto error;
   2.121  	}
   2.122 -	info->dev = input_dev;
   2.123 +	info->kbd = kbd;
   2.124 +
   2.125 +	/* pointing device */
   2.126 +	ptr = input_allocate_device();
   2.127 +	if (!ptr)
   2.128 +		goto error_nomem;
   2.129 +	ptr->name = "Xen Virtual Pointer";
   2.130 +	ptr->phys = info->phys;
   2.131 +	ptr->id.bustype = BUS_PCI;
   2.132 +	ptr->id.vendor = 0x5853;
   2.133 +	ptr->id.product = 0xfffe;
   2.134 +	ptr->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
   2.135 +	for (i = BTN_LEFT; i <= BTN_TASK; i++)
   2.136 +		set_bit(i, ptr->keybit);
   2.137 +	ptr->relbit[0] = BIT(REL_X) | BIT(REL_Y);
   2.138 +	input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
   2.139 +	input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
   2.140 +
   2.141 +	ret = input_register_device(ptr);
   2.142 +	if (ret) {
   2.143 +		input_free_device(ptr);
   2.144 +		xenbus_dev_fatal(dev, ret, "input_register_device(ptr)");
   2.145 +		goto error;
   2.146 +	}
   2.147 +	info->ptr = ptr;
   2.148  
   2.149  	ret = xenkbd_connect_backend(dev, info);
   2.150  	if (ret < 0)
   2.151 @@ -155,7 +191,8 @@ static int xenkbd_remove(struct xenbus_d
   2.152  	struct xenkbd_info *info = dev->dev.driver_data;
   2.153  
   2.154  	xenkbd_disconnect_backend(info);
   2.155 -	input_unregister_device(info->dev);
   2.156 +	input_unregister_device(info->kbd);
   2.157 +	input_unregister_device(info->ptr);
   2.158  	free_page((unsigned long)info->page);
   2.159  	kfree(info);
   2.160  	return 0;
     3.1 --- a/linux-2.6-xen-sparse/include/asm-i386/a.out.h	Wed Feb 07 10:46:18 2007 -0700
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,26 +0,0 @@
     3.4 -#ifndef __I386_A_OUT_H__
     3.5 -#define __I386_A_OUT_H__
     3.6 -
     3.7 -struct exec
     3.8 -{
     3.9 -  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
    3.10 -  unsigned a_text;		/* length of text, in bytes */
    3.11 -  unsigned a_data;		/* length of data, in bytes */
    3.12 -  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
    3.13 -  unsigned a_syms;		/* length of symbol table data in file, in bytes */
    3.14 -  unsigned a_entry;		/* start address */
    3.15 -  unsigned a_trsize;		/* length of relocation info for text, in bytes */
    3.16 -  unsigned a_drsize;		/* length of relocation info for data, in bytes */
    3.17 -};
    3.18 -
    3.19 -#define N_TRSIZE(a)	((a).a_trsize)
    3.20 -#define N_DRSIZE(a)	((a).a_drsize)
    3.21 -#define N_SYMSIZE(a)	((a).a_syms)
    3.22 -
    3.23 -#ifdef __KERNEL__
    3.24 -
    3.25 -#define STACK_TOP	(TASK_SIZE - 3*PAGE_SIZE)
    3.26 -
    3.27 -#endif
    3.28 -
    3.29 -#endif /* __A_OUT_GNU_H__ */
     4.1 --- a/linux-2.6-xen-sparse/net/core/skbuff.c	Wed Feb 07 10:46:18 2007 -0700
     4.2 +++ b/linux-2.6-xen-sparse/net/core/skbuff.c	Thu Feb 08 17:27:30 2007 +0000
     4.3 @@ -1897,6 +1897,29 @@ int skb_append_datato_frags(struct sock 
     4.4  }
     4.5  
     4.6  /**
     4.7 + *	skb_pull_rcsum - pull skb and update receive checksum
     4.8 + *	@skb: buffer to update
     4.9 + *	@start: start of data before pull
    4.10 + *	@len: length of data pulled
    4.11 + *
    4.12 + *	This function performs an skb_pull on the packet and updates
    4.13 + *	update the CHECKSUM_HW checksum.  It should be used on receive
    4.14 + *	path processing instead of skb_pull unless you know that the
    4.15 + *	checksum difference is zero (e.g., a valid IP header) or you
    4.16 + *	are setting ip_summed to CHECKSUM_NONE.
    4.17 + */
    4.18 +unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
    4.19 +{
    4.20 +	BUG_ON(len > skb->len);
    4.21 +	skb->len -= len;
    4.22 +	BUG_ON(skb->len < skb->data_len);
    4.23 +	skb_postpull_rcsum(skb, skb->data, len);
    4.24 +	return skb->data += len;
    4.25 +}
    4.26 +
    4.27 +EXPORT_SYMBOL_GPL(skb_pull_rcsum);
    4.28 +
    4.29 +/**
    4.30   *	skb_segment - Perform protocol segmentation on skb.
    4.31   *	@skb: buffer to segment
    4.32   *	@features: features for the output path (see dev->features)
    4.33 @@ -2022,29 +2045,6 @@ err:
    4.34  
    4.35  EXPORT_SYMBOL_GPL(skb_segment);
    4.36  
    4.37 -/**
    4.38 - *	skb_pull_rcsum - pull skb and update receive checksum
    4.39 - *	@skb: buffer to update
    4.40 - *	@start: start of data before pull
    4.41 - *	@len: length of data pulled
    4.42 - *
    4.43 - *	This function performs an skb_pull on the packet and updates
    4.44 - *	update the CHECKSUM_HW checksum.  It should be used on receive
    4.45 - *	path processing instead of skb_pull unless you know that the
    4.46 - *	checksum difference is zero (e.g., a valid IP header) or you
    4.47 - *	are setting ip_summed to CHECKSUM_NONE.
    4.48 - */
    4.49 -unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len)
    4.50 -{
    4.51 -	BUG_ON(len > skb->len);
    4.52 -	skb->len -= len;
    4.53 -	BUG_ON(skb->len < skb->data_len);
    4.54 -	skb_postpull_rcsum(skb, skb->data, len);
    4.55 -	return skb->data += len;
    4.56 -}
    4.57 -
    4.58 -EXPORT_SYMBOL_GPL(skb_pull_rcsum);
    4.59 -
    4.60  void __init skb_init(void)
    4.61  {
    4.62  	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
     5.1 --- a/tools/examples/vif-bridge	Wed Feb 07 10:46:18 2007 -0700
     5.2 +++ b/tools/examples/vif-bridge	Thu Feb 08 17:27:30 2007 +0000
     5.3 @@ -46,6 +46,13 @@ then
     5.4    fi
     5.5  fi
     5.6  
     5.7 +RET=0
     5.8 +ip link show $bridge 1>/dev/null 2>&1 || RET=1
     5.9 +if [ "$RET" -eq 1 ]
    5.10 +then
    5.11 +    fatal "Could not find bridge device $bridge"
    5.12 +fi
    5.13 +
    5.14  case "$command" in
    5.15      online)
    5.16  	setup_bridge_port "$vif"
     6.1 --- a/tools/examples/xen-hotplug-common.sh	Wed Feb 07 10:46:18 2007 -0700
     6.2 +++ b/tools/examples/xen-hotplug-common.sh	Thu Feb 08 17:27:30 2007 +0000
     6.3 @@ -28,14 +28,15 @@ export LANG="POSIX"
     6.4  unset $(set | grep ^LC_ | cut -d= -f1)
     6.5  
     6.6  fatal() {
     6.7 -  xenstore_write "$XENBUS_PATH"/hotplug-status error
     6.8 +  xenstore_write "$XENBUS_PATH/hotplug-error" "$*" \
     6.9 +                 "$XENBUS_PATH/hotplug-status" error
    6.10    log err "$@"
    6.11    exit 1
    6.12  }
    6.13  
    6.14  success() {
    6.15    # Tell DevController that backend is "connected"
    6.16 -  xenstore_write "$XENBUS_PATH"/hotplug-status connected
    6.17 +  xenstore_write "$XENBUS_PATH/hotplug-status" connected
    6.18  }
    6.19  
    6.20  do_or_die() {
     7.1 --- a/tools/ioemu/hw/cirrus_vga.c	Wed Feb 07 10:46:18 2007 -0700
     7.2 +++ b/tools/ioemu/hw/cirrus_vga.c	Thu Feb 08 17:27:30 2007 +0000
     7.3 @@ -3339,6 +3339,10 @@ void pci_cirrus_vga_init(PCIBus *bus, Di
     7.4      pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
     7.5      pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
     7.6      pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
     7.7 +    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
     7.8 +    pci_conf[0x2d] = 0x58;
     7.9 +    pci_conf[0x2e] = 0x01; /* subsystem device */
    7.10 +    pci_conf[0x2f] = 0x00;
    7.11  
    7.12      /* setup VGA */
    7.13      s = &d->cirrus_vga;
     8.1 --- a/tools/ioemu/hw/ide.c	Wed Feb 07 10:46:18 2007 -0700
     8.2 +++ b/tools/ioemu/hw/ide.c	Thu Feb 08 17:27:30 2007 +0000
     8.3 @@ -2502,6 +2502,10 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
     8.4      pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
     8.5      pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
     8.6      pci_conf[0x0e] = 0x00; // header_type
     8.7 +    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
     8.8 +    pci_conf[0x2d] = 0x58;
     8.9 +    pci_conf[0x2e] = 0x01; /* subsystem device */
    8.10 +    pci_conf[0x2f] = 0x00;
    8.11  
    8.12      pci_register_io_region((PCIDevice *)d, 4, 0x10, 
    8.13                             PCI_ADDRESS_SPACE_IO, bmdma_map);
     9.1 --- a/tools/ioemu/hw/rtl8139.c	Wed Feb 07 10:46:18 2007 -0700
     9.2 +++ b/tools/ioemu/hw/rtl8139.c	Thu Feb 08 17:27:30 2007 +0000
     9.3 @@ -3423,8 +3423,10 @@ void pci_rtl8139_init(PCIBus *bus, NICIn
     9.4      pci_conf[0x0e] = 0x00; /* header_type */
     9.5      pci_conf[0x3d] = 1;    /* interrupt pin 0 */
     9.6      pci_conf[0x34] = 0xdc;
     9.7 -    pci_conf[0x2c] = pci_conf[0x00]; // same as Vendor ID
     9.8 -    pci_conf[0x2d] = pci_conf[0x01];
     9.9 +    pci_conf[0x2c] = 0x53; /* subsystem vendor: XenSource */
    9.10 +    pci_conf[0x2d] = 0x58;
    9.11 +    pci_conf[0x2e] = 0x01; /* subsystem device */
    9.12 +    pci_conf[0x2f] = 0x00;
    9.13  
    9.14      s = &d->rtl8139;
    9.15  
    10.1 --- a/tools/ioemu/xenstore.c	Wed Feb 07 10:46:18 2007 -0700
    10.2 +++ b/tools/ioemu/xenstore.c	Thu Feb 08 17:27:30 2007 +0000
    10.3 @@ -10,6 +10,7 @@
    10.4  
    10.5  #include "vl.h"
    10.6  #include "block_int.h"
    10.7 +#include <unistd.h>
    10.8  
    10.9  static struct xs_handle *xsh = NULL;
   10.10  static char *hd_filename[MAX_DISKS];
   10.11 @@ -52,11 +53,40 @@ void xenstore_check_new_media_present(in
   10.12      qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout);
   10.13  }
   10.14  
   10.15 +static int waitForDevice(char *path, char *field, char *desired)
   10.16 +{ 
   10.17 +    char *buf = NULL, *stat = NULL;
   10.18 +    unsigned int len;
   10.19 +    int val = 1;
   10.20 +
   10.21 +    /* loop until we find a value in xenstore, return 
   10.22 +     * if it was what we wanted, or not
   10.23 +     */
   10.24 +    while (1) {
   10.25 +        if (pasprintf(&buf, "%s/%s", path, field) == -1)
   10.26 +            goto done;
   10.27 +        free(stat);
   10.28 +        stat = xs_read(xsh, XBT_NULL, buf, &len);
   10.29 +        if (stat == NULL) {
   10.30 +            usleep(100000); /* 1/10th second, no path found */
   10.31 +        } else {
   10.32 +            val = strcmp(stat, desired);
   10.33 +            goto done;
   10.34 +        }
   10.35 +    }
   10.36 +
   10.37 +done:
   10.38 +    free(stat);
   10.39 +    free(buf);
   10.40 +    return val;
   10.41 +}
   10.42 +
   10.43  void xenstore_parse_domain_config(int domid)
   10.44  {
   10.45      char **e = NULL;
   10.46      char *buf = NULL, *path;
   10.47 -    char *bpath = NULL, *dev = NULL, *params = NULL, *type = NULL;
   10.48 +    char *fpath = NULL, *bpath = NULL,
   10.49 +         *dev = NULL, *params = NULL, *type = NULL;
   10.50      int i;
   10.51      unsigned int len, num, hd_index;
   10.52  
   10.53 @@ -120,7 +150,35 @@ void xenstore_parse_domain_config(int do
   10.54  	    hd_filename[hd_index] = params;	/* strdup() */
   10.55  	    params = NULL;		/* don't free params on re-use */
   10.56  	}
   10.57 +        /* 
   10.58 +         * check if device has a phantom vbd; the phantom is hooked
   10.59 +         * to the frontend device (for ease of cleanup), so lookup 
   10.60 +         * the frontend device, and see if there is a phantom_vbd
   10.61 +         * if there is, we will use resolution as the filename
   10.62 +         */
   10.63 +	if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
   10.64 +	    continue;
   10.65 +	free(fpath);
   10.66 +        fpath = xs_read(xsh, XBT_NULL, buf, &len);
   10.67 +	if (fpath != NULL) {
   10.68 +
   10.69 +            if (waitForDevice(fpath, "hotplug-status", "connected")) {
   10.70 +               continue;
   10.71 +            }
   10.72 +
   10.73 +	    if (pasprintf(&buf, "%s/dev", fpath) == -1)
   10.74 +	        continue;
   10.75 +            params = xs_read(xsh, XBT_NULL, buf , &len);
   10.76 +	    if (params != NULL) {
   10.77 +                free(hd_filename[hd_index]);
   10.78 +                hd_filename[hd_index] = params;
   10.79 +                params = NULL;              /* don't free params on re-use */
   10.80 +            }
   10.81 +        }
   10.82  	bs_table[hd_index] = bdrv_new(dev);
   10.83 +        /* re-establish buf */
   10.84 +	if (pasprintf(&buf, "%s/params", bpath) == -1)
   10.85 +	    continue;
   10.86  	/* check if it is a cdrom */
   10.87  	if (type && !strcmp(type, "cdrom")) {
   10.88  	    bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM);
    11.1 --- a/tools/libxc/xc_hvm_restore.c	Wed Feb 07 10:46:18 2007 -0700
    11.2 +++ b/tools/libxc/xc_hvm_restore.c	Thu Feb 08 17:27:30 2007 +0000
    11.3 @@ -69,7 +69,6 @@ read_exact(int fd, void *buf, size_t cou
    11.4  int xc_hvm_restore(int xc_handle, int io_fd,
    11.5                       uint32_t dom, unsigned long nr_pfns,
    11.6                       unsigned int store_evtchn, unsigned long *store_mfn,
    11.7 -                     unsigned int console_evtchn, unsigned long *console_mfn,
    11.8                       unsigned int pae, unsigned int apic)
    11.9  {
   11.10      DECLARE_DOMCTL;
   11.11 @@ -104,8 +103,8 @@ int xc_hvm_restore(int xc_handle, int io
   11.12      memsize = (unsigned long long)*store_mfn;
   11.13      v_end = memsize << 20;
   11.14  
   11.15 -    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", 
   11.16 -            dom, nr_pfns, store_evtchn, *store_mfn, console_evtchn, *console_mfn, pae, apic);
   11.17 +    DPRINTF("xc_hvm_restore:dom=%d, nr_pfns=0x%lx, store_evtchn=%d, *store_mfn=%ld, pae=%u, apic=%u.\n", 
   11.18 +            dom, nr_pfns, store_evtchn, *store_mfn, pae, apic);
   11.19  
   11.20      max_pfn = nr_pfns;
   11.21  
    12.1 --- a/tools/libxc/xc_hvm_save.c	Wed Feb 07 10:46:18 2007 -0700
    12.2 +++ b/tools/libxc/xc_hvm_save.c	Thu Feb 08 17:27:30 2007 +0000
    12.3 @@ -27,6 +27,7 @@
    12.4  #include <stdlib.h>
    12.5  #include <unistd.h>
    12.6  #include <sys/time.h>
    12.7 +#include <xen/hvm/e820.h>
    12.8  
    12.9  #include "xc_private.h"
   12.10  #include "xg_private.h"
   12.11 @@ -275,9 +276,8 @@ int xc_hvm_save(int xc_handle, int io_fd
   12.12      /* A copy of the CPU context of the guest. */
   12.13      vcpu_guest_context_t ctxt;
   12.14  
   12.15 -    /* A table containg the type of each PFN (/not/ MFN!). */
   12.16 -    unsigned long *pfn_type = NULL;
   12.17 -    unsigned long *pfn_batch = NULL;
   12.18 +    /* A table containg the PFNs (/not/ MFN!) to map. */
   12.19 +    xen_pfn_t *pfn_batch = NULL;
   12.20  
   12.21      /* A copy of hvm domain context buffer*/
   12.22      uint32_t hvm_buf_size;
   12.23 @@ -290,7 +290,6 @@ int xc_hvm_save(int xc_handle, int io_fd
   12.24      unsigned char *region_base = NULL;
   12.25  
   12.26      uint32_t nr_pfns, rec_size, nr_vcpus;
   12.27 -    unsigned long *page_array = NULL;
   12.28  
   12.29      /* power of 2 order of max_pfn */
   12.30      int order_nr;
   12.31 @@ -361,18 +360,12 @@ int xc_hvm_save(int xc_handle, int io_fd
   12.32          goto out;
   12.33      }
   12.34  
   12.35 -    max_pfn = live_shinfo->arch.max_pfn;
   12.36 -
   12.37      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); 
   12.38  
   12.39 -    /* nr_pfns: total pages excluding vga acc mem
   12.40 -     * max_pfn: nr_pfns + 0x20 vga hole(0xa0~0xc0)
   12.41 -     * getdomaininfo.tot_pages: all the allocated pages for this domain
   12.42 -     */
   12.43      if (live) {
   12.44          ERROR("hvm domain doesn't support live migration now.\n");
   12.45          goto out;
   12.46 -
   12.47 +        
   12.48          if (xc_shadow_control(xc_handle, dom,
   12.49                                XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
   12.50                                NULL, 0, NULL, 0, NULL) < 0) {
   12.51 @@ -381,6 +374,7 @@ int xc_hvm_save(int xc_handle, int io_fd
   12.52          }
   12.53  
   12.54          /* excludes vga acc mem */
   12.55 +        /* XXX will need to check whether acceleration is enabled here! */
   12.56          nr_pfns = info.nr_pages - 0x800;
   12.57  
   12.58          last_iter = 0;
   12.59 @@ -396,8 +390,8 @@ int xc_hvm_save(int xc_handle, int io_fd
   12.60              ERROR("HVM Domain appears not to have suspended");
   12.61              goto out;
   12.62          }
   12.63 -        nr_pfns = info.nr_pages;
   12.64 -        DPRINTF("after suspend hvm domain nr_pages=0x%x.\n", nr_pfns);
   12.65 +
   12.66 +        nr_pfns = info.nr_pages; 
   12.67      }
   12.68  
   12.69      DPRINTF("after 1st handle hvm domain nr_pfns=0x%x, nr_pages=0x%lx, max_memkb=0x%lx, live=%d.\n",
   12.70 @@ -406,10 +400,15 @@ int xc_hvm_save(int xc_handle, int io_fd
   12.71              info.max_memkb,
   12.72              live);
   12.73  
   12.74 -    nr_pfns = info.nr_pages;
   12.75 -
   12.76 -    /*XXX: caculate the VGA hole*/
   12.77 -    max_pfn = nr_pfns + 0x20;
   12.78 +    /* Calculate the highest PFN of "normal" memory:
   12.79 +     * HVM memory is sequential except for the VGA and MMIO holes, and
   12.80 +     * we have nr_pfns of it (which now excludes the cirrus video RAM) */
   12.81 +    max_pfn = nr_pfns; 
   12.82 +    /* Skip the VGA hole from 0xa0000 to 0xc0000 */
   12.83 +    max_pfn += 0x20;   
   12.84 +    /* Skip the MMIO hole: 256MB just below 4GB */
   12.85 +    if ( max_pfn >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT) )
   12.86 +        max_pfn += (HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT); 
   12.87  
   12.88      skip_this_iter = 0;/*XXX*/
   12.89      /* pretend we sent all the pages last iteration */
   12.90 @@ -424,7 +423,6 @@ int xc_hvm_save(int xc_handle, int io_fd
   12.91      to_send = malloc(BITMAP_SIZE);
   12.92      to_skip = malloc(BITMAP_SIZE);
   12.93  
   12.94 -    page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn);
   12.95  
   12.96      hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0);
   12.97      if ( hvm_buf_size == -1 )
   12.98 @@ -434,7 +432,7 @@ int xc_hvm_save(int xc_handle, int io_fd
   12.99      }
  12.100      hvm_buf = malloc(hvm_buf_size);
  12.101  
  12.102 -    if (!to_send ||!to_skip ||!page_array ||!hvm_buf) {
  12.103 +    if (!to_send ||!to_skip ||!hvm_buf) {
  12.104          ERROR("Couldn't allocate memory");
  12.105          goto out;
  12.106      }
  12.107 @@ -454,26 +452,16 @@ int xc_hvm_save(int xc_handle, int io_fd
  12.108  
  12.109      analysis_phase(xc_handle, dom, max_pfn, to_skip, 0);
  12.110  
  12.111 -    /* get all the HVM domain pfns */
  12.112 -    for ( i = 0; i < max_pfn; i++)
  12.113 -        page_array[i] = i;
  12.114 -
  12.115  
  12.116      /* We want zeroed memory so use calloc rather than malloc. */
  12.117 -    pfn_type  = calloc(MAX_BATCH_SIZE, sizeof(*pfn_type));
  12.118      pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(*pfn_batch));
  12.119  
  12.120 -    if ((pfn_type == NULL) || (pfn_batch == NULL)) {
  12.121 -        ERROR("failed to alloc memory for pfn_type and/or pfn_batch arrays");
  12.122 +    if (pfn_batch == NULL) {
  12.123 +        ERROR("failed to alloc memory for pfn_batch array");
  12.124          errno = ENOMEM;
  12.125          goto out;
  12.126      }
  12.127  
  12.128 -    if (lock_pages(pfn_type, MAX_BATCH_SIZE * sizeof(*pfn_type))) {
  12.129 -        ERROR("Unable to lock");
  12.130 -        goto out;
  12.131 -    }
  12.132 -
  12.133      /* Start writing out the saved-domain record. */
  12.134      if (!write_exact(io_fd, &max_pfn, sizeof(unsigned long))) {
  12.135          ERROR("write: max_pfn");
  12.136 @@ -511,16 +499,15 @@ int xc_hvm_save(int xc_handle, int io_fd
  12.137              }
  12.138  
  12.139  
  12.140 -            /* load pfn_type[] with the mfn of all the pages we're doing in
  12.141 +            /* load pfn_batch[] with the mfn of all the pages we're doing in
  12.142                 this batch. */
  12.143              for (batch = 0; batch < MAX_BATCH_SIZE && N < max_pfn ; N++) {
  12.144  
  12.145                  int n = permute(N, max_pfn, order_nr);
  12.146  
  12.147                  if (debug) {
  12.148 -                    DPRINTF("%d pfn= %08lx mfn= %08lx %d \n",
  12.149 -                            iter, (unsigned long)n, page_array[n],
  12.150 -                            test_bit(n, to_send));
  12.151 +                    DPRINTF("%d pfn= %08lx %d \n",
  12.152 +                            iter, (unsigned long)n, test_bit(n, to_send));
  12.153                  }
  12.154  
  12.155                  if (!last_iter && test_bit(n, to_send)&& test_bit(n, to_skip))
  12.156 @@ -530,10 +517,12 @@ int xc_hvm_save(int xc_handle, int io_fd
  12.157                        (test_bit(n, to_send) && last_iter)))
  12.158                      continue;
  12.159  
  12.160 -                if (n >= 0xa0 && n < 0xc0) {
  12.161 -/*                    DPRINTF("get a vga hole pfn= %x.\n", n);*/
  12.162 +                /* Skip PFNs that aren't really there */
  12.163 +                if ((n >= 0xa0 && n < 0xc0) /* VGA hole */
  12.164 +                    || (n >= (HVM_BELOW_4G_MMIO_START >> PAGE_SHIFT)
  12.165 +                        && n < (1ULL << 32) >> PAGE_SHIFT)) /* 4G MMIO hole */
  12.166                      continue;
  12.167 -                }
  12.168 +
  12.169                  /*
  12.170                  ** we get here if:
  12.171                  **  1. page is marked to_send & hasn't already been re-dirtied
  12.172 @@ -541,7 +530,6 @@ int xc_hvm_save(int xc_handle, int io_fd
  12.173                  */
  12.174  
  12.175                  pfn_batch[batch] = n;
  12.176 -                pfn_type[batch]  = page_array[n];
  12.177  
  12.178                  batch++;
  12.179              }
  12.180 @@ -573,7 +561,6 @@ int xc_hvm_save(int xc_handle, int io_fd
  12.181                  goto out;
  12.182              }
  12.183  
  12.184 -
  12.185              sent_this_iter += batch;
  12.186  
  12.187              munmap(region_base, batch*PAGE_SIZE);
  12.188 @@ -723,9 +710,6 @@ int xc_hvm_save(int xc_handle, int io_fd
  12.189      }
  12.190  
  12.191      free(hvm_buf);
  12.192 -    free(page_array);
  12.193 -
  12.194 -    free(pfn_type);
  12.195      free(pfn_batch);
  12.196      free(to_send);
  12.197      free(to_skip);
    13.1 --- a/tools/libxc/xenguest.h	Wed Feb 07 10:46:18 2007 -0700
    13.2 +++ b/tools/libxc/xenguest.h	Thu Feb 08 17:27:30 2007 +0000
    13.3 @@ -58,8 +58,7 @@ int xc_linux_restore(int xc_handle, int 
    13.4   */
    13.5  int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom,
    13.6                        unsigned long nr_pfns, unsigned int store_evtchn,
    13.7 -                      unsigned long *store_mfn, unsigned int console_evtchn,
    13.8 -                      unsigned long *console_mfn,
    13.9 +                      unsigned long *store_mfn, 
   13.10                        unsigned int pae, unsigned int apic);
   13.11  
   13.12  /**
    14.1 --- a/tools/libxc/xg_private.c	Wed Feb 07 10:46:18 2007 -0700
    14.2 +++ b/tools/libxc/xg_private.c	Thu Feb 08 17:27:30 2007 +0000
    14.3 @@ -210,8 +210,7 @@ int xc_hvm_save(int xc_handle, int io_fd
    14.4  __attribute__((weak)) 
    14.5  int xc_hvm_restore(int xc_handle, int io_fd, uint32_t dom,
    14.6                     unsigned long nr_pfns, unsigned int store_evtchn,
    14.7 -                   unsigned long *store_mfn, unsigned int console_evtchn,
    14.8 -                   unsigned long *console_mfn,
    14.9 +                   unsigned long *store_mfn,
   14.10                     unsigned int pae, unsigned int apic)
   14.11  {
   14.12      errno = ENOSYS;
    15.1 --- a/tools/misc/Makefile	Wed Feb 07 10:46:18 2007 -0700
    15.2 +++ b/tools/misc/Makefile	Thu Feb 08 17:27:30 2007 +0000
    15.3 @@ -9,7 +9,7 @@ CFLAGS   += $(INCLUDES)
    15.4  
    15.5  HDRS     = $(wildcard *.h)
    15.6  
    15.7 -TARGETS  = xenperf xc_shadow
    15.8 +TARGETS  = xenperf xc_shadow xen-detect
    15.9  
   15.10  INSTALL_BIN  = $(TARGETS) xencons
   15.11  INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf
   15.12 @@ -41,5 +41,5 @@ clean:
   15.13  %.o: %.c $(HDRS) Makefile
   15.14  	$(CC) -c $(CFLAGS) -o $@ $<
   15.15  
   15.16 -$(TARGETS): %: %.o Makefile
   15.17 +xenperf xc_shadow: %: %.o Makefile
   15.18  	$(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/misc/xen-detect.c	Thu Feb 08 17:27:30 2007 +0000
    16.3 @@ -0,0 +1,108 @@
    16.4 +/******************************************************************************
    16.5 + * xen_detect.c
    16.6 + * 
    16.7 + * Simple GNU C / POSIX application to detect execution on Xen VMM platform.
    16.8 + * 
    16.9 + * Copyright (c) 2007, XenSource Inc.
   16.10 + * 
   16.11 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   16.12 + * of this software and associated documentation files (the "Software"), to
   16.13 + * deal in the Software without restriction, including without limitation the
   16.14 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   16.15 + * sell copies of the Software, and to permit persons to whom the Software is
   16.16 + * furnished to do so, subject to the following conditions:
   16.17 + *
   16.18 + * The above copyright notice and this permission notice shall be included in
   16.19 + * all copies or substantial portions of the Software.
   16.20 + *
   16.21 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16.22 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   16.23 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   16.24 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   16.25 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   16.26 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   16.27 + * DEALINGS IN THE SOFTWARE.
   16.28 + */
   16.29 +
   16.30 +#include <stdint.h>
   16.31 +#include <stdio.h>
   16.32 +#include <stdlib.h>
   16.33 +#include <string.h>
   16.34 +#include <sys/types.h>
   16.35 +#include <sys/wait.h>
   16.36 +#include <unistd.h>
   16.37 +
   16.38 +static int pv_context;
   16.39 +
   16.40 +static void cpuid(uint32_t idx,
   16.41 +                  uint32_t *eax,
   16.42 +                  uint32_t *ebx,
   16.43 +                  uint32_t *ecx,
   16.44 +                  uint32_t *edx)
   16.45 +{
   16.46 +    asm volatile (
   16.47 +        "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid"
   16.48 +        : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
   16.49 +        : "0" (idx), "1" (pv_context) );
   16.50 +}
   16.51 +
   16.52 +static int check_for_xen(void)
   16.53 +{
   16.54 +    uint32_t eax, ebx, ecx, edx;
   16.55 +    char signature[13];
   16.56 +
   16.57 +    cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
   16.58 +    *(uint32_t *)(signature + 0) = ebx;
   16.59 +    *(uint32_t *)(signature + 4) = ecx;
   16.60 +    *(uint32_t *)(signature + 8) = edx;
   16.61 +    signature[12] = '\0';
   16.62 +
   16.63 +    if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
   16.64 +        return 0;
   16.65 +
   16.66 +    cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
   16.67 +    printf("Running in %s context on Xen v%d.%d.\n",
   16.68 +           pv_context ? "PV" : "HVM", (uint16_t)(eax >> 16), (uint16_t)eax);
   16.69 +    return 1;
   16.70 +}
   16.71 +
   16.72 +int main(void)
   16.73 +{
   16.74 +    pid_t pid;
   16.75 +    int status;
   16.76 +    uint32_t dummy;
   16.77 +
   16.78 +    /* Check for execution in HVM context. */
   16.79 +    if ( check_for_xen() )
   16.80 +        return 0;
   16.81 +
   16.82 +    /* Now we check for execution in PV context. */
   16.83 +    pv_context = 1;
   16.84 +
   16.85 +    /*
   16.86 +     * Fork a child to test the paravirtualised CPUID instruction.
   16.87 +     * If executed outside Xen PV context, the extended opcode will fault.
   16.88 +     */
   16.89 +    pid = fork();
   16.90 +    switch ( pid )
   16.91 +    {
   16.92 +    case 0:
   16.93 +        /* Child: test paravirtualised CPUID opcode and then exit cleanly. */
   16.94 +        cpuid(0x40000000, &dummy, &dummy, &dummy, &dummy);
   16.95 +        exit(0);
   16.96 +    case -1:
   16.97 +        fprintf(stderr, "Fork failed.\n");
   16.98 +        return 0;
   16.99 +    }
  16.100 +
  16.101 +    /*
  16.102 +     * Parent waits for child to terminate and checks for clean exit.
  16.103 +     * Only if the exit is clean is it safe for us to try the extended CPUID.
  16.104 +     */
  16.105 +    waitpid(pid, &status, 0);
  16.106 +    if ( WIFEXITED(status) && check_for_xen() )
  16.107 +        return 0;
  16.108 +
  16.109 +    printf("Not running on Xen.\n");
  16.110 +    return 0;
  16.111 +}
    17.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Wed Feb 07 10:46:18 2007 -0700
    17.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Thu Feb 08 17:27:30 2007 +0000
    17.3 @@ -239,8 +239,11 @@ def restore(xd, fd, dominfo = None, paus
    17.4  
    17.5          forkHelper(cmd, fd, handler.handler, True)
    17.6  
    17.7 -        if handler.store_mfn is None or handler.console_mfn is None:
    17.8 -            raise XendError('Could not read store/console MFN')
    17.9 +        if handler.store_mfn is None:
   17.10 +            raise XendError('Could not read store MFN')
   17.11 +
   17.12 +        if not is_hvm and handler.console_mfn is None:
   17.13 +            raise XendError('Could not read console MFN')        
   17.14  
   17.15          dominfo.waitForDevices() # Wait for backends to set up
   17.16          if not paused:
    18.1 --- a/tools/python/xen/xend/XendConfig.py	Wed Feb 07 10:46:18 2007 -0700
    18.2 +++ b/tools/python/xen/xend/XendConfig.py	Thu Feb 08 17:27:30 2007 +0000
    18.3 @@ -1148,6 +1148,47 @@ class XendConfig(dict):
    18.4          # no valid device to add
    18.5          return ''
    18.6  
    18.7 +    def phantom_device_add(self, dev_type, cfg_xenapi = None,
    18.8 +                   target = None):
    18.9 +        """Add a phantom tap device configuration in XenAPI struct format.
   18.10 +        """
   18.11 +
   18.12 +        if target == None:
   18.13 +            target = self
   18.14 +        
   18.15 +        if dev_type not in XendDevices.valid_devices() and \
   18.16 +           dev_type not in XendDevices.pseudo_devices():        
   18.17 +            raise XendConfigError("XendConfig: %s not a valid device type" %
   18.18 +                            dev_type)
   18.19 +
   18.20 +        if cfg_xenapi == None:
   18.21 +            raise XendConfigError("XendConfig: device_add requires some "
   18.22 +                                  "config.")
   18.23 +
   18.24 +        if cfg_xenapi:
   18.25 +            log.debug("XendConfig.phantom_device_add: %s" % str(cfg_xenapi))
   18.26 + 
   18.27 +        if cfg_xenapi:
   18.28 +            dev_info = {}            
   18.29 +            if dev_type in ('vbd', 'tap'):
   18.30 +                if dev_type == 'vbd':
   18.31 +                    dev_info['uname'] = cfg_xenapi.get('image', '')
   18.32 +                    dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
   18.33 +                elif dev_type == 'tap':
   18.34 +                    if cfg_xenapi.get('image').find('tap:') == -1:
   18.35 +                        dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
   18.36 +                    dev_info['dev'] =  '/dev/%s' % cfg_xenapi.get('device')
   18.37 +                    dev_info['uname'] = cfg_xenapi.get('image')
   18.38 +                dev_info['mode'] = cfg_xenapi.get('mode')
   18.39 +                dev_info['backend'] = '0'
   18.40 +                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
   18.41 +                dev_info['uuid'] = dev_uuid
   18.42 +                self['devices'][dev_uuid] = (dev_type, dev_info)
   18.43 +                self['vbd_refs'].append(dev_uuid)
   18.44 +                return dev_uuid
   18.45 +
   18.46 +        return ''
   18.47 +
   18.48      def console_add(self, protocol, location, other_config = {}):
   18.49          dev_uuid = uuid.createString()
   18.50          if protocol == 'vt100':
    19.1 --- a/tools/python/xen/xend/XendDomain.py	Wed Feb 07 10:46:18 2007 -0700
    19.2 +++ b/tools/python/xen/xend/XendDomain.py	Thu Feb 08 17:27:30 2007 +0000
    19.3 @@ -800,7 +800,10 @@ class XendDomain:
    19.4                                  "support.")
    19.5  
    19.6              path = self._managed_check_point_path(dom_uuid)
    19.7 -            fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
    19.8 +            oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
    19.9 +            if hasattr(os, "O_LARGEFILE"):
   19.10 +                oflags |= os.O_LARGEFILE
   19.11 +            fd = os.open(path, oflags)
   19.12              try:
   19.13                  # For now we don't support 'live checkpoint' 
   19.14                  XendCheckpoint.save(fd, dominfo, False, False, path)
   19.15 @@ -840,8 +843,11 @@ class XendDomain:
   19.16                  # Restore that replaces the existing XendDomainInfo
   19.17                  try:
   19.18                      log.debug('Current DomainInfo state: %d' % dominfo.state)
   19.19 +                    oflags = os.O_RDONLY
   19.20 +                    if hasattr(os, "O_LARGEFILE"):
   19.21 +                        oflags |= os.O_LARGEFILE
   19.22                      XendCheckpoint.restore(self,
   19.23 -                                           os.open(chkpath, os.O_RDONLY),
   19.24 +                                           os.open(chkpath, oflags),
   19.25                                             dominfo,
   19.26                                             paused = start_paused)
   19.27                      os.unlink(chkpath)
   19.28 @@ -1009,7 +1015,10 @@ class XendDomain:
   19.29          @raise XendError: Failure to restore domain
   19.30          """
   19.31          try:
   19.32 -            fd = os.open(src, os.O_RDONLY)
   19.33 +            oflags = os.O_RDONLY
   19.34 +            if hasattr(os, "O_LARGEFILE"):
   19.35 +                oflags |= os.O_LARGEFILE
   19.36 +            fd = os.open(src, oflags)
   19.37              try:
   19.38                  return self.domain_restore_fd(fd, paused=paused)
   19.39              finally:
   19.40 @@ -1193,7 +1202,10 @@ class XendDomain:
   19.41              if dominfo.getDomid() == DOM0_ID:
   19.42                  raise XendError("Cannot save privileged domain %i" % domid)
   19.43  
   19.44 -            fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
   19.45 +            oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
   19.46 +            if hasattr(os, "O_LARGEFILE"):
   19.47 +                oflags |= os.O_LARGEFILE
   19.48 +            fd = os.open(dst, oflags)
   19.49              try:
   19.50                  # For now we don't support 'live checkpoint' 
   19.51                  XendCheckpoint.save(fd, dominfo, False, False, dst)
    20.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Feb 07 10:46:18 2007 -0700
    20.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Feb 08 17:27:30 2007 +0000
    20.3 @@ -1416,7 +1416,7 @@ class XendDomainInfo:
    20.4                                        self.info['image'],
    20.5                                        self.info['devices'])
    20.6  
    20.7 -            localtime = self.info.get('localtime', False)
    20.8 +            localtime = self.info.get('platform_localtime', False)
    20.9              if localtime:
   20.10                  xc.domain_set_time_offset(self.domid)
   20.11  
   20.12 @@ -1565,19 +1565,54 @@ class XendDomainInfo:
   20.13      # VM Destroy
   20.14      # 
   20.15  
   20.16 +    def _prepare_phantom_paths(self):
   20.17 +        # get associated devices to destroy
   20.18 +        # build list of phantom devices to be removed after normal devices
   20.19 +        plist = []
   20.20 +        from xen.xend.xenstore.xstransact import xstransact
   20.21 +        t = xstransact("%s/device/vbd" % GetDomainPath(self.domid))
   20.22 +        for dev in t.list():
   20.23 +            backend_phantom_vbd = xstransact.Read("%s/device/vbd/%s/phantom_vbd" \
   20.24 +                                  % (self.dompath, dev))
   20.25 +            if backend_phantom_vbd is not None:
   20.26 +                frontend_phantom_vbd =  xstransact.Read("%s/frontend" \
   20.27 +                                  % backend_phantom_vbd)
   20.28 +                plist.append(backend_phantom_vbd)
   20.29 +                plist.append(frontend_phantom_vbd)
   20.30 +        return plist
   20.31 +
   20.32 +    def _cleanup_phantom_devs(self, plist):
   20.33 +        # remove phantom devices
   20.34 +        if not plist == []:
   20.35 +            time.sleep(2)
   20.36 +        for paths in plist:
   20.37 +            if paths.find('backend') != -1:
   20.38 +                from xen.xend.server import DevController
   20.39 +                # Modify online status /before/ updating state (latter is watched by
   20.40 +                # drivers, so this ordering avoids a race).
   20.41 +                xstransact.Write(paths, 'online', "0")
   20.42 +                xstransact.Write(paths, 'state', str(DevController.xenbusState['Closing']))
   20.43 +            # force
   20.44 +            xstransact.Remove(paths)
   20.45 +
   20.46      def destroy(self):
   20.47          """Cleanup VM and destroy domain.  Nothrow guarantee."""
   20.48  
   20.49          log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
   20.50  
   20.51 +        paths = self._prepare_phantom_paths()
   20.52 +
   20.53          self._cleanupVm()
   20.54          if self.dompath is not None:
   20.55              self.destroyDomain()
   20.56  
   20.57 +        self._cleanup_phantom_devs(paths)
   20.58  
   20.59      def destroyDomain(self):
   20.60          log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
   20.61  
   20.62 +        paths = self._prepare_phantom_paths()
   20.63 +
   20.64          try:
   20.65              if self.domid is not None:
   20.66                  xc.domain_destroy(self.domid)
   20.67 @@ -1591,7 +1626,7 @@ class XendDomainInfo:
   20.68          XendDomain.instance().remove_domain(self)
   20.69  
   20.70          self.cleanupDomain()
   20.71 -
   20.72 +        self._cleanup_phantom_devs(paths)
   20.73  
   20.74      def resumeDomain(self):
   20.75          log.debug("XendDomainInfo.resumeDomain(%s)", str(self.domid))
   20.76 @@ -2211,6 +2246,25 @@ class XendDomainInfo:
   20.77  
   20.78          return dev_uuid
   20.79  
   20.80 +    def create_phantom_vbd_with_vdi(self, xenapi_vbd, vdi_image_path):
   20.81 +        """Create a VBD using a VDI from XendStorageRepository.
   20.82 +
   20.83 +        @param xenapi_vbd: vbd struct from the Xen API
   20.84 +        @param vdi_image_path: VDI UUID
   20.85 +        @rtype: string
   20.86 +        @return: uuid of the device
   20.87 +        """
   20.88 +        xenapi_vbd['image'] = vdi_image_path
   20.89 +        dev_uuid = self.info.phantom_device_add('tap', cfg_xenapi = xenapi_vbd)
   20.90 +        if not dev_uuid:
   20.91 +            raise XendError('Failed to create device')
   20.92 +
   20.93 +        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
   20.94 +            _, config = self.info['devices'][dev_uuid]
   20.95 +            config['devid'] = self.getDeviceController('tap').createDevice(config)
   20.96 +
   20.97 +        return config['devid']
   20.98 +
   20.99      def create_vif(self, xenapi_vif):
  20.100          """Create VIF device from the passed struct in Xen API format.
  20.101  
    21.1 --- a/tools/python/xen/xend/server/BlktapController.py	Wed Feb 07 10:46:18 2007 -0700
    21.2 +++ b/tools/python/xen/xend/server/BlktapController.py	Thu Feb 08 17:27:30 2007 +0000
    21.3 @@ -2,7 +2,10 @@
    21.4  
    21.5  
    21.6  from xen.xend.server.blkif import BlkifController
    21.7 +from xen.xend.XendLogging import log
    21.8  
    21.9 +phantomDev = 0;
   21.10 +phantomId = 0;
   21.11  
   21.12  class BlktapController(BlkifController):
   21.13      def __init__(self, vm):
   21.14 @@ -12,3 +15,62 @@ class BlktapController(BlkifController):
   21.15          """@see DevController#frontendRoot"""
   21.16          
   21.17          return "%s/device/vbd" % self.vm.getDomainPath()
   21.18 +
   21.19 +    def getDeviceDetails(self, config):
   21.20 +        (devid, back, front) = BlkifController.getDeviceDetails(self, config)
   21.21 +
   21.22 +        phantomDevid = 0
   21.23 +        wrapped = False
   21.24 +
   21.25 +        try:
   21.26 +            imagetype = self.vm.info['image']['type']
   21.27 +        except:
   21.28 +            imagetype = ""
   21.29 +
   21.30 +        if imagetype == 'hvm':
   21.31 +            tdevname = back['dev']
   21.32 +            index = ['c', 'd', 'e', 'f', 'g', 'h', 'i', \
   21.33 +                     'j', 'l', 'm', 'n', 'o', 'p']
   21.34 +            while True:
   21.35 +                global phantomDev
   21.36 +                global phantomId
   21.37 +                import os, stat
   21.38 +
   21.39 +                phantomId = phantomId + 1
   21.40 +                if phantomId == 16:
   21.41 +                    if index[phantomDev] == index[-1]:
   21.42 +                        if wrapped:
   21.43 +                            raise VmError(" No loopback block \
   21.44 +                                       devices are available. ")
   21.45 +                        wrapped = True
   21.46 +                        phantomDev = 0
   21.47 +                    else:
   21.48 +                        phantomDev = phantomDev + 1
   21.49 +                    phantomId = 1
   21.50 +                devname = 'xvd%s%d' % (index[phantomDev], phantomId)
   21.51 +                try:
   21.52 +                    info = os.stat('/dev/%s' % devname)
   21.53 +                except:
   21.54 +                    break
   21.55 +
   21.56 +            vbd = { 'mode': 'w', 'device': devname }
   21.57 +            fn = 'tap:%s' % back['params']
   21.58 +
   21.59 +            # recurse ... by creating the vbd, then fallthrough
   21.60 +            # and finish creating the original device
   21.61 +
   21.62 +            from xen.xend import XendDomain
   21.63 +            dom0 = XendDomain.instance().privilegedDomain()
   21.64 +            phantomDevid = dom0.create_phantom_vbd_with_vdi(vbd, fn)
   21.65 +            # we need to wait for this device at a higher level
   21.66 +            # the vbd that gets created will have a link to us
   21.67 +            # and will let them do it there
   21.68 +
   21.69 +        # add a hook to point to the phantom device,
   21.70 +        # root path is always the same (dom0 tap)
   21.71 +        if phantomDevid != 0:
   21.72 +            front['phantom_vbd'] = '/local/domain/0/backend/tap/0/%s' \
   21.73 +                                   % str(phantomDevid)
   21.74 +
   21.75 +        return (devid, back, front)
   21.76 +
    22.1 --- a/tools/python/xen/xend/server/DevController.py	Wed Feb 07 10:46:18 2007 -0700
    22.2 +++ b/tools/python/xen/xend/server/DevController.py	Thu Feb 08 17:27:30 2007 +0000
    22.3 @@ -153,9 +153,9 @@ class DevController:
    22.4          log.debug("Waiting for %s.", devid)
    22.5  
    22.6          if not self.hotplug:
    22.7 -            return 
    22.8 -        
    22.9 -        status = self.waitForBackend(devid)
   22.10 +            return
   22.11 +
   22.12 +        (status, err) = self.waitForBackend(devid)
   22.13  
   22.14          if status == Timeout:
   22.15              self.destroyDevice(devid, False)
   22.16 @@ -165,25 +165,22 @@ class DevController:
   22.17  
   22.18          elif status == Error:
   22.19              self.destroyDevice(devid, False)
   22.20 -            raise VmError("Device %s (%s) could not be connected. "
   22.21 -                          "Backend device not found." %
   22.22 -                          (devid, self.deviceClass))
   22.23 -
   22.24 +            if err is None:
   22.25 +                raise VmError("Device %s (%s) could not be connected. "
   22.26 +                              "Backend device not found." %
   22.27 +                              (devid, self.deviceClass))
   22.28 +            else:
   22.29 +                raise VmError("Device %s (%s) could not be connected. "
   22.30 +                              "%s" % (devid, self.deviceClass, err))
   22.31          elif status == Missing:
   22.32              # Don't try to destroy the device; it's already gone away.
   22.33              raise VmError("Device %s (%s) could not be connected. "
   22.34                            "Device not found." % (devid, self.deviceClass))
   22.35  
   22.36          elif status == Busy:
   22.37 -            err = None
   22.38 -            frontpath = self.frontendPath(devid)
   22.39 -            backpath = xstransact.Read(frontpath, "backend")
   22.40 -            if backpath:
   22.41 -                err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
   22.42 -            if not err:
   22.43 +            self.destroyDevice(devid, False)
   22.44 +            if err is None:
   22.45                  err = "Busy."
   22.46 -                
   22.47 -            self.destroyDevice(devid, False)
   22.48              raise VmError("Device %s (%s) could not be connected.\n%s" %
   22.49                            (devid, self.deviceClass, err))
   22.50  
   22.51 @@ -476,19 +473,36 @@ class DevController:
   22.52      def waitForBackend(self, devid):
   22.53  
   22.54          frontpath = self.frontendPath(devid)
   22.55 +        # lookup a phantom 
   22.56 +        phantomPath = xstransact.Read(frontpath, 'phantom_vbd')
   22.57 +        if phantomPath is not None:
   22.58 +            log.debug("Waiting for %s's phantom %s.", devid, phantomPath)
   22.59 +            statusPath = phantomPath + '/' + HOTPLUG_STATUS_NODE
   22.60 +            ev = Event()
   22.61 +            result = { 'status': Timeout }
   22.62 +            xswatch(statusPath, hotplugStatusCallback, ev, result)
   22.63 +            ev.wait(DEVICE_CREATE_TIMEOUT)
   22.64 +            err = xstransact.Read(statusPath, HOTPLUG_ERROR_NODE)
   22.65 +            if result['status'] != 'Connected':
   22.66 +                return (result['status'], err)
   22.67 +            
   22.68          backpath = xstransact.Read(frontpath, "backend")
   22.69  
   22.70 +
   22.71          if backpath:
   22.72              statusPath = backpath + '/' + HOTPLUG_STATUS_NODE
   22.73              ev = Event()
   22.74              result = { 'status': Timeout }
   22.75 -            
   22.76 +
   22.77              xswatch(statusPath, hotplugStatusCallback, ev, result)
   22.78  
   22.79              ev.wait(DEVICE_CREATE_TIMEOUT)
   22.80 -            return result['status']
   22.81 +
   22.82 +            err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
   22.83 +
   22.84 +            return (result['status'], err)
   22.85          else:
   22.86 -            return Missing
   22.87 +            return (Missing, None)
   22.88  
   22.89  
   22.90      def backendPath(self, backdom, devid):
    23.1 --- a/tools/xcutils/xc_restore.c	Wed Feb 07 10:46:18 2007 -0700
    23.2 +++ b/tools/xcutils/xc_restore.c	Thu Feb 08 17:27:30 2007 +0000
    23.3 @@ -45,14 +45,15 @@ main(int argc, char **argv)
    23.4           /* pass the memsize to xc_hvm_restore to find the store_mfn */
    23.5          store_mfn = hvm;
    23.6          ret = xc_hvm_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn,
    23.7 -                &store_mfn, console_evtchn, &console_mfn, pae, apic);
    23.8 +                &store_mfn, pae, apic);
    23.9      } else 
   23.10          ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, store_evtchn,
   23.11                  &store_mfn, console_evtchn, &console_mfn);
   23.12  
   23.13      if (ret == 0) {
   23.14  	printf("store-mfn %li\n", store_mfn);
   23.15 -	printf("console-mfn %li\n", console_mfn);
   23.16 +        if (!hvm)
   23.17 +            printf("console-mfn %li\n", console_mfn);
   23.18  	fflush(stdout);
   23.19      }
   23.20  
    24.1 --- a/tools/xenfb/vncfb.c	Wed Feb 07 10:46:18 2007 -0700
    24.2 +++ b/tools/xenfb/vncfb.c	Thu Feb 08 17:27:30 2007 +0000
    24.3 @@ -57,7 +57,8 @@ unsigned char keycode_table[512];
    24.4  static void *kbd_layout;
    24.5  
    24.6  static int btnmap[] = {
    24.7 -	BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_FORWARD, BTN_BACK
    24.8 +	BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE,
    24.9 +	BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK
   24.10  };
   24.11  
   24.12  static void on_kbd_event(rfbBool down, rfbKeySym keycode, rfbClientPtr cl)
   24.13 @@ -73,11 +74,12 @@ static void on_kbd_event(rfbBool down, r
   24.14  	 */
   24.15  	rfbScreenInfoPtr server = cl->screen;
   24.16  	struct xenfb *xenfb = server->screenData;
   24.17 +	int scancode;
   24.18  
   24.19 -	if( keycode >= 'A' && keycode <= 'Z' )
   24.20 +	if (keycode >= 'A' && keycode <= 'Z')
   24.21  		keycode += 'a' - 'A';
   24.22  
   24.23 -	int scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
   24.24 +	scancode = keycode_table[keysym2scancode(kbd_layout, keycode)];
   24.25  	if (scancode == 0)
   24.26  		return;
   24.27  	if (xenfb_send_key(xenfb, down, scancode) < 0)
    25.1 --- a/xen/arch/powerpc/machine_kexec.c	Wed Feb 07 10:46:18 2007 -0700
    25.2 +++ b/xen/arch/powerpc/machine_kexec.c	Thu Feb 08 17:27:30 2007 +0000
    25.3 @@ -19,6 +19,11 @@ void machine_reboot_kexec(xen_kexec_imag
    25.4      printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
    25.5  }
    25.6  
    25.7 +void machine_kexec(xen_kexec_image_t *image)
    25.8 +{
    25.9 +    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   25.10 +}
   25.11 +
   25.12  /*
   25.13   * Local variables:
   25.14   * mode: C
    26.1 --- a/xen/arch/x86/crash.c	Wed Feb 07 10:46:18 2007 -0700
    26.2 +++ b/xen/arch/x86/crash.c	Thu Feb 08 17:27:30 2007 +0000
    26.3 @@ -11,7 +11,6 @@
    26.4  #include <asm/atomic.h>
    26.5  #include <asm/elf.h>
    26.6  #include <asm/percpu.h>
    26.7 -#include <asm/kexec.h>
    26.8  #include <xen/types.h>
    26.9  #include <xen/irq.h>
   26.10  #include <asm/ipi.h>
    27.1 --- a/xen/arch/x86/hvm/hvm.c	Wed Feb 07 10:46:18 2007 -0700
    27.2 +++ b/xen/arch/x86/hvm/hvm.c	Thu Feb 08 17:27:30 2007 +0000
    27.3 @@ -106,7 +106,6 @@ void hvm_migrate_timers(struct vcpu *v)
    27.4      pit_migrate_timers(v);
    27.5      rtc_migrate_timers(v);
    27.6      hpet_migrate_timers(v);
    27.7 -    pmtimer_migrate_timers(v);
    27.8      if ( vcpu_vlapic(v)->pt.enabled )
    27.9          migrate_timer(&vcpu_vlapic(v)->pt.timer, v->processor);
   27.10  }
   27.11 @@ -170,7 +169,6 @@ void hvm_domain_destroy(struct domain *d
   27.12  {
   27.13      pit_deinit(d);
   27.14      rtc_deinit(d);
   27.15 -    pmtimer_deinit(d);
   27.16      hpet_deinit(d);
   27.17  
   27.18      if ( d->arch.hvm_domain.shared_page_va )
    28.1 --- a/xen/arch/x86/hvm/pmtimer.c	Wed Feb 07 10:46:18 2007 -0700
    28.2 +++ b/xen/arch/x86/hvm/pmtimer.c	Thu Feb 08 17:27:30 2007 +0000
    28.3 @@ -2,17 +2,6 @@
    28.4  #include <asm/hvm/io.h>
    28.5  #include <asm/hvm/support.h>
    28.6  
    28.7 -#define TMR_STS (1 << 0)
    28.8 -static void pmt_update_status(void *opaque)
    28.9 -{
   28.10 -   PMTState *s = opaque;
   28.11 -   s->pm1_status |= TMR_STS;
   28.12 -
   28.13 -   /* TODO: When TMR_EN == 1, generate a SCI event */
   28.14 -
   28.15 -   set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
   28.16 -}
   28.17 -
   28.18  static int handle_pmt_io(ioreq_t *p)
   28.19  {
   28.20      struct vcpu *v = current;
   28.21 @@ -30,42 +19,62 @@ static int handle_pmt_io(ioreq_t *p)
   28.22          /* PM_TMR_BLK is read-only */
   28.23          return 1;
   28.24      } else if (p->dir == 1) { /* read */
   28.25 +        /* Set the correct value in the timer, accounting for time
   28.26 +         * elapsed since the last time we did that. */
   28.27          curr_gtime = hvm_get_guest_time(s->vcpu);
   28.28 -        s->pm1_timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
   28.29 -        p->data = s->pm1_timer;
   28.30 +        s->pm.timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
   28.31 +        p->data = s->pm.timer;
   28.32          s->last_gtime = curr_gtime;
   28.33          return 1;
   28.34      }
   28.35      return 0;
   28.36  }
   28.37  
   28.38 +static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
   28.39 +{
   28.40 +    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
   28.41 +    uint32_t x;
   28.42 +
   28.43 +    /* Update the counter to the guest's current time.  We always save
   28.44 +     * with the domain paused, so the saved time should be after the
   28.45 +     * last_gtime, but just in case, make sure we only go forwards */
   28.46 +    x = ((s->vcpu->arch.hvm_vcpu.guest_time - s->last_gtime) * s->scale) >> 32;
   28.47 +    if ( x < 1UL<<31 )
   28.48 +        s->pm.timer += x;
   28.49 +    return hvm_save_entry(PMTIMER, 0, h, &s->pm);
   28.50 +}
   28.51 +
   28.52 +static int pmtimer_load(struct domain *d, hvm_domain_context_t *h)
   28.53 +{
   28.54 +    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
   28.55 +
   28.56 +    /* Reload the counter */
   28.57 +    if ( hvm_load_entry(PMTIMER, h, &s->pm) )
   28.58 +        return -EINVAL;
   28.59 +
   28.60 +    /* Calculate future counter values from now. */
   28.61 +    s->last_gtime = hvm_get_guest_time(s->vcpu);
   28.62 +    
   28.63 +    return 0;
   28.64 +}
   28.65 +
   28.66 +HVM_REGISTER_SAVE_RESTORE(PMTIMER, pmtimer_save, pmtimer_load, 
   28.67 +                          1, HVMSR_PER_DOM);
   28.68 +
   28.69 +
   28.70  void pmtimer_init(struct vcpu *v, int base)
   28.71  {
   28.72      PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
   28.73  
   28.74 -    s->pm1_timer = 0;
   28.75 -    s->pm1_status = 0;
   28.76 +    s->pm.timer = 0;
   28.77      s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
   28.78      s->vcpu = v;
   28.79  
   28.80 -    init_timer(&s->timer, pmt_update_status, s, v->processor);
   28.81 -    /* ACPI supports a 32-bit power management timer */
   28.82 -    set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
   28.83 -    
   28.84 +    /* Not implemented: we should set TMR_STS (bit 0 of PM1a_STS) every
   28.85 +     * time the timer's top bit flips, and generate an SCI if TMR_EN
   28.86 +     * (bit 0 of PM1a_EN) is set.  For now, those registers are in
   28.87 +     * qemu-dm, and we just calculate the timer's value on demand. */  
   28.88 +
   28.89      register_portio_handler(v->domain, base, 4, handle_pmt_io);
   28.90  }
   28.91  
   28.92 -void pmtimer_migrate_timers(struct vcpu *v)
   28.93 -{
   28.94 -    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
   28.95 -
   28.96 -    if (vpmt->vcpu == v)
   28.97 -        migrate_timer(&vpmt->timer, v->processor);
   28.98 -}
   28.99 -
  28.100 -void pmtimer_deinit(struct domain *d)
  28.101 -{
  28.102 -    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
  28.103 -
  28.104 -    kill_timer(&s->timer);
  28.105 -}
    29.1 --- a/xen/arch/x86/machine_kexec.c	Wed Feb 07 10:46:18 2007 -0700
    29.2 +++ b/xen/arch/x86/machine_kexec.c	Thu Feb 08 17:27:30 2007 +0000
    29.3 @@ -15,11 +15,15 @@
    29.4  #include <xen/types.h>
    29.5  #include <xen/console.h>
    29.6  #include <xen/kexec.h>
    29.7 -#include <asm/kexec.h>
    29.8  #include <xen/domain_page.h>
    29.9  #include <asm/fixmap.h>
   29.10  #include <asm/hvm/hvm.h>
   29.11  
   29.12 +typedef void (*relocate_new_kernel_t)(
   29.13 +                unsigned long indirection_page,
   29.14 +                unsigned long *page_list,
   29.15 +                unsigned long start_address);
   29.16 +
   29.17  int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
   29.18  {
   29.19      unsigned long prev_ma = 0;
   29.20 @@ -40,8 +44,26 @@ int machine_kexec_load(int type, int slo
   29.21          else
   29.22          {
   29.23              /* Odd pages: va for previous ma. */
   29.24 -            set_fixmap(fix_base + (k >> 1), prev_ma);
   29.25 -            image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
   29.26 +            if ( IS_COMPAT(dom0) )
   29.27 +            {
   29.28 +
   29.29 +                /*
   29.30 +                 * The compatability bounce code sets up a page table
   29.31 +                 * with a 1-1 mapping of the first 1G of memory so
   29.32 +                 * VA==PA here.
   29.33 +                 *
   29.34 +                 * This Linux purgatory code still sets up separate
   29.35 +                 * high and low mappings on the control page (entries
   29.36 +                 * 0 and 1) but it is harmless if they are equal since
   29.37 +                 * that PT is not live at the time.
   29.38 +                 */
   29.39 +                image->page_list[k] = prev_ma;
   29.40 +            }
   29.41 +            else
   29.42 +            {
   29.43 +                set_fixmap(fix_base + (k >> 1), prev_ma);
   29.44 +                image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
   29.45 +            }
   29.46          }
   29.47      }
   29.48  
   29.49 @@ -94,6 +116,31 @@ void machine_reboot_kexec(xen_kexec_imag
   29.50      BUG();
   29.51  }
   29.52  
   29.53 +void machine_kexec(xen_kexec_image_t *image)
   29.54 +{
   29.55 +#ifdef CONFIG_COMPAT
   29.56 +    if ( IS_COMPAT(dom0) )
   29.57 +    {
   29.58 +        extern void compat_machine_kexec(unsigned long rnk,
   29.59 +                                         unsigned long indirection_page,
   29.60 +                                         unsigned long *page_list,
   29.61 +                                         unsigned long start_address);
   29.62 +        compat_machine_kexec(image->page_list[1],
   29.63 +                             image->indirection_page,
   29.64 +                             image->page_list,
   29.65 +                             image->start_address);
   29.66 +    }
   29.67 +    else
   29.68 +#endif
   29.69 +    {
   29.70 +        relocate_new_kernel_t rnk;
   29.71 +
   29.72 +        rnk = (relocate_new_kernel_t) image->page_list[1];
   29.73 +        (*rnk)(image->indirection_page, image->page_list,
   29.74 +               image->start_address);
   29.75 +    }
   29.76 +}
   29.77 +
   29.78  /*
   29.79   * Local variables:
   29.80   * mode: C
    30.1 --- a/xen/arch/x86/x86_64/Makefile	Wed Feb 07 10:46:18 2007 -0700
    30.2 +++ b/xen/arch/x86/x86_64/Makefile	Thu Feb 08 17:27:30 2007 +0000
    30.3 @@ -1,4 +1,5 @@
    30.4  obj-y += entry.o
    30.5 +obj-y += compat_kexec.o
    30.6  obj-y += gpr_switch.o
    30.7  obj-y += mm.o
    30.8  obj-y += traps.o
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/xen/arch/x86/x86_64/compat_kexec.S	Thu Feb 08 17:27:30 2007 +0000
    31.3 @@ -0,0 +1,126 @@
    31.4 +/*
    31.5 + * Compatibility kexec handler.
    31.6 + */
    31.7 +
    31.8 +#include <xen/config.h>
    31.9 +
   31.10 +#include <asm/asm_defns.h>
   31.11 +#include <asm/msr.h>
   31.12 +#include <asm/page.h>
   31.13 +
   31.14 +.text
   31.15 +
   31.16 +        .code64
   31.17 +
   31.18 +ENTRY(compat_machine_kexec)
   31.19 +        /* x86/64                        x86/32  */
   31.20 +        /* %rdi - relocate_new_kernel_t  CALL    */
   31.21 +        /* %rsi - indirection page       4(%esp) */
   31.22 +        /* %rdx - page_list              8(%esp) */
   31.23 +        /* %rcx - start address         12(%esp) */
   31.24 +        /*        cpu has pae           16(%esp) */
   31.25 +
   31.26 +        /* Shim the 64 bit page_list into a 32 bit page_list. */
   31.27 +        mov $12,%r9
   31.28 +        lea compat_page_list(%rip), %rbx
   31.29 +1:      dec %r9
   31.30 +        movl (%rdx,%r9,8),%eax
   31.31 +        movl %eax,(%rbx,%r9,4)
   31.32 +        test %r9,%r9
   31.33 +        jnz 1b
   31.34 +
   31.35 +        movq %rbx,%rdx
   31.36 +        mov $__PAGE_OFFSET,%rbx
   31.37 +        sub %rbx, %rdx
   31.38 +
   31.39 +        /*
   31.40 +         * Setup an identity mapped region in PML4[0] of idle page
   31.41 +         * table.
   31.42 +         */
   31.43 +        lea idle_pg_table_l3(%rip),%rax
   31.44 +        sub %rbx,%rax
   31.45 +        or  $0x63,%rax
   31.46 +        mov %rax, idle_pg_table(%rip)
   31.47 +
   31.48 +        /* Switch to idle page table. */
   31.49 +        movq $(idle_pg_table - __PAGE_OFFSET), %rax
   31.50 +        movq %rax, %cr3
   31.51 +
   31.52 +        /* Jump to low identity mapping in compatibility mode. */
   31.53 +        ljmp *compatibility_mode_far(%rip)
   31.54 +        ud2
   31.55 +
   31.56 +compatibility_mode_far:
   31.57 +        .long compatibility_mode - __PAGE_OFFSET
   31.58 +        .long __HYPERVISOR_CS32
   31.59 +
   31.60 +        .code32
   31.61 +
   31.62 +compatibility_mode:
   31.63 +        /* Setup some sane segments. */
   31.64 +        movl $__HYPERVISOR_DS32, %eax
   31.65 +        movl %eax, %ds
   31.66 +        movl %eax, %es
   31.67 +        movl %eax, %fs
   31.68 +        movl %eax, %gs
   31.69 +        movl %eax, %ss
   31.70 +
   31.71 +        /* Push arguments onto stack. */
   31.72 +        pushl $1   /* 16(%esp) - cpu has pae */
   31.73 +        pushl %ecx /* 12(%esp) - start address */
   31.74 +        pushl %edx /*  8(%esp) - page list */
   31.75 +        pushl %esi /*  4(%esp) - indirection page */
   31.76 +        pushl %edi /*  0(%esp) - CALL */
   31.77 +
   31.78 +        /* Disable paging and therefore leave 64 bit mode. */
   31.79 +        movl %cr0, %eax
   31.80 +        andl $~X86_CR0_PG, %eax
   31.81 +        movl %eax, %cr0
   31.82 +
   31.83 +        /* Switch to 32 bit page table. */
   31.84 +        movl  $compat_pg_table - __PAGE_OFFSET, %eax
   31.85 +        movl  %eax, %cr3
   31.86 +
   31.87 +        /* Clear MSR_EFER[LME], disabling long mode */
   31.88 +        movl    $MSR_EFER,%ecx
   31.89 +        rdmsr
   31.90 +        btcl    $_EFER_LME,%eax
   31.91 +        wrmsr
   31.92 +
   31.93 +        /* Re-enable paging, but only 32 bit mode now. */
   31.94 +        movl %cr0, %eax
   31.95 +        orl $X86_CR0_PG, %eax
   31.96 +        movl %eax, %cr0
   31.97 +
   31.98 +        popl %eax
   31.99 +        call *%eax
  31.100 +        ud2
  31.101 +
  31.102 +compat_page_list:
  31.103 +        .fill 12,4,0
  31.104 +
  31.105 +        .align 32,0
  31.106 +
  31.107 +        /*
  31.108 +         * These compat page tables contain an identity mapping of the
  31.109 +         * first 1G of the physical address space.
  31.110 +         */
  31.111 +compat_pg_table:
  31.112 +        .long compat_pg_table_l2 + 0*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
  31.113 +        .long 0, 0
  31.114 +        .long 0, 0
  31.115 +        .long 0, 0
  31.116 +
  31.117 +        .align 4096,0
  31.118 +
  31.119 +compat_pg_table_l2:
  31.120 +        .macro identmap from=0, count=512
  31.121 +        .if \count-1
  31.122 +        identmap "(\from+0)","(\count/2)"
  31.123 +        identmap "(\from+(0x200000*(\count/2)))","(\count/2)"
  31.124 +        .else
  31.125 +        .quad 0x00000000000000e3 + \from
  31.126 +        .endif
  31.127 +        .endm
  31.128 +
  31.129 +        identmap
    32.1 --- a/xen/common/kexec.c	Wed Feb 07 10:46:18 2007 -0700
    32.2 +++ b/xen/common/kexec.c	Thu Feb 08 17:27:30 2007 +0000
    32.3 @@ -6,7 +6,6 @@
    32.4   * - Magnus Damm <magnus@valinux.co.jp>
    32.5   */
    32.6  
    32.7 -#include <asm/kexec.h>
    32.8  #include <xen/lib.h>
    32.9  #include <xen/ctype.h>
   32.10  #include <xen/errno.h>
    33.1 --- a/xen/common/memory.c	Wed Feb 07 10:46:18 2007 -0700
    33.2 +++ b/xen/common/memory.c	Thu Feb 08 17:27:30 2007 +0000
    33.3 @@ -175,11 +175,13 @@ int guest_remove_page(struct domain *d, 
    33.4  
    33.5      if ( unlikely(!page_is_removable(page)) )
    33.6      {
    33.7 +        shadow_drop_references(d, page);
    33.8          /* We'll make this a guest-visible error in future, so take heed! */
    33.9 -        gdprintk(XENLOG_INFO, "Dom%d freeing in-use page %lx (pseudophys %lx):"
   33.10 -                " count=%lx type=%lx\n",
   33.11 -                d->domain_id, mfn, get_gpfn_from_mfn(mfn),
   33.12 -                (unsigned long)page->count_info, page->u.inuse.type_info);
   33.13 +        if ( !page_is_removable(page) )
   33.14 +            gdprintk(XENLOG_INFO, "Dom%d freeing in-use page %lx "
   33.15 +                     "(pseudophys %lx): count=%lx type=%lx\n",
   33.16 +                     d->domain_id, mfn, get_gpfn_from_mfn(mfn),
   33.17 +                     (unsigned long)page->count_info, page->u.inuse.type_info);
   33.18      }
   33.19  
   33.20      guest_physmap_remove_page(d, gmfn, mfn);
    34.1 --- a/xen/drivers/char/console.c	Wed Feb 07 10:46:18 2007 -0700
    34.2 +++ b/xen/drivers/char/console.c	Thu Feb 08 17:27:30 2007 +0000
    34.3 @@ -223,7 +223,7 @@ int console_steal(int handle, void (*fn)
    34.4      if ( (handle == -1) || (handle != sercon_handle) )
    34.5          return 0;
    34.6  
    34.7 -    if ( serial_steal_fn == NULL )
    34.8 +    if ( serial_steal_fn != NULL )
    34.9          return -EBUSY;
   34.10  
   34.11      serial_steal_fn = fn;
    35.1 --- a/xen/include/asm-ia64/kexec.h	Wed Feb 07 10:46:18 2007 -0700
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,25 +0,0 @@
    35.4 -#ifndef __IA64_KEXEC_H__
    35.5 -#define __IA64_KEXEC_H__
    35.6 -
    35.7 -#include <xen/lib.h>       /* for printk() used in stub */
    35.8 -#include <xen/types.h>
    35.9 -#include <public/xen.h>
   35.10 -#include <xen/kexec.h>
   35.11 -
   35.12 -static inline void machine_kexec(xen_kexec_image_t *image)
   35.13 -{
   35.14 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   35.15 -}
   35.16 -
   35.17 -#endif /* __IA64_KEXEC_H__ */
   35.18 -
   35.19 -/*
   35.20 - * Local variables:
   35.21 - * mode: C
   35.22 - * c-set-style: "BSD"
   35.23 - * c-basic-offset: 4
   35.24 - * tab-width: 4
   35.25 - * indent-tabs-mode: nil
   35.26 - * End:
   35.27 - */
   35.28 -
    36.1 --- a/xen/include/asm-powerpc/kexec.h	Wed Feb 07 10:46:18 2007 -0700
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,25 +0,0 @@
    36.4 -#ifndef _ASM_KEXEC_H__
    36.5 -#define _ASM_KEXEC_H__
    36.6 -
    36.7 -#include <xen/lib.h>       /* for printk() used in stub */
    36.8 -#include <xen/types.h>
    36.9 -#include <public/xen.h>
   36.10 -#include <xen/kexec.h>
   36.11 -
   36.12 -static inline void machine_kexec(xen_kexec_image_t *image)
   36.13 -{
   36.14 -    printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
   36.15 -}
   36.16 -
   36.17 -#endif /* _ASM_KEXEC_H__ */
   36.18 -
   36.19 -/*
   36.20 - * Local variables:
   36.21 - * mode: C
   36.22 - * c-set-style: "BSD"
   36.23 - * c-basic-offset: 4
   36.24 - * tab-width: 4
   36.25 - * indent-tabs-mode: nil
   36.26 - * End:
   36.27 - */
   36.28 -
    37.1 --- a/xen/include/asm-x86/config.h	Wed Feb 07 10:46:18 2007 -0700
    37.2 +++ b/xen/include/asm-x86/config.h	Thu Feb 08 17:27:30 2007 +0000
    37.3 @@ -145,9 +145,9 @@
    37.4   * Compatibility guest area layout:
    37.5   *  0x0000000000000000 - 0x00000000f57fffff [3928MB,            PML4:0]
    37.6   *    Guest-defined use.
    37.7 - *  0x0000000f58000000 - 0x00000000ffffffff [168MB,             PML4:0]
    37.8 + *  0x00000000f5800000 - 0x00000000ffffffff [168MB,             PML4:0]
    37.9   *    Read-only machine-to-phys translation table (GUEST ACCESSIBLE).
   37.10 - *  0x0000000000000000 - 0x00000000ffffffff [508GB,             PML4:0]
   37.11 + *  0x0000000100000000 - 0x0000007fffffffff [508GB,             PML4:0]
   37.12   *    Unused.
   37.13   *  0x0000008000000000 - 0x000000ffffffffff [512GB, 2^39 bytes, PML4:1]
   37.14   *    Hypercall argument translation area.
    38.1 --- a/xen/include/asm-x86/hvm/vpt.h	Wed Feb 07 10:46:18 2007 -0700
    38.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Thu Feb 08 17:27:30 2007 +0000
    38.3 @@ -94,14 +94,12 @@ typedef struct RTCState {
    38.4      struct periodic_time pt;
    38.5  } RTCState;
    38.6  
    38.7 -#define FREQUENCE_PMTIMER  3579545
    38.8 +#define FREQUENCE_PMTIMER  3579545  /* Timer should run at 3.579545 MHz */
    38.9  typedef struct PMTState {
   38.10 -    uint32_t pm1_timer;
   38.11 -    uint32_t pm1_status;
   38.12 -    uint64_t last_gtime;
   38.13 -    struct timer timer;
   38.14 -    uint64_t scale;
   38.15 -    struct vcpu *vcpu;
   38.16 +    struct hvm_hw_pmtimer pm;   /* 32bit timer value */
   38.17 +    struct vcpu *vcpu;          /* Keeps sync with this vcpu's guest-time */
   38.18 +    uint64_t last_gtime;        /* Last (guest) time we updated the timer */
   38.19 +    uint64_t scale;             /* Multiplier to get from tsc to timer ticks */
   38.20  } PMTState;
   38.21  
   38.22  struct pl_time {    /* platform time */
   38.23 @@ -134,8 +132,6 @@ void rtc_migrate_timers(struct vcpu *v);
   38.24  void rtc_deinit(struct domain *d);
   38.25  int is_rtc_periodic_irq(void *opaque);
   38.26  void pmtimer_init(struct vcpu *v, int base);
   38.27 -void pmtimer_migrate_timers(struct vcpu *v);
   38.28 -void pmtimer_deinit(struct domain *d);
   38.29  
   38.30  void hpet_migrate_timers(struct vcpu *v);
   38.31  void hpet_init(struct vcpu *v);
    39.1 --- a/xen/include/asm-x86/kexec.h	Wed Feb 07 10:46:18 2007 -0700
    39.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.3 @@ -1,20 +0,0 @@
    39.4 -#ifndef __X86_KEXEC_H__
    39.5 -#define __X86_KEXEC_H__
    39.6 -
    39.7 -#ifdef __x86_64__
    39.8 -#include <asm/x86_64/kexec.h>
    39.9 -#else
   39.10 -#include <asm/x86_32/kexec.h>
   39.11 -#endif
   39.12 -
   39.13 -#endif /* __X86_KEXEC_H__ */
   39.14 -
   39.15 -/*
   39.16 - * Local variables:
   39.17 - * mode: C
   39.18 - * c-set-style: "BSD"
   39.19 - * c-basic-offset: 4
   39.20 - * tab-width: 4
   39.21 - * indent-tabs-mode: nil
   39.22 - * End:
   39.23 - */
    40.1 --- a/xen/include/asm-x86/shadow.h	Wed Feb 07 10:46:18 2007 -0700
    40.2 +++ b/xen/include/asm-x86/shadow.h	Thu Feb 08 17:27:30 2007 +0000
    40.3 @@ -355,8 +355,9 @@ int sh_remove_all_mappings(struct vcpu *
    40.4  static inline void 
    40.5  shadow_drop_references(struct domain *d, struct page_info *p)
    40.6  {
    40.7 -    /* See the comment about locking in sh_remove_all_mappings */
    40.8 -    sh_remove_all_mappings(d->vcpu[0], _mfn(page_to_mfn(p)));
    40.9 +    if ( unlikely(shadow_mode_enabled(d)) )
   40.10 +        /* See the comment about locking in sh_remove_all_mappings */
   40.11 +        sh_remove_all_mappings(d->vcpu[0], _mfn(page_to_mfn(p)));
   40.12  }
   40.13  
   40.14  /* Remove all shadows of the guest mfn. */
    41.1 --- a/xen/include/asm-x86/x86_32/kexec.h	Wed Feb 07 10:46:18 2007 -0700
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,39 +0,0 @@
    41.4 -/******************************************************************************
    41.5 - * kexec.h
    41.6 - * 
    41.7 - * Based heavily on machine_kexec.c and kexec.h from Linux 2.6.19-rc1
    41.8 - *
    41.9 - */
   41.10 -  
   41.11 -#ifndef __X86_KEXEC_X86_32_H__
   41.12 -#define __X86_KEXEC_X86_32_H__
   41.13 -
   41.14 -#include <xen/types.h>
   41.15 -#include <xen/kexec.h>
   41.16 -
   41.17 -typedef asmlinkage void (*relocate_new_kernel_t)(
   41.18 -               unsigned long indirection_page,
   41.19 -               unsigned long page_list,
   41.20 -               unsigned long start_address,
   41.21 -               unsigned int has_pae);
   41.22 -
   41.23 -static inline void machine_kexec(xen_kexec_image_t *image)
   41.24 -{
   41.25 -    relocate_new_kernel_t rnk;
   41.26 -
   41.27 -    rnk = (relocate_new_kernel_t) image->page_list[1];
   41.28 -    (*rnk)(image->indirection_page, (unsigned long)image->page_list, 
   41.29 -           image->start_address, (unsigned long)cpu_has_pae);
   41.30 -}
   41.31 -
   41.32 -#endif /* __X86_KEXEC_X86_32_H__ */
   41.33 -
   41.34 -/*
   41.35 - * Local variables:
   41.36 - * mode: C
   41.37 - * c-set-style: "BSD"
   41.38 - * c-basic-offset: 4
   41.39 - * tab-width: 4
   41.40 - * indent-tabs-mode: nil
   41.41 - * End:
   41.42 - */
    42.1 --- a/xen/include/asm-x86/x86_64/kexec.h	Wed Feb 07 10:46:18 2007 -0700
    42.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.3 @@ -1,38 +0,0 @@
    42.4 -/******************************************************************************
    42.5 - * kexec.h
    42.6 - * 
    42.7 - * Based heavily on machine_kexec.c and kexec.h from Linux 2.6.19-rc1
    42.8 - *
    42.9 - */
   42.10 -
   42.11 -#ifndef __X86_64_KEXEC_H__
   42.12 -#define __X86_64_KEXEC_H__
   42.13 -  
   42.14 -#include <xen/types.h>
   42.15 -#include <xen/kexec.h>
   42.16 -
   42.17 -typedef void (*relocate_new_kernel_t)(
   42.18 -                unsigned long indirection_page,
   42.19 -                unsigned long page_list,
   42.20 -                unsigned long start_address);
   42.21 -
   42.22 -static inline void machine_kexec(xen_kexec_image_t *image)
   42.23 -{
   42.24 -    relocate_new_kernel_t rnk;
   42.25 -
   42.26 -    rnk = (relocate_new_kernel_t) image->page_list[1];
   42.27 -    (*rnk)(image->indirection_page, (unsigned long)image->page_list, 
   42.28 -           image->start_address);
   42.29 -}
   42.30 -
   42.31 -#endif /* __X86_64_KEXEC_H__ */
   42.32 -
   42.33 -/*
   42.34 - * Local variables:
   42.35 - * mode: C
   42.36 - * c-set-style: "BSD"
   42.37 - * c-basic-offset: 4
   42.38 - * tab-width: 4
   42.39 - * indent-tabs-mode: nil
   42.40 - * End:
   42.41 - */
    43.1 --- a/xen/include/public/hvm/save.h	Wed Feb 07 10:46:18 2007 -0700
    43.2 +++ b/xen/include/public/hvm/save.h	Thu Feb 08 17:27:30 2007 +0000
    43.3 @@ -382,10 +382,20 @@ struct hvm_hw_hpet {
    43.4  DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
    43.5  
    43.6  
    43.7 +/*
    43.8 + * PM timer
    43.9 + */
   43.10 +
   43.11 +struct hvm_hw_pmtimer {
   43.12 +    uint32_t timer;
   43.13 +};
   43.14 +
   43.15 +DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
   43.16 +
   43.17  /* 
   43.18   * Largest type-code in use
   43.19   */
   43.20 -#define HVM_SAVE_CODE_MAX 12
   43.21 +#define HVM_SAVE_CODE_MAX 13
   43.22  
   43.23  
   43.24  /* 
    44.1 --- a/xen/include/xen/kexec.h	Wed Feb 07 10:46:18 2007 -0700
    44.2 +++ b/xen/include/xen/kexec.h	Thu Feb 08 17:27:30 2007 +0000
    44.3 @@ -25,6 +25,7 @@ int machine_kexec_load(int type, int slo
    44.4  void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image);
    44.5  void machine_kexec_reserved(xen_kexec_reserve_t *reservation);
    44.6  void machine_reboot_kexec(xen_kexec_image_t *image);
    44.7 +void machine_kexec(xen_kexec_image_t *image);
    44.8  void kexec_crash(void);
    44.9  void kexec_crash_save_cpu(void);
   44.10  crash_xen_info_t *kexec_crash_save_info(void);