ia64/xen-unstable

changeset 14087:6510cb03aae1

Merge with xen-ia64-unstable.hg.
author kfraser@localhost.localdomain
date Fri Feb 23 10:38:33 2007 +0000 (2007-02-23)
parents 202eb735b425 e8470a1a01af
children d7fe2318fc5f
files
line diff
     1.1 --- a/tools/blktap/drivers/block-aio.c	Thu Feb 22 10:15:29 2007 -0700
     1.2 +++ b/tools/blktap/drivers/block-aio.c	Fri Feb 23 10:38:33 2007 +0000
     1.3 @@ -152,9 +152,9 @@ static inline void init_fds(struct disk_
     1.4  }
     1.5  
     1.6  /* Open the disk file and initialize aio state. */
     1.7 -int tdaio_open (struct disk_driver *dd, const char *name)
     1.8 +int tdaio_open (struct disk_driver *dd, const char *name, td_flag_t flags)
     1.9  {
    1.10 -	int i, fd, ret = 0;
    1.11 +	int i, fd, ret = 0, o_flags;
    1.12  	struct td_state    *s   = dd->td_state;
    1.13  	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
    1.14  
    1.15 @@ -187,12 +187,15 @@ int tdaio_open (struct disk_driver *dd, 
    1.16  		prv->iocb_free[i] = &prv->iocb_list[i];
    1.17  
    1.18  	/* Open the file */
    1.19 -        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
    1.20 +	o_flags = O_DIRECT | O_LARGEFILE | 
    1.21 +		((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
    1.22 +        fd = open(name, o_flags);
    1.23  
    1.24          if ( (fd == -1) && (errno == EINVAL) ) {
    1.25  
    1.26                  /* Maybe O_DIRECT isn't supported. */
    1.27 -                fd = open(name, O_RDWR | O_LARGEFILE);
    1.28 +		o_flags &= ~O_DIRECT;
    1.29 +                fd = open(name, o_flags);
    1.30                  if (fd != -1) DPRINTF("WARNING: Accessing image without"
    1.31                                       "O_DIRECT! (%s)\n", name);
    1.32  
    1.33 @@ -280,6 +283,9 @@ int tdaio_submit(struct disk_driver *dd)
    1.34  	int ret;
    1.35  	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
    1.36  
    1.37 +	if (!prv->iocb_queued)
    1.38 +		return 0;
    1.39 +
    1.40  	ret = io_submit(prv->aio_ctx, prv->iocb_queued, prv->iocb_queue);
    1.41  	
    1.42  	/* XXX: TODO: Handle error conditions here. */
    1.43 @@ -324,12 +330,13 @@ int tdaio_do_callbacks(struct disk_drive
    1.44  	return rsp;
    1.45  }
    1.46  
    1.47 -int tdaio_has_parent(struct disk_driver *dd)
    1.48 +int tdaio_get_parent_id(struct disk_driver *dd, struct disk_id *id)
    1.49  {
    1.50 -	return 0;
    1.51 +	return TD_NO_PARENT;
    1.52  }
    1.53  
    1.54 -int tdaio_get_parent(struct disk_driver *dd, struct disk_driver *parent)
    1.55 +int tdaio_validate_parent(struct disk_driver *dd, 
    1.56 +			  struct disk_driver *parent, td_flag_t flags)
    1.57  {
    1.58  	return -EINVAL;
    1.59  }
    1.60 @@ -341,8 +348,8 @@ struct tap_disk tapdisk_aio = {
    1.61  	.td_queue_read      = tdaio_queue_read,
    1.62  	.td_queue_write     = tdaio_queue_write,
    1.63  	.td_submit          = tdaio_submit,
    1.64 -	.td_has_parent      = tdaio_has_parent,
    1.65 -	.td_get_parent      = tdaio_get_parent,
    1.66  	.td_close           = tdaio_close,
    1.67  	.td_do_callbacks    = tdaio_do_callbacks,
    1.68 +	.td_get_parent_id   = tdaio_get_parent_id,
    1.69 +	.td_validate_parent = tdaio_validate_parent
    1.70  };
     2.1 --- a/tools/blktap/drivers/block-qcow.c	Thu Feb 22 10:15:29 2007 -0700
     2.2 +++ b/tools/blktap/drivers/block-qcow.c	Fri Feb 23 10:38:33 2007 +0000
     2.3 @@ -209,23 +209,6 @@ static int init_aio_state(struct disk_dr
     2.4  	return -1;
     2.5  }
     2.6  
     2.7 -/*
     2.8 - *Test if block is zero. 
     2.9 - * Return: 
    2.10 - *       1 for TRUE
    2.11 - *       0 for FALSE
    2.12 - */
    2.13 -static inline int IS_ZERO(char *buf, int len)
    2.14 -{
    2.15 -	int i;
    2.16 -
    2.17 -	for (i = 0; i < len; i++) {
    2.18 -		/*if not zero, return false*/
    2.19 -		if (ZERO_TEST(*(buf + i))) return 0; 
    2.20 -	}
    2.21 -	return 1;
    2.22 -}
    2.23 -
    2.24  static uint32_t gen_cksum(char *ptr, int len)
    2.25  {
    2.26  	unsigned char *md;
    2.27 @@ -825,9 +808,9 @@ static inline void init_fds(struct disk_
    2.28  }
    2.29  
    2.30  /* Open the disk file and initialize qcow state. */
    2.31 -int tdqcow_open (struct disk_driver *dd, const char *name)
    2.32 +int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags)
    2.33  {
    2.34 -	int fd, len, i, shift, ret, size, l1_table_size;
    2.35 +	int fd, len, i, shift, ret, size, l1_table_size, o_flags;
    2.36  	struct td_state     *bs = dd->td_state;
    2.37  	struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
    2.38  	char *buf;
    2.39 @@ -838,7 +821,9 @@ int tdqcow_open (struct disk_driver *dd,
    2.40  
    2.41   	DPRINTF("QCOW: Opening %s\n",name);
    2.42  
    2.43 -	fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
    2.44 +	o_flags = O_DIRECT | O_LARGEFILE | 
    2.45 +		((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
    2.46 +	fd = open(name, o_flags);
    2.47  	if (fd < 0) {
    2.48  		DPRINTF("Unable to open %s (%d)\n",name,0 - errno);
    2.49  		return -1;
    2.50 @@ -1016,7 +1001,8 @@ int tdqcow_queue_read(struct disk_driver
    2.51  				 * as busy and try again later */
    2.52  				return cb(dd, -EBUSY, sector + n,
    2.53  					  nb_sectors - n, id, private);
    2.54 -			} else rsp += ret;
    2.55 +			} else
    2.56 +				rsp += ret;
    2.57  		} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
    2.58  			aio_unlock(s, sector);
    2.59  			if (decompress_cluster(s, cluster_offset) < 0) {
    2.60 @@ -1403,21 +1389,15 @@ int qcow_compress_cluster(struct tdqcow_
    2.61  	return 0;
    2.62  }
    2.63  
    2.64 -int tdqcow_has_parent(struct disk_driver *dd)
    2.65 -{
    2.66 -	struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
    2.67 -	return (s->backing_file_offset ? 1 : 0);
    2.68 -}
    2.69 -
    2.70 -int tdqcow_get_parent(struct disk_driver *cdd, struct disk_driver *pdd)
    2.71 +int tdqcow_get_parent_id(struct disk_driver *dd, struct disk_id *id)
    2.72  {
    2.73  	off_t off;
    2.74  	char *buf, *filename;
    2.75 -	int len, secs, ret = -1;
    2.76 -	struct tdqcow_state *child  = (struct tdqcow_state *)cdd->private;
    2.77 +	int len, secs, err = -EINVAL;
    2.78 +	struct tdqcow_state *child  = (struct tdqcow_state *)dd->private;
    2.79  
    2.80  	if (!child->backing_file_offset)
    2.81 -		return -1;
    2.82 +		return TD_NO_PARENT;
    2.83  
    2.84  	/* read the backing file name */
    2.85  	len  = child->backing_file_size;
    2.86 @@ -1432,14 +1412,39 @@ int tdqcow_get_parent(struct disk_driver
    2.87  
    2.88  	if (read(child->fd, buf, secs << 9) != secs << 9)
    2.89  		goto out;
    2.90 -	filename      = buf + (child->backing_file_offset - off);
    2.91 -	filename[len] = '\0';
    2.92 +	filename       = buf + (child->backing_file_offset - off);
    2.93 +	filename[len]  = '\0';
    2.94  
    2.95 -	/*Open backing file*/
    2.96 -	ret = tdqcow_open(pdd, filename);
    2.97 +	id->name       = strdup(filename);
    2.98 +	id->drivertype = DISK_TYPE_QCOW;
    2.99 +	err            = 0;
   2.100   out:
   2.101  	free(buf);
   2.102 -	return ret;
   2.103 +	return err;
   2.104 +}
   2.105 +
   2.106 +int tdqcow_validate_parent(struct disk_driver *child,
   2.107 +			   struct disk_driver *parent, td_flag_t flags)
   2.108 +{
   2.109 +	struct stat stats;
   2.110 +	uint64_t psize, csize;
   2.111 +	struct tdqcow_state *c = (struct tdqcow_state *)child->private;
   2.112 +	struct tdqcow_state *p = (struct tdqcow_state *)parent->private;
   2.113 +	
   2.114 +	if (stat(p->name, &stats))
   2.115 +		return -EINVAL;
   2.116 +	if (get_filesize(p->name, &psize, &stats))
   2.117 +		return -EINVAL;
   2.118 +
   2.119 +	if (stat(c->name, &stats))
   2.120 +		return -EINVAL;
   2.121 +	if (get_filesize(c->name, &csize, &stats))
   2.122 +		return -EINVAL;
   2.123 +
   2.124 +	if (csize != psize)
   2.125 +		return -EINVAL;
   2.126 +
   2.127 +	return 0;
   2.128  }
   2.129  
   2.130  struct tap_disk tapdisk_qcow = {
   2.131 @@ -1449,8 +1454,8 @@ struct tap_disk tapdisk_qcow = {
   2.132  	.td_queue_read       = tdqcow_queue_read,
   2.133  	.td_queue_write      = tdqcow_queue_write,
   2.134  	.td_submit           = tdqcow_submit,
   2.135 -	.td_has_parent       = tdqcow_has_parent,
   2.136 -	.td_get_parent       = tdqcow_get_parent,
   2.137  	.td_close            = tdqcow_close,
   2.138  	.td_do_callbacks     = tdqcow_do_callbacks,
   2.139 +	.td_get_parent_id    = tdqcow_get_parent_id,
   2.140 +	.td_validate_parent  = tdqcow_validate_parent
   2.141  };
     3.1 --- a/tools/blktap/drivers/block-ram.c	Thu Feb 22 10:15:29 2007 -0700
     3.2 +++ b/tools/blktap/drivers/block-ram.c	Fri Feb 23 10:38:33 2007 +0000
     3.3 @@ -135,11 +135,11 @@ static inline void init_fds(struct disk_
     3.4  }
     3.5  
     3.6  /* Open the disk file and initialize ram state. */
     3.7 -int tdram_open (struct disk_driver *dd, const char *name)
     3.8 +int tdram_open (struct disk_driver *dd, const char *name, td_flag_t flags)
     3.9  {
    3.10  	char *p;
    3.11  	uint64_t size;
    3.12 -	int i, fd, ret = 0, count = 0;
    3.13 +	int i, fd, ret = 0, count = 0, o_flags;
    3.14  	struct td_state    *s     = dd->td_state;
    3.15  	struct tdram_state *prv   = (struct tdram_state *)dd->private;
    3.16  
    3.17 @@ -167,12 +167,15 @@ int tdram_open (struct disk_driver *dd, 
    3.18  	}
    3.19  
    3.20  	/* Open the file */
    3.21 -        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
    3.22 +	o_flags = O_DIRECT | O_LARGEFILE | 
    3.23 +		((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
    3.24 +        fd = open(name, o_flags);
    3.25  
    3.26          if ((fd == -1) && (errno == EINVAL)) {
    3.27  
    3.28                  /* Maybe O_DIRECT isn't supported. */
    3.29 -                fd = open(name, O_RDWR | O_LARGEFILE);
    3.30 +		o_flags &= ~O_DIRECT;
    3.31 +                fd = open(name, o_flags);
    3.32                  if (fd != -1) DPRINTF("WARNING: Accessing image without"
    3.33                                       "O_DIRECT! (%s)\n", name);
    3.34  
    3.35 @@ -275,12 +278,13 @@ int tdram_do_callbacks(struct disk_drive
    3.36  	return 1;
    3.37  }
    3.38  
    3.39 -int tdram_has_parent(struct disk_driver *dd)
    3.40 +int tdram_get_parent_id(struct disk_driver *dd, struct disk_id *id)
    3.41  {
    3.42 -	return 0;
    3.43 +	return TD_NO_PARENT;
    3.44  }
    3.45  
    3.46 -int tdram_get_parent(struct disk_driver *dd, struct disk_driver *parent)
    3.47 +int tdram_validate_parent(struct disk_driver *dd, 
    3.48 +			  struct disk_driver *parent, td_flag_t flags)
    3.49  {
    3.50  	return -EINVAL;
    3.51  }
    3.52 @@ -292,8 +296,8 @@ struct tap_disk tapdisk_ram = {
    3.53  	.td_queue_read      = tdram_queue_read,
    3.54  	.td_queue_write     = tdram_queue_write,
    3.55  	.td_submit          = tdram_submit,
    3.56 -	.td_has_parent      = tdram_has_parent,
    3.57 -	.td_get_parent      = tdram_get_parent,
    3.58  	.td_close           = tdram_close,
    3.59  	.td_do_callbacks    = tdram_do_callbacks,
    3.60 +	.td_get_parent_id   = tdram_get_parent_id,
    3.61 +	.td_validate_parent = tdram_validate_parent
    3.62  };
     4.1 --- a/tools/blktap/drivers/block-sync.c	Thu Feb 22 10:15:29 2007 -0700
     4.2 +++ b/tools/blktap/drivers/block-sync.c	Fri Feb 23 10:38:33 2007 +0000
     4.3 @@ -118,9 +118,9 @@ static inline void init_fds(struct disk_
     4.4  }
     4.5  
     4.6  /* Open the disk file and initialize aio state. */
     4.7 -int tdsync_open (struct disk_driver *dd, const char *name)
     4.8 +int tdsync_open (struct disk_driver *dd, const char *name, td_flag_t flags)
     4.9  {
    4.10 -	int i, fd, ret = 0;
    4.11 +	int i, fd, ret = 0, o_flags;
    4.12  	struct td_state     *s   = dd->td_state;
    4.13  	struct tdsync_state *prv = (struct tdsync_state *)dd->private;
    4.14  	
    4.15 @@ -130,11 +130,14 @@ int tdsync_open (struct disk_driver *dd,
    4.16  		return (0 - errno);
    4.17  	
    4.18  	/* Open the file */
    4.19 -        fd = open(name, O_RDWR | O_DIRECT | O_LARGEFILE);
    4.20 +	o_flags = O_DIRECT | O_LARGEFILE | 
    4.21 +		((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
    4.22 +        fd = open(name, o_flags);
    4.23  
    4.24          if ( (fd == -1) && (errno == EINVAL) ) {
    4.25  
    4.26                  /* Maybe O_DIRECT isn't supported. */
    4.27 +		o_flags &= ~O_DIRECT;
    4.28                  fd = open(name, O_RDWR | O_LARGEFILE);
    4.29                  if (fd != -1) DPRINTF("WARNING: Accessing image without"
    4.30                                       "O_DIRECT! (%s)\n", name);
    4.31 @@ -223,12 +226,13 @@ int tdsync_do_callbacks(struct disk_driv
    4.32  	return 1;
    4.33  }
    4.34  
    4.35 -int tdsync_has_parent(struct disk_driver *dd)
    4.36 +int tdsync_get_parent_id(struct disk_driver *dd, struct disk_id *id)
    4.37  {
    4.38 -	return 0;
    4.39 +	return TD_NO_PARENT;
    4.40  }
    4.41  
    4.42 -int tdsync_get_parent(struct disk_driver *dd, struct disk_driver *parent)
    4.43 +int tdsync_validate_parent(struct disk_driver *dd, 
    4.44 +			   struct disk_driver *parent, td_flag_t flags)
    4.45  {
    4.46  	return -EINVAL;
    4.47  }
    4.48 @@ -240,8 +244,8 @@ struct tap_disk tapdisk_sync = {
    4.49  	.td_queue_read       = tdsync_queue_read,
    4.50  	.td_queue_write      = tdsync_queue_write,
    4.51  	.td_submit           = tdsync_submit,
    4.52 -	.td_has_parent       = tdsync_has_parent,
    4.53 -	.td_get_parent       = tdsync_get_parent,
    4.54  	.td_close            = tdsync_close,
    4.55  	.td_do_callbacks     = tdsync_do_callbacks,
    4.56 +	.td_get_parent_id    = tdsync_get_parent_id,
    4.57 +	.td_validate_parent  = tdsync_validate_parent
    4.58  };
     5.1 --- a/tools/blktap/drivers/block-vmdk.c	Thu Feb 22 10:15:29 2007 -0700
     5.2 +++ b/tools/blktap/drivers/block-vmdk.c	Fri Feb 23 10:38:33 2007 +0000
     5.3 @@ -119,10 +119,11 @@ static inline void init_fds(struct disk_
     5.4  }
     5.5  
     5.6  /* Open the disk file and initialize aio state. */
     5.7 -static int tdvmdk_open (struct disk_driver *dd, const char *name)
     5.8 +static int tdvmdk_open (struct disk_driver *dd, 
     5.9 +			const char *name, td_flag_t flags)
    5.10  {
    5.11  	int ret, fd;
    5.12 -    	int l1_size, i;
    5.13 +    	int l1_size, i, o_flags;
    5.14      	uint32_t magic;
    5.15  	struct td_state     *s   = dd->td_state;
    5.16  	struct tdvmdk_state *prv = (struct tdvmdk_state *)dd->private;
    5.17 @@ -133,12 +134,15 @@ static int tdvmdk_open (struct disk_driv
    5.18  		return -1;
    5.19  	
    5.20  	/* Open the file */
    5.21 -        fd = open(name, O_RDWR | O_LARGEFILE); 
    5.22 +	o_flags = O_DIRECT | O_LARGEFILE | 
    5.23 +		((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
    5.24 +        fd = open(name, o_flags); 
    5.25  
    5.26          if ( (fd == -1) && (errno == EINVAL) ) {
    5.27  
    5.28                  /* Maybe O_DIRECT isn't supported. */
    5.29 -                fd = open(name, O_RDWR | O_LARGEFILE);
    5.30 +		o_flags &= ~O_DIRECT;
    5.31 +                fd = open(name, o_flags);
    5.32                  if (fd != -1) DPRINTF("WARNING: Accessing image without"
    5.33                                       "O_DIRECT! (%s)\n", name);
    5.34  
    5.35 @@ -394,12 +398,13 @@ static int tdvmdk_do_callbacks(struct di
    5.36  	return 1;
    5.37  }
    5.38  
    5.39 -static int tdvmdk_has_parent(struct disk_driver *dd)
    5.40 +static int tdvmdk_get_parent_id(struct disk_driver *dd, struct disk_id *id)
    5.41  {
    5.42 -	return 0;
    5.43 +	return TD_NO_PARENT;
    5.44  }
    5.45  
    5.46 -static int tdvmdk_get_parent(struct disk_driver *dd, struct disk_driver *parent)
    5.47 +static int tdvmdk_validate_parent(struct disk_driver *dd, 
    5.48 +				  struct disk_driver *parent, td_flag_t flags)
    5.49  {
    5.50  	return -EINVAL;
    5.51  }
    5.52 @@ -411,8 +416,8 @@ struct tap_disk tapdisk_vmdk = {
    5.53  	.td_queue_read       = tdvmdk_queue_read,
    5.54  	.td_queue_write      = tdvmdk_queue_write,
    5.55  	.td_submit           = tdvmdk_submit,
    5.56 -	.td_has_parent       = tdvmdk_has_parent,
    5.57 -	.td_get_parent       = tdvmdk_get_parent,
    5.58  	.td_close            = tdvmdk_close,
    5.59  	.td_do_callbacks     = tdvmdk_do_callbacks,
    5.60 +	.td_get_parent_id    = tdvmdk_get_parent_id,
    5.61 +	.td_validate_parent  = tdvmdk_validate_parent
    5.62  };
     6.1 --- a/tools/blktap/drivers/img2qcow.c	Thu Feb 22 10:15:29 2007 -0700
     6.2 +++ b/tools/blktap/drivers/img2qcow.c	Fri Feb 23 10:38:33 2007 +0000
     6.3 @@ -201,7 +201,7 @@ int main(int argc, char *argv[])
     6.4  	dd.private  = malloc(dd.drv->private_data_size);
     6.5  
     6.6          /*Open qcow file*/
     6.7 -        if (dd.drv->td_open(&dd, argv[1])!=0) {
     6.8 +        if (dd.drv->td_open(&dd, argv[1], 0)!=0) {
     6.9  		DFPRINTF("Unable to open Qcow file [%s]\n",argv[1]);
    6.10  		exit(-1);
    6.11  	}
     7.1 --- a/tools/blktap/drivers/qcow2raw.c	Thu Feb 22 10:15:29 2007 -0700
     7.2 +++ b/tools/blktap/drivers/qcow2raw.c	Fri Feb 23 10:38:33 2007 +0000
     7.3 @@ -169,7 +169,7 @@ int main(int argc, char *argv[])
     7.4  	ddqcow.drv = &tapdisk_qcow;
     7.5  	ddqcow.private = malloc(ddqcow.drv->private_data_size);
     7.6  
     7.7 -        if (ddqcow.drv->td_open(&ddqcow, argv[2])!=0) {
     7.8 +        if (ddqcow.drv->td_open(&ddqcow, argv[2], TD_RDONLY)!=0) {
     7.9  		DFPRINTF("Unable to open Qcow file [%s]\n",argv[2]);
    7.10  		exit(-1);
    7.11  	} else DFPRINTF("QCOW file opened, size %llu\n",
    7.12 @@ -270,7 +270,7 @@ int main(int argc, char *argv[])
    7.13  	ddaio.drv = &tapdisk_aio;
    7.14  	ddaio.private = malloc(ddaio.drv->private_data_size);
    7.15  
    7.16 -        if (ddaio.drv->td_open(&ddaio, argv[1])!=0) {
    7.17 +        if (ddaio.drv->td_open(&ddaio, argv[1], 0)!=0) {
    7.18  		DFPRINTF("Unable to open Qcow file [%s]\n", argv[1]);
    7.19  		exit(-1);
    7.20  	}
     8.1 --- a/tools/blktap/drivers/tapdisk.c	Thu Feb 22 10:15:29 2007 -0700
     8.2 +++ b/tools/blktap/drivers/tapdisk.c	Fri Feb 23 10:38:33 2007 +0000
     8.3 @@ -81,6 +81,15 @@ void daemonize(void)
     8.4  	return;
     8.5  }
     8.6  
     8.7 +static void free_driver(struct disk_driver *d)
     8.8 +{
     8.9 +	if (d->name)
    8.10 +		free(d->name);
    8.11 +	if (d->private)
    8.12 +		free(d->private);
    8.13 +	free(d);
    8.14 +}
    8.15 +
    8.16  static void unmap_disk(struct td_state *s)
    8.17  {
    8.18  	tapdev_info_t *info = s->ring_info;
    8.19 @@ -91,8 +100,7 @@ static void unmap_disk(struct td_state *
    8.20  	while (dd) {
    8.21  		tmp = dd->next;
    8.22  		dd->drv->td_close(dd);
    8.23 -		free(dd->private);
    8.24 -		free(dd);
    8.25 +		free_driver(dd);
    8.26  		dd = tmp;
    8.27  	}
    8.28  
    8.29 @@ -112,7 +120,6 @@ static void unmap_disk(struct td_state *
    8.30  	free(s);
    8.31  
    8.32  	return;
    8.33 -
    8.34  }
    8.35  
    8.36  void sig_handler(int sig)
    8.37 @@ -205,26 +212,6 @@ static struct td_state *state_init(void)
    8.38  	return s;
    8.39  }
    8.40  
    8.41 -static struct disk_driver *disk_init(struct td_state *s, struct tap_disk *drv)
    8.42 -{
    8.43 -	struct disk_driver *dd;
    8.44 -
    8.45 -	dd = calloc(1, sizeof(struct disk_driver));
    8.46 -	if (!dd)
    8.47 -		return NULL;
    8.48 -	
    8.49 -	dd->private = malloc(drv->private_data_size);
    8.50 -	if (!dd->private) {
    8.51 -		free(dd);
    8.52 -		return NULL;
    8.53 -	}
    8.54 -
    8.55 -	dd->drv      = drv;
    8.56 -	dd->td_state = s;
    8.57 -
    8.58 -	return dd;
    8.59 -}
    8.60 -
    8.61  static int map_new_dev(struct td_state *s, int minor)
    8.62  {
    8.63  	int tap_fd;
    8.64 @@ -280,49 +267,94 @@ static int map_new_dev(struct td_state *
    8.65  	return -1;
    8.66  }
    8.67  
    8.68 -static int open_disk(struct td_state *s, struct disk_driver *dd, char *path)
    8.69 +static struct disk_driver *disk_init(struct td_state *s, 
    8.70 +				     struct tap_disk *drv, char *name)
    8.71 +{
    8.72 +	struct disk_driver *dd;
    8.73 +
    8.74 +	dd = calloc(1, sizeof(struct disk_driver));
    8.75 +	if (!dd)
    8.76 +		return NULL;
    8.77 +	
    8.78 +	dd->private = malloc(drv->private_data_size);
    8.79 +	if (!dd->private) {
    8.80 +		free(dd);
    8.81 +		return NULL;
    8.82 +	}
    8.83 +
    8.84 +	dd->drv      = drv;
    8.85 +	dd->td_state = s;
    8.86 +	dd->name     = name;
    8.87 +
    8.88 +	return dd;
    8.89 +}
    8.90 +
    8.91 +static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
    8.92  {
    8.93  	int err;
    8.94 -	struct disk_driver *d = dd;
    8.95 +	char *dup;
    8.96 +	struct disk_id id;
    8.97 +	struct disk_driver *d;
    8.98 +
    8.99 +	dup = strdup(path);
   8.100 +	if (!dup)
   8.101 +		return -ENOMEM;
   8.102  
   8.103 -	err = dd->drv->td_open(dd, path);
   8.104 +	memset(&id, 0, sizeof(struct disk_id));
   8.105 +	s->disks = d = disk_init(s, drv, dup);
   8.106 +	if (!d)
   8.107 +		return -ENOMEM;
   8.108 +
   8.109 +	err = drv->td_open(d, path, 0);
   8.110  	if (err)
   8.111 -		return err;
   8.112 +		goto fail;
   8.113  
   8.114  	/* load backing files as necessary */
   8.115 -	while (d->drv->td_has_parent(d)) {
   8.116 +	while ((err = d->drv->td_get_parent_id(d, &id)) == 0) {
   8.117  		struct disk_driver *new;
   8.118  		
   8.119 -		new = calloc(1, sizeof(struct disk_driver));
   8.120 +		if (id.drivertype > MAX_DISK_TYPES || 
   8.121 +		    !get_driver(id.drivertype) || !id.name)
   8.122 +			goto fail;
   8.123 +
   8.124 +		dup = strdup(id.name);
   8.125 +		if (!dup)
   8.126 +			goto fail;
   8.127 +
   8.128 +		new = disk_init(s, get_driver(id.drivertype), dup);
   8.129  		if (!new)
   8.130  			goto fail;
   8.131 -		new->drv      = d->drv;
   8.132 -		new->td_state = s;
   8.133 -		new->private  = malloc(new->drv->private_data_size);
   8.134 -		if (!new->private) {
   8.135 -			free(new);
   8.136 -			goto fail;
   8.137 -		}
   8.138 -		
   8.139 -		err = d->drv->td_get_parent(d, new);
   8.140 +
   8.141 +		err = new->drv->td_open(new, new->name, TD_RDONLY);
   8.142  		if (err)
   8.143  			goto fail;
   8.144  
   8.145 +		err = d->drv->td_validate_parent(d, new, 0);
   8.146 +		if (err) {
   8.147 +			d->next = new;
   8.148 +			goto fail;
   8.149 +		}
   8.150 +
   8.151  		d = d->next = new;
   8.152 +		free(id.name);
   8.153  	}
   8.154  
   8.155 -	return 0;
   8.156 +	if (err >= 0)
   8.157 +		return 0;
   8.158  
   8.159   fail:
   8.160  	DPRINTF("failed opening disk\n");
   8.161 -	while (dd) {
   8.162 -		d = dd->next;
   8.163 -		dd->drv->td_close(dd);
   8.164 -		free(dd->private);
   8.165 -		free(dd);
   8.166 -		dd = d;
   8.167 +	if (id.name)
   8.168 +		free(id.name);
   8.169 +	d = s->disks;
   8.170 +	while (d) {
   8.171 +		struct disk_driver *tmp = d->next;
   8.172 +		d->drv->td_close(d);
   8.173 +		free_driver(d);
   8.174 +		d = tmp;
   8.175  	}
   8.176 -	return err;
   8.177 +	s->disks = NULL;
   8.178 +	return -1;
   8.179  }
   8.180  
   8.181  static int read_msg(char *buf)
   8.182 @@ -334,7 +366,6 @@ static int read_msg(char *buf)
   8.183  	msg_newdev_t *msg_dev;
   8.184  	msg_pid_t *msg_pid;
   8.185  	struct tap_disk *drv;
   8.186 -	struct disk_driver *dd;
   8.187  	int ret = -1;
   8.188  	struct td_state *s = NULL;
   8.189  	fd_list_entry_t *entry;
   8.190 @@ -369,14 +400,8 @@ static int read_msg(char *buf)
   8.191  			if (s == NULL)
   8.192  				goto params_done;
   8.193  
   8.194 -			s->disks = dd = disk_init(s, drv);
   8.195 -			if (!dd) {
   8.196 -				free(s);
   8.197 -				goto params_done;
   8.198 -			}
   8.199 -
   8.200  			/*Open file*/
   8.201 -			ret = open_disk(s, dd, path);
   8.202 +			ret = open_disk(s, drv, path);
   8.203  			if (ret)
   8.204  				goto params_done;
   8.205  
   8.206 @@ -785,6 +810,19 @@ int main(int argc, char *argv[])
   8.207  					}
   8.208  				}
   8.209  
   8.210 +				/* completed io from above may have 
   8.211 +				 * queued new requests on chained disks */
   8.212 +				if (progress_made) {
   8.213 +					td_for_each_disk(ptr->s, dd) {
   8.214 +						dd->early += 
   8.215 +							dd->drv->td_submit(dd);
   8.216 +						if (dd->early > 0) {
   8.217 +							io_done(dd, 10);
   8.218 +							dd->early = 0;
   8.219 +						}
   8.220 +					}
   8.221 +				}
   8.222 +
   8.223  				if (FD_ISSET(ptr->tap_fd, &readfds) ||
   8.224  				    (info->busy.req && progress_made))
   8.225  					get_io_request(ptr->s);
     9.1 --- a/tools/blktap/drivers/tapdisk.h	Thu Feb 22 10:15:29 2007 -0700
     9.2 +++ b/tools/blktap/drivers/tapdisk.h	Fri Feb 23 10:38:33 2007 +0000
     9.3 @@ -42,10 +42,15 @@
     9.4   * 
     9.5   *   - The fd used for poll is an otherwise unused pipe, which allows poll to 
     9.6   *     be safely called without ever returning anything.
     9.7 - * 
     9.8 + *
     9.9   * NOTE: tapdisk uses the number of sectors submitted per request as a 
    9.10   * ref count.  Plugins must use the callback function to communicate the
    9.11   * completion--or error--of every sector submitted to them.
    9.12 + *
    9.13 + * td_get_parent_id returns:
    9.14 + *     0 if parent id successfully retrieved
    9.15 + *     TD_NO_PARENT if no parent exists
    9.16 + *     -errno on error
    9.17   */
    9.18  
    9.19  #ifndef TAPDISK_H_
    9.20 @@ -71,12 +76,23 @@
    9.21  #define MAX_IOFD                 2
    9.22  
    9.23  #define BLK_NOT_ALLOCATED       99
    9.24 +#define TD_NO_PARENT             1
    9.25 +
    9.26 +typedef uint32_t td_flag_t;
    9.27 +
    9.28 +#define TD_RDONLY                1
    9.29  
    9.30  struct td_state;
    9.31  struct tap_disk;
    9.32  
    9.33 +struct disk_id {
    9.34 +	char *name;
    9.35 +	int drivertype;
    9.36 +};
    9.37 +
    9.38  struct disk_driver {
    9.39  	int early;
    9.40 +	char *name;
    9.41  	void *private;
    9.42  	int io_fd[MAX_IOFD];
    9.43  	struct tap_disk *drv;
    9.44 @@ -105,18 +121,20 @@ typedef int (*td_callback_t)(struct disk
    9.45  struct tap_disk {
    9.46  	const char *disk_type;
    9.47  	int private_data_size;
    9.48 -	int (*td_open)        (struct disk_driver *dd, const char *name);
    9.49 -	int (*td_queue_read)  (struct disk_driver *dd, uint64_t sector,
    9.50 -			       int nb_sectors, char *buf, td_callback_t cb, 
    9.51 -			       int id, void *prv);
    9.52 -	int (*td_queue_write) (struct disk_driver *dd, uint64_t sector,
    9.53 -			       int nb_sectors, char *buf, td_callback_t cb, 
    9.54 -			       int id, void *prv);
    9.55 -	int (*td_submit)      (struct disk_driver *dd);
    9.56 -	int (*td_has_parent)  (struct disk_driver *dd);
    9.57 -	int (*td_get_parent)  (struct disk_driver *dd, struct disk_driver *p);
    9.58 -	int (*td_close)       (struct disk_driver *dd);
    9.59 -	int (*td_do_callbacks)(struct disk_driver *dd, int sid);
    9.60 +	int (*td_open)           (struct disk_driver *dd, 
    9.61 +				  const char *name, td_flag_t flags);
    9.62 +	int (*td_queue_read)     (struct disk_driver *dd, uint64_t sector,
    9.63 +				  int nb_sectors, char *buf, td_callback_t cb,
    9.64 +				  int id, void *prv);
    9.65 +	int (*td_queue_write)    (struct disk_driver *dd, uint64_t sector,
    9.66 +				  int nb_sectors, char *buf, td_callback_t cb, 
    9.67 +				  int id, void *prv);
    9.68 +	int (*td_submit)         (struct disk_driver *dd);
    9.69 +	int (*td_close)          (struct disk_driver *dd);
    9.70 +	int (*td_do_callbacks)   (struct disk_driver *dd, int sid);
    9.71 +	int (*td_get_parent_id)  (struct disk_driver *dd, struct disk_id *id);
    9.72 +	int (*td_validate_parent)(struct disk_driver *dd, 
    9.73 +				  struct disk_driver *p, td_flag_t flags);
    9.74  };
    9.75  
    9.76  typedef struct disk_info {
    10.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Feb 22 10:15:29 2007 -0700
    10.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Feb 23 10:38:33 2007 +0000
    10.3 @@ -982,6 +982,12 @@ static void svm_hvm_inject_exception(
    10.4          v->arch.hvm_svm.vmcb->cr2 = v->arch.hvm_svm.cpu_cr2 = cr2;
    10.5  }
    10.6  
    10.7 +static int svm_event_injection_faulted(struct vcpu *v)
    10.8 +{
    10.9 +    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   10.10 +    return vmcb->exitintinfo.fields.v;
   10.11 +}
   10.12 +
   10.13  int start_svm(void)
   10.14  {
   10.15      u32 eax, ecx, edx;
   10.16 @@ -1058,6 +1064,8 @@ int start_svm(void)
   10.17      hvm_funcs.init_ap_context = svm_init_ap_context;
   10.18      hvm_funcs.init_hypercall_page = svm_init_hypercall_page;
   10.19  
   10.20 +    hvm_funcs.event_injection_faulted = svm_event_injection_faulted;
   10.21 +
   10.22      hvm_enable();
   10.23  
   10.24      return 1;
    11.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Feb 22 10:15:29 2007 -0700
    11.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Feb 23 10:38:33 2007 +0000
    11.3 @@ -990,6 +990,16 @@ static void vmx_update_vtpr(struct vcpu 
    11.4      /* VMX doesn't have a V_TPR field */
    11.5  }
    11.6  
    11.7 +static int vmx_event_injection_faulted(struct vcpu *v)
    11.8 +{
    11.9 +    unsigned int idtv_info_field;
   11.10 +
   11.11 +    ASSERT(v == current);
   11.12 +
   11.13 +    idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
   11.14 +    return (idtv_info_field & INTR_INFO_VALID_MASK);
   11.15 +}
   11.16 +
   11.17  /* Setup HVM interfaces */
   11.18  static void vmx_setup_hvm_funcs(void)
   11.19  {
   11.20 @@ -1025,6 +1035,8 @@ static void vmx_setup_hvm_funcs(void)
   11.21      hvm_funcs.init_ap_context = vmx_init_ap_context;
   11.22  
   11.23      hvm_funcs.init_hypercall_page = vmx_init_hypercall_page;
   11.24 +
   11.25 +    hvm_funcs.event_injection_faulted = vmx_event_injection_faulted;
   11.26  }
   11.27  
   11.28  int start_vmx(void)
    12.1 --- a/xen/arch/x86/mm/shadow/common.c	Thu Feb 22 10:15:29 2007 -0700
    12.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Feb 23 10:38:33 2007 +0000
    12.3 @@ -275,6 +275,10 @@ hvm_emulate_write(enum x86_segment seg,
    12.4      unsigned long addr;
    12.5      int rc;
    12.6  
    12.7 +    /* How many emulations could we save if we unshadowed on stack writes? */
    12.8 +    if ( seg == x86_seg_ss )
    12.9 +        perfc_incrc(shadow_fault_emulate_stack);
   12.10 +
   12.11      rc = hvm_translate_linear_addr(
   12.12          seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
   12.13      if ( rc )
    13.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Feb 22 10:15:29 2007 -0700
    13.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Fri Feb 23 10:38:33 2007 +0000
    13.3 @@ -2901,8 +2901,28 @@ static int sh_page_fault(struct vcpu *v,
    13.4          goto not_a_shadow_fault;
    13.5  
    13.6      if ( is_hvm_domain(d) )
    13.7 +    {
    13.8 +        /*
    13.9 +         * If we are in the middle of injecting an exception or interrupt then
   13.10 +         * we should not emulate: it is not the instruction at %eip that caused
   13.11 +         * the fault. Furthermore it is almost certainly the case the handler
   13.12 +         * stack is currently considered to be a page table, so we should
   13.13 +         * unshadow the faulting page before exiting.
   13.14 +         */
   13.15 +        if ( unlikely(hvm_event_injection_faulted(v)) )
   13.16 +        {
   13.17 +            gdprintk(XENLOG_DEBUG, "write to pagetable during event "
   13.18 +                     "injection: cr2=%#lx, mfn=%#lx\n", 
   13.19 +                     va, mfn_x(gmfn));
   13.20 +            sh_remove_shadows(v, gmfn, 0 /* thorough */, 1 /* must succeed */);
   13.21 +            goto done;
   13.22 +        }
   13.23 +
   13.24          hvm_store_cpu_guest_regs(v, regs, NULL);
   13.25 -    SHADOW_PRINTK("emulate: eip=%#lx\n", (unsigned long)regs->eip);
   13.26 +    }
   13.27 +
   13.28 +    SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", 
   13.29 +                  (unsigned long)regs->eip, (unsigned long)regs->esp);
   13.30  
   13.31      emul_ops = shadow_init_emulation(&emul_ctxt, regs);
   13.32  
    14.1 --- a/xen/arch/x86/setup.c	Thu Feb 22 10:15:29 2007 -0700
    14.2 +++ b/xen/arch/x86/setup.c	Fri Feb 23 10:38:33 2007 +0000
    14.3 @@ -476,7 +476,7 @@ void __init __start_xen(multiboot_info_t
    14.4              s = initial_images_end;
    14.5          init_boot_pages(s, e);
    14.6  
    14.7 -#if defined (CONFIG_X86_64)
    14.8 +#if defined(CONFIG_X86_64)
    14.9          /*
   14.10           * x86/64 maps all registered RAM. Points to note:
   14.11           *  1. The initial pagetable already maps low 1GB, so skip that.
   14.12 @@ -508,7 +508,6 @@ void __init __start_xen(multiboot_info_t
   14.13          unsigned long kdump_start, kdump_size, k;
   14.14  
   14.15          /* Mark images pages as free for now. */
   14.16 -
   14.17          init_boot_pages(initial_images_start, initial_images_end);
   14.18  
   14.19          kdump_start = kexec_crash_area.start;
   14.20 @@ -526,17 +525,19 @@ void __init __start_xen(multiboot_info_t
   14.21          kdump_size >>= PAGE_SHIFT;
   14.22  
   14.23          /* Allocate pages for Kdump memory area. */
   14.24 -
   14.25 -        k = alloc_boot_pages_at(kdump_size, kdump_start);
   14.26 -        if ( k != kdump_start )
   14.27 +        if ( !reserve_boot_pages(kdump_start, kdump_size) )
   14.28              panic("Unable to reserve Kdump memory\n");
   14.29  
   14.30          /* Allocate pages for relocated initial images. */
   14.31 -
   14.32          k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
   14.33          k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
   14.34  
   14.35 +#if defined(CONFIG_X86_32)
   14.36 +        /* Must allocate within bootstrap 1:1 limits. */
   14.37 +        k = alloc_boot_low_pages(k, 1); /* 0x0 - HYPERVISOR_VIRT_START */
   14.38 +#else
   14.39          k = alloc_boot_pages(k, 1);
   14.40 +#endif
   14.41          if ( k == 0 )
   14.42              panic("Unable to allocate initial images memory\n");
   14.43  
    15.1 --- a/xen/arch/x86/x86_64/mm.c	Thu Feb 22 10:15:29 2007 -0700
    15.2 +++ b/xen/arch/x86/x86_64/mm.c	Fri Feb 23 10:38:33 2007 +0000
    15.3 @@ -44,7 +44,8 @@ struct page_info *alloc_xen_pagetable(vo
    15.4      if ( !early_boot )
    15.5          return alloc_domheap_page(NULL);
    15.6  
    15.7 -    pfn = alloc_boot_pages(1, 1);
    15.8 +    /* Early pagetables must come from low 1GB of memory. */
    15.9 +    pfn = alloc_boot_low_pages(1, 1); /* 0x0 - 0x40000000 */
   15.10      return ((pfn == 0) ? NULL : mfn_to_page(pfn));
   15.11  }
   15.12  
    16.1 --- a/xen/common/page_alloc.c	Thu Feb 22 10:15:29 2007 -0700
    16.2 +++ b/xen/common/page_alloc.c	Fri Feb 23 10:38:33 2007 +0000
    16.3 @@ -95,9 +95,10 @@ static unsigned long scrub_pages;
    16.4  static unsigned long *alloc_bitmap;
    16.5  #define PAGES_PER_MAPWORD (sizeof(unsigned long) * 8)
    16.6  
    16.7 -#define allocated_in_map(_pn)                 \
    16.8 -( !! (alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & \
    16.9 -     (1UL<<((_pn)&(PAGES_PER_MAPWORD-1)))) )
   16.10 +#define allocated_in_map(_pn)                       \
   16.11 +({  unsigned long ___pn = (_pn);                    \
   16.12 +    !!(alloc_bitmap[___pn/PAGES_PER_MAPWORD] &      \
   16.13 +       (1UL<<(___pn&(PAGES_PER_MAPWORD-1)))); })
   16.14  
   16.15  /*
   16.16   * Hint regarding bitwise arithmetic in map_{alloc,free}:
   16.17 @@ -240,36 +241,65 @@ void init_boot_pages(paddr_t ps, paddr_t
   16.18      }
   16.19  }
   16.20  
   16.21 -unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at)
   16.22 +int reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns)
   16.23  {
   16.24      unsigned long i;
   16.25  
   16.26      for ( i = 0; i < nr_pfns; i++ )
   16.27 -        if ( allocated_in_map(pfn_at + i) )
   16.28 +        if ( allocated_in_map(first_pfn + i) )
   16.29               break;
   16.30  
   16.31 -    if ( i == nr_pfns )
   16.32 +    if ( i != nr_pfns )
   16.33 +        return 0;
   16.34 +
   16.35 +    map_alloc(first_pfn, nr_pfns);
   16.36 +    return 1;
   16.37 +}
   16.38 +
   16.39 +unsigned long alloc_boot_low_pages(
   16.40 +    unsigned long nr_pfns, unsigned long pfn_align)
   16.41 +{
   16.42 +    unsigned long pg, i;
   16.43 +
   16.44 +    /* Search forwards to obtain lowest available range. */
   16.45 +    for ( pg = first_valid_mfn & ~(pfn_align-1);
   16.46 +          (pg + nr_pfns) < max_page;
   16.47 +          pg = (pg + i + pfn_align - 1) & ~(pfn_align - 1) )
   16.48      {
   16.49 -        map_alloc(pfn_at, nr_pfns);
   16.50 -        return pfn_at;
   16.51 +        for ( i = 0; i < nr_pfns; i++ )
   16.52 +            if ( allocated_in_map(pg+i) )
   16.53 +                break;
   16.54 +        if ( i == nr_pfns )
   16.55 +        {
   16.56 +            map_alloc(pg, nr_pfns);
   16.57 +            return pg;
   16.58 +        }
   16.59      }
   16.60  
   16.61      return 0;
   16.62  }
   16.63  
   16.64 -unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align)
   16.65 +unsigned long alloc_boot_pages(
   16.66 +    unsigned long nr_pfns, unsigned long pfn_align)
   16.67  {
   16.68 -    unsigned long pg;
   16.69 +    unsigned long pg, i;
   16.70  
   16.71 -    pg = first_valid_mfn & ~(pfn_align-1);
   16.72 -    while ( (pg + nr_pfns) < max_page )
   16.73 +    /* Search backwards to obtain highest available range. */
   16.74 +    for ( pg = (max_page - nr_pfns) & ~(pfn_align - 1);
   16.75 +          pg >= first_valid_mfn;
   16.76 +          pg = (pg + i - nr_pfns) & ~(pfn_align - 1) )
   16.77      {
   16.78 -        if ( alloc_boot_pages_at(nr_pfns, pg) != 0 )
   16.79 -            break;
   16.80 -        pg += pfn_align;
   16.81 +        for ( i = 0; i < nr_pfns; i++ )
   16.82 +            if ( allocated_in_map(pg+i) )
   16.83 +                break;
   16.84 +        if ( i == nr_pfns )
   16.85 +        {
   16.86 +            map_alloc(pg, nr_pfns);
   16.87 +            return pg;
   16.88 +        }
   16.89      }
   16.90  
   16.91 -    return pg;
   16.92 +    return 0;
   16.93  }
   16.94  
   16.95  
    17.1 --- a/xen/include/asm-x86/hvm/hvm.h	Thu Feb 22 10:15:29 2007 -0700
    17.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Fri Feb 23 10:38:33 2007 +0000
    17.3 @@ -134,6 +134,8 @@ struct hvm_function_table {
    17.4                              int vcpuid, int trampoline_vector);
    17.5  
    17.6      void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
    17.7 +
    17.8 +    int  (*event_injection_faulted)(struct vcpu *v);
    17.9  };
   17.10  
   17.11  extern struct hvm_function_table hvm_funcs;
   17.12 @@ -262,4 +264,9 @@ hvm_inject_exception(unsigned int trapnr
   17.13  
   17.14  int hvm_bringup_ap(int vcpuid, int trampoline_vector);
   17.15  
   17.16 +static inline int hvm_event_injection_faulted(struct vcpu *v)
   17.17 +{
   17.18 +    return hvm_funcs.event_injection_faulted(v);
   17.19 +}
   17.20 +
   17.21  #endif /* __ASM_X86_HVM_HVM_H__ */
    18.1 --- a/xen/include/asm-x86/perfc_defn.h	Thu Feb 22 10:15:29 2007 -0700
    18.2 +++ b/xen/include/asm-x86/perfc_defn.h	Fri Feb 23 10:38:33 2007 +0000
    18.3 @@ -56,6 +56,7 @@ PERFCOUNTER_CPU(shadow_fault_bail_user_s
    18.4  PERFCOUNTER_CPU(shadow_fault_emulate_read, "shadow_fault emulates a read")
    18.5  PERFCOUNTER_CPU(shadow_fault_emulate_write, "shadow_fault emulates a write")
    18.6  PERFCOUNTER_CPU(shadow_fault_emulate_failed, "shadow_fault emulator fails")
    18.7 +PERFCOUNTER_CPU(shadow_fault_emulate_stack, "shadow_fault emulate stack write")
    18.8  PERFCOUNTER_CPU(shadow_fault_mmio,     "shadow_fault handled as mmio")
    18.9  PERFCOUNTER_CPU(shadow_fault_fixed,    "shadow_fault fixed fault")
   18.10  PERFCOUNTER_CPU(shadow_ptwr_emulate,   "shadow causes ptwr to emulate")
    19.1 --- a/xen/include/xen/mm.h	Thu Feb 22 10:15:29 2007 -0700
    19.2 +++ b/xen/include/xen/mm.h	Fri Feb 23 10:38:33 2007 +0000
    19.3 @@ -39,8 +39,11 @@ struct page_info;
    19.4  /* Boot-time allocator. Turns into generic allocator after bootstrap. */
    19.5  paddr_t init_boot_allocator(paddr_t bitmap_start);
    19.6  void init_boot_pages(paddr_t ps, paddr_t pe);
    19.7 -unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align);
    19.8 -unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at);
    19.9 +unsigned long alloc_boot_pages(
   19.10 +    unsigned long nr_pfns, unsigned long pfn_align);
   19.11 +unsigned long alloc_boot_low_pages(
   19.12 +    unsigned long nr_pfns, unsigned long pfn_align);
   19.13 +int reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns);
   19.14  void end_boot_allocator(void);
   19.15  
   19.16  /* Generic allocator. These functions are *not* interrupt-safe. */
    20.1 --- a/xen/include/xen/perfc.h	Thu Feb 22 10:15:29 2007 -0700
    20.2 +++ b/xen/include/xen/perfc.h	Fri Feb 23 10:38:33 2007 +0000
    20.3 @@ -5,6 +5,7 @@
    20.4  #ifdef PERF_COUNTERS
    20.5  
    20.6  #include <xen/lib.h>
    20.7 +#include <xen/smp.h>
    20.8  #include <asm/atomic.h>
    20.9  
   20.10  /*