direct-io.hg

changeset 8487:cd914808acf1

Merge
author djm@kirby.fc.hp.com
date Tue Jan 03 10:19:20 2006 -0600 (2006-01-03)
parents 903fb46f240e 5b30599761b3
children 71c61c288171
files xen/arch/ia64/xen/domain.c
line diff
     1.1 --- a/.hgignore	Tue Jan 03 08:59:00 2006 -0600
     1.2 +++ b/.hgignore	Tue Jan 03 10:19:20 2006 -0600
     1.3 @@ -181,6 +181,7 @@
     1.4  ^xen/TAGS$
     1.5  ^xen/arch/x86/asm-offsets\.s$
     1.6  ^xen/arch/x86/boot/mkelf32$
     1.7 +^xen/arch/x86/xen\.lds$
     1.8  ^xen/ddb/.*$
     1.9  ^xen/include/asm$
    1.10  ^xen/include/asm-.*/asm-offsets\.h$
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c	Tue Jan 03 08:59:00 2006 -0600
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c	Tue Jan 03 10:19:20 2006 -0600
     2.3 @@ -389,6 +389,30 @@ grant_write(struct file *file, const cha
     2.4  	return -ENOSYS;
     2.5  }
     2.6  
     2.7 +static int __init
     2.8 +gnttab_proc_init(void)
     2.9 +{
    2.10 +	/*
    2.11 +	 *  /proc/xen/grant : used by libxc to access grant tables
    2.12 +	 */
    2.13 +	if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
    2.14 +		WPRINTK("Unable to create grant xen proc entry\n");
    2.15 +		return -1;
    2.16 +	}
    2.17 +
    2.18 +	grant_file_ops.read   = grant_pde->proc_fops->read;
    2.19 +	grant_file_ops.write  = grant_pde->proc_fops->write;
    2.20 +
    2.21 +	grant_pde->proc_fops  = &grant_file_ops;
    2.22 +
    2.23 +	grant_pde->read_proc  = &grant_read;
    2.24 +	grant_pde->write_proc = &grant_write;
    2.25 +
    2.26 +	return 0;
    2.27 +}
    2.28 +
    2.29 +device_initcall(gnttab_proc_init);
    2.30 +
    2.31  #endif /* CONFIG_PROC_FS */
    2.32  
    2.33  int
    2.34 @@ -446,29 +470,11 @@ gnttab_init(void)
    2.35  	gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
    2.36  	gnttab_free_head  = NR_RESERVED_ENTRIES;
    2.37  
    2.38 -#ifdef CONFIG_PROC_FS
    2.39 -	/*
    2.40 -	 *  /proc/xen/grant : used by libxc to access grant tables
    2.41 -	 */
    2.42 -	if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
    2.43 -		WPRINTK("Unable to create grant xen proc entry\n");
    2.44 -		return -1;
    2.45 -	}
    2.46 -
    2.47 -	grant_file_ops.read   = grant_pde->proc_fops->read;
    2.48 -	grant_file_ops.write  = grant_pde->proc_fops->write;
    2.49 -
    2.50 -	grant_pde->proc_fops  = &grant_file_ops;
    2.51 -
    2.52 -	grant_pde->read_proc  = &grant_read;
    2.53 -	grant_pde->write_proc = &grant_write;
    2.54 -#endif
    2.55 -
    2.56  	printk("Grant table initialized\n");
    2.57  	return 0;
    2.58  }
    2.59  
    2.60 -__initcall(gnttab_init);
    2.61 +core_initcall(gnttab_init);
    2.62  
    2.63  /*
    2.64   * Local variables:
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Tue Jan 03 08:59:00 2006 -0600
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Tue Jan 03 10:19:20 2006 -0600
     3.3 @@ -331,7 +331,12 @@ static void connect(struct blkfront_info
     3.4  		return;
     3.5  	}
     3.6  
     3.7 -        xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
     3.8 +	err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
     3.9 +	if (err) {
    3.10 +		xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
    3.11 +		                 info->xbdev->otherend);
    3.12 +		return;
    3.13 +	}
    3.14  
    3.15  	(void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected); 
    3.16  
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Tue Jan 03 08:59:00 2006 -0600
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Tue Jan 03 10:19:20 2006 -0600
     4.3 @@ -82,7 +82,7 @@ typedef struct netif_st {
     4.4  #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
     4.5  
     4.6  void netif_creditlimit(netif_t *netif);
     4.7 -int  netif_disconnect(netif_t *netif);
     4.8 +void netif_disconnect(netif_t *netif);
     4.9  
    4.10  netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
    4.11  void free_netif(netif_t *netif);
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Tue Jan 03 08:59:00 2006 -0600
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Tue Jan 03 10:19:20 2006 -0600
     5.3 @@ -196,9 +196,13 @@ int netif_map(netif_t *netif, unsigned l
     5.4  		return 0;
     5.5  
     5.6  	netif->tx_comms_area = alloc_vm_area(PAGE_SIZE);
     5.7 +	if (netif->tx_comms_area == NULL)
     5.8 +		return -ENOMEM;
     5.9  	netif->rx_comms_area = alloc_vm_area(PAGE_SIZE);
    5.10 -	if (netif->tx_comms_area == NULL || netif->rx_comms_area == NULL)
    5.11 +	if (netif->rx_comms_area == NULL) {
    5.12 +		free_vm_area(netif->tx_comms_area);
    5.13  		return -ENOMEM;
    5.14 +	}
    5.15  
    5.16  	err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref);
    5.17  	if (err) {
    5.18 @@ -247,13 +251,9 @@ static void free_netif_callback(void *ar
    5.19  {
    5.20  	netif_t *netif = (netif_t *)arg;
    5.21  
    5.22 -	/* Already disconnected? */
    5.23 -	if (!netif->irq)
    5.24 -		return;
    5.25 -
    5.26 -	unbind_from_irqhandler(netif->irq, netif);
    5.27 -	netif->irq = 0;
    5.28 -
    5.29 +	if (netif->irq)
    5.30 +		unbind_from_irqhandler(netif->irq, netif);
    5.31 +	
    5.32  	unregister_netdev(netif->dev);
    5.33  
    5.34  	if (netif->tx.sring) {
    5.35 @@ -290,10 +290,10 @@ void netif_creditlimit(netif_t *netif)
    5.36  #endif
    5.37  }
    5.38  
    5.39 -int netif_disconnect(netif_t *netif)
    5.40 +void netif_disconnect(netif_t *netif)
    5.41  {
    5.42 -
    5.43 -	if (netif->status == CONNECTED) {
    5.44 +	switch (netif->status) {
    5.45 +	case CONNECTED:
    5.46  		rtnl_lock();
    5.47  		netif->status = DISCONNECTING;
    5.48  		wmb();
    5.49 @@ -301,10 +301,14 @@ int netif_disconnect(netif_t *netif)
    5.50  			__netif_down(netif);
    5.51  		rtnl_unlock();
    5.52  		netif_put(netif);
    5.53 -		return 0; /* Caller should not send response message. */
    5.54 +		break;
    5.55 +	case DISCONNECTED:
    5.56 +		BUG_ON(atomic_read(&netif->refcnt) != 0);
    5.57 +		free_netif(netif);
    5.58 +		break;
    5.59 +	default:
    5.60 +		BUG();
    5.61  	}
    5.62 -
    5.63 -	return 1;
    5.64  }
    5.65  
    5.66  /*
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Tue Jan 03 08:59:00 2006 -0600
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Tue Jan 03 10:19:20 2006 -0600
     6.3 @@ -117,6 +117,8 @@ struct netfront_info
     6.4  	int rx_min_target, rx_max_target, rx_target;
     6.5  	struct sk_buff_head rx_batch;
     6.6  
     6.7 +	struct timer_list rx_refill_timer;
     6.8 +
     6.9  	/*
    6.10  	 * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
    6.11  	 * array is an index into a chain of free entries.
    6.12 @@ -517,6 +519,13 @@ static void network_tx_buf_gc(struct net
    6.13  }
    6.14  
    6.15  
    6.16 +static void rx_refill_timeout(unsigned long data)
    6.17 +{
    6.18 +	struct net_device *dev = (struct net_device *)data;
    6.19 +	netif_rx_schedule(dev);
    6.20 +}
    6.21 +
    6.22 +
    6.23  static void network_alloc_rx_buffers(struct net_device *dev)
    6.24  {
    6.25  	unsigned short id;
    6.26 @@ -534,7 +543,7 @@ static void network_alloc_rx_buffers(str
    6.27  	 * Allocate skbuffs greedily, even though we batch updates to the
    6.28  	 * receive ring. This creates a less bursty demand on the memory
    6.29  	 * allocator, so should reduce the chance of failed allocation requests
    6.30 -	 *  both for ourself and for other kernel subsystems.
    6.31 +	 * both for ourself and for other kernel subsystems.
    6.32  	 */
    6.33  	batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
    6.34  	for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
    6.35 @@ -545,8 +554,15 @@ static void network_alloc_rx_buffers(str
    6.36  		skb = alloc_xen_skb(
    6.37  			((PAGE_SIZE - sizeof(struct skb_shared_info)) &
    6.38  			 (-SKB_DATA_ALIGN(1))) - 16);
    6.39 -		if (skb == NULL)
    6.40 -			break;
    6.41 +		if (skb == NULL) {
    6.42 +			/* Any skbuffs queued for refill? Force them out. */
    6.43 +			if (i != 0)
    6.44 +				goto refill;
    6.45 +			/* Could not allocate any skbuffs. Try again later. */
    6.46 +			mod_timer(&np->rx_refill_timer,
    6.47 +				  jiffies + (HZ/10));
    6.48 +			return;
    6.49 +		}
    6.50  		__skb_queue_tail(&np->rx_batch, skb);
    6.51  	}
    6.52  
    6.53 @@ -554,6 +570,12 @@ static void network_alloc_rx_buffers(str
    6.54  	if (i < (np->rx_target/2))
    6.55  		return;
    6.56  
    6.57 +	/* Adjust our fill target if we risked running out of buffers. */
    6.58 +	if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
    6.59 +	    ((np->rx_target *= 2) > np->rx_max_target))
    6.60 +		np->rx_target = np->rx_max_target;
    6.61 +
    6.62 + refill:
    6.63  	for (i = 0; ; i++) {
    6.64  		if ((skb = __skb_dequeue(&np->rx_batch)) == NULL)
    6.65  			break;
    6.66 @@ -608,11 +630,6 @@ static void network_alloc_rx_buffers(str
    6.67  	/* Above is a suitable barrier to ensure backend will see requests. */
    6.68  	np->rx.req_prod_pvt = req_prod + i;
    6.69  	RING_PUSH_REQUESTS(&np->rx);
    6.70 -
    6.71 -	/* Adjust our fill target if we risked running out of buffers. */
    6.72 -	if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
    6.73 -	    ((np->rx_target *= 2) > np->rx_max_target))
    6.74 -		np->rx_target = np->rx_max_target;
    6.75  }
    6.76  
    6.77  
    6.78 @@ -1077,6 +1094,10 @@ static int create_netdev(int handle, str
    6.79  	np->rx_min_target = RX_MIN_TARGET;
    6.80  	np->rx_max_target = RX_MAX_TARGET;
    6.81  
    6.82 +	init_timer(&np->rx_refill_timer);
    6.83 +	np->rx_refill_timer.data = (unsigned long)netdev;
    6.84 +	np->rx_refill_timer.function = rx_refill_timeout;
    6.85 +
    6.86  	/* Initialise {tx,rx}_skbs as a free chain containing every entry. */
    6.87  	for (i = 0; i <= NET_TX_RING_SIZE; i++) {
    6.88  		np->tx_skbs[i] = (void *)((unsigned long) i+1);
    6.89 @@ -1188,34 +1209,15 @@ static int netfront_remove(struct xenbus
    6.90  
    6.91  	DPRINTK("%s\n", dev->nodename);
    6.92  
    6.93 -	netif_free(info);
    6.94 -	kfree(info);
    6.95 +	netif_disconnect_backend(info);
    6.96 +	free_netdev(info->netdev);
    6.97  
    6.98  	return 0;
    6.99  }
   6.100  
   6.101  
   6.102 -static void netif_free(struct netfront_info *info)
   6.103 -{
   6.104 -	netif_disconnect_backend(info);
   6.105 -	close_netdev(info);
   6.106 -}
   6.107 -
   6.108 -
   6.109  static void close_netdev(struct netfront_info *info)
   6.110  {
   6.111 -	if (info->netdev) {
   6.112 -#ifdef CONFIG_PROC_FS
   6.113 -		xennet_proc_delif(info->netdev);
   6.114 -#endif
   6.115 -		unregister_netdev(info->netdev);
   6.116 -		info->netdev = NULL;
   6.117 -	}
   6.118 -}
   6.119 -
   6.120 -
   6.121 -static void netif_disconnect_backend(struct netfront_info *info)
   6.122 -{
   6.123  	/* Stop old i/f to prevent errors whilst we rebuild the state. */
   6.124  	spin_lock_irq(&info->tx_lock);
   6.125  	spin_lock(&info->rx_lock);
   6.126 @@ -1223,17 +1225,37 @@ static void netif_disconnect_backend(str
   6.127  	/* info->backend_state = BEST_DISCONNECTED; */
   6.128  	spin_unlock(&info->rx_lock);
   6.129  	spin_unlock_irq(&info->tx_lock);
   6.130 -    
   6.131 +
   6.132 +#ifdef CONFIG_PROC_FS
   6.133 +	xennet_proc_delif(info->netdev);
   6.134 +#endif
   6.135 +
   6.136 +	if (info->irq)
   6.137 +		unbind_from_irqhandler(info->irq, info->netdev);
   6.138 +	info->evtchn = info->irq = 0;
   6.139 +
   6.140 +	del_timer_sync(&info->rx_refill_timer);
   6.141 +
   6.142 +	unregister_netdev(info->netdev);
   6.143 +}
   6.144 +
   6.145 +
   6.146 +static void netif_disconnect_backend(struct netfront_info *info)
   6.147 +{
   6.148  	end_access(info->tx_ring_ref, info->tx.sring);
   6.149  	end_access(info->rx_ring_ref, info->rx.sring);
   6.150  	info->tx_ring_ref = GRANT_INVALID_REF;
   6.151  	info->rx_ring_ref = GRANT_INVALID_REF;
   6.152  	info->tx.sring = NULL;
   6.153  	info->rx.sring = NULL;
   6.154 +}
   6.155  
   6.156 -	if (info->irq)
   6.157 -		unbind_from_irqhandler(info->irq, info->netdev);
   6.158 -	info->evtchn = info->irq = 0;
   6.159 +
   6.160 +static void netif_free(struct netfront_info *info)
   6.161 +{
   6.162 +	close_netdev(info);
   6.163 +	netif_disconnect_backend(info);
   6.164 +	free_netdev(info->netdev);
   6.165  }
   6.166  
   6.167  
     7.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/bug.h	Tue Jan 03 08:59:00 2006 -0600
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,16 +0,0 @@
     7.4 -#ifndef _I386_BUG_H
     7.5 -#define _I386_BUG_H
     7.6 -
     7.7 -#include <linux/config.h>
     7.8 -
     7.9 -#define BUG() do { \
    7.10 -	printk("kernel BUG at %s:%d (%s)!\n", \
    7.11 -	       __FILE__, __LINE__, __FUNCTION__); \
    7.12 -	dump_stack(); \
    7.13 -	panic("BUG!"); \
    7.14 -} while (0)
    7.15 -#define HAVE_ARCH_BUG
    7.16 -
    7.17 -#include <asm-generic/bug.h>
    7.18 -
    7.19 -#endif
     8.1 --- a/tools/examples/xmexample.vmx	Tue Jan 03 08:59:00 2006 -0600
     8.2 +++ b/tools/examples/xmexample.vmx	Tue Jan 03 10:19:20 2006 -0600
     8.3 @@ -30,6 +30,9 @@ name = "ExampleVMXDomain"
     8.4  # the number of cpus guest platform has, default=1
     8.5  vcpus=1
     8.6  
     8.7 +# enable/disalbe vmx guest ACPI, default=0 (disabled)
     8.8 +#acpi=0
     8.9 +
    8.10  # List of which CPUS this domain is allowed to use, default Xen picks
    8.11  #cpus = ""         # leave to Xen to pick
    8.12  #cpus = "0"        # all vcpus run on CPU0
     9.1 --- a/tools/firmware/vmxassist/Makefile	Tue Jan 03 08:59:00 2006 -0600
     9.2 +++ b/tools/firmware/vmxassist/Makefile	Tue Jan 03 10:19:20 2006 -0600
     9.3 @@ -24,7 +24,7 @@ include $(XEN_ROOT)/tools/Rules.mk
     9.4  # The emulator code lives in ROM space
     9.5  TEXTADDR=0x000D0000
     9.6  
     9.7 -DEFINES=-DDEBUG -D_ACPI_ -DTEXTADDR=$(TEXTADDR)
     9.8 +DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
     9.9  XENINC=-I$(XEN_ROOT)/tools/libxc
    9.10  
    9.11  LD       = ld
    10.1 --- a/tools/firmware/vmxassist/acpi_madt.c	Tue Jan 03 08:59:00 2006 -0600
    10.2 +++ b/tools/firmware/vmxassist/acpi_madt.c	Tue Jan 03 10:19:20 2006 -0600
    10.3 @@ -24,23 +24,75 @@
    10.4  
    10.5  extern int puts(const char *s);
    10.6  
    10.7 -#define VCPU_NR_PAGE        0x0009F000
    10.8 -#define VCPU_NR_OFFSET      0x00000800
    10.9 -#define VCPU_MAGIC          0x76637075  /* "vcpu" */
   10.10 +#define HVM_INFO_PAGE	0x0009F000
   10.11 +#define HVM_INFO_OFFSET	0x00000800
   10.12 +
   10.13 +struct hvm_info_table {
   10.14 +	char     signature[8]; /* "HVM INFO" */
   10.15 +	uint32_t length;
   10.16 +	uint8_t  checksum;
   10.17 +	uint8_t  acpi_enabled;
   10.18 +	uint8_t  pad[2];
   10.19 +	uint32_t nr_vcpus;
   10.20 +};
   10.21 +
   10.22 +static struct hvm_info_table *table = NULL;
   10.23 +
   10.24 +static int
   10.25 +checksum_valid(uint8_t *ptr, int len)
   10.26 +{
   10.27 +	uint8_t sum=0;
   10.28 +	int i;
   10.29 +
   10.30 +	for (i = 0; i < len; i++)
   10.31 +		sum += ptr[i];
   10.32 +
   10.33 +	return (sum == 0);
   10.34 +}
   10.35  
   10.36 -/* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */
   10.37 -static int
   10.38 +/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
   10.39 +static struct hvm_info_table *
   10.40 +get_hvm_info_table(void)
   10.41 +{
   10.42 +	struct hvm_info_table *t;
   10.43 +	char signature[] = "HVM INFO";
   10.44 +	int i;
   10.45 +
   10.46 +	if (table != NULL)
   10.47 +		return table;
   10.48 +
   10.49 +	t = (struct hvm_info_table *)(HVM_INFO_PAGE + HVM_INFO_OFFSET);
   10.50 +
   10.51 +	/* strncmp(t->signature, "HVM INFO", 8) */
   10.52 +	for (i = 0; i < 8; i++) {
   10.53 +		if (signature[i] != t->signature[i]) {
   10.54 +			puts("Bad hvm info signature\n");
   10.55 +			return NULL;
   10.56 +		}
   10.57 +	}
   10.58 +
   10.59 +	if (!checksum_valid((uint8_t *)t, t->length)) {
   10.60 +		puts("Bad hvm info checksum\n");
   10.61 +		return NULL;
   10.62 +	}
   10.63 +
   10.64 +	table = t;
   10.65 +
   10.66 +	return table;
   10.67 +}
   10.68 +
   10.69 +int
   10.70  get_vcpu_nr(void)
   10.71  {
   10.72 -	unsigned int *vcpus;
   10.73 +	struct hvm_info_table *t = get_hvm_info_table();
   10.74 +	return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
   10.75 +}
   10.76  
   10.77 -	vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET);
   10.78 -	if (vcpus[0] != VCPU_MAGIC) {
   10.79 -		puts("Bad vcpus magic, set vcpu number to 1 by default.\n");
   10.80 -		return 1;
   10.81 -	}
   10.82 -
   10.83 -	return vcpus[1];
   10.84 +int
   10.85 +get_acpi_enabled(void)
   10.86 +{
   10.87 +	struct hvm_info_table *t = get_hvm_info_table();
   10.88 +	return (t ? t->acpi_enabled : 0); /* default no acpi */
   10.89  }
   10.90  
   10.91  static void *
    11.1 --- a/tools/firmware/vmxassist/vmxloader.c	Tue Jan 03 08:59:00 2006 -0600
    11.2 +++ b/tools/firmware/vmxassist/vmxloader.c	Tue Jan 03 10:19:20 2006 -0600
    11.3 @@ -24,12 +24,10 @@
    11.4  #include "machine.h"
    11.5  #include "roms.h"
    11.6  
    11.7 -#ifdef _ACPI_
    11.8  #include "acpi.h"
    11.9  #include "../acpi/acpi2_0.h"  // for ACPI_PHYSICAL_ADDRESS
   11.10  int acpi_madt_update(unsigned char* acpi_start);
   11.11 -#endif
   11.12 -
   11.13 +int get_acpi_enabled(void);
   11.14  
   11.15  /*
   11.16   * C runtime start off
   11.17 @@ -120,18 +118,17 @@ main(void)
   11.18  		memcpy((void *)0xC0000,
   11.19  			vgabios_stdvga, sizeof(vgabios_stdvga));
   11.20  	}
   11.21 -#ifdef _ACPI_
   11.22 -	puts("Loading ACPI ...\n");
   11.23  
   11.24 -	acpi_madt_update(acpi);
   11.25 -
   11.26 -	if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
   11.27 -		/* make sure acpi table does not overlap rombios
   11.28 - 		 * currently acpi less than 8K will be OK.
   11.29 -		 */
   11.30 -		 memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
   11.31 +	if (get_acpi_enabled() != 0) {
   11.32 +		puts("Loading ACPI ...\n");
   11.33 +		acpi_madt_update((unsigned char*)acpi);
   11.34 +		if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
   11.35 +			/* make sure acpi table does not overlap rombios
   11.36 +			 * currently acpi less than 8K will be OK.
   11.37 +			 */
   11.38 +			memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
   11.39 +		}
   11.40  	}
   11.41 -#endif
   11.42  
   11.43  	puts("Loading VMXAssist ...\n");
   11.44  	memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
    12.1 --- a/tools/ioemu/vl.c	Tue Jan 03 08:59:00 2006 -0600
    12.2 +++ b/tools/ioemu/vl.c	Tue Jan 03 10:19:20 2006 -0600
    12.3 @@ -2948,6 +2948,7 @@ int main(int argc, char **argv)
    12.4              case QEMU_OPTION_vcpus:
    12.5                  vcpus = atoi(optarg);
    12.6                  fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
    12.7 +                break;
    12.8              case QEMU_OPTION_pci:
    12.9                  pci_enabled = 1;
   12.10                  break;
    13.1 --- a/tools/libxc/Makefile	Tue Jan 03 08:59:00 2006 -0600
    13.2 +++ b/tools/libxc/Makefile	Tue Jan 03 10:19:20 2006 -0600
    13.3 @@ -27,6 +27,11 @@ SRCS       += xc_tbuf.c
    13.4  ifeq ($(XEN_TARGET_ARCH),x86_32)
    13.5  SRCS       += xc_ptrace.c
    13.6  SRCS       += xc_ptrace_core.c
    13.7 +SRCS       += xc_pagetab.c
    13.8 +endif
    13.9 +
   13.10 +ifeq ($(XEN_TARGET_ARCH),x86_64)
   13.11 +SRCS       += xc_pagetab.c
   13.12  endif
   13.13  
   13.14  BUILD_SRCS :=
    14.1 --- a/tools/libxc/xc_domain.c	Tue Jan 03 08:59:00 2006 -0600
    14.2 +++ b/tools/libxc/xc_domain.c	Tue Jan 03 10:19:20 2006 -0600
    14.3 @@ -404,6 +404,38 @@ int xc_domain_setinfo(int xc_handle,
    14.4  
    14.5  }
    14.6  
    14.7 +int xc_domain_irq_permission(int xc_handle,
    14.8 +                             uint32_t domid,
    14.9 +                             uint8_t pirq,
   14.10 +                             uint8_t allow_access)
   14.11 +{
   14.12 +    dom0_op_t op;
   14.13 +
   14.14 +    op.cmd = DOM0_IRQ_PERMISSION;
   14.15 +    op.u.irq_permission.domain = domid;
   14.16 +    op.u.irq_permission.pirq = pirq;
   14.17 +    op.u.irq_permission.allow_access = allow_access;
   14.18 +
   14.19 +    return do_dom0_op(xc_handle, &op);
   14.20 +}
   14.21 +
   14.22 +int xc_domain_iomem_permission(int xc_handle,
   14.23 +                               uint32_t domid,
   14.24 +                               unsigned long first_pfn,
   14.25 +                               unsigned long nr_pfns,
   14.26 +                               uint8_t allow_access)
   14.27 +{
   14.28 +    dom0_op_t op;
   14.29 +
   14.30 +    op.cmd = DOM0_IOMEM_PERMISSION;
   14.31 +    op.u.iomem_permission.domain = domid;
   14.32 +    op.u.iomem_permission.first_pfn = first_pfn;
   14.33 +	op.u.iomem_permission.nr_pfns = nr_pfns;
   14.34 +    op.u.iomem_permission.allow_access = allow_access;
   14.35 +
   14.36 +    return do_dom0_op(xc_handle, &op);
   14.37 +}
   14.38 +
   14.39  /*
   14.40   * Local variables:
   14.41   * mode: C
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/libxc/xc_pagetab.c	Tue Jan 03 10:19:20 2006 -0600
    15.3 @@ -0,0 +1,192 @@
    15.4 +/******************************************************************************
    15.5 + * xc_pagetab.c
    15.6 + *
    15.7 + * Function to translate virtual to physical addresses.
    15.8 + */
    15.9 +#include "xc_private.h"
   15.10 +
   15.11 +#if defined(__i386__)
   15.12 +
   15.13 +#define L1_PAGETABLE_SHIFT_PAE	12
   15.14 +#define L2_PAGETABLE_SHIFT_PAE	21
   15.15 +#define L3_PAGETABLE_SHIFT_PAE	30
   15.16 +
   15.17 +#define L1_PAGETABLE_SHIFT		12
   15.18 +#define L2_PAGETABLE_SHIFT		22
   15.19 +
   15.20 +#define L0_PAGETABLE_MASK_PAE	0x0000000ffffff000ULL
   15.21 +#define L1_PAGETABLE_MASK_PAE	0x1ffULL
   15.22 +#define L2_PAGETABLE_MASK_PAE	0x1ffULL
   15.23 +#define L3_PAGETABLE_MASK_PAE	0x3ULL
   15.24 +
   15.25 +#define L0_PAGETABLE_MASK		0xfffff000ULL
   15.26 +#define L1_PAGETABLE_MASK		0x3ffULL
   15.27 +#define L2_PAGETABLE_MASK		0x3ffULL
   15.28 +
   15.29 +#elif defined(__x86_64__)
   15.30 +
   15.31 +#define L1_PAGETABLE_SHIFT_PAE	12
   15.32 +#define L2_PAGETABLE_SHIFT_PAE	21
   15.33 +#define L3_PAGETABLE_SHIFT_PAE	30
   15.34 +#define L4_PAGETABLE_SHIFT_PAE	39
   15.35 +
   15.36 +#define L1_PAGETABLE_SHIFT		L1_PAGETABLE_SHIFT_PAE
   15.37 +#define L2_PAGETABLE_SHIFT		L2_PAGETABLE_SHIFT_PAE
   15.38 +
   15.39 +#define L0_PAGETABLE_MASK_PAE	0x000000fffffff000ULL
   15.40 +#define L1_PAGETABLE_MASK_PAE	0x1ffULL
   15.41 +#define L2_PAGETABLE_MASK_PAE	0x1ffULL
   15.42 +#define L3_PAGETABLE_MASK_PAE	0x1ffULL
   15.43 +#define L4_PAGETABLE_MASK_PAE	0x1ffULL
   15.44 +
   15.45 +#define L0_PAGETABLE_MASK		L0_PAGETABLE_MASK_PAE
   15.46 +#define L1_PAGETABLE_MASK		L1_PAGETABLE_MASK_PAE
   15.47 +#define L2_PAGETABLE_MASK		L2_PAGETABLE_MASK_PAE
   15.48 +
   15.49 +#endif
   15.50 +
   15.51 +unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
   15.52 +                                           int vcpu, unsigned long long virt )
   15.53 +{
   15.54 +    vcpu_guest_context_t ctx;
   15.55 +    unsigned long long cr3;
   15.56 +    void *pd, *pt, *pdppage = NULL, *pdp, *pml = NULL;
   15.57 +    unsigned long long pde, pte, pdpe, pmle;
   15.58 +    unsigned long mfn = 0;
   15.59 +#if defined (__i386__)
   15.60 +    static int pt_levels = 0;
   15.61 +
   15.62 +    if (pt_levels == 0) {
   15.63 +        xen_capabilities_info_t xen_caps = "";
   15.64 +
   15.65 +        if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
   15.66 +            goto out;
   15.67 +        if (strstr(xen_caps, "xen-3.0-x86_64"))
   15.68 +            pt_levels = 4;
   15.69 +        else if (strstr(xen_caps, "xen-3.0-x86_32p"))
   15.70 +            pt_levels = 3;
   15.71 +        else if (strstr(xen_caps, "xen-3.0-x86_32"))
   15.72 +            pt_levels = 2;
   15.73 +        else
   15.74 +            goto out;
   15.75 +    }
   15.76 +#elif defined (__x86_64__)
   15.77 +#define pt_levels 4
   15.78 +#endif
   15.79 +
   15.80 +    if (xc_domain_get_vcpu_context(xc_handle, dom, vcpu, &ctx) != 0) {
   15.81 +        fprintf(stderr, "failed to retreive vcpu context\n");
   15.82 +        goto out;
   15.83 +    }
   15.84 +    cr3 = ctx.ctrlreg[3];
   15.85 +
   15.86 +    /* Page Map Level 4 */
   15.87 +
   15.88 +#if defined(__i386__)
   15.89 +    pmle = cr3;
   15.90 +#elif defined(__x86_64__)
   15.91 +    pml = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, cr3 >> PAGE_SHIFT);
   15.92 +    if (pml == NULL) {
   15.93 +        fprintf(stderr, "failed to map PML4\n");
   15.94 +        goto out;
   15.95 +    }
   15.96 +    pmle = *(unsigned long long *)(pml + 8 * ((virt >> L4_PAGETABLE_SHIFT_PAE) & L4_PAGETABLE_MASK_PAE));
   15.97 +    if((pmle & 1) == 0) {
   15.98 +        fprintf(stderr, "page entry not present in PML4\n");
   15.99 +        goto out_unmap_pml;
  15.100 +    }
  15.101 +#endif
  15.102 +
  15.103 +    /* Page Directory Pointer Table */
  15.104 +
  15.105 +    if (pt_levels >= 3) {
  15.106 +        pdppage = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pmle >> PAGE_SHIFT);
  15.107 +        if (pdppage == NULL) {
  15.108 +            fprintf(stderr, "failed to map PDP\n");
  15.109 +            goto out_unmap_pml;
  15.110 +        }
  15.111 +        if (pt_levels >= 4)
  15.112 +            pdp = pdppage;
  15.113 +        else
  15.114 +            /* PDP is only 32 bit aligned with 3 level pts */
  15.115 +            pdp = pdppage + (pmle & ~(XC_PAGE_MASK | 0x1f));
  15.116 +
  15.117 +        pdpe = *(unsigned long long *)(pdp + 8 * ((virt >> L3_PAGETABLE_SHIFT_PAE) & L3_PAGETABLE_MASK_PAE));
  15.118 +
  15.119 +        if((pdpe & 1) == 0) {
  15.120 +            fprintf(stderr, "page entry not present in PDP\n");
  15.121 +            goto out_unmap_pdp;
  15.122 +        }
  15.123 +    } else {
  15.124 +        pdpe = pmle;
  15.125 +    }
  15.126 +
  15.127 +    /* Page Directory */
  15.128 +
  15.129 +    pd = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, pdpe >> PAGE_SHIFT);
  15.130 +    if (pd == NULL) {
  15.131 +        fprintf(stderr, "failed to map PD\n");
  15.132 +        goto out_unmap_pdp;
  15.133 +    }
  15.134 +
  15.135 +    if (pt_levels >= 3)
  15.136 +        pde = *(unsigned long long *)(pd + 8 * ((virt >> L2_PAGETABLE_SHIFT_PAE) & L2_PAGETABLE_MASK_PAE));
  15.137 +    else
  15.138 +        pde = *(unsigned long long *)(pd + 4 * ((virt >> L2_PAGETABLE_SHIFT) & L2_PAGETABLE_MASK));
  15.139 +
  15.140 +    if ((pde & 1) == 0) {
  15.141 +        fprintf(stderr, "page entry not present in PD\n");
  15.142 +        goto out_unmap_pd;
  15.143 +    }
  15.144 +
  15.145 +    /* Page Table */
  15.146 +
  15.147 +    if (pde & 0x00000008) { /* 4M page (or 2M in PAE mode) */
  15.148 +        fprintf(stderr, "Cannot currently cope with 2/4M pages\n");
  15.149 +        exit(-1);
  15.150 +    } else { /* 4k page */
  15.151 +        pt = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
  15.152 +                                  pde >> PAGE_SHIFT);
  15.153 +
  15.154 +        if (pt == NULL) {
  15.155 +            fprintf(stderr, "failed to map PT\n");
  15.156 +            goto out_unmap_pd;
  15.157 +        }
  15.158 +
  15.159 +        if (pt_levels >= 3)
  15.160 +            pte = *(unsigned long long *)(pt + 8 * ((virt >> L1_PAGETABLE_SHIFT_PAE) & L1_PAGETABLE_MASK_PAE));
  15.161 +        else
  15.162 +            pte = *(unsigned long long *)(pt + 4 * ((virt >> L1_PAGETABLE_SHIFT) & L1_PAGETABLE_MASK));
  15.163 +
  15.164 +        if ((pte & 0x00000001) == 0) {
  15.165 +            fprintf(stderr, "page entry not present in PT\n");
  15.166 +            goto out_unmap_pt;
  15.167 +        }
  15.168 +
  15.169 +        if (pt_levels >= 3)
  15.170 +            mfn = (pte & L0_PAGETABLE_MASK_PAE) >> PAGE_SHIFT;
  15.171 +        else
  15.172 +            mfn = (pte & L0_PAGETABLE_MASK) >> PAGE_SHIFT;
  15.173 +    }
  15.174 +
  15.175 + out_unmap_pt:
  15.176 +    munmap(pt, PAGE_SIZE);
  15.177 + out_unmap_pd:
  15.178 +    munmap(pd, PAGE_SIZE);
  15.179 + out_unmap_pdp:
  15.180 +    munmap(pdppage, PAGE_SIZE);
  15.181 + out_unmap_pml:
  15.182 +    munmap(pml, PAGE_SIZE);
  15.183 + out:
  15.184 +    return mfn;
  15.185 +}
  15.186 +
  15.187 +/*
  15.188 + * Local variables:
  15.189 + * mode: C
  15.190 + * c-set-style: "BSD"
  15.191 + * c-basic-offset: 4
  15.192 + * tab-width: 4
  15.193 + * indent-tabs-mode: nil
  15.194 + * End:
  15.195 + */
    16.1 --- a/tools/libxc/xc_vmx_build.c	Tue Jan 03 08:59:00 2006 -0600
    16.2 +++ b/tools/libxc/xc_vmx_build.c	Tue Jan 03 10:19:20 2006 -0600
    16.3 @@ -33,8 +33,17 @@
    16.4  #define E820_MAP_NR_OFFSET  0x000001E8
    16.5  #define E820_MAP_OFFSET     0x000002D0
    16.6  
    16.7 -#define VCPU_NR_PAGE        0x0009F000
    16.8 -#define VCPU_NR_OFFSET      0x00000800
    16.9 +#define HVM_INFO_PAGE        0x0009F000
   16.10 +#define HVM_INFO_OFFSET      0x00000800
   16.11 +
   16.12 +struct hvm_info_table {
   16.13 +    char     signature[8]; /* "HVM INFO" */
   16.14 +    uint32_t length;
   16.15 +    uint8_t  checksum;
   16.16 +    uint8_t  acpi_enabled;
   16.17 +    uint8_t  pad[2];
   16.18 +    uint32_t nr_vcpus;
   16.19 +};
   16.20  
   16.21  struct e820entry {
   16.22      uint64_t addr;
   16.23 @@ -119,26 +128,45 @@ static unsigned char build_e820map(void 
   16.24      return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
   16.25  }
   16.26  
   16.27 +static void 
   16.28 +set_hvm_info_checksum(struct hvm_info_table *t)
   16.29 +{
   16.30 +    uint8_t *ptr = (uint8_t *)t, sum = 0;
   16.31 +    unsigned int i;
   16.32 +
   16.33 +    t->checksum = 0;
   16.34 +
   16.35 +    for (i = 0; i < t->length; i++)
   16.36 +        sum += *ptr++;
   16.37 +
   16.38 +    t->checksum = -sum;
   16.39 +}
   16.40 +
   16.41  /*
   16.42 - * Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader
   16.43 - * vmxloader will use it to config ACPI MADT table
   16.44 + * Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader
   16.45 + * vmxloader will use this info to set BIOS accordingly
   16.46   */
   16.47 -#define VCPU_MAGIC      0x76637075  /* "vcpu" */
   16.48 -static int set_vcpu_nr(int xc_handle, uint32_t dom,
   16.49 -                        unsigned long *pfn_list, unsigned int vcpus)
   16.50 +static int set_hvm_info(int xc_handle, uint32_t dom,
   16.51 +                        unsigned long *pfn_list, unsigned int vcpus,
   16.52 +                        unsigned int acpi)
   16.53  {
   16.54 -    char         *va_map;
   16.55 -    unsigned int *va_vcpus;
   16.56 +    char *va_map;
   16.57 +    struct hvm_info_table *va_hvm;
   16.58  
   16.59      va_map = xc_map_foreign_range(xc_handle, dom,
   16.60                                    PAGE_SIZE, PROT_READ|PROT_WRITE,
   16.61 -                                  pfn_list[VCPU_NR_PAGE >> PAGE_SHIFT]);
   16.62 +                                  pfn_list[HVM_INFO_PAGE >> PAGE_SHIFT]);
   16.63      if ( va_map == NULL )
   16.64          return -1;
   16.65  
   16.66 -    va_vcpus = (unsigned int *)(va_map + VCPU_NR_OFFSET);
   16.67 -    va_vcpus[0] = VCPU_MAGIC;
   16.68 -    va_vcpus[1] = vcpus;
   16.69 +    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
   16.70 +    memset(va_hvm, 0, sizeof(*va_hvm));
   16.71 +    strncpy(va_hvm->signature, "HVM INFO", 8);
   16.72 +    va_hvm->length       = sizeof(struct hvm_info_table);
   16.73 +    va_hvm->acpi_enabled = acpi;
   16.74 +    va_hvm->nr_vcpus     = vcpus;
   16.75 +    
   16.76 +    set_hvm_info_checksum(va_hvm);
   16.77  
   16.78      munmap(va_map, PAGE_SIZE);
   16.79  
   16.80 @@ -281,6 +309,7 @@ static int setup_guest(int xc_handle,
   16.81                         unsigned int control_evtchn,
   16.82                         unsigned int lapic,
   16.83                         unsigned int vcpus,
   16.84 +                       unsigned int acpi,
   16.85                         unsigned int store_evtchn,
   16.86                         unsigned long *store_mfn)
   16.87  {
   16.88 @@ -490,8 +519,8 @@ static int setup_guest(int xc_handle,
   16.89              goto error_out;
   16.90      }
   16.91  
   16.92 -    if (set_vcpu_nr(xc_handle, dom, page_array, vcpus)) {
   16.93 -        fprintf(stderr, "Couldn't set vcpu number for VMX guest.\n");
   16.94 +    if (set_hvm_info(xc_handle, dom, page_array, vcpus, acpi)) {
   16.95 +        fprintf(stderr, "Couldn't set hvm info for VMX guest.\n");
   16.96          goto error_out;
   16.97      }
   16.98  
   16.99 @@ -574,29 +603,6 @@ static int setup_guest(int xc_handle,
  16.100      return -1;
  16.101  }
  16.102  
  16.103 -#define VMX_FEATURE_FLAG 0x20
  16.104 -
  16.105 -static int vmx_identify(void)
  16.106 -{
  16.107 -    int eax, ecx;
  16.108 -
  16.109 -    __asm__ __volatile__ (
  16.110 -#if defined(__i386__)
  16.111 -                          "push %%ebx; cpuid; pop %%ebx"
  16.112 -#elif defined(__x86_64__)
  16.113 -                          "push %%rbx; cpuid; pop %%rbx"
  16.114 -#endif
  16.115 -                          : "=a" (eax), "=c" (ecx)
  16.116 -                          : "0" (1)
  16.117 -                          : "dx");
  16.118 -
  16.119 -    if (!(ecx & VMX_FEATURE_FLAG)) {
  16.120 -        return -1;
  16.121 -    }
  16.122 -
  16.123 -    return 0;
  16.124 -}
  16.125 -
  16.126  int xc_vmx_build(int xc_handle,
  16.127                   uint32_t domid,
  16.128                   int memsize,
  16.129 @@ -604,6 +610,7 @@ int xc_vmx_build(int xc_handle,
  16.130                   unsigned int control_evtchn,
  16.131                   unsigned int lapic,
  16.132                   unsigned int vcpus,
  16.133 +                 unsigned int acpi,
  16.134                   unsigned int store_evtchn,
  16.135                   unsigned long *store_mfn)
  16.136  {
  16.137 @@ -613,10 +620,18 @@ int xc_vmx_build(int xc_handle,
  16.138      unsigned long nr_pages;
  16.139      char         *image = NULL;
  16.140      unsigned long image_size;
  16.141 +    xen_capabilities_info_t xen_caps;
  16.142  
  16.143 -    if ( vmx_identify() < 0 )
  16.144 +    if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
  16.145      {
  16.146 -        PERROR("CPU doesn't support VMX Extensions");
  16.147 +        PERROR("Failed to get xen version info");
  16.148 +        goto error_out;
  16.149 +    }
  16.150 +
  16.151 +    if ( !strstr(xen_caps, "hvm") )
  16.152 +    {
  16.153 +        PERROR("CPU doesn't support VMX Extensions or "
  16.154 +               "CPU VMX Extensions are not turned on");
  16.155          goto error_out;
  16.156      }
  16.157  
  16.158 @@ -659,7 +674,7 @@ int xc_vmx_build(int xc_handle,
  16.159  
  16.160      if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
  16.161                       ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
  16.162 -                     lapic, vcpus, store_evtchn, store_mfn) < 0)
  16.163 +                     lapic, vcpus, acpi, store_evtchn, store_mfn) < 0)
  16.164      {
  16.165          ERROR("Error constructing guest OS");
  16.166          goto error_out;
    17.1 --- a/tools/libxc/xenctrl.h	Tue Jan 03 08:59:00 2006 -0600
    17.2 +++ b/tools/libxc/xenctrl.h	Tue Jan 03 10:19:20 2006 -0600
    17.3 @@ -380,6 +380,17 @@ int xc_domain_ioport_permission(int xc_h
    17.4                                  uint32_t nr_ports,
    17.5                                  uint32_t allow_access);
    17.6  
    17.7 +int xc_domain_irq_permission(int xc_handle,
    17.8 +                             uint32_t domid,
    17.9 +                             uint8_t pirq,
   17.10 +                             uint8_t allow_access);
   17.11 +
   17.12 +int xc_domain_iomem_permission(int xc_handle,
   17.13 +                               uint32_t domid,
   17.14 +                               unsigned long first_pfn,
   17.15 +                               unsigned long nr_pfns,
   17.16 +                               uint8_t allow_access);
   17.17 +
   17.18  unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid, 
   17.19  				    unsigned long mfn);
   17.20  
   17.21 @@ -416,6 +427,19 @@ void *xc_map_foreign_range(int xc_handle
   17.22  void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
   17.23                             unsigned long *arr, int num );
   17.24  
   17.25 +/**
   17.26 + * Translates a virtual address in the context of a given domain and
   17.27 + * vcpu returning the machine page frame number of the associated
   17.28 + * page.
   17.29 + *
   17.30 + * @parm xc_handle a handle on an open hypervisor interface
   17.31 + * @parm dom the domain to perform the translation in
   17.32 + * @parm vcpu the vcpu to perform the translation on
   17.33 + * @parm virt the virtual address to translate
   17.34 + */
   17.35 +unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
   17.36 +					   int vcpu, unsigned long long virt);
   17.37 +
   17.38  int xc_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf, 
   17.39                      unsigned long max_pfns);
   17.40  
    18.1 --- a/tools/libxc/xenguest.h	Tue Jan 03 08:59:00 2006 -0600
    18.2 +++ b/tools/libxc/xenguest.h	Tue Jan 03 10:19:20 2006 -0600
    18.3 @@ -58,6 +58,7 @@ int xc_vmx_build(int xc_handle,
    18.4                   unsigned int control_evtchn,
    18.5                   unsigned int lapic,
    18.6                   unsigned int vcpus,
    18.7 +                 unsigned int acpi,
    18.8                   unsigned int store_evtchn,
    18.9                   unsigned long *store_mfn);
   18.10  
    19.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Tue Jan 03 08:59:00 2006 -0600
    19.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Tue Jan 03 10:19:20 2006 -0600
    19.3 @@ -364,19 +364,20 @@ static PyObject *pyxc_vmx_build(XcObject
    19.4      int control_evtchn, store_evtchn;
    19.5      int vcpus = 1;
    19.6      int lapic = 0;
    19.7 +    int acpi = 0;
    19.8      int memsize;
    19.9      unsigned long store_mfn = 0;
   19.10  
   19.11      static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
   19.12 -                                "memsize", "image", "lapic", "vcpus", NULL };
   19.13 +                                "memsize", "image", "lapic", "vcpus", "acpi",NULL };
   19.14  
   19.15 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
   19.16 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list,
   19.17                                        &dom, &control_evtchn, &store_evtchn,
   19.18 -                                      &memsize, &image, &lapic, &vcpus) )
   19.19 +                                      &memsize, &image, &lapic, &vcpus,&acpi) )
   19.20          return NULL;
   19.21  
   19.22      if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn,
   19.23 -                      lapic, vcpus, store_evtchn, &store_mfn) != 0 )
   19.24 +                      lapic, vcpus, acpi, store_evtchn, &store_mfn) != 0 )
   19.25          return PyErr_SetFromErrno(xc_error);
   19.26  
   19.27      return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
   19.28 @@ -774,6 +775,52 @@ static PyObject *pyxc_domain_ioport_perm
   19.29      return zero;
   19.30  }
   19.31  
   19.32 +static PyObject *pyxc_domain_irq_permission(PyObject *self,
   19.33 +                                            PyObject *args,
   19.34 +                                            PyObject *kwds)
   19.35 +{
   19.36 +    XcObject *xc = (XcObject *)self;
   19.37 +    uint32_t dom;
   19.38 +    int pirq, allow_access, ret;
   19.39 +
   19.40 +    static char *kwd_list[] = { "dom", "pirq", "allow_access", NULL };
   19.41 +
   19.42 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list, 
   19.43 +                                      &dom, &pirq, &allow_access) )
   19.44 +        return NULL;
   19.45 +
   19.46 +    ret = xc_domain_irq_permission(
   19.47 +        xc->xc_handle, dom, pirq, allow_access);
   19.48 +    if ( ret != 0 )
   19.49 +        return PyErr_SetFromErrno(xc_error);
   19.50 +
   19.51 +    Py_INCREF(zero);
   19.52 +    return zero;
   19.53 +}
   19.54 +
   19.55 +static PyObject *pyxc_domain_iomem_permission(PyObject *self,
   19.56 +                                               PyObject *args,
   19.57 +                                               PyObject *kwds)
   19.58 +{
   19.59 +    XcObject *xc = (XcObject *)self;
   19.60 +    uint32_t dom;
   19.61 +    unsigned long first_pfn, nr_pfns, allow_access, ret;
   19.62 +
   19.63 +    static char *kwd_list[] = { "dom", "first_pfn", "nr_pfns", "allow_access", NULL };
   19.64 +
   19.65 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list, 
   19.66 +                                      &dom, &first_pfn, &nr_pfns, &allow_access) )
   19.67 +        return NULL;
   19.68 +
   19.69 +    ret = xc_domain_iomem_permission(
   19.70 +        xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
   19.71 +    if ( ret != 0 )
   19.72 +        return PyErr_SetFromErrno(xc_error);
   19.73 +
   19.74 +    Py_INCREF(zero);
   19.75 +    return zero;
   19.76 +}
   19.77 +
   19.78  
   19.79  static PyObject *dom_op(XcObject *self, PyObject *args,
   19.80                          int (*fn)(int, uint32_t))
   19.81 @@ -1070,6 +1117,25 @@ static PyMethodDef pyxc_methods[] = {
   19.82        " allow_access [int]: Non-zero means enable access; else disable access\n\n"
   19.83        "Returns: [int] 0 on success; -1 on error.\n" },
   19.84  
   19.85 +    { "domain_irq_permission",
   19.86 +      (PyCFunction)pyxc_domain_irq_permission,
   19.87 +      METH_VARARGS | METH_KEYWORDS, "\n"
   19.88 +      "Allow a domain access to a physical IRQ\n"
   19.89 +      " dom          [int]: Identifier of domain to be allowed access.\n"
   19.90 +      " pirq         [int]: The Physical IRQ\n"
   19.91 +      " allow_access [int]: Non-zero means enable access; else disable access\n\n"
   19.92 +      "Returns: [int] 0 on success; -1 on error.\n" },
   19.93 +
   19.94 +    { "domain_iomem_permission",
   19.95 +      (PyCFunction)pyxc_domain_iomem_permission,
   19.96 +      METH_VARARGS | METH_KEYWORDS, "\n"
   19.97 +      "Allow a domain access to a range of IO memory pages\n"
   19.98 +      " dom          [int]: Identifier of domain to be allowed access.\n"
   19.99 +      " first_pfn   [long]: First page of I/O Memory\n"
  19.100 +      " nr_pfns     [long]: Number of pages of I/O Memory (>0)\n"
  19.101 +      " allow_access [int]: Non-zero means enable access; else disable access\n\n"
  19.102 +      "Returns: [int] 0 on success; -1 on error.\n" },
  19.103 +
  19.104      { "pages_to_kib",
  19.105        (PyCFunction)pyxc_pages_to_kib,
  19.106        METH_VARARGS, "\n"
    20.1 --- a/tools/python/xen/xend/image.py	Tue Jan 03 08:59:00 2006 -0600
    20.2 +++ b/tools/python/xen/xend/image.py	Tue Jan 03 10:19:20 2006 -0600
    20.3 @@ -189,11 +189,16 @@ class VmxImageHandler(ImageHandler):
    20.4      def configure(self, imageConfig, deviceConfig):
    20.5          ImageHandler.configure(self, imageConfig, deviceConfig)
    20.6  
    20.7 +        info = xc.xeninfo()
    20.8 +        if not 'hvm' in info['xen_caps']:
    20.9 +            raise VmError("vmx: not an Intel VT platform, we stop creating!")
   20.10 +
   20.11          self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
   20.12          self.device_model = sxp.child_value(imageConfig, 'device_model')
   20.13          if not self.device_model:
   20.14              raise VmError("vmx: missing device model")
   20.15          self.display = sxp.child_value(imageConfig, 'display')
   20.16 +        self.xauthority = sxp.child_value(imageConfig, 'xauthority')
   20.17  
   20.18          self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
   20.19                          ("image/device-model", self.device_model),
   20.20 @@ -209,6 +214,8 @@ class VmxImageHandler(ImageHandler):
   20.21          if not lapic is None:
   20.22              self.lapic = int(lapic)
   20.23  
   20.24 +        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
   20.25 +        
   20.26      def buildDomain(self):
   20.27          # Create an event channel
   20.28          self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
   20.29 @@ -224,6 +231,7 @@ class VmxImageHandler(ImageHandler):
   20.30          log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
   20.31          log.debug("lapic          = %d", self.lapic)
   20.32          log.debug("vcpus          = %d", self.vm.getVCpuCount())
   20.33 +        log.debug("acpi           = %d", self.acpi)
   20.34  
   20.35          return xc.vmx_build(dom            = self.vm.getDomid(),
   20.36                              image          = self.kernel,
   20.37 @@ -231,9 +239,9 @@ class VmxImageHandler(ImageHandler):
   20.38                              store_evtchn   = store_evtchn,
   20.39                              memsize        = self.vm.getMemoryTarget() / 1024,
   20.40                              lapic          = self.lapic,
   20.41 +                            acpi           = self.acpi,
   20.42                              vcpus          = self.vm.getVCpuCount())
   20.43  
   20.44 -
   20.45      # Return a list of cmd line args to the device models based on the
   20.46      # xm config file
   20.47      def parseDeviceModelArgs(self, imageConfig, deviceConfig):
   20.48 @@ -264,44 +272,44 @@ class VmxImageHandler(ImageHandler):
   20.49          nics = 0
   20.50          for (name, info) in deviceConfig:
   20.51              if name == 'vbd':
   20.52 -               uname = sxp.child_value(info, 'uname')
   20.53 -               typedev = sxp.child_value(info, 'dev')
   20.54 -               (_, vbdparam) = string.split(uname, ':', 1)
   20.55 -               if re.match('^ioemu:', typedev):
   20.56 -                  (emtype, vbddev) = string.split(typedev, ':', 1)
   20.57 -               else:
   20.58 -                  emtype = 'vbd'
   20.59 -                  vbddev = typedev
   20.60 -               if emtype != 'ioemu':
   20.61 -                  continue;
   20.62 -               vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
   20.63 -               if vbddev not in vbddev_list:
   20.64 -                  raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
   20.65 -               ret.append("-%s" % vbddev)
   20.66 -               ret.append("%s" % vbdparam)
   20.67 +                uname = sxp.child_value(info, 'uname')
   20.68 +                typedev = sxp.child_value(info, 'dev')
   20.69 +                (_, vbdparam) = string.split(uname, ':', 1)
   20.70 +                if 'ioemu:' in typedev:
   20.71 +                    (emtype, vbddev) = string.split(typedev, ':', 1)
   20.72 +                else:
   20.73 +                    emtype = 'vbd'
   20.74 +                    vbddev = typedev
   20.75 +                if emtype == 'vbd':
   20.76 +                    continue;
   20.77 +                vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
   20.78 +                if vbddev not in vbddev_list:
   20.79 +                    raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
   20.80 +                ret.append("-%s" % vbddev)
   20.81 +                ret.append("%s" % vbdparam)
   20.82              if name == 'vif':
   20.83 -               type = sxp.child_value(info, 'type')
   20.84 -               if type != 'ioemu':
   20.85 -                   continue
   20.86 -               nics += 1
   20.87 -               if mac != None:
   20.88 -                   continue
   20.89 -               mac = sxp.child_value(info, 'mac')
   20.90 -               bridge = sxp.child_value(info, 'bridge')
   20.91 -               if mac == None:
   20.92 -                   mac = randomMAC()
   20.93 -               if bridge == None:
   20.94 -                   bridge = 'xenbr0'
   20.95 -               ret.append("-macaddr")
   20.96 -               ret.append("%s" % mac)
   20.97 -               ret.append("-bridge")
   20.98 -               ret.append("%s" % bridge)
   20.99 +                type = sxp.child_value(info, 'type')
  20.100 +                if type != 'ioemu':
  20.101 +                    continue
  20.102 +                nics += 1
  20.103 +                if mac != None:
  20.104 +                    continue
  20.105 +                mac = sxp.child_value(info, 'mac')
  20.106 +                bridge = sxp.child_value(info, 'bridge')
  20.107 +                if mac == None:
  20.108 +                    mac = randomMAC()
  20.109 +                if bridge == None:
  20.110 +                    bridge = 'xenbr0'
  20.111 +                ret.append("-macaddr")
  20.112 +                ret.append("%s" % mac)
  20.113 +                ret.append("-bridge")
  20.114 +                ret.append("%s" % bridge)
  20.115              if name == 'vtpm':
  20.116 -               instance = sxp.child_value(info, 'pref_instance')
  20.117 -               ret.append("-instance")
  20.118 -               ret.append("%s" % instance)
  20.119 +                instance = sxp.child_value(info, 'pref_instance')
  20.120 +                ret.append("-instance")
  20.121 +                ret.append("%s" % instance)
  20.122          ret.append("-nics")
  20.123 -        ret.append("%d" % nics) 
  20.124 +        ret.append("%d" % nics)
  20.125          return ret
  20.126  
  20.127      def configVNC(self, config):
  20.128 @@ -340,6 +348,8 @@ class VmxImageHandler(ImageHandler):
  20.129          env = dict(os.environ)
  20.130          if self.display:
  20.131              env['DISPLAY'] = self.display
  20.132 +        if self.xauthority:
  20.133 +            env['XAUTHORITY'] = self.xauthority
  20.134          log.info("spawning device models: %s %s", self.device_model, args)
  20.135          self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
  20.136          log.info("device model pid: %d", self.pid)
    21.1 --- a/tools/python/xen/xend/server/blkif.py	Tue Jan 03 08:59:00 2006 -0600
    21.2 +++ b/tools/python/xen/xend/server/blkif.py	Tue Jan 03 10:19:20 2006 -0600
    21.3 @@ -31,7 +31,7 @@ class BlkifController(DevController):
    21.4      """Block device interface controller. Handles all block devices
    21.5      for a domain.
    21.6      """
    21.7 -    
    21.8 +
    21.9      def __init__(self, vm):
   21.10          """Create a block device controller.
   21.11          """
   21.12 @@ -40,9 +40,9 @@ class BlkifController(DevController):
   21.13  
   21.14      def getDeviceDetails(self, config):
   21.15          """@see DevController.getDeviceDetails"""
   21.16 -        
   21.17 +
   21.18          dev = sxp.child_value(config, 'dev')
   21.19 -        if re.match('^ioemu:', dev):
   21.20 +        if 'ioemu:' in dev:
   21.21              return (None,{},{})
   21.22  
   21.23          devid = blkif.blkdev_name_to_number(dev)
    22.1 --- a/tools/python/xen/xm/create.py	Tue Jan 03 08:59:00 2006 -0600
    22.2 +++ b/tools/python/xen/xm/create.py	Tue Jan 03 10:19:20 2006 -0600
    22.3 @@ -164,6 +164,10 @@ gopts.var('lapic', val='LAPIC',
    22.4            fn=set_int, default=0,
    22.5            use="Disable or enable local APIC of VMX domain.")
    22.6  
    22.7 +gopts.var('acpi', val='ACPI',
    22.8 +          fn=set_int, default=0,
    22.9 +          use="Disable or enable ACPI of VMX domain.")
   22.10 +
   22.11  gopts.var('vcpus', val='VCPUS',
   22.12            fn=set_int, default=1,
   22.13            use="# of Virtual CPUS in domain.")
   22.14 @@ -388,6 +392,10 @@ gopts.var('display', val='DISPLAY',
   22.15            fn=set_value, default=None,
   22.16            use="X11 display to use")
   22.17  
   22.18 +gopts.var('xauthority', val='XAUTHORITY',
   22.19 +          fn=set_value, default=None,
   22.20 +          use="X11 Authority to use")
   22.21 +
   22.22  
   22.23  def err(msg):
   22.24      """Print an error to stderr and exit.
   22.25 @@ -526,7 +534,8 @@ def configure_vmx(config_image, vals):
   22.26      """
   22.27      args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
   22.28               'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
   22.29 -             'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic']
   22.30 +             'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic',
   22.31 +             'xauthority', 'acpi' ]
   22.32      for a in args:
   22.33          if (vals.__dict__[a]):
   22.34              config_image.append([a, vals.__dict__[a]])
   22.35 @@ -801,6 +810,9 @@ def parseCommandLine(argv):
   22.36      if not gopts.vals.display:
   22.37          gopts.vals.display = os.getenv("DISPLAY")
   22.38  
   22.39 +    if not gopts.vals.xauthority:
   22.40 +        gopts.vals.xauthority = os.getenv("XAUTHORITY")
   22.41 +
   22.42      # Process remaining args as config variables.
   22.43      for arg in args:
   22.44          if '=' in arg:
    23.1 --- a/tools/python/xen/xm/main.py	Tue Jan 03 08:59:00 2006 -0600
    23.2 +++ b/tools/python/xen/xm/main.py	Tue Jan 03 10:19:20 2006 -0600
    23.3 @@ -75,7 +75,7 @@ domname_help = "domname <DomId>         
    23.4  vcpu_set_help = """vcpu-set <DomId> <VCPUs>         Set the number of VCPUs for a domain"""
    23.5  vcpu_list_help = "vcpu-list <DomId>                List the VCPUs for a domain (or all domains)"
    23.6  vcpu_pin_help = "vcpu-pin <DomId> <VCPU> <CPUs>   Set which cpus a VCPU can use" 
    23.7 -dmesg_help =   "dmesg [--clear]                  Read or clear Xen's message buffer"
    23.8 +dmesg_help =   "dmesg [-c|--clear]               Read or clear Xen's message buffer"
    23.9  info_help =    "info                             Get information about the xen host"
   23.10  rename_help =  "rename <DomId> <New Name>        Rename a domain"
   23.11  log_help =     "log                              Print the xend log"
   23.12 @@ -672,7 +672,7 @@ its contents if the [-c|--clear] flag is
   23.13          server.xend_node_clear_dmesg()
   23.14  
   23.15  def xm_log(args):
   23.16 -    arg_check(args, 'xm-log', 0)
   23.17 +    arg_check(args, "log", 0)
   23.18      
   23.19      from xen.xend.XendClient import server
   23.20      print server.xend_node_log()
   23.21 @@ -845,8 +845,8 @@ aliases = {
   23.22      "balloon": "mem-set",
   23.23      "set-vcpus": "vcpu-set",
   23.24      "vif-list": "network-list",
   23.25 -    "vbd-create": "block-create",
   23.26 -    "vbd-destroy": "block-destroy",
   23.27 +    "vbd-create": "block-attach",
   23.28 +    "vbd-destroy": "block-detach",
   23.29      "vbd-list": "block-list",
   23.30      }
   23.31  
    24.1 --- a/tools/vtpm_manager/README	Tue Jan 03 08:59:00 2006 -0600
    24.2 +++ b/tools/vtpm_manager/README	Tue Jan 03 10:19:20 2006 -0600
    24.3 @@ -53,11 +53,6 @@ DUMMY_BACKEND                -> vtpm_man
    24.4  
    24.5  MANUAL_DM_LAUNCH             -> Must manually launch & kill VTPMs
    24.6  
    24.7 -WELL_KNOWN_SRK_AUTH          -> Rather than randomly generating the password for the SRK,
    24.8 -                                use a well known value. This is necessary for sharing use
    24.9 -                                of the SRK across applications. Such as VTPM and Dom0
   24.10 -                                measurement software.
   24.11 -
   24.12  WELL_KNOWN_OWNER_AUTH        -> Rather than randomly generating the password for the owner,
   24.13                                  use a well known value. This is useful for debugging and for
   24.14                                  poor bios which do not support clearing TPM if OwnerAuth is
    25.1 --- a/tools/vtpm_manager/Rules.mk	Tue Jan 03 08:59:00 2006 -0600
    25.2 +++ b/tools/vtpm_manager/Rules.mk	Tue Jan 03 10:19:20 2006 -0600
    25.3 @@ -56,8 +56,7 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT
    25.4  # Do not have manager launch DMs.
    25.5  #CFLAGS += -DMANUAL_DM_LAUNCH
    25.6  
    25.7 -# Fixed SRK
    25.8 -CFLAGS += -DWELL_KNOWN_SRK_AUTH
    25.9 +# Fixed OwnerAuth
   25.10  #CFLAGS += -DWELL_KNOWN_OWNER_AUTH
   25.11  
   25.12  # TPM Hardware Device or TPM Simulator
    26.1 --- a/tools/vtpm_manager/manager/securestorage.c	Tue Jan 03 08:59:00 2006 -0600
    26.2 +++ b/tools/vtpm_manager/manager/securestorage.c	Tue Jan 03 10:19:20 2006 -0600
    26.3 @@ -65,7 +65,7 @@ TPM_RESULT envelope_encrypt(const buffer
    26.4    UINT32 i;
    26.5    struct pack_constbuf_t symkey_cipher32, data_cipher32;
    26.6    
    26.7 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
    26.8 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Input[%d]: 0x", buffer_len(inbuf));
    26.9    for (i=0; i< buffer_len(inbuf); i++)
   26.10      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
   26.11    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   26.12 @@ -94,6 +94,12 @@ TPM_RESULT envelope_encrypt(const buffer
   26.13  	       BSG_TPM_SIZE32_DATA, &data_cipher32);
   26.14  
   26.15    vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
   26.16 +
   26.17 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Output[%d]: 0x", buffer_len(sealed_data));
   26.18 +  for (i=0; i< buffer_len(sealed_data); i++)
   26.19 +    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_data->bytes[i]);
   26.20 +  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   26.21 +
   26.22    goto egress;
   26.23  
   26.24   abort_egress:
   26.25 @@ -125,7 +131,7 @@ TPM_RESULT envelope_decrypt(const long  
   26.26  
   26.27    memset(&symkey, 0, sizeof(symkey_t));
   26.28  
   26.29 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
   26.30 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%ld]: 0x", cipher_size);
   26.31    for (i=0; i< cipher_size; i++)
   26.32      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
   26.33    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   26.34 @@ -155,6 +161,11 @@ TPM_RESULT envelope_decrypt(const long  
   26.35    
   26.36    // Decrypt State
   26.37    TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) );
   26.38 +
   26.39 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data));
   26.40 +  for (i=0; i< buffer_len(unsealed_data); i++)
   26.41 +    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", unsealed_data->bytes[i]);
   26.42 +  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   26.43    
   26.44    goto egress;
   26.45    
   26.46 @@ -291,124 +302,175 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
   26.47    return status;
   26.48  }
   26.49  
   26.50 +
   26.51  TPM_RESULT VTPM_SaveService(void) {
   26.52    TPM_RESULT status=TPM_SUCCESS;
   26.53    int fh, dmis=-1;
   26.54 -  
   26.55 -  BYTE *flat_global;
   26.56 -  int flat_global_size, bytes_written;
   26.57 +
   26.58 +  BYTE *flat_boot_key, *flat_dmis, *flat_enc;
   26.59 +  buffer_t clear_flat_global, enc_flat_global;
   26.60    UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
   26.61 +  UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
   26.62    struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
   26.63 -  
   26.64 +  struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes};
   26.65 +
   26.66    struct hashtable_itr *dmi_itr;
   26.67    VTPM_DMI_RESOURCE *dmi_res;
   26.68 -  
   26.69 -  UINT32 flat_global_full_size;
   26.70 -  
   26.71 -  // Global Values needing to be saved
   26.72 -  flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
   26.73 -    sizeof(UINT32) +       // storagekeysize
   26.74 -    storageKeySize +       // storage key
   26.75 -    hashtable_count(vtpm_globals->dmi_map) * // num DMIS
   26.76 -    (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
   26.77 -  
   26.78 -  
   26.79 -  flat_global = (BYTE *) malloc( flat_global_full_size);
   26.80 -  
   26.81 -  flat_global_size = BSG_PackList(flat_global, 4,
   26.82 -				  BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
   26.83 -				  BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
   26.84 -				  BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
   26.85 -				  BSG_TPM_SIZE32_DATA, &storage_key_pack);
   26.86 -  
   26.87 +
   26.88 +  UINT32 boot_key_size, flat_dmis_size;
   26.89 +
   26.90 +  // Initially fill these with buffer sizes for each data type. Later fill
   26.91 +  // in actual size, once flattened.
   26.92 +  boot_key_size =  sizeof(UINT32) +       // bootkeysize
   26.93 +                   bootKeySize;           // boot key
   26.94 +
   26.95 +  TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths
   26.96 +                                              sizeof(UINT32) +// storagekeysize
   26.97 +                                              storageKeySize, NULL) ); // storage key
   26.98 +
   26.99 +  flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
  26.100 +                   (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
  26.101 +
  26.102 +  flat_boot_key = (BYTE *) malloc( boot_key_size );
  26.103 +  flat_enc = (BYTE *) malloc( sizeof(UINT32) );
  26.104 +  flat_dmis = (BYTE *) malloc( flat_dmis_size );
  26.105 +
  26.106 +  boot_key_size = BSG_PackList(flat_boot_key, 1,
  26.107 +                               BSG_TPM_SIZE32_DATA, &boot_key_pack);
  26.108 +
  26.109 +  BSG_PackList(clear_flat_global.bytes, 3,
  26.110 +                BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
  26.111 +                BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
  26.112 +                BSG_TPM_SIZE32_DATA, &storage_key_pack);
  26.113 +
  26.114 +  TPMTRYRETURN(envelope_encrypt(&clear_flat_global,
  26.115 +                                &vtpm_globals->bootKey,
  26.116 +                                &enc_flat_global) );
  26.117 +
  26.118 +  BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);
  26.119 +
  26.120    // Per DMI values to be saved
  26.121    if (hashtable_count(vtpm_globals->dmi_map) > 0) {
  26.122 -    
  26.123 +
  26.124      dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
  26.125      do {
  26.126        dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
  26.127        dmis++;
  26.128  
  26.129        // No need to save dmi0.
  26.130 -      if (dmi_res->dmi_id == 0) 	
  26.131 -	continue;
  26.132 -      
  26.133 -      
  26.134 -      flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
  26.135 -					BSG_TYPE_UINT32, &dmi_res->dmi_id,
  26.136 -					BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  26.137 -					BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  26.138 -      
  26.139 +      if (dmi_res->dmi_id == 0)
  26.140 +        continue;
  26.141 +
  26.142 +
  26.143 +      flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3,
  26.144 +                                        BSG_TYPE_UINT32, &dmi_res->dmi_id,
  26.145 +                                        BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  26.146 +                                        BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  26.147 +
  26.148      } while (hashtable_iterator_advance(dmi_itr));
  26.149    }
  26.150 -  
  26.151 -  //FIXME: Once we have a way to protect a TPM key, we should use it to 
  26.152 -  //       encrypt this blob. BUT, unless there is a way to ensure the key is
  26.153 -  //       not used by other apps, this encryption is useless.
  26.154 +
  26.155    fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
  26.156    if (fh == -1) {
  26.157      vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE);
  26.158      status = TPM_IOERROR;
  26.159      goto abort_egress;
  26.160    }
  26.161 -  
  26.162 -  if ( (bytes_written = write(fh, flat_global, flat_global_size)) != flat_global_size ) {
  26.163 -    vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes written.\n", bytes_written, flat_global_size);
  26.164 +
  26.165 +  if ( ( write(fh, flat_boot_key, boot_key_size) != boot_key_size ) ||
  26.166 +       ( write(fh, flat_enc, sizeof(UINT32)) != sizeof(UINT32) ) ||
  26.167 +       ( write(fh, enc_flat_global.bytes, buffer_len(&enc_flat_global)) != buffer_len(&enc_flat_global) ) ||
  26.168 +       ( write(fh, flat_dmis, flat_dmis_size) != flat_dmis_size ) ) {
  26.169 +    vtpmlogerror(VTPM_LOG_VTPM, "Failed to completely write service data.\n");
  26.170      status = TPM_IOERROR;
  26.171      goto abort_egress;
  26.172 -  }
  26.173 -  vtpm_globals->DMI_table_dirty = FALSE; 
  26.174 -  
  26.175 + }
  26.176 +
  26.177 +  vtpm_globals->DMI_table_dirty = FALSE;
  26.178 +
  26.179    goto egress;
  26.180 -  
  26.181 +
  26.182   abort_egress:
  26.183   egress:
  26.184 -  
  26.185 -  free(flat_global);
  26.186 +
  26.187 +  free(flat_boot_key);
  26.188 +  free(flat_enc);
  26.189 +  buffer_free(&enc_flat_global);
  26.190 +  free(flat_dmis);
  26.191    close(fh);
  26.192 -  
  26.193 +
  26.194    vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis);
  26.195    return status;
  26.196  }
  26.197  
  26.198  TPM_RESULT VTPM_LoadService(void) {
  26.199 -  
  26.200 +
  26.201    TPM_RESULT status=TPM_SUCCESS;
  26.202    int fh, stat_ret, dmis=0;
  26.203    long fh_size = 0, step_size;
  26.204 -  BYTE *flat_global=NULL;
  26.205 -  struct pack_buf_t storage_key_pack;
  26.206 -  UINT32 *dmi_id_key;
  26.207 -  
  26.208 +  BYTE *flat_table=NULL;
  26.209 +  buffer_t  unsealed_data;
  26.210 +  struct pack_buf_t storage_key_pack, boot_key_pack;
  26.211 +  UINT32 *dmi_id_key, enc_size;
  26.212 +
  26.213    VTPM_DMI_RESOURCE *dmi_res;
  26.214    struct stat file_stat;
  26.215 -  
  26.216 +
  26.217 +  TPM_HANDLE boot_key_handle;
  26.218 +  TPM_AUTHDATA boot_usage_auth;
  26.219 +  memset(&boot_usage_auth, 0, sizeof(TPM_AUTHDATA));
  26.220 +
  26.221    fh = open(STATE_FILE, O_RDONLY );
  26.222    stat_ret = fstat(fh, &file_stat);
  26.223 -  if (stat_ret == 0) 
  26.224 +  if (stat_ret == 0)
  26.225      fh_size = file_stat.st_size;
  26.226    else {
  26.227      status = TPM_IOERROR;
  26.228      goto abort_egress;
  26.229    }
  26.230 -  
  26.231 -  flat_global = (BYTE *) malloc(fh_size);
  26.232 -  
  26.233 -  if ((long) read(fh, flat_global, fh_size) != fh_size ) {
  26.234 +
  26.235 +  flat_table = (BYTE *) malloc(fh_size);
  26.236 +
  26.237 +  if ((long) read(fh, flat_table, fh_size) != fh_size ) {
  26.238      status = TPM_IOERROR;
  26.239      goto abort_egress;
  26.240    }
  26.241 -  
  26.242 +
  26.243 +  // Read Boot Key
  26.244 +  step_size = BSG_UnpackList( flat_table, 2,
  26.245 +                              BSG_TPM_SIZE32_DATA, &boot_key_pack,
  26.246 +                              BSG_TYPE_UINT32, &enc_size);
  26.247 +
  26.248 +  TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) );
  26.249 +  TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) );
  26.250 +
  26.251 +  //Load Boot Key
  26.252 +  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
  26.253 +                              TPM_SRK_KEYHANDLE,
  26.254 +                              &vtpm_globals->bootKeyWrap,
  26.255 +                              &SRK_AUTH,
  26.256 +                              &boot_key_handle,
  26.257 +                              &vtpm_globals->keyAuth,
  26.258 +                              &vtpm_globals->bootKey,
  26.259 +                              FALSE) );
  26.260 +
  26.261 +  TPMTRYRETURN( envelope_decrypt(enc_size,
  26.262 +                                 flat_table + step_size,
  26.263 +                                 vtpm_globals->manager_tcs_handle,
  26.264 +                                 boot_key_handle,
  26.265 +                                 (const TPM_AUTHDATA*) &boot_usage_auth,
  26.266 +                                 &unsealed_data) );
  26.267 +  step_size += enc_size;
  26.268 +
  26.269    // Global Values needing to be saved
  26.270 -  step_size = BSG_UnpackList( flat_global, 4,
  26.271 -			      BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
  26.272 -			      BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
  26.273 -			      BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
  26.274 -			      BSG_TPM_SIZE32_DATA, &storage_key_pack);
  26.275 -  
  26.276 +  BSG_UnpackList( unsealed_data.bytes, 3,
  26.277 +                  BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
  26.278 +                  BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
  26.279 +                  BSG_TPM_SIZE32_DATA, &storage_key_pack);
  26.280 +
  26.281    TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
  26.282    TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) );
  26.283 -  
  26.284 +
  26.285    // Per DMI values to be saved
  26.286    while ( step_size < fh_size ){
  26.287      if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
  26.288 @@ -417,35 +479,38 @@ TPM_RESULT VTPM_LoadService(void) {
  26.289      } else {
  26.290        dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
  26.291        dmis++;
  26.292 -      
  26.293 +
  26.294        dmi_res->connected = FALSE;
  26.295 -      
  26.296 -      step_size += BSG_UnpackList(flat_global + step_size, 3,
  26.297 -				  BSG_TYPE_UINT32, &dmi_res->dmi_id, 
  26.298 -				  BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  26.299 -				  BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  26.300 -      
  26.301 +
  26.302 +      step_size += BSG_UnpackList(flat_table + step_size, 3,
  26.303 +                                 BSG_TYPE_UINT32, &dmi_res->dmi_id,
  26.304 +                                 BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  26.305 +                                 BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  26.306 +
  26.307        // install into map
  26.308        dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
  26.309        *dmi_id_key = dmi_res->dmi_id;
  26.310        if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
  26.311 -	status = TPM_FAIL;
  26.312 -	goto abort_egress;
  26.313 +        status = TPM_FAIL;
  26.314 +        goto abort_egress;
  26.315        }
  26.316 -      
  26.317 +
  26.318      }
  26.319 -    
  26.320 +
  26.321    }
  26.322 -  
  26.323 +
  26.324    vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis);
  26.325    goto egress;
  26.326 -  
  26.327 +
  26.328   abort_egress:
  26.329    vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status));
  26.330   egress:
  26.331 -  
  26.332 -  free(flat_global);
  26.333 +
  26.334 +  free(flat_table);
  26.335    close(fh);
  26.336 -  
  26.337 +
  26.338 +  // TODO: Could be nice and evict BootKey. (Need to add EvictKey to VTSP.
  26.339 +
  26.340    return status;
  26.341  }
  26.342 +
    27.1 --- a/tools/vtpm_manager/manager/vtpm_manager.c	Tue Jan 03 08:59:00 2006 -0600
    27.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.c	Tue Jan 03 10:19:20 2006 -0600
    27.3 @@ -74,16 +74,15 @@ VTPM_GLOBALS *vtpm_globals=NULL;
    27.4  #endif
    27.5  
    27.6  // --------------------------- Well Known Auths --------------------------
    27.7 -#ifdef WELL_KNOWN_SRK_AUTH
    27.8 -static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    27.9 +const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   27.10                                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
   27.11 -#endif
   27.12  
   27.13  #ifdef WELL_KNOWN_OWNER_AUTH
   27.14  static BYTE FIXED_OWNER_AUTH[20] =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   27.15                                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
   27.16  #endif
   27.17 -                                  
   27.18 +
   27.19 +
   27.20  // -------------------------- Hash table functions --------------------
   27.21  
   27.22  static unsigned int hashfunc32(void *ky) {
   27.23 @@ -100,13 +99,7 @@ TPM_RESULT VTPM_Create_Service(){
   27.24    
   27.25    TPM_RESULT status = TPM_SUCCESS;
   27.26    
   27.27 -  // Generate Auth's for SRK & Owner
   27.28 -#ifdef WELL_KNOWN_SRK_AUTH 
   27.29 -  memcpy(vtpm_globals->srk_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
   27.30 -#else    
   27.31 -  Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );  
   27.32 -#endif
   27.33 -  
   27.34 +  // Generate Auth for Owner
   27.35  #ifdef WELL_KNOWN_OWNER_AUTH 
   27.36    memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH, sizeof(TPM_AUTHDATA));
   27.37  #else    
   27.38 @@ -116,14 +109,14 @@ TPM_RESULT VTPM_Create_Service(){
   27.39    // Take Owership of TPM
   27.40    CRYPTO_INFO ek_cryptoInfo;
   27.41    
   27.42 -  vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
   27.43    status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
   27.44    
   27.45    // If we can read PubEK then there is no owner and we should take it.
   27.46    if (status == TPM_SUCCESS) { 
   27.47 +    vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
   27.48      TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
   27.49  				    (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
   27.50 -				    (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
   27.51 +				    &SRK_AUTH,
   27.52  				    &ek_cryptoInfo,
   27.53  				    &vtpm_globals->keyAuth)); 
   27.54    
   27.55 @@ -142,7 +135,7 @@ TPM_RESULT VTPM_Create_Service(){
   27.56    TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
   27.57  			  TPM_ET_KEYHANDLE,
   27.58  			  TPM_SRK_KEYHANDLE, 
   27.59 -			  (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
   27.60 +			  &SRK_AUTH,
   27.61  			  &sharedsecret, 
   27.62  			  &osap) ); 
   27.63  
   27.64 @@ -157,8 +150,43 @@ TPM_RESULT VTPM_Create_Service(){
   27.65  				    &vtpm_globals->storageKeyWrap,
   27.66  				    &osap) );
   27.67    
   27.68 -  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
   27.69 +  // Generate boot key's auth
   27.70 +  Crypto_GetRandom(  &vtpm_globals->storage_key_usage_auth, 
   27.71 +		     sizeof(TPM_AUTHDATA) );
   27.72 +  
   27.73 +  TPM_AUTHDATA bootKeyWrapAuth;
   27.74 +  memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
   27.75    
   27.76 +  TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
   27.77 +			  TPM_ET_KEYHANDLE,
   27.78 +			  TPM_SRK_KEYHANDLE, 
   27.79 +			  &SRK_AUTH,
   27.80 +			  &sharedsecret, 
   27.81 +			  &osap) ); 
   27.82 +
   27.83 +  osap.fContinueAuthSession = FALSE;
   27.84 + 
   27.85 +  // FIXME: This key protects the global secrets on disk. It should use TPM
   27.86 +  //        PCR bindings to limit its use to legit configurations.
   27.87 +  //        Current binds are open, implying a Trusted VM contains this code.
   27.88 +  //        If this VM is not Trusted, use measurement and PCR bindings.
   27.89 +  TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
   27.90 +				    TPM_KEY_BIND,
   27.91 +				    (const TPM_AUTHDATA*)&bootKeyWrapAuth,
   27.92 +				    TPM_SRK_KEYHANDLE, 
   27.93 +				    (const TPM_AUTHDATA*)&sharedsecret,
   27.94 +				    &vtpm_globals->bootKeyWrap,
   27.95 +				    &osap) );
   27.96 +
   27.97 +  // Populate CRYPTO_INFO vtpm_globals->bootKey. This does not load it into the TPM
   27.98 +  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
   27.99 +                              TPM_SRK_KEYHANDLE,
  27.100 +                              &vtpm_globals->bootKeyWrap,
  27.101 +                              NULL,
  27.102 +                              NULL,
  27.103 +                              NULL,
  27.104 +                              &vtpm_globals->bootKey,
  27.105 +                              TRUE ) );
  27.106    goto egress;
  27.107    
  27.108   abort_egress:
  27.109 @@ -278,24 +306,26 @@ void *VTPM_Service_Handler(void *threadT
  27.110  #endif
  27.111  
  27.112      // Check status of rx_fh. If necessary attempt to re-open it.    
  27.113 +    char* s = NULL;
  27.114      if (*rx_fh < 0) {
  27.115  #ifdef VTPM_MULTI_VM
  27.116 -      *rx_fh = open(VTPM_BE_DEV, O_RDWR);
  27.117 +      s = VTPM_BE_DEV;
  27.118  #else
  27.119        if (threadType == BE_LISTENER_THREAD) 
  27.120    #ifdef DUMMY_BACKEND
  27.121 -	*rx_fh = open("/tmp/in.fifo", O_RDWR);
  27.122 +	s = "/tmp/in.fifo";
  27.123    #else
  27.124 -        *rx_fh = open(VTPM_BE_DEV, O_RDWR);
  27.125 +      s = VTPM_BE_DEV;
  27.126    #endif
  27.127        else  // DMI Listener   
  27.128 -	*rx_fh = open(VTPM_RX_FIFO, O_RDWR);
  27.129 +	s = VTPM_RX_FIFO;
  27.130 +      *rx_fh = open(s, O_RDWR);
  27.131  #endif    
  27.132      }
  27.133      
  27.134      // Respond to failures to open rx_fh
  27.135      if (*rx_fh < 0) {
  27.136 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
  27.137 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh for %s.\n", s);
  27.138  #ifdef VTPM_MULTI_VM
  27.139        return TPM_IOERROR; 
  27.140  #else
  27.141 @@ -713,7 +743,7 @@ void *VTPM_Service_Handler(void *threadT
  27.142  
  27.143  ///////////////////////////////////////////////////////////////////////////////
  27.144  TPM_RESULT VTPM_Init_Service() {
  27.145 -  TPM_RESULT status = TPM_FAIL;   
  27.146 +  TPM_RESULT status = TPM_FAIL, serviceStatus;   
  27.147    BYTE *randomsead;
  27.148    UINT32 randomsize;
  27.149  
  27.150 @@ -737,7 +767,7 @@ TPM_RESULT VTPM_Init_Service() {
  27.151    
  27.152    // Create new TCS Object
  27.153    vtpm_globals->manager_tcs_handle = 0;
  27.154 -  
  27.155 + 
  27.156    TPMTRYRETURN(TCS_create());
  27.157    
  27.158    // Create TCS Context for service
  27.159 @@ -756,17 +786,24 @@ TPM_RESULT VTPM_Init_Service() {
  27.160    vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
  27.161  
  27.162  	// If failed, create new Service.
  27.163 -  if (VTPM_LoadService() != TPM_SUCCESS)
  27.164 +  serviceStatus = VTPM_LoadService();
  27.165 +  if (serviceStatus == TPM_IOERROR) {
  27.166 +    vtpmloginfo(VTPM_LOG_VTPM, "Failed to read service file. Assuming first time initialization.\n");
  27.167      TPMTRYRETURN( VTPM_Create_Service() );    
  27.168 +  } else if (serviceStatus != TPM_SUCCESS) {
  27.169 +    vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing service file");
  27.170 +    exit(1);
  27.171 +  }
  27.172  
  27.173    //Load Storage Key 
  27.174    TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
  27.175  			      TPM_SRK_KEYHANDLE,
  27.176  			      &vtpm_globals->storageKeyWrap,
  27.177 -			      (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
  27.178 +			      &SRK_AUTH,
  27.179  			      &vtpm_globals->storageKeyHandle,
  27.180  			      &vtpm_globals->keyAuth,
  27.181 -			      &vtpm_globals->storageKey) );
  27.182 +			      &vtpm_globals->storageKey,
  27.183 +                              FALSE ) );
  27.184  
  27.185    // Create entry for Dom0 for control messages
  27.186    TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
  27.187 @@ -797,12 +834,11 @@ void VTPM_Stop_Service() {
  27.188  		free (dmi_itr);
  27.189    }
  27.190    
  27.191 -	
  27.192 +  if ( (vtpm_globals->DMI_table_dirty) && (VTPM_SaveService() != TPM_SUCCESS) )
  27.193 +    vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
  27.194 +
  27.195    TCS_CloseContext(vtpm_globals->manager_tcs_handle);
  27.196 -  
  27.197 -  if ( (vtpm_globals->DMI_table_dirty) &&
  27.198 -       (VTPM_SaveService() != TPM_SUCCESS) )
  27.199 -    vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
  27.200 +  TCS_destroy();
  27.201    
  27.202    hashtable_destroy(vtpm_globals->dmi_map, 1);
  27.203    free(vtpm_globals);
    28.1 --- a/tools/vtpm_manager/manager/vtpmpriv.h	Tue Jan 03 08:59:00 2006 -0600
    28.2 +++ b/tools/vtpm_manager/manager/vtpmpriv.h	Tue Jan 03 10:19:20 2006 -0600
    28.3 @@ -108,6 +108,7 @@ typedef struct tdVTPM_GLOBALS {
    28.4    TCS_CONTEXT_HANDLE  manager_tcs_handle;     // TCS Handle used by manager
    28.5    TPM_HANDLE          storageKeyHandle;       // Key used by persistent store
    28.6    CRYPTO_INFO         storageKey;             // For software encryption
    28.7 +  CRYPTO_INFO         bootKey;                // For saving table
    28.8    TCS_AUTH            keyAuth;                // OIAP session for storageKey 
    28.9    BOOL                DMI_table_dirty;        // Indicates that a command
   28.10                                                // has updated the DMI table
   28.11 @@ -115,15 +116,17 @@ typedef struct tdVTPM_GLOBALS {
   28.12      
   28.13    // Persistent Data
   28.14    TPM_AUTHDATA        owner_usage_auth;       // OwnerAuth of real TPM
   28.15 -  TPM_AUTHDATA        srk_usage_auth;         // SRK Auth of real TPM    
   28.16    buffer_t            storageKeyWrap;         // Wrapped copy of storageKey
   28.17 +  TPM_AUTHDATA        srk_usage_auth;
   28.18 +  TPM_AUTHDATA        storage_key_usage_auth; 
   28.19  
   28.20 -  TPM_AUTHDATA        storage_key_usage_auth; 
   28.21 -    
   28.22 +  buffer_t            bootKeyWrap;            // Wrapped copy of boot key 
   28.23 +
   28.24  }VTPM_GLOBALS;
   28.25  
   28.26 -//Global dmi map
   28.27 -extern VTPM_GLOBALS *vtpm_globals;
   28.28 +// --------------------------- Global Values --------------------------
   28.29 +extern VTPM_GLOBALS *vtpm_globals;   // Key info and DMI states
   28.30 +extern const TPM_AUTHDATA SRK_AUTH;  // SRK Well Known Auth Value
   28.31  
   28.32  // ********************** Command Handler Prototypes ***********************
   28.33  TPM_RESULT VTPM_Handle_Load_NVM(       VTPM_DMI_RESOURCE *myDMI, 
    29.1 --- a/tools/vtpm_manager/manager/vtsp.c	Tue Jan 03 08:59:00 2006 -0600
    29.2 +++ b/tools/vtpm_manager/manager/vtsp.c	Tue Jan 03 10:19:20 2006 -0600
    29.3 @@ -563,63 +563,69 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEX
    29.4                          const TPM_AUTHDATA          *parentAuth,
    29.5                          TPM_HANDLE                  *newKeyHandle,
    29.6                          TCS_AUTH                    *auth,
    29.7 -                        CRYPTO_INFO                 *cryptoinfo /*= NULL*/) {
    29.8 +                        CRYPTO_INFO                 *cryptoinfo,
    29.9 +                        const BOOL                  skipTPMLoad) { 
   29.10    
   29.11    
   29.12 -  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
   29.13 +  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key %s.\n", (!skipTPMLoad ? "into TPM" : "only into memory"));
   29.14    
   29.15    TPM_RESULT status = TPM_SUCCESS;
   29.16    TPM_COMMAND_CODE command = TPM_ORD_LoadKey;
   29.17 -  
   29.18 -  BYTE *paramText;        // Digest to make Auth.
   29.19 +
   29.20 +  BYTE *paramText=NULL;        // Digest to make Auth.
   29.21    UINT32 paramTextSize;
   29.22 +
   29.23 +  // SkipTPMLoad stops key from being loaded into TPM, but still generates CRYPTO_INFO for it
   29.24 +  if (! skipTPMLoad) { 
   29.25    
   29.26 -  if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
   29.27 -      (newKeyHandle==NULL) || (auth==NULL)) {
   29.28 -    status = TPM_BAD_PARAMETER;
   29.29 -    goto abort_egress;
   29.30 -  }
   29.31 -  
   29.32 -  // Generate Extra TCS Parameters
   29.33 -  TPM_HANDLE phKeyHMAC;
   29.34 +    if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
   29.35 +        (newKeyHandle==NULL) || (auth==NULL)) {
   29.36 +      status = TPM_BAD_PARAMETER;
   29.37 +      goto abort_egress;
   29.38 +    }
   29.39    
   29.40 -  // Generate HMAC
   29.41 -  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
   29.42 +    // Generate Extra TCS Parameters
   29.43 +    TPM_HANDLE phKeyHMAC;
   29.44    
   29.45 -  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
   29.46 +    // Generate HMAC
   29.47 +    Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
   29.48 +  
   29.49 +    paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
   29.50    
   29.51 -  paramTextSize = BSG_PackList(paramText, 1,
   29.52 -			       BSG_TPM_COMMAND_CODE, &command);
   29.53 +    paramTextSize = BSG_PackList(paramText, 1,
   29.54 +  			         BSG_TPM_COMMAND_CODE, &command);
   29.55    
   29.56 -  memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
   29.57 -  paramTextSize += buffer_len(rgbWrappedKeyBlob);
   29.58 +    memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
   29.59 +    paramTextSize += buffer_len(rgbWrappedKeyBlob);
   29.60    
   29.61 -  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
   29.62 +    TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
   29.63  			      parentAuth, auth) );
   29.64    
   29.65 -  // Call TCS
   29.66 -  TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
   29.67 -				     hUnwrappingKey,
   29.68 -				     buffer_len(rgbWrappedKeyBlob),
   29.69 -				     rgbWrappedKeyBlob->bytes,
   29.70 -				     auth,
   29.71 -				     newKeyHandle,
   29.72 -				     &phKeyHMAC) );
   29.73 +    // Call TCS
   29.74 +    TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
   29.75 +				       hUnwrappingKey,
   29.76 +				       buffer_len(rgbWrappedKeyBlob),
   29.77 +				       rgbWrappedKeyBlob->bytes,
   29.78 +				       auth,
   29.79 +				       newKeyHandle,
   29.80 +				       &phKeyHMAC) );
   29.81    
   29.82 -  // Verify Auth
   29.83 -  paramTextSize = BSG_PackList(paramText, 3,
   29.84 -			       BSG_TPM_RESULT, &status,
   29.85 -			       BSG_TPM_COMMAND_CODE, &command,
   29.86 -			       BSG_TPM_HANDLE, newKeyHandle);
   29.87 +    // Verify Auth
   29.88 +    paramTextSize = BSG_PackList(paramText, 3,
   29.89 +			         BSG_TPM_RESULT, &status,
   29.90 +			         BSG_TPM_COMMAND_CODE, &command,
   29.91 +			         BSG_TPM_HANDLE, newKeyHandle);
   29.92    
   29.93 -  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
   29.94 -			    parentAuth, auth, 
   29.95 -			    hContext) );
   29.96 +    TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
   29.97 +			      parentAuth, auth, 
   29.98 +			      hContext) );
   29.99 +  } 
  29.100    
  29.101 -  // Unpack/return key structure
  29.102 +  // Build cryptoinfo structure for software crypto function. 
  29.103    if (cryptoinfo != NULL) {
  29.104      TPM_KEY newKey;
  29.105      
  29.106 +    // Unpack/return key structure
  29.107      BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey);
  29.108      TPM_RSA_KEY_PARMS rsaKeyParms;
  29.109      
    30.1 --- a/tools/vtpm_manager/manager/vtsp.h	Tue Jan 03 08:59:00 2006 -0600
    30.2 +++ b/tools/vtpm_manager/manager/vtsp.h	Tue Jan 03 10:19:20 2006 -0600
    30.3 @@ -86,7 +86,8 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEX
    30.4                          const TPM_AUTHDATA          *parentAuth,
    30.5                          TPM_HANDLE                  *newKeyHandle,
    30.6                          TCS_AUTH                    *pAuth,
    30.7 -                        CRYPTO_INFO                 *cryptoinfo);
    30.8 +                        CRYPTO_INFO                 *cryptoinfo,
    30.9 +                        const BOOL                  skipTPMLoad);
   30.10  
   30.11  TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
   30.12                          const TPM_KEY_HANDLE        key_handle,
    31.1 --- a/tools/xentrace/Makefile	Tue Jan 03 08:59:00 2006 -0600
    31.2 +++ b/tools/xentrace/Makefile	Tue Jan 03 10:19:20 2006 -0600
    31.3 @@ -15,25 +15,37 @@ HDRS     = $(wildcard *.h)
    31.4  OBJS     = $(patsubst %.c,%.o,$(wildcard *.c))
    31.5  
    31.6  BIN      = xentrace tbctl setsize
    31.7 +LIBBIN   = 
    31.8  SCRIPTS  = xentrace_format
    31.9  MAN1     = $(wildcard *.1)
   31.10  MAN8     = $(wildcard *.8)
   31.11  
   31.12 +ifeq ($(XEN_TARGET_ARCH),x86_32)
   31.13 +LIBBIN  += xenctx
   31.14 +endif
   31.15 +
   31.16 +ifeq ($(XEN_TARGET_ARCH),x86_64)
   31.17 +LIBBIN  += xenctx
   31.18 +endif
   31.19 +
   31.20  all: build
   31.21 -build: $(BIN)
   31.22 +build: $(BIN) $(LIBBIN)
   31.23  
   31.24  install: build
   31.25  	[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
   31.26 +	[ -z "$(LIBBIN)"] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
   31.27 +		$(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
   31.28  	[ -d $(DESTDIR)/usr/share/man/man1 ] || \
   31.29  		$(INSTALL_DIR) $(DESTDIR)/usr/share/man/man1
   31.30  	[ -d $(DESTDIR)/usr/share/man/man8 ] || \
   31.31  		$(INSTALL_DIR) $(DESTDIR)/usr/share/man/man8
   31.32  	$(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin
   31.33 +	[ -z "$(LIBBIN)"] || $(INSTALL_PROG) $(LIBBIN) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
   31.34  	$(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/share/man/man1
   31.35  	$(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/share/man/man8
   31.36  
   31.37  clean:
   31.38 -	$(RM) *.a *.so *.o *.rpm $(BIN)
   31.39 +	$(RM) *.a *.so *.o *.rpm $(BIN) $(LIBBIN)
   31.40  
   31.41  %: %.c $(HDRS) Makefile
   31.42  	$(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl
    32.1 --- a/tools/xentrace/xenctx.c	Tue Jan 03 08:59:00 2006 -0600
    32.2 +++ b/tools/xentrace/xenctx.c	Tue Jan 03 10:19:20 2006 -0600
    32.3 @@ -20,15 +20,184 @@
    32.4  #include <errno.h>
    32.5  #include <argp.h>
    32.6  #include <signal.h>
    32.7 +#include <string.h>
    32.8 +#include <getopt.h>
    32.9  
   32.10  #include "xenctrl.h"
   32.11  
   32.12 +int xc_handle = 0;
   32.13 +int domid = 0;
   32.14 +int frame_ptrs = 0;
   32.15 +int stack_trace = 0;
   32.16 +
   32.17 +#if defined (__i386__)
   32.18 +#define FMT_SIZE_T		"%08x"
   32.19 +#define STACK_POINTER(regs)	(regs->esp)
   32.20 +#define FRAME_POINTER(regs)	(regs->ebp)
   32.21 +#define INSTR_POINTER(regs)	(regs->eip)
   32.22 +#define STACK_ROWS		4
   32.23 +#define STACK_COLS		8
   32.24 +#elif defined (__x86_64__)
   32.25 +#define FMT_SIZE_T		"%016lx"
   32.26 +#define STACK_POINTER(regs)	(regs->rsp)
   32.27 +#define FRAME_POINTER(regs)	(regs->rbp)
   32.28 +#define INSTR_POINTER(regs)	(regs->rip)
   32.29 +#define STACK_ROWS		4
   32.30 +#define STACK_COLS		4
   32.31 +#endif
   32.32 +
   32.33 +struct symbol {
   32.34 +    size_t address;
   32.35 +    char type;
   32.36 +    char *name;
   32.37 +    struct symbol *next;
   32.38 +} *symbol_table = NULL;
   32.39 +
   32.40 +size_t kernel_stext, kernel_etext, kernel_sinittext, kernel_einittext;
   32.41 +
   32.42 +int is_kernel_text(size_t addr)
   32.43 +{
   32.44 +#if defined (__i386__)
   32.45 +    if (symbol_table == NULL)
   32.46 +        return (addr > 0xc000000);
   32.47 +#elif defined (__x86_64__)
   32.48 +    if (symbol_table == NULL)
   32.49 +        return (addr > 0xffffffff80000000UL);
   32.50 +#endif
   32.51 +
   32.52 +    if (addr >= kernel_stext &&
   32.53 +        addr <= kernel_etext)
   32.54 +        return 1;
   32.55 +    if (addr >= kernel_sinittext &&
   32.56 +        addr <= kernel_einittext)
   32.57 +        return 1;
   32.58 +    return 0;
   32.59 +}
   32.60 +
   32.61 +void free_symbol(struct symbol *symbol)
   32.62 +{
   32.63 +    if (symbol == NULL)
   32.64 +        return;
   32.65 +    if (symbol->name)
   32.66 +        free(symbol->name);
   32.67 +    free(symbol);
   32.68 +}
   32.69 +
   32.70 +void insert_symbol(struct symbol *symbol)
   32.71 +{
   32.72 +    static struct symbol *prev = NULL;
   32.73 +    struct symbol *s = symbol_table;
   32.74 +
   32.75 +    if (s == NULL) {
   32.76 +        symbol_table = symbol;
   32.77 +        symbol->next = NULL;
   32.78 +        return;
   32.79 +    }
   32.80 +
   32.81 +    /* The System.map is usually already sorted... */
   32.82 +    if (prev
   32.83 +        && prev->address < symbol->address
   32.84 +        && (!prev->next || prev->next->address > symbol->address)) {
   32.85 +        s = prev;
   32.86 +    } else {
   32.87 +        /* ... otherwise do crappy/slow search for the correct place */
   32.88 +        while(s && s->next && s->next->address < symbol->address)
   32.89 +            s = s->next;
   32.90 +    }
   32.91 +
   32.92 +    symbol->next = s->next;
   32.93 +    s->next = symbol;
   32.94 +    prev = symbol;
   32.95 +}
   32.96 +
   32.97 +struct symbol *lookup_symbol(size_t address)
   32.98 +{
   32.99 +    struct symbol *s = symbol_table;
  32.100 +
  32.101 +    while(s && s->next && s->next->address < address)
  32.102 +        s = s->next;
  32.103 +
  32.104 +    if (s && s->address < address)
  32.105 +        return s;
  32.106 +
  32.107 +    return NULL;
  32.108 +}
  32.109 +
  32.110 +void print_symbol(size_t addr)
  32.111 +{
  32.112 +    struct symbol *s;
  32.113 +
  32.114 +    if (!is_kernel_text(addr))
  32.115 +        return;
  32.116 +
  32.117 +    s = lookup_symbol(addr);
  32.118 +
  32.119 +    if (s==NULL)
  32.120 +        return;
  32.121 +
  32.122 +    if (addr==s->address)
  32.123 +        printf("%s", s->name);
  32.124 +    else
  32.125 +        printf("%s+%#x", s->name, (unsigned int)(addr - s->address));
  32.126 +}
  32.127 +
  32.128 +void read_symbol_table(const char *symtab)
  32.129 +{
  32.130 +    char line[256];
  32.131 +    char *p;
  32.132 +    struct symbol *symbol;
  32.133 +    FILE *f;
  32.134 +
  32.135 +    f = fopen(symtab, "r");
  32.136 +    if(f == NULL) {
  32.137 +        fprintf(stderr, "failed to open symbol table %s\n", symtab);
  32.138 +        exit(-1);
  32.139 +    }
  32.140 +
  32.141 +    while(!feof(f)) {
  32.142 +        if(fgets(line,256,f)==NULL)
  32.143 +            break;
  32.144 +
  32.145 +        symbol = malloc(sizeof(*symbol));
  32.146 +
  32.147 +        /* need more checks for syntax here... */
  32.148 +        symbol->address = strtoull(line, &p, 16);
  32.149 +        p++;
  32.150 +        symbol->type = *p++;
  32.151 +        p++;
  32.152 +
  32.153 +        /* in the future we should handle the module name
  32.154 +         * being appended here, this would allow us to use
  32.155 +         * /proc/kallsyms as our symbol table
  32.156 +         */
  32.157 +        if (p[strlen(p)-1] == '\n')
  32.158 +            p[strlen(p)-1] = '\0';
  32.159 +        symbol->name = strdup(p);
  32.160 +
  32.161 +        insert_symbol(symbol);
  32.162 +
  32.163 +        if (strcmp(symbol->name, "_stext") == 0)
  32.164 +            kernel_stext = symbol->address;
  32.165 +        else if (strcmp(symbol->name, "_etext") == 0)
  32.166 +            kernel_etext = symbol->address;
  32.167 +        else if (strcmp(symbol->name, "_sinittext") == 0)
  32.168 +            kernel_sinittext = symbol->address;
  32.169 +        else if (strcmp(symbol->name, "_einittext") == 0)
  32.170 +            kernel_einittext = symbol->address;
  32.171 +    }
  32.172 +
  32.173 +    fclose(f);
  32.174 +}
  32.175 +
  32.176  #ifdef __i386__
  32.177  void print_ctx(vcpu_guest_context_t *ctx1)
  32.178  {
  32.179      struct cpu_user_regs *regs = &ctx1->user_regs;
  32.180  
  32.181 -    printf("eip: %08x\t", regs->eip);
  32.182 +    printf("eip: %08x ", regs->eip);
  32.183 +    print_symbol(regs->eip);
  32.184 +    printf("\n");
  32.185 +
  32.186      printf("esp: %08x\n", regs->esp);
  32.187  
  32.188      printf("eax: %08x\t", regs->eax);
  32.189 @@ -51,7 +220,9 @@ void print_ctx(vcpu_guest_context_t *ctx
  32.190  {
  32.191      struct cpu_user_regs *regs = &ctx1->user_regs;
  32.192  
  32.193 -    printf("rip: %08lx\t", regs->rip);
  32.194 +    printf("rip: %08lx ", regs->rip);
  32.195 +    print_symbol(regs->rip);
  32.196 +    printf("\n");
  32.197      printf("rsp: %08lx\n", regs->rsp);
  32.198  
  32.199      printf("rax: %08lx\t", regs->rax);
  32.200 @@ -63,8 +234,8 @@ void print_ctx(vcpu_guest_context_t *ctx
  32.201      printf("rdi: %08lx\t", regs->rdi);
  32.202      printf("rbp: %08lx\n", regs->rbp);
  32.203  
  32.204 -    printf("r8: %08lx\t", regs->r8);
  32.205 -    printf("r9: %08lx\t", regs->r9);
  32.206 +    printf(" r8: %08lx\t", regs->r8);
  32.207 +    printf(" r9: %08lx\t", regs->r9);
  32.208      printf("r10: %08lx\t", regs->r10);
  32.209      printf("r11: %08lx\n", regs->r11);
  32.210  
  32.211 @@ -81,35 +252,238 @@ void print_ctx(vcpu_guest_context_t *ctx
  32.212  }
  32.213  #endif
  32.214  
  32.215 -void dump_ctx(uint32_t domid, uint32_t vcpu)
  32.216 +void *map_page(vcpu_guest_context_t *ctx, int vcpu, size_t virt)
  32.217 +{
  32.218 +    static unsigned long previous_mfn = 0;
  32.219 +    static void *mapped = NULL;
  32.220 +
  32.221 +    unsigned long mfn = xc_translate_foreign_address(xc_handle, domid, vcpu, virt);
  32.222 +    unsigned long offset = virt & ~XC_PAGE_MASK;
  32.223 +
  32.224 +    if (mapped && mfn == previous_mfn)
  32.225 +        goto out;
  32.226 +
  32.227 +    if (mapped)
  32.228 +        munmap(mapped, XC_PAGE_SIZE);
  32.229 +
  32.230 +    previous_mfn = mfn;
  32.231 +
  32.232 +    mapped = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE, PROT_READ, mfn);
  32.233 +
  32.234 +    if (mapped == NULL) {
  32.235 +        fprintf(stderr, "failed to map page.\n");
  32.236 +        exit(-1);
  32.237 +    }
  32.238 +
  32.239 + out:
  32.240 +    return (void *)(mapped + offset);
  32.241 +}
  32.242 +
  32.243 +void print_stack(vcpu_guest_context_t *ctx, int vcpu)
  32.244 +{
  32.245 +    struct cpu_user_regs *regs = &ctx->user_regs;
  32.246 +    size_t stack = STACK_POINTER(regs);
  32.247 +    size_t stack_limit = (STACK_POINTER(regs) & XC_PAGE_MASK) + XC_PAGE_SIZE;
  32.248 +    size_t frame;
  32.249 +    size_t instr;
  32.250 +    size_t *p;
  32.251 +    int i;
  32.252 +
  32.253 +    printf("\n");
  32.254 +    printf("Stack:\n");
  32.255 +    for (i=1; i<STACK_ROWS+1 && stack < stack_limit; i++) {
  32.256 +        while(stack < stack_limit && stack < STACK_POINTER(regs) + i*STACK_COLS*sizeof(stack)) {
  32.257 +            p = map_page(ctx, vcpu, stack);
  32.258 +            printf(" " FMT_SIZE_T, *p);
  32.259 +            stack += sizeof(stack);
  32.260 +        }
  32.261 +        printf("\n");
  32.262 +    }
  32.263 +    printf("\n");
  32.264 +
  32.265 +    printf("Code:\n");
  32.266 +    instr = INSTR_POINTER(regs) - 21;
  32.267 +    for(i=0; i<32; i++) {
  32.268 +        unsigned char *c = map_page(ctx, vcpu, instr+i);
  32.269 +        if (instr+i == INSTR_POINTER(regs))
  32.270 +            printf("<%02x> ", *c);
  32.271 +        else
  32.272 +            printf("%02x ", *c);
  32.273 +    }
  32.274 +    printf("\n");
  32.275 +
  32.276 +    printf("\n");
  32.277 +
  32.278 +    if(stack_trace)
  32.279 +        printf("Stack Trace:\n");
  32.280 +    else
  32.281 +        printf("Call Trace:\n");
  32.282 +    printf("%c [<" FMT_SIZE_T ">] ", stack_trace ? '*' : ' ', INSTR_POINTER(regs));
  32.283 +
  32.284 +    print_symbol(INSTR_POINTER(regs));
  32.285 +    printf(" <--\n");
  32.286 +    if (frame_ptrs) {
  32.287 +        stack = STACK_POINTER(regs);
  32.288 +        frame = FRAME_POINTER(regs);
  32.289 +        while(frame && stack < stack_limit) {
  32.290 +            if (stack_trace) {
  32.291 +                while (stack < frame) {
  32.292 +                    p = map_page(ctx, vcpu, stack);
  32.293 +                    printf("|   " FMT_SIZE_T "   ", *p);
  32.294 +                    printf("\n");
  32.295 +                    stack += sizeof(*p);
  32.296 +                }
  32.297 +            } else {
  32.298 +                stack = frame;
  32.299 +            }
  32.300 +
  32.301 +            p = map_page(ctx, vcpu, stack);
  32.302 +            frame = *p;
  32.303 +            if (stack_trace)
  32.304 +                printf("|-- " FMT_SIZE_T "\n", *p);
  32.305 +            stack += sizeof(*p);
  32.306 +
  32.307 +            if (frame) {
  32.308 +                p = map_page(ctx, vcpu, stack);
  32.309 +                printf("%c [<" FMT_SIZE_T ">] ", stack_trace ? '|' : ' ', *p);
  32.310 +                print_symbol(*p);
  32.311 +                printf("\n");
  32.312 +                stack += sizeof(*p);
  32.313 +            }
  32.314 +        }
  32.315 +    } else {
  32.316 +        stack = STACK_POINTER(regs);
  32.317 +        while(stack < stack_limit) {
  32.318 +            p = map_page(ctx, vcpu, stack);
  32.319 +            if (is_kernel_text(*p)) {
  32.320 +                printf("  [<" FMT_SIZE_T ">] ", *p);
  32.321 +                print_symbol(*p);
  32.322 +                printf("\n");
  32.323 +            } else if (stack_trace) {
  32.324 +                printf("    " FMT_SIZE_T "\n", *p);
  32.325 +            }
  32.326 +            stack += sizeof(*p);
  32.327 +        }
  32.328 +    }
  32.329 +}
  32.330 +
  32.331 +void dump_ctx(int vcpu)
  32.332  {
  32.333      int ret;
  32.334      vcpu_guest_context_t ctx;
  32.335  
  32.336 -    int xc_handle = xc_interface_open(); /* for accessing control interface */
  32.337 +    xc_handle = xc_interface_open(); /* for accessing control interface */
  32.338 +
  32.339 +    ret = xc_domain_pause(xc_handle, domid);
  32.340 +    if (ret < 0) {
  32.341 +        perror("xc_domain_pause");
  32.342 +        exit(-1);
  32.343 +    }
  32.344  
  32.345      ret = xc_domain_get_vcpu_context(xc_handle, domid, vcpu, &ctx);
  32.346 -    if (ret != 0) {
  32.347 +    if (ret < 0) {
  32.348 +        xc_domain_unpause(xc_handle, domid);
  32.349          perror("xc_domain_get_vcpu_context");
  32.350          exit(-1);
  32.351      }
  32.352 +
  32.353      print_ctx(&ctx);
  32.354 +    if (is_kernel_text(ctx.user_regs.eip))
  32.355 +        print_stack(&ctx, vcpu);
  32.356 +
  32.357 +    ret = xc_domain_unpause(xc_handle, domid);
  32.358 +    if (ret < 0) {
  32.359 +        perror("xc_domain_unpause");
  32.360 +        exit(-1);
  32.361 +    }
  32.362 +
  32.363      xc_interface_close(xc_handle);
  32.364 +    if (ret < 0) {
  32.365 +        perror("xc_interface_close");
  32.366 +        exit(-1);
  32.367 +    }
  32.368 +}
  32.369 +
  32.370 +void usage(void)
  32.371 +{
  32.372 +    printf("usage:\n\n");
  32.373 +
  32.374 +    printf("  xenctx [options] <DOMAIN> [VCPU]\n\n");
  32.375 +
  32.376 +    printf("options:\n");
  32.377 +    printf("  -f, --frame-pointers\n");
  32.378 +    printf("                    assume the kernel was compiled with\n");
  32.379 +    printf("                    frame pointers.\n");
  32.380 +    printf("  -s SYMTAB, --symbol-table=SYMTAB\n");
  32.381 +    printf("                    read symbol table from SYMTAB.\n");
  32.382 +    printf("  --stack-trace     print a complete stack trace.\n");
  32.383  }
  32.384  
  32.385  int main(int argc, char **argv)
  32.386  {
  32.387 +    int ch;
  32.388 +    const char *sopts = "fs:h";
  32.389 +    const struct option lopts[] = {
  32.390 +        {"stack-trace", 0, NULL, 'S'},
  32.391 +        {"symbol-table", 1, NULL, 's'},
  32.392 +        {"frame-pointers", 0, NULL, 'f'},
  32.393 +        {"help", 0, NULL, 'h'},
  32.394 +        {0, 0, 0, 0}
  32.395 +    };
  32.396 +    const char *symbol_table = NULL;
  32.397 +
  32.398      int vcpu = 0;
  32.399  
  32.400 -    if (argc < 2) {
  32.401 -        printf("usage: xenctx <domid> <optional vcpu>\n");
  32.402 +    while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
  32.403 +        switch(ch) {
  32.404 +        case 'f':
  32.405 +            frame_ptrs = 1;
  32.406 +            break;
  32.407 +        case 's':
  32.408 +            symbol_table = optarg;
  32.409 +            break;
  32.410 +        case 'S':
  32.411 +            stack_trace = 1;
  32.412 +            break;
  32.413 +        case 'h':
  32.414 +            usage();
  32.415 +            exit(-1);
  32.416 +        case '?':
  32.417 +            fprintf(stderr, "%s --help for more options\n", argv[0]);
  32.418 +            exit(-1);
  32.419 +        }
  32.420 +    }
  32.421 +
  32.422 +    argv += optind; argc -= optind;
  32.423 +
  32.424 +    if (argc < 1 || argc > 2) {
  32.425 +        printf("usage: xenctx [options] <domid> <optional vcpu>\n");
  32.426          exit(-1);
  32.427      }
  32.428  
  32.429 -    if (argc == 3)
  32.430 -        vcpu = atoi(argv[2]);
  32.431 +    domid = atoi(argv[0]);
  32.432 +    if (domid==0) {
  32.433 +            fprintf(stderr, "cannot trace dom0\n");
  32.434 +            exit(-1);
  32.435 +    }
  32.436  
  32.437 -    dump_ctx(atoi(argv[1]), vcpu);
  32.438 +    if (argc == 2)
  32.439 +        vcpu = atoi(argv[1]);
  32.440 +
  32.441 +    if (symbol_table)
  32.442 +        read_symbol_table(symbol_table);
  32.443 +
  32.444 +    dump_ctx(vcpu);
  32.445  
  32.446      return 0;
  32.447  }
  32.448 +
  32.449 +/*
  32.450 + * Local variables:
  32.451 + * mode: C
  32.452 + * c-set-style: "BSD"
  32.453 + * c-basic-offset: 4
  32.454 + * tab-width: 4
  32.455 + * indent-tabs-mode: nil
  32.456 + * End:
  32.457 + */
    33.1 --- a/xen/arch/ia64/xen/domain.c	Tue Jan 03 08:59:00 2006 -0600
    33.2 +++ b/xen/arch/ia64/xen/domain.c	Tue Jan 03 10:19:20 2006 -0600
    33.3 @@ -181,7 +181,7 @@ static void init_switch_stack(struct vcp
    33.4  	memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
    33.5  }
    33.6  
    33.7 -void arch_do_createdomain(struct vcpu *v)
    33.8 +int arch_do_createdomain(struct vcpu *v)
    33.9  {
   33.10  	struct domain *d = v->domain;
   33.11  	struct thread_info *ti = alloc_thread_info(v);
   33.12 @@ -248,7 +248,9 @@ void arch_do_createdomain(struct vcpu *v
   33.13  		}
   33.14  	} else
   33.15   		d->arch.mm = NULL;
   33.16 - 	printf ("arch_do_create_domain: domain=%p\n", d);
   33.17 +	printf ("arch_do_create_domain: domain=%p\n", d);
   33.18 +
   33.19 +	return 0;
   33.20  }
   33.21  
   33.22  void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
   33.23 @@ -754,7 +756,10 @@ void alloc_dom0(void)
   33.24   */
   33.25  void physdev_init_dom0(struct domain *d)
   33.26  {
   33.27 -	set_bit(_DOMF_physdev_access, &d->domain_flags);
   33.28 +	if (iomem_permit_access(d, 0UL, ~0UL))
   33.29 +		BUG();
   33.30 +	if (irqs_permit_access(d, 0, NR_PIRQS-1))
   33.31 +		BUG();
   33.32  }
   33.33  
   33.34  unsigned int vmx_dom0 = 0;
    34.1 --- a/xen/arch/ia64/xen/irq.c	Tue Jan 03 08:59:00 2006 -0600
    34.2 +++ b/xen/arch/ia64/xen/irq.c	Tue Jan 03 10:19:20 2006 -0600
    34.3 @@ -1378,9 +1378,6 @@ int pirq_guest_bind(struct vcpu *d, int 
    34.4      unsigned long       flags;
    34.5      int                 rc = 0;
    34.6  
    34.7 -    if ( !IS_CAPABLE_PHYSDEV(d->domain) )
    34.8 -        return -EPERM;
    34.9 -
   34.10      spin_lock_irqsave(&desc->lock, flags);
   34.11  
   34.12      action = (irq_guest_action_t *)desc->action;
    35.1 --- a/xen/arch/x86/Makefile	Tue Jan 03 08:59:00 2006 -0600
    35.2 +++ b/xen/arch/x86/Makefile	Tue Jan 03 10:19:20 2006 -0600
    35.3 @@ -29,6 +29,7 @@ ifeq ($(TARGET_SUBARCH),x86_32)
    35.4  endif
    35.5  
    35.6  OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS))
    35.7 +OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS))
    35.8  
    35.9  ifneq ($(crash_debug),y)
   35.10  OBJS := $(patsubst cdb%.o,,$(OBJS))
   35.11 @@ -43,22 +44,25 @@ default: $(TARGET)
   35.12  $(CURDIR)/arch.o: $(OBJS)
   35.13  	$(LD) $(LDFLAGS) -r -o $@ $(OBJS)
   35.14  
   35.15 -$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(TARGET_SUBARCH)/xen.lds
   35.16 -	$(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
   35.17 +$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) xen.lds
   35.18 +	$(LD) $(LDFLAGS) -T xen.lds -N \
   35.19  	    boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $@
   35.20  	$(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
   35.21  	$(MAKE) $(BASEDIR)/xen-syms.o
   35.22 -	$(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
   35.23 +	$(LD) $(LDFLAGS) -T xen.lds -N \
   35.24  	    boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
   35.25  	$(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
   35.26  	$(MAKE) $(BASEDIR)/xen-syms.o
   35.27 -	$(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
   35.28 +	$(LD) $(LDFLAGS) -T xen.lds -N \
   35.29  	    boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
   35.30  	rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o
   35.31  
   35.32  asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS)
   35.33  	$(CC) $(CFLAGS) -S -o $@ $<
   35.34  
   35.35 +xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(HDRS)
   35.36 +	$(CC) $(CFLAGS) -P -E -Ui386 -D__ASSEMBLY__ -o $@ $<
   35.37 +
   35.38  boot/mkelf32: boot/mkelf32.c
   35.39  	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
   35.40  
   35.41 @@ -73,5 +77,6 @@ clean:
   35.42  	rm -f dm/*.o dm/*~ dm/core
   35.43  	rm -f genapic/*.o genapic/*~ genapic/core
   35.44  	rm -f cpu/*.o cpu/*~ cpu/core
   35.45 +	rm -f xen.lds
   35.46  
   35.47  .PHONY: default clean
    36.1 --- a/xen/arch/x86/boot/x86_32.S	Tue Jan 03 08:59:00 2006 -0600
    36.2 +++ b/xen/arch/x86/boot/x86_32.S	Tue Jan 03 10:19:20 2006 -0600
    36.3 @@ -1,5 +1,6 @@
    36.4  #include <xen/config.h>
    36.5  #include <public/xen.h>
    36.6 +#include <asm/asm_defns.h>
    36.7  #include <asm/desc.h>
    36.8  #include <asm/page.h>
    36.9  #include <asm/msr.h>
   36.10 @@ -53,6 +54,7 @@ 3:      in      %dx,%al
   36.11          mov     %ecx,%gs
   36.12          ljmp    $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
   36.13  1:      lss     stack_start-__PAGE_OFFSET,%esp
   36.14 +        add     $(STACK_SIZE-CPUINFO_sizeof-__PAGE_OFFSET),%esp
   36.15  
   36.16          /* Reset EFLAGS (subsumes CLI and CLD). */
   36.17  	pushl	$0
   36.18 @@ -189,7 +191,7 @@ 1:      jmp     1b
   36.19  /*** STACK LOCATION ***/
   36.20          
   36.21  ENTRY(stack_start)
   36.22 -        .long cpu0_stack + STACK_SIZE - 200 - __PAGE_OFFSET
   36.23 +        .long cpu0_stack
   36.24          .long __HYPERVISOR_DS
   36.25          
   36.26  /*** DESCRIPTOR TABLES ***/
   36.27 @@ -256,10 +258,6 @@ ENTRY(idle_pg_table_l2)
   36.28          .fill 1*PAGE_SIZE,1,0
   36.29  #endif
   36.30  
   36.31 -#if (STACK_ORDER == 0)
   36.32 -.section ".bss.page_aligned","w"
   36.33 -#else
   36.34 -.section ".bss.twopage_aligned","w"
   36.35 -#endif
   36.36 +.section ".bss.stack_aligned","w"
   36.37  ENTRY(cpu0_stack)
   36.38          .fill STACK_SIZE,1,0
    37.1 --- a/xen/arch/x86/boot/x86_64.S	Tue Jan 03 08:59:00 2006 -0600
    37.2 +++ b/xen/arch/x86/boot/x86_64.S	Tue Jan 03 10:19:20 2006 -0600
    37.3 @@ -1,5 +1,6 @@
    37.4  #include <xen/config.h>
    37.5  #include <public/xen.h>
    37.6 +#include <asm/asm_defns.h>
    37.7  #include <asm/desc.h>
    37.8  #include <asm/page.h>
    37.9  #include <asm/msr.h>
   37.10 @@ -121,7 +122,8 @@ 1:      /* Now in compatibility mode. Lo
   37.11          mov     %rcx,%cr4
   37.12  
   37.13          mov     stack_start(%rip),%rsp
   37.14 -        
   37.15 +        or      $(STACK_SIZE-CPUINFO_sizeof),%rsp
   37.16 +
   37.17          /* Reset EFLAGS (subsumes CLI and CLD). */
   37.18          pushq   $0
   37.19          popf
   37.20 @@ -140,7 +142,7 @@ 1:      /* Now in compatibility mode. Lo
   37.21          mov     %ecx,%ss
   37.22  
   37.23          lidt    idt_descr(%rip)
   37.24 -                
   37.25 +
   37.26          cmp     $(SECONDARY_CPU_FLAG),%ebx
   37.27          je      start_secondary
   37.28  
   37.29 @@ -219,7 +221,7 @@ idt:
   37.30          .quad   idt_table
   37.31  
   37.32  ENTRY(stack_start)
   37.33 -        .quad   cpu0_stack + STACK_SIZE - 200
   37.34 +        .quad   cpu0_stack
   37.35  
   37.36  high_start:
   37.37          .quad   __high_start
   37.38 @@ -265,10 +267,6 @@ ENTRY(idle_pg_table_l2)
   37.39          .org 0x4000 + PAGE_SIZE
   37.40          .code64
   37.41  
   37.42 -#if (STACK_ORDER == 0)
   37.43 -.section ".bss.page_aligned","w"
   37.44 -#else
   37.45 -.section ".bss.twopage_aligned","w"
   37.46 -#endif
   37.47 +.section ".bss.stack_aligned","w"
   37.48  ENTRY(cpu0_stack)
   37.49          .fill STACK_SIZE,1,0
    38.1 --- a/xen/arch/x86/dom0_ops.c	Tue Jan 03 08:59:00 2006 -0600
    38.2 +++ b/xen/arch/x86/dom0_ops.c	Tue Jan 03 10:19:20 2006 -0600
    38.3 @@ -17,6 +17,7 @@
    38.4  #include <asm/msr.h>
    38.5  #include <xen/trace.h>
    38.6  #include <xen/console.h>
    38.7 +#include <xen/iocap.h>
    38.8  #include <asm/shadow.h>
    38.9  #include <asm/irq.h>
   38.10  #include <asm/processor.h>
   38.11 @@ -141,7 +142,6 @@ long arch_do_dom0_op(dom0_op_t *op, dom0
   38.12          struct domain *d;
   38.13          unsigned int fp = op->u.ioport_permission.first_port;
   38.14          unsigned int np = op->u.ioport_permission.nr_ports;
   38.15 -        unsigned int p;
   38.16  
   38.17          ret = -EINVAL;
   38.18          if ( (fp + np) > 65536 )
   38.19 @@ -152,26 +152,12 @@ long arch_do_dom0_op(dom0_op_t *op, dom0
   38.20              op->u.ioport_permission.domain)) == NULL) )
   38.21              break;
   38.22  
   38.23 -        ret = -ENOMEM;
   38.24 -        if ( d->arch.iobmp_mask != NULL )
   38.25 -        {
   38.26 -            if ( (d->arch.iobmp_mask = xmalloc_array(
   38.27 -                u8, IOBMP_BYTES)) == NULL )
   38.28 -            {
   38.29 -                put_domain(d);
   38.30 -                break;
   38.31 -            }
   38.32 -            memset(d->arch.iobmp_mask, 0xFF, IOBMP_BYTES);
   38.33 -        }
   38.34 -
   38.35 -        ret = 0;
   38.36 -        for ( p = fp; p < (fp + np); p++ )
   38.37 -        {
   38.38 -            if ( op->u.ioport_permission.allow_access )
   38.39 -                clear_bit(p, d->arch.iobmp_mask);
   38.40 -            else
   38.41 -                set_bit(p, d->arch.iobmp_mask);
   38.42 -        }
   38.43 +        if ( np == 0 )
   38.44 +            ret = 0;
   38.45 +        else if ( op->u.ioport_permission.allow_access )
   38.46 +            ret = ioports_permit_access(d, fp, fp + np - 1);
   38.47 +        else
   38.48 +            ret = ioports_deny_access(d, fp, fp + np - 1);
   38.49  
   38.50          put_domain(d);
   38.51      }
    39.1 --- a/xen/arch/x86/domain.c	Tue Jan 03 08:59:00 2006 -0600
    39.2 +++ b/xen/arch/x86/domain.c	Tue Jan 03 10:19:20 2006 -0600
    39.3 @@ -20,6 +20,7 @@
    39.4  #include <xen/delay.h>
    39.5  #include <xen/softirq.h>
    39.6  #include <xen/grant_table.h>
    39.7 +#include <xen/iocap.h>
    39.8  #include <asm/regs.h>
    39.9  #include <asm/mc146818rtc.h>
   39.10  #include <asm/system.h>
   39.11 @@ -35,9 +36,7 @@
   39.12  #include <xen/console.h>
   39.13  #include <xen/elf.h>
   39.14  #include <asm/vmx.h>
   39.15 -#include <asm/vmx_vmcs.h>
   39.16  #include <asm/msr.h>
   39.17 -#include <asm/physdev.h>
   39.18  #include <xen/kernel.h>
   39.19  #include <xen/multicall.h>
   39.20  
   39.21 @@ -98,7 +97,7 @@ void startup_cpu_idle_loop(void)
   39.22      cpu_set(smp_processor_id(), v->domain->cpumask);
   39.23      v->arch.schedule_tail = continue_idle_task;
   39.24  
   39.25 -    idle_loop();
   39.26 +    reset_stack_and_jump(idle_loop);
   39.27  }
   39.28  
   39.29  static long no_idt[2];
   39.30 @@ -185,11 +184,17 @@ void dump_pageframe_info(struct domain *
   39.31  {
   39.32      struct pfn_info *page;
   39.33  
   39.34 -    if ( d->tot_pages < 10 )
   39.35 +    printk("Memory pages belonging to domain %u:\n", d->domain_id);
   39.36 +
   39.37 +    if ( d->tot_pages >= 10 )
   39.38 +    {
   39.39 +        printk("    DomPage list too long to display\n");
   39.40 +    }
   39.41 +    else
   39.42      {
   39.43          list_for_each_entry ( page, &d->page_list, list )
   39.44          {
   39.45 -            printk("Page %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
   39.46 +            printk("    DomPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
   39.47                     _p(page_to_phys(page)), _p(page_to_pfn(page)),
   39.48                     page->count_info, page->u.inuse.type_info);
   39.49          }
   39.50 @@ -197,15 +202,10 @@ void dump_pageframe_info(struct domain *
   39.51  
   39.52      list_for_each_entry ( page, &d->xenpage_list, list )
   39.53      {
   39.54 -        printk("XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
   39.55 +        printk("    XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
   39.56                 _p(page_to_phys(page)), _p(page_to_pfn(page)),
   39.57                 page->count_info, page->u.inuse.type_info);
   39.58      }
   39.59 -
   39.60 -    page = virt_to_page(d->shared_info);
   39.61 -    printk("Shared_info@%p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
   39.62 -           _p(page_to_phys(page)), _p(page_to_pfn(page)), page->count_info,
   39.63 -           page->u.inuse.type_info);
   39.64  }
   39.65  
   39.66  struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
   39.67 @@ -250,21 +250,34 @@ void free_perdomain_pt(struct domain *d)
   39.68  #endif
   39.69  }
   39.70  
   39.71 -void arch_do_createdomain(struct vcpu *v)
   39.72 +int arch_do_createdomain(struct vcpu *v)
   39.73  {
   39.74      struct domain *d = v->domain;
   39.75      l1_pgentry_t gdt_l1e;
   39.76 -    int vcpuid, pdpt_order;
   39.77 +    int vcpuid, pdpt_order, rc;
   39.78  #ifdef __x86_64__
   39.79      int i;
   39.80  #endif
   39.81  
   39.82      if ( is_idle_task(d) )
   39.83 -        return;
   39.84 +        return 0;
   39.85 +
   39.86 +    d->arch.ioport_caps = 
   39.87 +        rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex);
   39.88 +    if ( d->arch.ioport_caps == NULL )
   39.89 +        return -ENOMEM;
   39.90 +
   39.91 +    if ( (d->shared_info = alloc_xenheap_page()) == NULL )
   39.92 +        return -ENOMEM;
   39.93 +
   39.94 +    if ( (rc = ptwr_init(d)) != 0 )
   39.95 +    {
   39.96 +        free_xenheap_page(d->shared_info);
   39.97 +        return rc;
   39.98 +    }
   39.99  
  39.100      v->arch.schedule_tail = continue_nonidle_task;
  39.101  
  39.102 -    d->shared_info = alloc_xenheap_page();
  39.103      memset(d->shared_info, 0, PAGE_SIZE);
  39.104      v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
  39.105      v->cpumap = CPUMAP_RUNANYWHERE;
  39.106 @@ -308,10 +321,10 @@ void arch_do_createdomain(struct vcpu *v
  39.107                              __PAGE_HYPERVISOR);
  39.108  #endif
  39.109  
  39.110 -    (void)ptwr_init(d);
  39.111 -
  39.112      shadow_lock_init(d);
  39.113      INIT_LIST_HEAD(&d->arch.free_shadow_frames);
  39.114 +
  39.115 +    return 0;
  39.116  }
  39.117  
  39.118  void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
  39.119 @@ -348,6 +361,8 @@ int arch_set_info_guest(
  39.120               ((c->user_regs.ss & 3) == 0) )
  39.121              return -EINVAL;
  39.122      }
  39.123 +    else if ( !hvm_enabled )
  39.124 +        return -EINVAL;
  39.125  
  39.126      clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
  39.127      if ( c->flags & VGCF_I387_VALID )
  39.128 @@ -953,8 +968,6 @@ void domain_relinquish_resources(struct 
  39.129  
  39.130      BUG_ON(!cpus_empty(d->cpumask));
  39.131  
  39.132 -    physdev_destroy_state(d);
  39.133 -
  39.134      ptwr_destroy(d);
  39.135  
  39.136      /* Drop the in-use references to page-table bases. */
    40.1 --- a/xen/arch/x86/domain_build.c	Tue Jan 03 08:59:00 2006 -0600
    40.2 +++ b/xen/arch/x86/domain_build.c	Tue Jan 03 10:19:20 2006 -0600
    40.3 @@ -16,13 +16,13 @@
    40.4  #include <xen/kernel.h>
    40.5  #include <xen/domain.h>
    40.6  #include <xen/compile.h>
    40.7 +#include <xen/iocap.h>
    40.8  #include <asm/regs.h>
    40.9  #include <asm/system.h>
   40.10  #include <asm/io.h>
   40.11  #include <asm/processor.h>
   40.12  #include <asm/desc.h>
   40.13  #include <asm/i387.h>
   40.14 -#include <asm/physdev.h>
   40.15  #include <asm/shadow.h>
   40.16  
   40.17  static long dom0_nrpages;
   40.18 @@ -94,9 +94,9 @@ static struct pfn_info *alloc_chunk(stru
   40.19      return page;
   40.20  }
   40.21  
   40.22 -static void process_dom0_ioports_disable()
   40.23 +static void process_dom0_ioports_disable(void)
   40.24  {
   40.25 -    unsigned long io_from, io_to, io_nr;
   40.26 +    unsigned long io_from, io_to;
   40.27      char *t, *u, *s = opt_dom0_ioports_disable;
   40.28  
   40.29      if ( *s == '\0' )
   40.30 @@ -126,8 +126,8 @@ static void process_dom0_ioports_disable
   40.31          printk("Disabling dom0 access to ioport range %04lx-%04lx\n",
   40.32              io_from, io_to);
   40.33  
   40.34 -        io_nr = io_to - io_from + 1;
   40.35 -        physdev_modify_ioport_access_range(dom0, 0, io_from, io_nr);
   40.36 +        if ( ioports_deny_access(dom0, io_from, io_to) != 0 )
   40.37 +            BUG();
   40.38      }
   40.39  }
   40.40  
   40.41 @@ -183,7 +183,6 @@ int construct_dom0(struct domain *d,
   40.42      /* Machine address of next candidate page-table page. */
   40.43      unsigned long mpt_alloc;
   40.44  
   40.45 -    extern void physdev_init_dom0(struct domain *);
   40.46      extern void translate_l2pgtable(
   40.47          struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn);
   40.48  
   40.49 @@ -692,9 +691,6 @@ int construct_dom0(struct domain *d,
   40.50      zap_low_mappings(l2start);
   40.51      zap_low_mappings(idle_pg_table_l2);
   40.52  #endif
   40.53 -    
   40.54 -    /* DOM0 gets access to everything. */
   40.55 -    physdev_init_dom0(d);
   40.56  
   40.57      init_domain_time(d);
   40.58  
   40.59 @@ -746,20 +742,29 @@ int construct_dom0(struct domain *d,
   40.60          printk("dom0: shadow setup done\n");
   40.61      }
   40.62  
   40.63 +    i = 0;
   40.64 +
   40.65 +    /* DOM0 is permitted full I/O capabilities. */
   40.66 +    i |= ioports_permit_access(dom0, 0, 0xFFFF);
   40.67 +    i |= iomem_permit_access(dom0, 0UL, ~0UL);
   40.68 +    i |= irqs_permit_access(dom0, 0, NR_PIRQS-1);
   40.69 +
   40.70      /*
   40.71       * Modify I/O port access permissions.
   40.72       */
   40.73      /* Master Interrupt Controller (PIC). */
   40.74 -    physdev_modify_ioport_access_range(dom0, 0, 0x20, 2);
   40.75 +    i |= ioports_deny_access(dom0, 0x20, 0x21);
   40.76      /* Slave Interrupt Controller (PIC). */
   40.77 -    physdev_modify_ioport_access_range(dom0, 0, 0xA0, 2);
   40.78 +    i |= ioports_deny_access(dom0, 0xA0, 0xA1);
   40.79      /* Interval Timer (PIT). */
   40.80 -    physdev_modify_ioport_access_range(dom0, 0, 0x40, 4);
   40.81 +    i |= ioports_deny_access(dom0, 0x40, 0x43);
   40.82      /* PIT Channel 2 / PC Speaker Control. */
   40.83 -    physdev_modify_ioport_access_range(dom0, 0, 0x61, 1);
   40.84 -    /* Command-line passed i/o ranges */
   40.85 +    i |= ioports_deny_access(dom0, 0x61, 0x61);
   40.86 +    /* Command-line I/O ranges. */
   40.87      process_dom0_ioports_disable();
   40.88  
   40.89 +    BUG_ON(i != 0);
   40.90 +
   40.91      return 0;
   40.92  }
   40.93  
    41.1 --- a/xen/arch/x86/irq.c	Tue Jan 03 08:59:00 2006 -0600
    41.2 +++ b/xen/arch/x86/irq.c	Tue Jan 03 10:19:20 2006 -0600
    41.3 @@ -199,16 +199,12 @@ int pirq_guest_unmask(struct domain *d)
    41.4  int pirq_guest_bind(struct vcpu *v, int irq, int will_share)
    41.5  {
    41.6      unsigned int        vector = irq_to_vector(irq);
    41.7 -    struct domain      *d = v->domain;
    41.8      irq_desc_t         *desc = &irq_desc[vector];
    41.9      irq_guest_action_t *action;
   41.10      unsigned long       flags;
   41.11      int                 rc = 0;
   41.12      cpumask_t           cpumask = CPU_MASK_NONE;
   41.13  
   41.14 -    if ( !IS_CAPABLE_PHYSDEV(d) )
   41.15 -        return -EPERM;
   41.16 -
   41.17      if ( vector == 0 )
   41.18          return -EBUSY;
   41.19  
    42.1 --- a/xen/arch/x86/mm.c	Tue Jan 03 08:59:00 2006 -0600
    42.2 +++ b/xen/arch/x86/mm.c	Tue Jan 03 10:19:20 2006 -0600
    42.3 @@ -96,6 +96,7 @@
    42.4  #include <xen/softirq.h>
    42.5  #include <xen/domain_page.h>
    42.6  #include <xen/event.h>
    42.7 +#include <xen/iocap.h>
    42.8  #include <asm/shadow.h>
    42.9  #include <asm/page.h>
   42.10  #include <asm/flushtlb.h>
   42.11 @@ -437,7 +438,6 @@ get_page_from_l1e(
   42.12      unsigned long mfn = l1e_get_pfn(l1e);
   42.13      struct pfn_info *page = pfn_to_page(mfn);
   42.14      int okay;
   42.15 -    extern int domain_iomem_in_pfn(struct domain *d, unsigned long pfn);
   42.16  
   42.17      if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
   42.18          return 1;
   42.19 @@ -455,8 +455,7 @@ get_page_from_l1e(
   42.20          if ( d == dom_io )
   42.21              d = current->domain;
   42.22  
   42.23 -        if ( (!IS_PRIV(d)) &&
   42.24 -             (!IS_CAPABLE_PHYSDEV(d) || !domain_iomem_in_pfn(d, mfn)) )
   42.25 +        if ( !iomem_access_permitted(d, mfn, mfn) )
   42.26          {
   42.27              MEM_LOG("Non-privileged attempt to map I/O space %08lx", mfn);
   42.28              return 0;
   42.29 @@ -1887,7 +1886,7 @@ int do_mmuext_op(
   42.30              break;
   42.31  
   42.32          case MMUEXT_FLUSH_CACHE:
   42.33 -            if ( unlikely(!IS_CAPABLE_PHYSDEV(d)) )
   42.34 +            if ( unlikely(!cache_flush_permitted(d)) )
   42.35              {
   42.36                  MEM_LOG("Non-physdev domain tried to FLUSH_CACHE.");
   42.37                  okay = 0;
    43.1 --- a/xen/arch/x86/physdev.c	Tue Jan 03 08:59:00 2006 -0600
    43.2 +++ b/xen/arch/x86/physdev.c	Tue Jan 03 10:19:20 2006 -0600
    43.3 @@ -14,27 +14,6 @@
    43.4  extern int ioapic_guest_read(int apicid, int address, u32 *pval);
    43.5  extern int ioapic_guest_write(int apicid, int address, u32 pval);
    43.6  
    43.7 -void physdev_modify_ioport_access_range(
    43.8 -    struct domain *d, int enable, int port, int num)
    43.9 -{
   43.10 -    int i;
   43.11 -    for ( i = port; i < (port + num); i++ )
   43.12 -        (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask);
   43.13 -}
   43.14 -
   43.15 -void physdev_destroy_state(struct domain *d)
   43.16 -{
   43.17 -    xfree(d->arch.iobmp_mask);
   43.18 -    d->arch.iobmp_mask = NULL;
   43.19 -}
   43.20 -
   43.21 -/* Check if a domain controls a device with IO memory within frame @pfn.
   43.22 - * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise.  */
   43.23 -int domain_iomem_in_pfn(struct domain *p, unsigned long pfn)
   43.24 -{
   43.25 -    return 0;
   43.26 -}
   43.27 -
   43.28  /*
   43.29   * Demuxing hypercall.
   43.30   */
   43.31 @@ -120,18 +99,6 @@ long do_physdev_op(physdev_op_t *uop)
   43.32      return ret;
   43.33  }
   43.34  
   43.35 -/* Domain 0 has read access to all devices. */
   43.36 -void physdev_init_dom0(struct domain *d)
   43.37 -{
   43.38 -    /* Access to all I/O ports. */
   43.39 -    d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES);
   43.40 -    BUG_ON(d->arch.iobmp_mask == NULL);
   43.41 -    memset(d->arch.iobmp_mask, 0, IOBMP_BYTES);
   43.42 -
   43.43 -    set_bit(_DOMF_physdev_access, &d->domain_flags);
   43.44 -}
   43.45 -
   43.46 -
   43.47  /*
   43.48   * Local variables:
   43.49   * mode: C
    44.1 --- a/xen/arch/x86/setup.c	Tue Jan 03 08:59:00 2006 -0600
    44.2 +++ b/xen/arch/x86/setup.c	Tue Jan 03 10:19:20 2006 -0600
    44.3 @@ -138,131 +138,19 @@ static void __init do_initcalls(void)
    44.4          (*call)();
    44.5  }
    44.6  
    44.7 -static void __init start_of_day(void)
    44.8 -{
    44.9 -    int i;
   44.10 -    unsigned long vgdt, gdt_pfn;
   44.11 -
   44.12 -    early_cpu_init();
   44.13 -
   44.14 -    paging_init();
   44.15 -
   44.16 -    /* Unmap the first page of CPU0's stack. */
   44.17 -    memguard_guard_stack(cpu0_stack);
   44.18 -
   44.19 -    open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
   44.20 -
   44.21 -    if ( opt_watchdog ) 
   44.22 -        nmi_watchdog = NMI_LOCAL_APIC;
   44.23 -
   44.24 -    sort_exception_tables();
   44.25 -
   44.26 -    arch_do_createdomain(current);
   44.27 -    
   44.28 -    /*
   44.29 -     * Map default GDT into its final positions in the idle page table. As
   44.30 -     * noted in arch_do_createdomain(), we must map for every possible VCPU#.
   44.31 -     */
   44.32 -    vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
   44.33 -    gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
   44.34 -    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
   44.35 -    {
   44.36 -        map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
   44.37 -        vgdt += 1 << PDPT_VCPU_VA_SHIFT;
   44.38 -    }
   44.39 -
   44.40 -    find_smp_config();
   44.41 -
   44.42 -    smp_alloc_memory();
   44.43 -
   44.44 -    dmi_scan_machine();
   44.45 -
   44.46 -    generic_apic_probe();
   44.47 -
   44.48 -    acpi_boot_table_init();
   44.49 -    acpi_boot_init();
   44.50 -
   44.51 -    if ( smp_found_config ) 
   44.52 -        get_smp_config();
   44.53 -
   44.54 -    init_apic_mappings();
   44.55 -
   44.56 -    init_IRQ();
   44.57 -
   44.58 -    trap_init();
   44.59 -
   44.60 -    ac_timer_init();
   44.61 -
   44.62 -    early_time_init();
   44.63 -
   44.64 -    arch_init_memory();
   44.65 -
   44.66 -    scheduler_init();
   44.67 -
   44.68 -    identify_cpu(&boot_cpu_data);
   44.69 -    if ( cpu_has_fxsr )
   44.70 -        set_in_cr4(X86_CR4_OSFXSR);
   44.71 -    if ( cpu_has_xmm )
   44.72 -        set_in_cr4(X86_CR4_OSXMMEXCPT);
   44.73 -
   44.74 -    if ( opt_nosmp )
   44.75 -    {
   44.76 -        max_cpus = 0;
   44.77 -        smp_num_siblings = 1;
   44.78 -        boot_cpu_data.x86_num_cores = 1;
   44.79 -    }
   44.80 -
   44.81 -    smp_prepare_cpus(max_cpus);
   44.82 -
   44.83 -    /* We aren't hotplug-capable yet. */
   44.84 -    BUG_ON(!cpus_empty(cpu_present_map));
   44.85 -    for_each_cpu ( i )
   44.86 -        cpu_set(i, cpu_present_map);
   44.87 -
   44.88 -    /*
   44.89 -     * Initialise higher-level timer functions. We do this fairly late
   44.90 -     * (post-SMP) because the time bases and scale factors need to be updated 
   44.91 -     * regularly, and SMP initialisation can cause a long delay with 
   44.92 -     * interrupts not yet enabled.
   44.93 -     */
   44.94 -    init_xen_time();
   44.95 -
   44.96 -    initialize_keytable();
   44.97 -
   44.98 -    serial_init_postirq();
   44.99 -
  44.100 -    BUG_ON(!local_irq_is_enabled());
  44.101 -
  44.102 -    for_each_present_cpu ( i )
  44.103 -    {
  44.104 -        if ( num_online_cpus() >= max_cpus )
  44.105 -            break;
  44.106 -        if ( !cpu_online(i) )
  44.107 -            __cpu_up(i);
  44.108 -    }
  44.109 -
  44.110 -    printk("Brought up %ld CPUs\n", (long)num_online_cpus());
  44.111 -    smp_cpus_done(max_cpus);
  44.112 -
  44.113 -    do_initcalls();
  44.114 -
  44.115 -    schedulers_start();
  44.116 -
  44.117 -    watchdog_enable();
  44.118 -}
  44.119 -
  44.120  #define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" )
  44.121  
  44.122  static struct e820entry e820_raw[E820MAX];
  44.123  
  44.124  void __init __start_xen(multiboot_info_t *mbi)
  44.125  {
  44.126 +    unsigned long vgdt, gdt_pfn;
  44.127      char *cmdline;
  44.128 +    unsigned long _initrd_start = 0, _initrd_len = 0;
  44.129 +    unsigned int initrdidx = 1;
  44.130      module_t *mod = (module_t *)__va(mbi->mods_addr);
  44.131      unsigned long nr_pages, modules_length;
  44.132      unsigned long initial_images_start, initial_images_end;
  44.133 -    unsigned long _initrd_start = 0, _initrd_len = 0;
  44.134 -    unsigned int initrdidx = 1;
  44.135      physaddr_t s, e;
  44.136      int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
  44.137      struct ns16550_defaults ns16550 = {
  44.138 @@ -486,7 +374,113 @@ void __init __start_xen(multiboot_info_t
  44.139  
  44.140      early_boot = 0;
  44.141  
  44.142 -    start_of_day();
  44.143 +    early_cpu_init();
  44.144 +
  44.145 +    paging_init();
  44.146 +
  44.147 +    /* Unmap the first page of CPU0's stack. */
  44.148 +    memguard_guard_stack(cpu0_stack);
  44.149 +
  44.150 +    open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
  44.151 +
  44.152 +    if ( opt_watchdog ) 
  44.153 +        nmi_watchdog = NMI_LOCAL_APIC;
  44.154 +
  44.155 +    sort_exception_tables();
  44.156 +
  44.157 +    if ( arch_do_createdomain(current) != 0 )
  44.158 +        BUG();
  44.159 +
  44.160 +    /*
  44.161 +     * Map default GDT into its final positions in the idle page table. As
  44.162 +     * noted in arch_do_createdomain(), we must map for every possible VCPU#.
  44.163 +     */
  44.164 +    vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
  44.165 +    gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
  44.166 +    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
  44.167 +    {
  44.168 +        map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
  44.169 +        vgdt += 1 << PDPT_VCPU_VA_SHIFT;
  44.170 +    }
  44.171 +
  44.172 +    find_smp_config();
  44.173 +
  44.174 +    smp_alloc_memory();
  44.175 +
  44.176 +    dmi_scan_machine();
  44.177 +
  44.178 +    generic_apic_probe();
  44.179 +
  44.180 +    acpi_boot_table_init();
  44.181 +    acpi_boot_init();
  44.182 +
  44.183 +    if ( smp_found_config ) 
  44.184 +        get_smp_config();
  44.185 +
  44.186 +    init_apic_mappings();
  44.187 +
  44.188 +    init_IRQ();
  44.189 +
  44.190 +    trap_init();
  44.191 +
  44.192 +    ac_timer_init();
  44.193 +
  44.194 +    early_time_init();
  44.195 +
  44.196 +    arch_init_memory();
  44.197 +
  44.198 +    scheduler_init();
  44.199 +
  44.200 +    identify_cpu(&boot_cpu_data);
  44.201 +    if ( cpu_has_fxsr )
  44.202 +        set_in_cr4(X86_CR4_OSFXSR);
  44.203 +    if ( cpu_has_xmm )
  44.204 +        set_in_cr4(X86_CR4_OSXMMEXCPT);
  44.205 +
  44.206 +    if ( opt_nosmp )
  44.207 +    {
  44.208 +        max_cpus = 0;
  44.209 +        smp_num_siblings = 1;
  44.210 +        boot_cpu_data.x86_num_cores = 1;
  44.211 +    }
  44.212 +
  44.213 +    smp_prepare_cpus(max_cpus);
  44.214 +
  44.215 +    /* We aren't hotplug-capable yet. */
  44.216 +    BUG_ON(!cpus_empty(cpu_present_map));
  44.217 +    for_each_cpu ( i )
  44.218 +        cpu_set(i, cpu_present_map);
  44.219 +
  44.220 +    /*
  44.221 +     * Initialise higher-level timer functions. We do this fairly late
  44.222 +     * (post-SMP) because the time bases and scale factors need to be updated 
  44.223 +     * regularly, and SMP initialisation can cause a long delay with 
  44.224 +     * interrupts not yet enabled.
  44.225 +     */
  44.226 +    init_xen_time();
  44.227 +
  44.228 +    initialize_keytable();
  44.229 +
  44.230 +    serial_init_postirq();
  44.231 +
  44.232 +    BUG_ON(!local_irq_is_enabled());
  44.233 +
  44.234 +    for_each_present_cpu ( i )
  44.235 +    {
  44.236 +        if ( num_online_cpus() >= max_cpus )
  44.237 +            break;
  44.238 +        if ( !cpu_online(i) )
  44.239 +            __cpu_up(i);
  44.240 +    }
  44.241 +
  44.242 +    printk("Brought up %ld CPUs\n", (long)num_online_cpus());
  44.243 +    smp_cpus_done(max_cpus);
  44.244 +
  44.245 +    do_initcalls();
  44.246 +
  44.247 +    schedulers_start();
  44.248 +
  44.249 +    watchdog_enable();
  44.250  
  44.251      shadow_mode_init();
  44.252  
    45.1 --- a/xen/arch/x86/smpboot.c	Tue Jan 03 08:59:00 2006 -0600
    45.2 +++ b/xen/arch/x86/smpboot.c	Tue Jan 03 10:19:20 2006 -0600
    45.3 @@ -763,7 +763,6 @@ static int __init do_boot_cpu(int apicid
    45.4  {
    45.5  	struct domain *idle;
    45.6  	struct vcpu *v;
    45.7 -	void *stack;
    45.8  	unsigned long boot_error;
    45.9  	int timeout, cpu;
   45.10  	unsigned long start_eip;
   45.11 @@ -786,16 +785,10 @@ static int __init do_boot_cpu(int apicid
   45.12  	/* So we see what's up   */
   45.13  	printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);
   45.14  
   45.15 -	stack = alloc_xenheap_pages(STACK_ORDER);
   45.16 -#if defined(__i386__)
   45.17 -	stack_start.esp = (void *)__pa(stack);
   45.18 -#elif defined(__x86_64__)
   45.19 -	stack_start.esp = stack;
   45.20 -#endif
   45.21 -	stack_start.esp += STACK_SIZE - sizeof(struct cpu_info);
   45.22 +	stack_start.esp = alloc_xenheap_pages(STACK_ORDER);
   45.23  
   45.24  	/* Debug build: detect stack overflow by setting up a guard page. */
   45.25 -	memguard_guard_stack(stack);
   45.26 +	memguard_guard_stack(stack_start.esp);
   45.27  
   45.28  	/*
   45.29  	 * This grunge runs the startup process for
    46.1 --- a/xen/arch/x86/traps.c	Tue Jan 03 08:59:00 2006 -0600
    46.2 +++ b/xen/arch/x86/traps.c	Tue Jan 03 10:19:20 2006 -0600
    46.3 @@ -41,6 +41,7 @@
    46.4  #include <xen/softirq.h>
    46.5  #include <xen/domain_page.h>
    46.6  #include <xen/symbols.h>
    46.7 +#include <xen/iocap.h>
    46.8  #include <asm/shadow.h>
    46.9  #include <asm/system.h>
   46.10  #include <asm/io.h>
   46.11 @@ -192,7 +193,8 @@ static void show_trace(struct cpu_user_r
   46.12  
   46.13      /* Bounds for range of valid frame pointer. */
   46.14      low  = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2);
   46.15 -    high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info));
   46.16 +    high = (low & ~(STACK_SIZE - 1)) + 
   46.17 +        (STACK_SIZE - sizeof(struct cpu_info) - 2*sizeof(unsigned long));
   46.18  
   46.19      /* The initial frame pointer. */
   46.20      next = regs->ebp;
   46.21 @@ -200,14 +202,14 @@ static void show_trace(struct cpu_user_r
   46.22      for ( ; ; )
   46.23      {
   46.24          /* Valid frame pointer? */
   46.25 -        if ( (next < low) || (next > high) )
   46.26 +        if ( (next < low) || (next >= high) )
   46.27          {
   46.28              /*
   46.29               * Exception stack frames have a different layout, denoted by an
   46.30               * inverted frame pointer.
   46.31               */
   46.32              next = ~next;
   46.33 -            if ( (next < low) || (next > high) )
   46.34 +            if ( (next < low) || (next >= high) )
   46.35                  break;
   46.36              frame = (unsigned long *)next;
   46.37              next  = frame[0];
   46.38 @@ -621,17 +623,7 @@ static inline int admin_io_okay(
   46.39      unsigned int port, unsigned int bytes,
   46.40      struct vcpu *v, struct cpu_user_regs *regs)
   46.41  {
   46.42 -    struct domain *d = v->domain;
   46.43 -    u16 x;
   46.44 -
   46.45 -    if ( d->arch.iobmp_mask != NULL )
   46.46 -    {
   46.47 -        x = *(u16 *)(d->arch.iobmp_mask + (port >> 3));
   46.48 -        if ( (x & (((1<<bytes)-1) << (port&7))) == 0 )
   46.49 -            return 1;
   46.50 -    }
   46.51 -
   46.52 -    return 0;
   46.53 +    return ioports_access_permitted(v->domain, port, port + bytes - 1);
   46.54  }
   46.55  
   46.56  /* Check admin limits. Silently fail the access if it is disallowed. */
   46.57 @@ -871,7 +863,7 @@ static int emulate_privileged_op(struct 
   46.58  
   46.59      case 0x09: /* WBINVD */
   46.60          /* Ignore the instruction if unprivileged. */
   46.61 -        if ( !IS_CAPABLE_PHYSDEV(v->domain) )
   46.62 +        if ( !cache_flush_permitted(v->domain) )
   46.63              DPRINTK("Non-physdev domain attempted WBINVD.\n");
   46.64          else
   46.65              wbinvd();
   46.66 @@ -885,7 +877,8 @@ static int emulate_privileged_op(struct 
   46.67          switch ( modrm_reg )
   46.68          {
   46.69          case 0: /* Read CR0 */
   46.70 -            *reg = v->arch.guest_context.ctrlreg[0];
   46.71 +            *reg = (read_cr0() & ~X86_CR0_TS) |
   46.72 +                v->arch.guest_context.ctrlreg[0];
   46.73              break;
   46.74  
   46.75          case 2: /* Read CR2 */
   46.76 @@ -927,6 +920,11 @@ static int emulate_privileged_op(struct 
   46.77          switch ( modrm_reg )
   46.78          {
   46.79          case 0: /* Write CR0 */
   46.80 +            if ( (*reg ^ read_cr0()) & ~X86_CR0_TS )
   46.81 +            {
   46.82 +                DPRINTK("Attempt to change unmodifiable CR0 flags.\n");
   46.83 +                goto fail;
   46.84 +            }
   46.85              (void)do_fpu_taskswitch(!!(*reg & X86_CR0_TS));
   46.86              break;
   46.87  
   46.88 @@ -941,6 +939,14 @@ static int emulate_privileged_op(struct 
   46.89              UNLOCK_BIGLOCK(v->domain);
   46.90              break;
   46.91  
   46.92 +        case 4:
   46.93 +            if ( *reg != (read_cr4() & ~(X86_CR4_PGE|X86_CR4_PSE)) )
   46.94 +            {
   46.95 +                DPRINTK("Attempt to change CR4 flags.\n");
   46.96 +                goto fail;
   46.97 +            }
   46.98 +            break;
   46.99 +
  46.100          default:
  46.101              goto fail;
  46.102          }
    47.1 --- a/xen/arch/x86/x86_32/xen.lds	Tue Jan 03 08:59:00 2006 -0600
    47.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.3 @@ -1,79 +0,0 @@
    47.4 -/* ld script to make i386 Linux kernel
    47.5 - * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
    47.6 - * Modified for i386 Xen by Keir Fraser
    47.7 - */
    47.8 -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
    47.9 -OUTPUT_ARCH(i386)
   47.10 -ENTRY(start)
   47.11 -PHDRS
   47.12 -{
   47.13 -  text PT_LOAD ;
   47.14 -}
   47.15 -SECTIONS
   47.16 -{
   47.17 -  . = 0xFF000000 + 0x100000;
   47.18 -  _text = .;			/* Text and read-only data */
   47.19 -  .text : {
   47.20 -	*(.text)
   47.21 -	*(.fixup)
   47.22 -	*(.gnu.warning)
   47.23 -	} :text =0x9090
   47.24 -  .text.lock : { *(.text.lock) } :text	/* out-of-line lock text */
   47.25 -
   47.26 -  _etext = .;			/* End of text section */
   47.27 -
   47.28 -  .rodata : { *(.rodata) *(.rodata.*) } :text
   47.29 -
   47.30 -  . = ALIGN(32);		/* Exception table */
   47.31 -  __start___ex_table = .;
   47.32 -  __ex_table : { *(__ex_table) } :text
   47.33 -  __stop___ex_table = .;
   47.34 -
   47.35 -  . = ALIGN(32);		/* Pre-exception table */
   47.36 -  __start___pre_ex_table = .;
   47.37 -  __pre_ex_table : { *(__pre_ex_table) } :text
   47.38 -  __stop___pre_ex_table = .;
   47.39 -
   47.40 -  .data : {			/* Data */
   47.41 -	*(.data)
   47.42 -	CONSTRUCTORS
   47.43 -	} :text
   47.44 -
   47.45 -  . = ALIGN(4096);		/* Init code and data */
   47.46 -  __init_begin = .;
   47.47 -  .text.init : { *(.text.init) } :text
   47.48 -  .data.init : { *(.data.init) } :text
   47.49 -  . = ALIGN(32);
   47.50 -  __setup_start = .;
   47.51 -  .setup.init : { *(.setup.init) } :text
   47.52 -  __setup_end = .;
   47.53 -  __initcall_start = .;
   47.54 -  .initcall.init : { *(.initcall.init) } :text
   47.55 -  __initcall_end = .;
   47.56 -  . = ALIGN(8192);
   47.57 -  __init_end = .;
   47.58 -
   47.59 -  __bss_start = .;		/* BSS */
   47.60 -  .bss : {
   47.61 -	*(.bss.twopage_aligned)
   47.62 -	*(.bss.page_aligned)
   47.63 -	*(.bss)
   47.64 -	} :text
   47.65 -  _end = . ;
   47.66 -
   47.67 -  /* Sections to be discarded */
   47.68 -  /DISCARD/ : {
   47.69 -	*(.text.exit)
   47.70 -	*(.data.exit)
   47.71 -	*(.exitcall.exit)
   47.72 -	}
   47.73 -
   47.74 -  /* Stabs debugging sections.  */
   47.75 -  .stab 0 : { *(.stab) }
   47.76 -  .stabstr 0 : { *(.stabstr) }
   47.77 -  .stab.excl 0 : { *(.stab.excl) }
   47.78 -  .stab.exclstr 0 : { *(.stab.exclstr) }
   47.79 -  .stab.index 0 : { *(.stab.index) }
   47.80 -  .stab.indexstr 0 : { *(.stab.indexstr) }
   47.81 -  .comment 0 : { *(.comment) }
   47.82 -}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/xen/arch/x86/x86_32/xen.lds.S	Tue Jan 03 10:19:20 2006 -0600
    48.3 @@ -0,0 +1,85 @@
    48.4 +/* ld script to make i386 Linux kernel
    48.5 + * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
    48.6 + * Modified for i386 Xen by Keir Fraser
    48.7 + */
    48.8 +
    48.9 +#include <xen/config.h>
   48.10 +#include <asm/page.h>
   48.11 +#undef ENTRY
   48.12 +#undef ALIGN
   48.13 +
   48.14 +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
   48.15 +OUTPUT_ARCH(i386)
   48.16 +ENTRY(start)
   48.17 +PHDRS
   48.18 +{
   48.19 +  text PT_LOAD ;
   48.20 +}
   48.21 +SECTIONS
   48.22 +{
   48.23 +  . = 0xFF000000 + 0x100000;
   48.24 +  _text = .;			/* Text and read-only data */
   48.25 +  .text : {
   48.26 +	*(.text)
   48.27 +	*(.fixup)
   48.28 +	*(.gnu.warning)
   48.29 +	} :text =0x9090
   48.30 +  .text.lock : { *(.text.lock) } :text	/* out-of-line lock text */
   48.31 +
   48.32 +  _etext = .;			/* End of text section */
   48.33 +
   48.34 +  .rodata : { *(.rodata) *(.rodata.*) } :text
   48.35 +
   48.36 +  . = ALIGN(32);		/* Exception table */
   48.37 +  __start___ex_table = .;
   48.38 +  __ex_table : { *(__ex_table) } :text
   48.39 +  __stop___ex_table = .;
   48.40 +
   48.41 +  . = ALIGN(32);		/* Pre-exception table */
   48.42 +  __start___pre_ex_table = .;
   48.43 +  __pre_ex_table : { *(__pre_ex_table) } :text
   48.44 +  __stop___pre_ex_table = .;
   48.45 +
   48.46 +  .data : {			/* Data */
   48.47 +	*(.data)
   48.48 +	CONSTRUCTORS
   48.49 +	} :text
   48.50 +
   48.51 +  . = ALIGN(4096);		/* Init code and data */
   48.52 +  __init_begin = .;
   48.53 +  .text.init : { *(.text.init) } :text
   48.54 +  .data.init : { *(.data.init) } :text
   48.55 +  . = ALIGN(32);
   48.56 +  __setup_start = .;
   48.57 +  .setup.init : { *(.setup.init) } :text
   48.58 +  __setup_end = .;
   48.59 +  __initcall_start = .;
   48.60 +  .initcall.init : { *(.initcall.init) } :text
   48.61 +  __initcall_end = .;
   48.62 +  . = ALIGN(STACK_SIZE);
   48.63 +  __init_end = .;
   48.64 +
   48.65 +  __bss_start = .;		/* BSS */
   48.66 +  .bss : {
   48.67 +	*(.bss.stack_aligned)
   48.68 +	*(.bss.page_aligned)
   48.69 +	*(.bss)
   48.70 +	} :text
   48.71 +  _end = . ;
   48.72 +
   48.73 +  /* Sections to be discarded */
   48.74 +  /DISCARD/ : {
   48.75 +	*(.text.exit)
   48.76 +	*(.data.exit)
   48.77 +	*(.exitcall.exit)
   48.78 +	}
   48.79 +
   48.80 +  /* Stabs debugging sections.  */
   48.81 +  .stab 0 : { *(.stab) }
   48.82 +  .stabstr 0 : { *(.stabstr) }
   48.83 +  .stab.excl 0 : { *(.stab.excl) }
   48.84 +  .stab.exclstr 0 : { *(.stab.exclstr) }
   48.85 +  .stab.index 0 : { *(.stab.index) }
   48.86 +  .stab.indexstr 0 : { *(.stab.indexstr) }
   48.87 +  .comment 0 : { *(.comment) }
   48.88 +}
    49.1 --- a/xen/arch/x86/x86_64/xen.lds	Tue Jan 03 08:59:00 2006 -0600
    49.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.3 @@ -1,77 +0,0 @@
    49.4 -/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */
    49.5 -/* Modified for x86-64 Xen by Keir Fraser */
    49.6 -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
    49.7 -OUTPUT_ARCH(i386:x86-64)
    49.8 -ENTRY(start)
    49.9 -PHDRS
   49.10 -{
   49.11 -  text PT_LOAD ;
   49.12 -}
   49.13 -SECTIONS
   49.14 -{
   49.15 -  . = 0xFFFF830000100000;
   49.16 -  _text = .;			/* Text and read-only data */
   49.17 -  .text : {
   49.18 -	*(.text)
   49.19 -	*(.fixup)
   49.20 -	*(.gnu.warning)
   49.21 -	} :text = 0x9090
   49.22 -  .text.lock : { *(.text.lock) } :text	/* out-of-line lock text */
   49.23 -
   49.24 -  _etext = .;			/* End of text section */
   49.25 -
   49.26 -  .rodata : { *(.rodata) *(.rodata.*) } :text
   49.27 -
   49.28 -  . = ALIGN(32);		/* Exception table */
   49.29 -  __start___ex_table = .;
   49.30 -  __ex_table : { *(__ex_table) } :text
   49.31 -  __stop___ex_table = .;
   49.32 -
   49.33 -  . = ALIGN(32);                /* Pre-exception table */
   49.34 -  __start___pre_ex_table = .;
   49.35 -  __pre_ex_table : { *(__pre_ex_table) } :text
   49.36 -  __stop___pre_ex_table = .;
   49.37 -
   49.38 -  .data : {			/* Data */
   49.39 -	*(.data)
   49.40 -	CONSTRUCTORS
   49.41 -	} :text
   49.42 -
   49.43 -  . = ALIGN(4096);		/* Init code and data */
   49.44 -  __init_begin = .;
   49.45 -  .text.init : { *(.text.init) } :text
   49.46 -  .data.init : { *(.data.init) } :text
   49.47 -  . = ALIGN(32);
   49.48 -  __setup_start = .;
   49.49 -  .setup.init : { *(.setup.init) } :text
   49.50 -  __setup_end = .;
   49.51 -  __initcall_start = .;
   49.52 -  .initcall.init : { *(.initcall.init) } :text
   49.53 -  __initcall_end = .;
   49.54 -  . = ALIGN(8192);
   49.55 -  __init_end = .;
   49.56 -
   49.57 -  __bss_start = .;		/* BSS */
   49.58 -  .bss : {
   49.59 -	*(.bss.twopage_aligned)
   49.60 -	*(.bss.page_aligned)
   49.61 -	*(.bss)
   49.62 -	} :text
   49.63 -  _end = . ;
   49.64 -
   49.65 -  /* Sections to be discarded */
   49.66 -  /DISCARD/ : {
   49.67 -	*(.text.exit)
   49.68 -	*(.data.exit)
   49.69 -	*(.exitcall.exit)
   49.70 -	}
   49.71 -
   49.72 -  /* Stabs debugging sections.  */
   49.73 -  .stab 0 : { *(.stab) }
   49.74 -  .stabstr 0 : { *(.stabstr) }
   49.75 -  .stab.excl 0 : { *(.stab.excl) }
   49.76 -  .stab.exclstr 0 : { *(.stab.exclstr) }
   49.77 -  .stab.index 0 : { *(.stab.index) }
   49.78 -  .stab.indexstr 0 : { *(.stab.indexstr) }
   49.79 -  .comment 0 : { *(.comment) }
   49.80 -}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/xen/arch/x86/x86_64/xen.lds.S	Tue Jan 03 10:19:20 2006 -0600
    50.3 @@ -0,0 +1,83 @@
    50.4 +/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */
    50.5 +/* Modified for x86-64 Xen by Keir Fraser */
    50.6 +
    50.7 +#include <xen/config.h>
    50.8 +#include <asm/page.h>
    50.9 +#undef ENTRY
   50.10 +#undef ALIGN
   50.11 +
   50.12 +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
   50.13 +OUTPUT_ARCH(i386:x86-64)
   50.14 +ENTRY(start)
   50.15 +PHDRS
   50.16 +{
   50.17 +  text PT_LOAD ;
   50.18 +}
   50.19 +SECTIONS
   50.20 +{
   50.21 +  . = 0xFFFF830000100000;
   50.22 +  _text = .;			/* Text and read-only data */
   50.23 +  .text : {
   50.24 +	*(.text)
   50.25 +	*(.fixup)
   50.26 +	*(.gnu.warning)
   50.27 +	} :text = 0x9090
   50.28 +  .text.lock : { *(.text.lock) } :text	/* out-of-line lock text */
   50.29 +
   50.30 +  _etext = .;			/* End of text section */
   50.31 +
   50.32 +  .rodata : { *(.rodata) *(.rodata.*) } :text
   50.33 +
   50.34 +  . = ALIGN(32);		/* Exception table */
   50.35 +  __start___ex_table = .;
   50.36 +  __ex_table : { *(__ex_table) } :text
   50.37 +  __stop___ex_table = .;
   50.38 +
   50.39 +  . = ALIGN(32);                /* Pre-exception table */
   50.40 +  __start___pre_ex_table = .;
   50.41 +  __pre_ex_table : { *(__pre_ex_table) } :text
   50.42 +  __stop___pre_ex_table = .;
   50.43 +
   50.44 +  .data : {			/* Data */
   50.45 +	*(.data)
   50.46 +	CONSTRUCTORS
   50.47 +	} :text
   50.48 +
   50.49 +  . = ALIGN(4096);		/* Init code and data */
   50.50 +  __init_begin = .;
   50.51 +  .text.init : { *(.text.init) } :text
   50.52 +  .data.init : { *(.data.init) } :text
   50.53 +  . = ALIGN(32);
   50.54 +  __setup_start = .;
   50.55 +  .setup.init : { *(.setup.init) } :text
   50.56 +  __setup_end = .;
   50.57 +  __initcall_start = .;
   50.58 +  .initcall.init : { *(.initcall.init) } :text
   50.59 +  __initcall_end = .;
   50.60 +  . = ALIGN(STACK_SIZE);
   50.61 +  __init_end = .;
   50.62 +
   50.63 +  __bss_start = .;		/* BSS */
   50.64 +  .bss : {
   50.65 +	*(.bss.stack_aligned)
   50.66 +	*(.bss.page_aligned)
   50.67 +	*(.bss)
   50.68 +	} :text
   50.69 +  _end = . ;
   50.70 +
   50.71 +  /* Sections to be discarded */
   50.72 +  /DISCARD/ : {
   50.73 +	*(.text.exit)
   50.74 +	*(.data.exit)
   50.75 +	*(.exitcall.exit)
   50.76 +	}
   50.77 +
   50.78 +  /* Stabs debugging sections.  */
   50.79 +  .stab 0 : { *(.stab) }
   50.80 +  .stabstr 0 : { *(.stabstr) }
   50.81 +  .stab.excl 0 : { *(.stab.excl) }
   50.82 +  .stab.exclstr 0 : { *(.stab.exclstr) }
   50.83 +  .stab.index 0 : { *(.stab.index) }
   50.84 +  .stab.indexstr 0 : { *(.stab.indexstr) }
   50.85 +  .comment 0 : { *(.comment) }
   50.86 +}
    51.1 --- a/xen/arch/x86/x86_emulate.c	Tue Jan 03 08:59:00 2006 -0600
    51.2 +++ b/xen/arch/x86/x86_emulate.c	Tue Jan 03 10:19:20 2006 -0600
    51.3 @@ -371,6 +371,21 @@ do{ __asm__ __volatile__ (              
    51.4     (_type)_x; \
    51.5  })
    51.6  
    51.7 +/* Access/update address held in a register, based on addressing mode. */
    51.8 +#define register_address(sel, reg)                                      \
    51.9 +    ((ad_bytes == sizeof(unsigned long)) ? (reg) :                      \
   51.10 +     ((mode == X86EMUL_MODE_REAL) ? /* implies ad_bytes == 2 */         \
   51.11 +      (((unsigned long)(sel) << 4) + ((reg) & 0xffff)) :                \
   51.12 +      ((reg) & ((1UL << (ad_bytes << 3)) - 1))))
   51.13 +#define register_address_increment(reg, inc)                            \
   51.14 +do {                                                                    \
   51.15 +    if ( ad_bytes == sizeof(unsigned long) )                            \
   51.16 +        (reg) += (inc);                                                 \
   51.17 +    else                                                                \
   51.18 +        (reg) = ((reg) & ~((1UL << (ad_bytes << 3)) - 1)) |             \
   51.19 +                (((reg) + (inc)) & ((1UL << (ad_bytes << 3)) - 1));     \
   51.20 +} while (0)
   51.21 +
   51.22  void *
   51.23  decode_register(
   51.24      uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs)
   51.25 @@ -420,32 +435,64 @@ x86_emulate_memop(
   51.26  {
   51.27      uint8_t b, d, sib, twobyte = 0, rex_prefix = 0;
   51.28      uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
   51.29 -    unsigned int op_bytes = (mode == 8) ? 4 : mode, ad_bytes = mode;
   51.30 -    unsigned int lock_prefix = 0, rep_prefix = 0, i;
   51.31 +    uint16_t *seg = NULL; /* override segment */
   51.32 +    unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
   51.33      int rc = 0;
   51.34      struct operand src, dst;
   51.35  
   51.36      /* Shadow copy of register state. Committed on successful emulation. */
   51.37      struct cpu_user_regs _regs = *regs;
   51.38  
   51.39 +    switch ( mode )
   51.40 +    {
   51.41 +    case X86EMUL_MODE_REAL:
   51.42 +    case X86EMUL_MODE_PROT16:
   51.43 +        op_bytes = ad_bytes = 2;
   51.44 +        break;
   51.45 +    case X86EMUL_MODE_PROT32:
   51.46 +        op_bytes = ad_bytes = 4;
   51.47 +        break;
   51.48 +#ifdef __x86_64__
   51.49 +    case X86EMUL_MODE_PROT64:
   51.50 +        op_bytes = 4;
   51.51 +        ad_bytes = 8;
   51.52 +        break;
   51.53 +#endif
   51.54 +    default:
   51.55 +        return -1;
   51.56 +    }
   51.57 +
   51.58      /* Legacy prefixes. */
   51.59      for ( i = 0; i < 8; i++ )
   51.60      {
   51.61          switch ( b = insn_fetch(uint8_t, 1, _regs.eip) )
   51.62          {
   51.63          case 0x66: /* operand-size override */
   51.64 -            op_bytes ^= 6;                    /* switch between 2/4 bytes */
   51.65 +            op_bytes ^= 6;      /* switch between 2/4 bytes */
   51.66              break;
   51.67          case 0x67: /* address-size override */
   51.68 -            ad_bytes ^= (mode == 8) ? 12 : 6; /* switch between 2/4/8 bytes */
   51.69 +            if ( mode == X86EMUL_MODE_PROT64 )
   51.70 +                ad_bytes ^= 12; /* switch between 4/8 bytes */
   51.71 +            else
   51.72 +                ad_bytes ^= 6;  /* switch between 2/4 bytes */
   51.73              break;
   51.74          case 0x2e: /* CS override */
   51.75 +            seg = &_regs.cs;
   51.76 +            break;
   51.77          case 0x3e: /* DS override */
   51.78 +            seg = &_regs.ds;
   51.79 +            break;
   51.80          case 0x26: /* ES override */
   51.81 +            seg = &_regs.es;
   51.82 +            break;
   51.83          case 0x64: /* FS override */
   51.84 +            seg = &_regs.fs;
   51.85 +            break;
   51.86          case 0x65: /* GS override */
   51.87 +            seg = &_regs.gs;
   51.88 +            break;
   51.89          case 0x36: /* SS override */
   51.90 -            DPRINTF("Warning: ignoring a segment override.\n");
   51.91 +            seg = &_regs.ss;
   51.92              break;
   51.93          case 0xf0: /* LOCK */
   51.94              lock_prefix = 1;
   51.95 @@ -461,8 +508,12 @@ x86_emulate_memop(
   51.96      }
   51.97   done_prefixes:
   51.98  
   51.99 +    /* Note quite the same as 80386 real mode, but hopefully good enough. */
  51.100 +    if ( (mode == X86EMUL_MODE_REAL) && (ad_bytes != 2) )
  51.101 +        goto cannot_emulate;
  51.102 +
  51.103      /* REX prefix. */
  51.104 -    if ( (mode == 8) && ((b & 0xf0) == 0x40) )
  51.105 +    if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
  51.106      {
  51.107          rex_prefix = b;
  51.108          if ( b & 8 )
  51.109 @@ -674,7 +725,7 @@ x86_emulate_memop(
  51.110          emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
  51.111          break;
  51.112      case 0x63: /* movsxd */
  51.113 -        if ( mode != 8 ) /* x86/64 long mode only */
  51.114 +        if ( mode != X86EMUL_MODE_PROT64 )
  51.115              goto cannot_emulate;
  51.116          dst.val = (int32_t)src.val;
  51.117          break;
  51.118 @@ -721,12 +772,13 @@ x86_emulate_memop(
  51.119          dst.val = src.val;
  51.120          break;
  51.121      case 0x8f: /* pop (sole member of Grp1a) */
  51.122 -        /* 64-bit mode: POP defaults to 64-bit operands. */
  51.123 -        if ( (mode == 8) && (dst.bytes == 4) )
  51.124 +        /* 64-bit mode: POP always pops a 64-bit operand. */
  51.125 +        if ( mode == X86EMUL_MODE_PROT64 )
  51.126              dst.bytes = 8;
  51.127 -        if ( (rc = ops->read_std(_regs.esp, &dst.val, dst.bytes)) != 0 )
  51.128 +        if ( (rc = ops->read_std(register_address(_regs.ss, _regs.esp),
  51.129 +                                 &dst.val, dst.bytes)) != 0 )
  51.130              goto done;
  51.131 -        _regs.esp += dst.bytes;
  51.132 +        register_address_increment(_regs.esp, dst.bytes);
  51.133          break;
  51.134      case 0xc0 ... 0xc1: grp2: /* Grp2 */
  51.135          switch ( modrm_reg )
  51.136 @@ -797,16 +849,17 @@ x86_emulate_memop(
  51.137              emulate_1op("dec", dst, _regs.eflags);
  51.138              break;
  51.139          case 6: /* push */
  51.140 -            /* 64-bit mode: PUSH defaults to 64-bit operands. */
  51.141 -            if ( (mode == 8) && (dst.bytes == 4) )
  51.142 +            /* 64-bit mode: PUSH always pushes a 64-bit operand. */
  51.143 +            if ( mode == X86EMUL_MODE_PROT64 )
  51.144              {
  51.145                  dst.bytes = 8;
  51.146                  if ( (rc = ops->read_std((unsigned long)dst.ptr,
  51.147                                           &dst.val, 8)) != 0 )
  51.148                      goto done;
  51.149              }
  51.150 -            _regs.esp -= dst.bytes;
  51.151 -            if ( (rc = ops->write_std(_regs.esp, dst.val, dst.bytes)) != 0 )
  51.152 +            register_address_increment(_regs.esp, -dst.bytes);
  51.153 +            if ( (rc = ops->write_std(register_address(_regs.ss, _regs.esp),
  51.154 +                                      dst.val, dst.bytes)) != 0 )
  51.155                  goto done;
  51.156              dst.val = dst.orig_val; /* skanky: disable writeback */
  51.157              break;
  51.158 @@ -873,19 +926,22 @@ x86_emulate_memop(
  51.159          {
  51.160              /* Write fault: destination is special memory. */
  51.161              dst.ptr = (unsigned long *)cr2;
  51.162 -            if ( (rc = ops->read_std(_regs.esi - _regs.edi + cr2, 
  51.163 +            if ( (rc = ops->read_std(register_address(seg ? *seg : _regs.ds,
  51.164 +                                                      _regs.esi),
  51.165                                       &dst.val, dst.bytes)) != 0 )
  51.166                  goto done;
  51.167          }
  51.168          else
  51.169          {
  51.170              /* Read fault: source is special memory. */
  51.171 -            dst.ptr = (unsigned long *)(_regs.edi - _regs.esi + cr2);
  51.172 +            dst.ptr = (unsigned long *)register_address(_regs.es, _regs.edi);
  51.173              if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
  51.174                  goto done;
  51.175          }
  51.176 -        _regs.esi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
  51.177 -        _regs.edi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
  51.178 +        register_address_increment(
  51.179 +            _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
  51.180 +        register_address_increment(
  51.181 +            _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
  51.182          break;
  51.183      case 0xa6 ... 0xa7: /* cmps */
  51.184          DPRINTF("Urk! I don't handle CMPS.\n");
  51.185 @@ -895,7 +951,8 @@ x86_emulate_memop(
  51.186          dst.bytes = (d & ByteOp) ? 1 : op_bytes;
  51.187          dst.ptr   = (unsigned long *)cr2;
  51.188          dst.val   = _regs.eax;
  51.189 -        _regs.edi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
  51.190 +        register_address_increment(
  51.191 +            _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
  51.192          break;
  51.193      case 0xac ... 0xad: /* lods */
  51.194          dst.type  = OP_REG;
  51.195 @@ -903,7 +960,8 @@ x86_emulate_memop(
  51.196          dst.ptr   = (unsigned long *)&_regs.eax;
  51.197          if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
  51.198              goto done;
  51.199 -        _regs.esi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
  51.200 +        register_address_increment(
  51.201 +            _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
  51.202          break;
  51.203      case 0xae ... 0xaf: /* scas */
  51.204          DPRINTF("Urk! I don't handle SCAS.\n");
    52.1 --- a/xen/common/dom0_ops.c	Tue Jan 03 08:59:00 2006 -0600
    52.2 +++ b/xen/common/dom0_ops.c	Tue Jan 03 10:19:20 2006 -0600
    52.3 @@ -16,6 +16,7 @@
    52.4  #include <xen/domain_page.h>
    52.5  #include <xen/trace.h>
    52.6  #include <xen/console.h>
    52.7 +#include <xen/iocap.h>
    52.8  #include <asm/current.h>
    52.9  #include <public/dom0_ops.h>
   52.10  #include <public/sched_ctl.h>
   52.11 @@ -582,6 +583,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   52.12          }
   52.13      }
   52.14      break;
   52.15 +
   52.16      case DOM0_SETDEBUGGING:
   52.17      {
   52.18          struct domain *d; 
   52.19 @@ -599,6 +601,53 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   52.20      }
   52.21      break;
   52.22  
   52.23 +    case DOM0_IRQ_PERMISSION:
   52.24 +    {
   52.25 +        struct domain *d;
   52.26 +        unsigned int pirq = op->u.irq_permission.pirq;
   52.27 +
   52.28 +        ret = -EINVAL;
   52.29 +        if ( pirq >= NR_PIRQS )
   52.30 +            break;
   52.31 +
   52.32 +        ret = -ESRCH;
   52.33 +        d = find_domain_by_id(op->u.irq_permission.domain);
   52.34 +        if ( d == NULL )
   52.35 +            break;
   52.36 +
   52.37 +        if ( op->u.irq_permission.allow_access )
   52.38 +            ret = irq_permit_access(d, pirq);
   52.39 +        else
   52.40 +            ret = irq_deny_access(d, pirq);
   52.41 +
   52.42 +        put_domain(d);
   52.43 +    }
   52.44 +    break;
   52.45 +
   52.46 +    case DOM0_IOMEM_PERMISSION:
   52.47 +    {
   52.48 +        struct domain *d;
   52.49 +        unsigned long pfn = op->u.iomem_permission.first_pfn;
   52.50 +        unsigned long nr_pfns = op->u.iomem_permission.nr_pfns;
   52.51 +
   52.52 +        ret = -EINVAL;
   52.53 +        if ( (pfn + nr_pfns - 1) < pfn ) /* wrap? */
   52.54 +            break;
   52.55 +
   52.56 +        ret = -ESRCH;
   52.57 +        d = find_domain_by_id(op->u.iomem_permission.domain);
   52.58 +        if ( d == NULL )
   52.59 +            break;
   52.60 +
   52.61 +        if ( op->u.iomem_permission.allow_access )
   52.62 +            ret = iomem_permit_access(d, pfn, pfn + nr_pfns - 1);
   52.63 +        else
   52.64 +            ret = iomem_deny_access(d, pfn, pfn + nr_pfns - 1);
   52.65 +
   52.66 +        put_domain(d);
   52.67 +    }
   52.68 +    break;
   52.69 +
   52.70  #ifdef PERF_COUNTERS
   52.71      case DOM0_PERFCCONTROL:
   52.72      {
    53.1 --- a/xen/common/domain.c	Tue Jan 03 08:59:00 2006 -0600
    53.2 +++ b/xen/common/domain.c	Tue Jan 03 10:19:20 2006 -0600
    53.3 @@ -16,6 +16,7 @@
    53.4  #include <xen/console.h>
    53.5  #include <xen/softirq.h>
    53.6  #include <xen/domain_page.h>
    53.7 +#include <xen/rangeset.h>
    53.8  #include <asm/debugger.h>
    53.9  #include <public/dom0_ops.h>
   53.10  #include <public/sched.h>
   53.11 @@ -52,22 +53,21 @@ struct domain *do_createdomain(domid_t d
   53.12  
   53.13      if ( !is_idle_task(d) &&
   53.14           ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
   53.15 -    {
   53.16 -        evtchn_destroy(d);
   53.17 -        free_domain(d);
   53.18 -        return NULL;
   53.19 -    }
   53.20 +        goto fail1;
   53.21      
   53.22      if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
   53.23 -    {
   53.24 -        grant_table_destroy(d);
   53.25 -        evtchn_destroy(d);
   53.26 -        free_domain(d);
   53.27 -        return NULL;
   53.28 -    }
   53.29 +        goto fail2;
   53.30 +
   53.31 +    rangeset_domain_initialise(d);
   53.32  
   53.33 -    arch_do_createdomain(v);
   53.34 -    
   53.35 +    d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
   53.36 +    d->irq_caps   = rangeset_new(d, "Interrupts", 0);
   53.37 +
   53.38 +    if ( (d->iomem_caps == NULL) ||
   53.39 +         (d->irq_caps == NULL) ||
   53.40 +         (arch_do_createdomain(v) != 0) )
   53.41 +        goto fail3;
   53.42 +
   53.43      if ( !is_idle_task(d) )
   53.44      {
   53.45          write_lock(&domlist_lock);
   53.46 @@ -83,6 +83,15 @@ struct domain *do_createdomain(domid_t d
   53.47      }
   53.48  
   53.49      return d;
   53.50 +
   53.51 + fail3:
   53.52 +    rangeset_domain_destroy(d);
   53.53 + fail2:
   53.54 +    grant_table_destroy(d);
   53.55 + fail1:
   53.56 +    evtchn_destroy(d);
   53.57 +    free_domain(d);
   53.58 +    return NULL;
   53.59  }
   53.60  
   53.61  
   53.62 @@ -271,6 +280,8 @@ void domain_destruct(struct domain *d)
   53.63      *pd = d->next_in_hashbucket;
   53.64      write_unlock(&domlist_lock);
   53.65  
   53.66 +    rangeset_domain_destroy(d);
   53.67 +
   53.68      evtchn_destroy(d);
   53.69      grant_table_destroy(d);
   53.70  
    54.1 --- a/xen/common/event_channel.c	Tue Jan 03 08:59:00 2006 -0600
    54.2 +++ b/xen/common/event_channel.c	Tue Jan 03 10:19:20 2006 -0600
    54.3 @@ -22,6 +22,7 @@
    54.4  #include <xen/sched.h>
    54.5  #include <xen/event.h>
    54.6  #include <xen/irq.h>
    54.7 +#include <xen/iocap.h>
    54.8  #include <asm/current.h>
    54.9  
   54.10  #include <public/xen.h>
   54.11 @@ -242,6 +243,9 @@ static long evtchn_bind_pirq(evtchn_bind
   54.12      if ( pirq >= ARRAY_SIZE(d->pirq_to_evtchn) )
   54.13          return -EINVAL;
   54.14  
   54.15 +    if ( !irq_access_permitted(d, pirq) )
   54.16 +        return -EPERM;
   54.17 +
   54.18      spin_lock(&d->evtchn_lock);
   54.19  
   54.20      if ( d->pirq_to_evtchn[pirq] != 0 )
    55.1 --- a/xen/common/keyhandler.c	Tue Jan 03 08:59:00 2006 -0600
    55.2 +++ b/xen/common/keyhandler.c	Tue Jan 03 10:19:20 2006 -0600
    55.3 @@ -11,6 +11,7 @@
    55.4  #include <xen/sched.h>
    55.5  #include <xen/softirq.h>
    55.6  #include <xen/domain.h>
    55.7 +#include <xen/rangeset.h>
    55.8  #include <asm/debugger.h>
    55.9  
   55.10  #define KEY_MAX 256
   55.11 @@ -109,31 +110,32 @@ static void do_task_queues(unsigned char
   55.12  
   55.13      for_each_domain ( d )
   55.14      {
   55.15 -        printk("Xen: DOM %u, flags=%lx refcnt=%d nr_pages=%d "
   55.16 -               "xenheap_pages=%d\n", d->domain_id, d->domain_flags,
   55.17 -               atomic_read(&d->refcnt), d->tot_pages, d->xenheap_pages);
   55.18 -        /* The handle is printed according to the OSF DCE UUID spec., even
   55.19 -           though it is not necessarily such a thing, for ease of use when it
   55.20 -           _is_ one of those. */
   55.21 -        printk("     handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
   55.22 +        printk("General information for domain %u:\n", d->domain_id);
   55.23 +        printk("    flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d\n",
   55.24 +               d->domain_flags, atomic_read(&d->refcnt),
   55.25 +               d->tot_pages, d->xenheap_pages);
   55.26 +        printk("    handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
   55.27                 "%02x%02x-%02x%02x%02x%02x%02x%02x\n",
   55.28                 d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3],
   55.29                 d->handle[ 4], d->handle[ 5], d->handle[ 6], d->handle[ 7],
   55.30                 d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11],
   55.31                 d->handle[12], d->handle[13], d->handle[14], d->handle[15]);
   55.32  
   55.33 +        rangeset_domain_printk(d);
   55.34 +
   55.35          dump_pageframe_info(d);
   55.36                 
   55.37 +        printk("VCPU information and callbacks for domain %u:\n",
   55.38 +               d->domain_id);
   55.39          for_each_vcpu ( d, v ) {
   55.40 -            printk("Guest: %p CPU %d [has=%c] flags=%lx "
   55.41 -                   "upcall_pend = %02x, upcall_mask = %02x\n", v,
   55.42 -                   v->processor,
   55.43 +            printk("    VCPU%d: CPU%d [has=%c] flags=%lx "
   55.44 +                   "upcall_pend = %02x, upcall_mask = %02x\n",
   55.45 +                   v->vcpu_id, v->processor,
   55.46                     test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F',
   55.47                     v->vcpu_flags,
   55.48                     v->vcpu_info->evtchn_upcall_pending, 
   55.49                     v->vcpu_info->evtchn_upcall_mask);
   55.50 -            printk("Notifying guest... %d/%d\n", d->domain_id, v->vcpu_id); 
   55.51 -            printk("port %d/%d stat %d %d %d\n",
   55.52 +            printk("    Notifying guest (virq %d, port %d, stat %d/%d/%d)\n",
   55.53                     VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
   55.54                     test_bit(v->virq_to_evtchn[VIRQ_DEBUG], 
   55.55                              &d->shared_info->evtchn_pending[0]),
    56.1 --- a/xen/common/memory.c	Tue Jan 03 08:59:00 2006 -0600
    56.2 +++ b/xen/common/memory.c	Tue Jan 03 10:19:20 2006 -0600
    56.3 @@ -15,6 +15,7 @@
    56.4  #include <xen/sched.h>
    56.5  #include <xen/event.h>
    56.6  #include <xen/shadow.h>
    56.7 +#include <xen/iocap.h>
    56.8  #include <asm/current.h>
    56.9  #include <asm/hardirq.h>
   56.10  #include <public/memory.h>
   56.11 @@ -35,7 +36,8 @@ increase_reservation(
   56.12           !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
   56.13          return 0;
   56.14  
   56.15 -    if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current->domain) )
   56.16 +    if ( (extent_order != 0) &&
   56.17 +         !multipage_allocation_permitted(current->domain) )
   56.18      {
   56.19          DPRINTK("Only I/O-capable domains may allocate multi-page extents.\n");
   56.20          return 0;
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/xen/common/rangeset.c	Tue Jan 03 10:19:20 2006 -0600
    57.3 @@ -0,0 +1,399 @@
    57.4 +/******************************************************************************
    57.5 + * rangeset.c
    57.6 + * 
    57.7 + * Creation, maintenance and automatic destruction of per-domain sets of
    57.8 + * numeric ranges.
    57.9 + * 
   57.10 + * Copyright (c) 2005, K A Fraser
   57.11 + */
   57.12 +
   57.13 +#include <xen/sched.h>
   57.14 +#include <xen/rangeset.h>
   57.15 +
   57.16 +/* An inclusive range [s,e] and pointer to next range in ascending order. */
   57.17 +struct range {
   57.18 +    struct list_head list;
   57.19 +    unsigned long s, e;
   57.20 +};
   57.21 +
   57.22 +struct rangeset {
   57.23 +    /* Owning domain and threaded list of rangesets. */
   57.24 +    struct list_head rangeset_list;
   57.25 +    struct domain   *domain;
   57.26 +
   57.27 +    /* Ordered list of ranges contained in this set, and protecting lock. */
   57.28 +    struct list_head range_list;
   57.29 +    spinlock_t       lock;
   57.30 +
   57.31 +    /* Pretty-printing name. */
   57.32 +    char             name[32];
   57.33 +
   57.34 +    /* RANGESETF flags. */
   57.35 +    unsigned int     flags;
   57.36 +};
   57.37 +
   57.38 +/*****************************
   57.39 + * Private range functions hide the underlying linked-list implemnetation.
   57.40 + */
   57.41 +
   57.42 +/* Find highest range lower than or containing s. NULL if no such range. */
   57.43 +static struct range *find_range(
   57.44 +    struct rangeset *r, unsigned long s)
   57.45 +{
   57.46 +    struct range *x = NULL, *y;
   57.47 +
   57.48 +    list_for_each_entry ( y, &r->range_list, list )
   57.49 +    {
   57.50 +        if ( y->s > s )
   57.51 +            break;
   57.52 +        x = y;
   57.53 +    }
   57.54 +
   57.55 +    return x;
   57.56 +}
   57.57 +
   57.58 +/* Return the lowest range in the set r, or NULL if r is empty. */
   57.59 +static struct range *first_range(
   57.60 +    struct rangeset *r)
   57.61 +{
   57.62 +    if ( list_empty(&r->range_list) )
   57.63 +        return NULL;
   57.64 +    return list_entry(r->range_list.next, struct range, list);
   57.65 +}
   57.66 +
   57.67 +/* Return range following x in ascending order, or NULL if x is the highest. */
   57.68 +static struct range *next_range(
   57.69 +    struct rangeset *r, struct range *x)
   57.70 +{
   57.71 +    if ( x->list.next == &r->range_list )
   57.72 +        return NULL;
   57.73 +    return list_entry(x->list.next, struct range, list);
   57.74 +}
   57.75 +
   57.76 +/* Insert range y after range x in r. Insert as first range if x is NULL. */
   57.77 +static void insert_range(
   57.78 +    struct rangeset *r, struct range *x, struct range *y)
   57.79 +{
   57.80 +    list_add(&y->list, (x != NULL) ? &x->list : &r->range_list);
   57.81 +}
   57.82 +
   57.83 +/* Remove a range from its list and free it. */
   57.84 +static void destroy_range(
   57.85 +    struct range *x)
   57.86 +{
   57.87 +    list_del(&x->list);
   57.88 +    xfree(x);
   57.89 +}
   57.90 +
   57.91 +/*****************************
   57.92 + * Core public functions
   57.93 + */
   57.94 +
   57.95 +int rangeset_add_range(
   57.96 +    struct rangeset *r, unsigned long s, unsigned long e)
   57.97 +{
   57.98 +    struct range *x, *y;
   57.99 +    int rc = 0;
  57.100 +
  57.101 +    spin_lock(&r->lock);
  57.102 +
  57.103 +    x = find_range(r, s);
  57.104 +    y = find_range(r, e);
  57.105 +
  57.106 +    if ( x == y )
  57.107 +    {
  57.108 +        if ( (x == NULL) || ((x->e < s) && ((x->e + 1) != s)) )
  57.109 +        {
  57.110 +            x = xmalloc(struct range);
  57.111 +            if ( x == NULL )
  57.112 +            {
  57.113 +                rc = -ENOMEM;
  57.114 +                goto out;
  57.115 +            }
  57.116 +
  57.117 +            x->s = s;
  57.118 +            x->e = e;
  57.119 +
  57.120 +            insert_range(r, y, x);
  57.121 +        }
  57.122 +        else if ( x->e < e )
  57.123 +            x->e = e;
  57.124 +    }
  57.125 +    else
  57.126 +    {
  57.127 +        if ( x == NULL )
  57.128 +        {
  57.129 +            x = first_range(r);
  57.130 +            x->s = s;
  57.131 +        }
  57.132 +        else if ( (x->e < s) && ((x->e + 1) != s) )
  57.133 +        {
  57.134 +            x = next_range(r, x);
  57.135 +            x->s = s;
  57.136 +        }
  57.137 +        
  57.138 +        x->e = (y->e > e) ? y->e : e;
  57.139 +
  57.140 +        for ( ; ; )
  57.141 +        {
  57.142 +            y = next_range(r, x);
  57.143 +            if ( (y == NULL) || (y->e > x->e) )
  57.144 +                break;
  57.145 +            destroy_range(y);
  57.146 +        }
  57.147 +    }
  57.148 +
  57.149 +    y = next_range(r, x);
  57.150 +    if ( (y != NULL) && ((x->e + 1) == y->s) )
  57.151 +    {
  57.152 +        x->e = y->e;
  57.153 +        destroy_range(y);
  57.154 +    }
  57.155 +
  57.156 + out:
  57.157 +    spin_unlock(&r->lock);
  57.158 +    return rc;
  57.159 +}
  57.160 +
  57.161 +int rangeset_remove_range(
  57.162 +    struct rangeset *r, unsigned long s, unsigned long e)
  57.163 +{
  57.164 +    struct range *x, *y, *t;
  57.165 +    int rc = 0;
  57.166 +
  57.167 +    spin_lock(&r->lock);
  57.168 +
  57.169 +    x = find_range(r, s);
  57.170 +    y = find_range(r, e);
  57.171 +
  57.172 +    if ( x == y )
  57.173 +    {
  57.174 +        if ( (x == NULL) || (x->e < s) )
  57.175 +            goto out;
  57.176 +
  57.177 +        if ( (x->s < s) && (x->e > e) )
  57.178 +        {
  57.179 +            y = xmalloc(struct range);
  57.180 +            if ( y == NULL )
  57.181 +            {
  57.182 +                rc = -ENOMEM;
  57.183 +                goto out;
  57.184 +            }
  57.185 +
  57.186 +            y->s = e + 1;
  57.187 +            y->e = x->e;
  57.188 +            x->e = s - 1;
  57.189 +
  57.190 +            insert_range(r, x, y);
  57.191 +        }
  57.192 +        else if ( (x->s == s) && (x->e <= e) )
  57.193 +            destroy_range(x);
  57.194 +        else if ( x->s == s )
  57.195 +            x->s = e + 1;
  57.196 +        else if ( x->e <= e )
  57.197 +            x->e = s - 1;
  57.198 +    }
  57.199 +    else
  57.200 +    {
  57.201 +        if ( x == NULL )
  57.202 +            x = first_range(r);
  57.203 +
  57.204 +        if ( x->s < s )
  57.205 +        {
  57.206 +            x->e = s - 1;
  57.207 +            x = next_range(r, x);
  57.208 +        }
  57.209 +
  57.210 +        while ( x != y )
  57.211 +        {
  57.212 +            t = x;
  57.213 +            x = next_range(r, x);
  57.214 +            destroy_range(t);
  57.215 +        }
  57.216 +
  57.217 +        x->s = e + 1;
  57.218 +        if ( x->s > x->e )
  57.219 +            destroy_range(x);
  57.220 +    }
  57.221 +
  57.222 + out:
  57.223 +    spin_unlock(&r->lock);
  57.224 +    return rc;
  57.225 +}
  57.226 +
  57.227 +int rangeset_contains_range(
  57.228 +    struct rangeset *r, unsigned long s, unsigned long e)
  57.229 +{
  57.230 +    struct range *x;
  57.231 +    int contains;
  57.232 +
  57.233 +    spin_lock(&r->lock);
  57.234 +    x = find_range(r, s);
  57.235 +    contains = (x && (x->e >= e));
  57.236 +    spin_unlock(&r->lock);
  57.237 +
  57.238 +    return contains;
  57.239 +}
  57.240 +
  57.241 +int rangeset_add_singleton(
  57.242 +    struct rangeset *r, unsigned long s)
  57.243 +{
  57.244 +    return rangeset_add_range(r, s, s);
  57.245 +}
  57.246 +
  57.247 +int rangeset_remove_singleton(
  57.248 +    struct rangeset *r, unsigned long s)
  57.249 +{
  57.250 +    return rangeset_remove_range(r, s, s);
  57.251 +}
  57.252 +
  57.253 +int rangeset_contains_singleton(
  57.254 +    struct rangeset *r, unsigned long s)
  57.255 +{
  57.256 +    return rangeset_contains_range(r, s, s);
  57.257 +}
  57.258 +
  57.259 +int rangeset_is_empty(
  57.260 +    struct rangeset *r)
  57.261 +{
  57.262 +    return list_empty(&r->range_list);
  57.263 +}
  57.264 +
  57.265 +struct rangeset *rangeset_new(
  57.266 +    struct domain *d, char *name, unsigned int flags)
  57.267 +{
  57.268 +    struct rangeset *r;
  57.269 +
  57.270 +    r = xmalloc(struct rangeset);
  57.271 +    if ( r == NULL )
  57.272 +        return NULL;
  57.273 +
  57.274 +    spin_lock_init(&r->lock);
  57.275 +    INIT_LIST_HEAD(&r->range_list);
  57.276 +
  57.277 +    BUG_ON(flags & ~RANGESETF_prettyprint_hex);
  57.278 +    r->flags = flags;
  57.279 +
  57.280 +    if ( name != NULL )
  57.281 +    {
  57.282 +        strncpy(r->name, name, sizeof(r->name));
  57.283 +        r->name[sizeof(r->name)-1] = '\0';
  57.284 +    }
  57.285 +    else
  57.286 +    {
  57.287 +        sprintf(r->name, "(no name)");
  57.288 +    }
  57.289 +
  57.290 +    if ( (r->domain = d) != NULL )
  57.291 +    {
  57.292 +        spin_lock(&d->rangesets_lock);
  57.293 +        list_add(&r->rangeset_list, &d->rangesets);
  57.294 +        spin_unlock(&d->rangesets_lock);
  57.295 +    }
  57.296 +
  57.297 +    return r;
  57.298 +}
  57.299 +
  57.300 +void rangeset_destroy(
  57.301 +    struct rangeset *r)
  57.302 +{
  57.303 +    struct range *x;
  57.304 +
  57.305 +    if ( r == NULL )
  57.306 +        return;
  57.307 +
  57.308 +    if ( r->domain != NULL )
  57.309 +    {
  57.310 +        spin_lock(&r->domain->rangesets_lock);
  57.311 +        list_del(&r->rangeset_list);
  57.312 +        spin_unlock(&r->domain->rangesets_lock);
  57.313 +    }
  57.314 +
  57.315 +    while ( (x = first_range(r)) != NULL )
  57.316 +        destroy_range(x);
  57.317 +
  57.318 +    xfree(r);
  57.319 +}
  57.320 +
  57.321 +void rangeset_domain_initialise(
  57.322 +    struct domain *d)
  57.323 +{
  57.324 +    INIT_LIST_HEAD(&d->rangesets);
  57.325 +    spin_lock_init(&d->rangesets_lock);
  57.326 +}
  57.327 +
  57.328 +void rangeset_domain_destroy(
  57.329 +    struct domain *d)
  57.330 +{
  57.331 +    struct rangeset *r;
  57.332 +
  57.333 +    while ( !list_empty(&d->rangesets) )
  57.334 +    {
  57.335 +        r = list_entry(d->rangesets.next, struct rangeset, rangeset_list);
  57.336 +
  57.337 +        BUG_ON(r->domain != d);
  57.338 +        r->domain = NULL;
  57.339 +        list_del(&r->rangeset_list);
  57.340 +
  57.341 +        rangeset_destroy(r);
  57.342 +    }
  57.343 +}
  57.344 +
  57.345 +/*****************************
  57.346 + * Pretty-printing functions
  57.347 + */
  57.348 +
  57.349 +static void print_limit(struct rangeset *r, unsigned long s)
  57.350 +{
  57.351 +    printk((r->flags & RANGESETF_prettyprint_hex) ? "%lx" : "%lu", s);
  57.352 +}
  57.353 +
  57.354 +void rangeset_printk(
  57.355 +    struct rangeset *r)
  57.356 +{
  57.357 +    int nr_printed = 0;
  57.358 +    struct range *x;
  57.359 +
  57.360 +    spin_lock(&r->lock);
  57.361 +
  57.362 +    printk("%-10s {", r->name);
  57.363 +
  57.364 +    for ( x = first_range(r); x != NULL; x = next_range(r, x) )
  57.365 +    {
  57.366 +        if ( nr_printed++ )
  57.367 +            printk(",");
  57.368 +        printk(" ");
  57.369 +        print_limit(r, x->s);
  57.370 +        if ( x->s != x->e )
  57.371 +        {
  57.372 +            printk("-");
  57.373 +            print_limit(r, x->e);
  57.374 +        }
  57.375 +    }
  57.376 +
  57.377 +    printk(" }");
  57.378 +
  57.379 +    spin_unlock(&r->lock);
  57.380 +}
  57.381 +
  57.382 +void rangeset_domain_printk(
  57.383 +    struct domain *d)
  57.384 +{
  57.385 +    struct rangeset *r;
  57.386 +
  57.387 +    printk("Rangesets belonging to domain %u:\n", d->domain_id);
  57.388 +
  57.389 +    spin_lock(&d->rangesets_lock);
  57.390 +
  57.391 +    if ( list_empty(&d->rangesets) )
  57.392 +        printk("    None\n");
  57.393 +
  57.394 +    list_for_each_entry ( r, &d->rangesets, rangeset_list )
  57.395 +    {
  57.396 +        printk("    ");
  57.397 +        rangeset_printk(r);
  57.398 +        printk("\n");
  57.399 +    }
  57.400 +
  57.401 +    spin_unlock(&d->rangesets_lock);
  57.402 +}
    58.1 --- a/xen/drivers/char/ns16550.c	Tue Jan 03 08:59:00 2006 -0600
    58.2 +++ b/xen/drivers/char/ns16550.c	Tue Jan 03 10:19:20 2006 -0600
    58.3 @@ -13,6 +13,7 @@
    58.4  #include <xen/irq.h>
    58.5  #include <xen/sched.h>
    58.6  #include <xen/serial.h>
    58.7 +#include <xen/iocap.h>
    58.8  #include <asm/io.h>
    58.9  
   58.10  /*
   58.11 @@ -233,11 +234,11 @@ static void ns16550_init_postirq(struct 
   58.12  }
   58.13  
   58.14  #ifdef CONFIG_X86
   58.15 -#include <asm/physdev.h>
   58.16  static void ns16550_endboot(struct serial_port *port)
   58.17  {
   58.18      struct ns16550 *uart = port->uart;
   58.19 -    physdev_modify_ioport_access_range(dom0, 0, uart->io_base, 8);
   58.20 +    if ( ioports_deny_access(dom0, uart->io_base, uart->io_base + 7) != 0 )
   58.21 +        BUG();
   58.22  }
   58.23  #else
   58.24  #define ns16550_endboot NULL
    59.1 --- a/xen/include/asm-ia64/domain.h	Tue Jan 03 08:59:00 2006 -0600
    59.2 +++ b/xen/include/asm-ia64/domain.h	Tue Jan 03 10:19:20 2006 -0600
    59.3 @@ -10,7 +10,7 @@
    59.4  #include <asm/vmx_platform.h>
    59.5  #include <xen/list.h>
    59.6  
    59.7 -extern void arch_do_createdomain(struct vcpu *);
    59.8 +extern int arch_do_createdomain(struct vcpu *);
    59.9  
   59.10  extern void domain_relinquish_resources(struct domain *);
   59.11  
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/xen/include/asm-ia64/iocap.h	Tue Jan 03 10:19:20 2006 -0600
    60.3 @@ -0,0 +1,10 @@
    60.4 +/******************************************************************************
    60.5 + * iocap.h
    60.6 + * 
    60.7 + * Architecture-specific per-domain I/O capabilities.
    60.8 + */
    60.9 +
   60.10 +#ifndef __IA64_IOCAP_H__
   60.11 +#define __IA64_IOCAP_H__
   60.12 +
   60.13 +#endif /* __IA64_IOCAP_H__ */
    61.1 --- a/xen/include/asm-x86/current.h	Tue Jan 03 08:59:00 2006 -0600
    61.2 +++ b/xen/include/asm-x86/current.h	Tue Jan 03 10:19:20 2006 -0600
    61.3 @@ -49,7 +49,7 @@ static inline struct cpu_info *get_cpu_i
    61.4  #define reset_stack_and_jump(__fn)              \
    61.5      __asm__ __volatile__ (                      \
    61.6          "mov %0,%%"__OP"sp; jmp "STR(__fn)      \
    61.7 -        : : "r" (guest_cpu_user_regs()) )
    61.8 +        : : "r" (guest_cpu_user_regs()) : "memory" )
    61.9  
   61.10  #define schedule_tail(_ed) (((_ed)->arch.schedule_tail)(_ed))
   61.11  
    62.1 --- a/xen/include/asm-x86/domain.h	Tue Jan 03 08:59:00 2006 -0600
    62.2 +++ b/xen/include/asm-x86/domain.h	Tue Jan 03 10:19:20 2006 -0600
    62.3 @@ -24,8 +24,8 @@ struct arch_domain
    62.4      /* Writable pagetables. */
    62.5      struct ptwr_info ptwr[2];
    62.6  
    62.7 -    /* I/O-port access bitmap mask. */
    62.8 -    u8 *iobmp_mask;       /* Address of IO bitmap mask, or NULL.      */
    62.9 +    /* I/O-port admin-specified access capabilities. */
   62.10 +    struct rangeset *ioport_caps;
   62.11  
   62.12      /* Shadow mode status and controls. */
   62.13      struct shadow_ops *ops;
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/xen/include/asm-x86/iocap.h	Tue Jan 03 10:19:20 2006 -0600
    63.3 @@ -0,0 +1,20 @@
    63.4 +/******************************************************************************
    63.5 + * iocap.h
    63.6 + * 
    63.7 + * Architecture-specific per-domain I/O capabilities.
    63.8 + */
    63.9 +
   63.10 +#ifndef __X86_IOCAP_H__
   63.11 +#define __X86_IOCAP_H__
   63.12 +
   63.13 +#define ioports_permit_access(d, s, e)                  \
   63.14 +    rangeset_add_range((d)->arch.ioport_caps, s, e)
   63.15 +#define ioports_deny_access(d, s, e)                    \
   63.16 +    rangeset_remove_range((d)->arch.ioport_caps, s, e)
   63.17 +#define ioports_access_permitted(d, s, e)               \
   63.18 +    rangeset_contains_range((d)->arch.ioport_caps, s, e)
   63.19 +
   63.20 +#define cache_flush_permitted(d)                       \
   63.21 +    (!rangeset_is_empty((d)->iomem_caps))
   63.22 +
   63.23 +#endif /* __X86_IOCAP_H__ */
    64.1 --- a/xen/include/asm-x86/msr.h	Tue Jan 03 08:59:00 2006 -0600
    64.2 +++ b/xen/include/asm-x86/msr.h	Tue Jan 03 10:19:20 2006 -0600
    64.3 @@ -12,7 +12,7 @@
    64.4         __asm__ __volatile__("rdmsr" \
    64.5  			    : "=a" (a__), "=d" (b__) \
    64.6  			    : "c" (msr)); \
    64.7 -       val = a__ | (b__<<32); \
    64.8 +       val = a__ | ((u64)b__<<32); \
    64.9  } while(0); 
   64.10  
   64.11  #define wrmsr(msr,val1,val2) \
    65.1 --- a/xen/include/asm-x86/physdev.h	Tue Jan 03 08:59:00 2006 -0600
    65.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.3 @@ -1,17 +0,0 @@
    65.4 -/******************************************************************************
    65.5 - * physdev.h
    65.6 - */
    65.7 -
    65.8 -#ifndef __XEN_PHYSDEV_H__
    65.9 -#define __XEN_PHYSDEV_H__
   65.10 -
   65.11 -#include <public/physdev.h>
   65.12 -
   65.13 -void physdev_modify_ioport_access_range(
   65.14 -    struct domain *d, int enable, int port, int num );
   65.15 -void physdev_destroy_state(struct domain *d);
   65.16 -int domain_iomem_in_pfn(struct domain *p, unsigned long pfn);
   65.17 -long do_physdev_op(physdev_op_t *uop);
   65.18 -void physdev_init_dom0(struct domain *d);
   65.19 -
   65.20 -#endif /* __XEN_PHYSDEV_H__ */
    66.1 --- a/xen/include/asm-x86/x86_emulate.h	Tue Jan 03 08:59:00 2006 -0600
    66.2 +++ b/xen/include/asm-x86/x86_emulate.h	Tue Jan 03 10:19:20 2006 -0600
    66.3 @@ -141,6 +141,12 @@ x86_emulate_write_std(
    66.4  
    66.5  struct cpu_user_regs;
    66.6  
    66.7 +/* Current execution mode, passed to the emulator. */
    66.8 +#define X86EMUL_MODE_REAL     0
    66.9 +#define X86EMUL_MODE_PROT16   2
   66.10 +#define X86EMUL_MODE_PROT32   4
   66.11 +#define X86EMUL_MODE_PROT64   8
   66.12 +
   66.13  /*
   66.14   * x86_emulate_memop: Emulate an instruction that faulted attempting to
   66.15   *                    read/write a 'special' memory area.
   66.16 @@ -149,6 +155,8 @@ struct cpu_user_regs;
   66.17   *  @ops:  Interface to access special memory.
   66.18   *  @mode: Current execution mode, represented by the default size of memory
   66.19   *         addresses, in bytes. Valid values are 2, 4 and 8 (x86/64 only).
   66.20 + *         Alternatively use the appropriate X86EMUL_MODE value (which also
   66.21 + *         includes a value for emulating real mode).
   66.22   */
   66.23  extern int
   66.24  x86_emulate_memop(
    67.1 --- a/xen/include/public/dom0_ops.h	Tue Jan 03 08:59:00 2006 -0600
    67.2 +++ b/xen/include/public/dom0_ops.h	Tue Jan 03 10:19:20 2006 -0600
    67.3 @@ -410,6 +410,21 @@ typedef struct {
    67.4      uint8_t enable;
    67.5  } dom0_setdebugging_t;
    67.6  
    67.7 +#define DOM0_IRQ_PERMISSION 46
    67.8 +typedef struct {
    67.9 +    domid_t domain;          /* domain to be affected */
   67.10 +    uint8_t pirq;
   67.11 +    uint8_t allow_access;    /* flag to specify enable/disable of IRQ access */
   67.12 +} dom0_irq_permission_t;
   67.13 +
   67.14 +#define DOM0_IOMEM_PERMISSION 47
   67.15 +typedef struct {
   67.16 +    domid_t  domain;          /* domain to be affected */
   67.17 +    unsigned long first_pfn;  /* first page (physical page number) in range */
   67.18 +    unsigned long nr_pfns;    /* number of pages in range (>0) */
   67.19 +    uint8_t allow_access;     /* allow (!0) or deny (0) access to range? */
   67.20 +} dom0_iomem_permission_t;
   67.21 + 
   67.22  typedef struct {
   67.23      uint32_t cmd;
   67.24      uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
   67.25 @@ -448,6 +463,8 @@ typedef struct {
   67.26          dom0_max_vcpus_t         max_vcpus;
   67.27          dom0_setdomainhandle_t   setdomainhandle;        
   67.28          dom0_setdebugging_t      setdebugging;
   67.29 +        dom0_irq_permission_t    irq_permission;
   67.30 +        dom0_iomem_permission_t  iomem_permission;
   67.31          uint8_t                  pad[128];
   67.32      } u;
   67.33  } dom0_op_t;
    68.1 --- a/xen/include/xen/compiler.h	Tue Jan 03 08:59:00 2006 -0600
    68.2 +++ b/xen/include/xen/compiler.h	Tue Jan 03 10:19:20 2006 -0600
    68.3 @@ -19,4 +19,10 @@
    68.4  #define __attribute_used__ __attribute__((__unused__))
    68.5  #endif
    68.6  
    68.7 +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
    68.8 +#define __must_check __attribute__((warn_unused_result))
    68.9 +#else
   68.10 +#define __must_check
   68.11 +#endif
   68.12 +
   68.13  #endif /* __LINUX_COMPILER_H */
    69.1 --- a/xen/include/xen/domain.h	Tue Jan 03 08:59:00 2006 -0600
    69.2 +++ b/xen/include/xen/domain.h	Tue Jan 03 10:19:20 2006 -0600
    69.3 @@ -13,9 +13,9 @@ struct vcpu *alloc_vcpu_struct(struct do
    69.4  
    69.5  extern void free_vcpu_struct(struct vcpu *v);
    69.6  
    69.7 -extern void arch_do_createdomain(struct vcpu *v);
    69.8 +extern int arch_do_createdomain(struct vcpu *v);
    69.9  
   69.10 -extern int  arch_set_info_guest(
   69.11 +extern int arch_set_info_guest(
   69.12      struct vcpu *v, struct vcpu_guest_context *c);
   69.13  
   69.14  extern void vcpu_migrate_cpu(struct vcpu *v, int newcpu);
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/xen/include/xen/iocap.h	Tue Jan 03 10:19:20 2006 -0600
    70.3 @@ -0,0 +1,34 @@
    70.4 +/******************************************************************************
    70.5 + * iocap.h
    70.6 + * 
    70.7 + * Per-domain I/O capabilities.
    70.8 + */
    70.9 +
   70.10 +#ifndef __XEN_IOCAP_H__
   70.11 +#define __XEN_IOCAP_H__
   70.12 +
   70.13 +#include <xen/rangeset.h>
   70.14 +#include <asm/iocap.h>
   70.15 +
   70.16 +#define iomem_permit_access(d, s, e)                    \
   70.17 +    rangeset_add_range((d)->iomem_caps, s, e)
   70.18 +#define iomem_deny_access(d, s, e)                      \
   70.19 +    rangeset_remove_range((d)->iomem_caps, s, e)
   70.20 +#define iomem_access_permitted(d, s, e)                 \
   70.21 +    rangeset_contains_range((d)->iomem_caps, s, e)
   70.22 +
   70.23 +#define irq_permit_access(d, i)                         \
   70.24 +    rangeset_add_singleton((d)->irq_caps, i)
   70.25 +#define irq_deny_access(d, i)                           \
   70.26 +    rangeset_remove_singleton((d)->irq_caps, i)
   70.27 +#define irqs_permit_access(d, s, e)                     \
   70.28 +    rangeset_add_range((d)->irq_caps, s, e)
   70.29 +#define irqs_deny_access(d, s, e)                       \
   70.30 +    rangeset_remove_range((d)->irq_caps, s, e)
   70.31 +#define irq_access_permitted(d, i)                      \
   70.32 +    rangeset_contains_singleton((d)->irq_caps, i)
   70.33 +
   70.34 +#define multipage_allocation_permitted(d)               \
   70.35 +    (!rangeset_is_empty((d)->iomem_caps))
   70.36 +
   70.37 +#endif /* __XEN_IOCAP_H__ */
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/xen/include/xen/rangeset.h	Tue Jan 03 10:19:20 2006 -0600
    71.3 @@ -0,0 +1,71 @@
    71.4 +/******************************************************************************
    71.5 + * rangeset.h
    71.6 + * 
    71.7 + * Creation, maintenance and automatic destruction of per-domain sets of
    71.8 + * numeric ranges.
    71.9 + * 
   71.10 + * Copyright (c) 2005, K A Fraser
   71.11 + */
   71.12 +
   71.13 +#ifndef __XEN_RANGESET_H__
   71.14 +#define __XEN_RANGESET_H__
   71.15 +
   71.16 +struct domain;
   71.17 +struct rangeset;
   71.18 +
   71.19 +/*
   71.20 + * Initialise/destroy per-domain rangeset information.
   71.21 + * 
   71.22 + * It is invalid to create or destroy a rangeset belonging to a domain @d
   71.23 + * before rangeset_domain_initialise(d) returns or after calling
   71.24 + * rangeset_domain_destroy(d).
   71.25 + */
   71.26 +void rangeset_domain_initialise(
   71.27 +    struct domain *d);
   71.28 +void rangeset_domain_destroy(
   71.29 +    struct domain *d);
   71.30 +
   71.31 +/*
   71.32 + * Create/destroy a rangeset. Optionally attach to specified domain @d for
   71.33 + * auto-destruction when the domain dies. A name may be specified, for use
   71.34 + * in debug pretty-printing, and various RANGESETF flags (defined below).
   71.35 + * 
   71.36 + * It is invalid to perform any operation on a rangeset @r after calling
   71.37 + * rangeset_destroy(r).
   71.38 + */
   71.39 +struct rangeset *rangeset_new(
   71.40 +    struct domain *d, char *name, unsigned int flags);
   71.41 +void rangeset_destroy(
   71.42 +    struct rangeset *r);
   71.43 +
   71.44 +/* Flags for passing to rangeset_new(). */
   71.45 + /* Pretty-print range limits in hexadecimal. */
   71.46 +#define _RANGESETF_prettyprint_hex 0
   71.47 +#define RANGESETF_prettyprint_hex  (1U << _RANGESETF_prettyprint_hex)
   71.48 +
   71.49 +int __must_check rangeset_is_empty(
   71.50 +    struct rangeset *r);
   71.51 +
   71.52 +/* Add/remove/query a numeric range. */
   71.53 +int __must_check rangeset_add_range(
   71.54 +    struct rangeset *r, unsigned long s, unsigned long e);
   71.55 +int __must_check rangeset_remove_range(
   71.56 +    struct rangeset *r, unsigned long s, unsigned long e);
   71.57 +int __must_check rangeset_contains_range(
   71.58 +    struct rangeset *r, unsigned long s, unsigned long e);
   71.59 +
   71.60 +/* Add/remove/query a single number. */
   71.61 +int __must_check rangeset_add_singleton(
   71.62 +    struct rangeset *r, unsigned long s);
   71.63 +int __must_check rangeset_remove_singleton(
   71.64 +    struct rangeset *r, unsigned long s);
   71.65 +int __must_check rangeset_contains_singleton(
   71.66 +    struct rangeset *r, unsigned long s);
   71.67 +
   71.68 +/* Rangeset pretty printing. */
   71.69 +void rangeset_printk(
   71.70 +    struct rangeset *r);
   71.71 +void rangeset_domain_printk(
   71.72 +    struct domain *d);
   71.73 +
   71.74 +#endif /* __XEN_RANGESET_H__ */
    72.1 --- a/xen/include/xen/sched.h	Tue Jan 03 08:59:00 2006 -0600
    72.2 +++ b/xen/include/xen/sched.h	Tue Jan 03 10:19:20 2006 -0600
    72.3 @@ -11,6 +11,7 @@
    72.4  #include <xen/time.h>
    72.5  #include <xen/ac_timer.h>
    72.6  #include <xen/grant_table.h>
    72.7 +#include <xen/rangeset.h>
    72.8  #include <asm/domain.h>
    72.9  
   72.10  extern unsigned long volatile jiffies;
   72.11 @@ -110,6 +111,9 @@ struct domain
   72.12      struct domain   *next_in_list;
   72.13      struct domain   *next_in_hashbucket;
   72.14  
   72.15 +    struct list_head rangesets;
   72.16 +    spinlock_t       rangesets_lock;
   72.17 +
   72.18      /* Event channel information. */
   72.19      struct evtchn   *evtchn[NR_EVTCHN_BUCKETS];
   72.20      spinlock_t       evtchn_lock;
   72.21 @@ -125,6 +129,10 @@ struct domain
   72.22      u16              pirq_to_evtchn[NR_PIRQS];
   72.23      u32              pirq_mask[NR_PIRQS/32];
   72.24  
   72.25 +    /* I/O capabilities (access to IRQs and memory-mapped I/O). */
   72.26 +    struct rangeset *iomem_caps;
   72.27 +    struct rangeset *irq_caps;
   72.28 +
   72.29      unsigned long    domain_flags;
   72.30      unsigned long    vm_assist;
   72.31  
   72.32 @@ -378,23 +386,20 @@ extern struct domain *domain_list;
   72.33   /* Is this domain privileged? */
   72.34  #define _DOMF_privileged       1
   72.35  #define DOMF_privileged        (1UL<<_DOMF_privileged)
   72.36 - /* May this domain do IO to physical devices? */
   72.37 -#define _DOMF_physdev_access   2
   72.38 -#define DOMF_physdev_access    (1UL<<_DOMF_physdev_access)
   72.39   /* Guest shut itself down for some reason. */
   72.40 -#define _DOMF_shutdown         3
   72.41 +#define _DOMF_shutdown         2
   72.42  #define DOMF_shutdown          (1UL<<_DOMF_shutdown)
   72.43   /* Guest is in process of shutting itself down (becomes DOMF_shutdown). */
   72.44 -#define _DOMF_shuttingdown     4
   72.45 +#define _DOMF_shuttingdown     3
   72.46  #define DOMF_shuttingdown      (1UL<<_DOMF_shuttingdown)
   72.47   /* Death rattle. */
   72.48 -#define _DOMF_dying            5
   72.49 +#define _DOMF_dying            4
   72.50  #define DOMF_dying             (1UL<<_DOMF_dying)
   72.51   /* Domain is paused by controller software. */
   72.52 -#define _DOMF_ctrl_pause       6
   72.53 +#define _DOMF_ctrl_pause       5
   72.54  #define DOMF_ctrl_pause        (1UL<<_DOMF_ctrl_pause)
   72.55   /* Domain is being debugged by controller software. */
   72.56 -#define _DOMF_debugging        7
   72.57 +#define _DOMF_debugging        6
   72.58  #define DOMF_debugging         (1UL<<_DOMF_debugging)
   72.59  
   72.60  
   72.61 @@ -422,8 +427,6 @@ static inline void vcpu_unblock(struct v
   72.62  
   72.63  #define IS_PRIV(_d)                                         \
   72.64      (test_bit(_DOMF_privileged, &(_d)->domain_flags))
   72.65 -#define IS_CAPABLE_PHYSDEV(_d)                              \
   72.66 -    (test_bit(_DOMF_physdev_access, &(_d)->domain_flags))
   72.67  
   72.68  #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
   72.69