direct-io.hg

changeset 10622:4b51d081378d

merge with xen-unstable.hg
author awilliam@xenbuild.aw
date Wed Jun 28 07:52:21 2006 -0600 (2006-06-28)
parents c4b68afe97d3 224597479812
children 856caf975abd 75b23b6a7cb7
files tools/libxc/xc_aout9.h tools/libxc/xc_ia64_stubs.c tools/libxc/xc_linux_build.c tools/libxc/xc_load_aout9.c
line diff
     1.1 --- a/Makefile	Wed Jun 28 07:51:52 2006 -0600
     1.2 +++ b/Makefile	Wed Jun 28 07:52:21 2006 -0600
     1.3 @@ -123,7 +123,10 @@ clean::
     1.4  
     1.5  # clean, but blow away kernel build tree plus tarballs
     1.6  .PHONY: distclean
     1.7 -distclean: clean
     1.8 +distclean:
     1.9 +	$(MAKE) -C xen distclean
    1.10 +	$(MAKE) -C tools distclean
    1.11 +	$(MAKE) -C docs distclean
    1.12  	rm -rf dist patches/tmp
    1.13  	for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done
    1.14  	for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done
     2.1 --- a/docs/Makefile	Wed Jun 28 07:51:52 2006 -0600
     2.2 +++ b/docs/Makefile	Wed Jun 28 07:52:21 2006 -0600
     2.3 @@ -80,6 +80,9 @@ clean:
     2.4  	rm -rf man5
     2.5  	rm -rf man1
     2.6  
     2.7 +.PHONY: distclean
     2.8 +distclean: clean
     2.9 +
    2.10  .PHONY: install
    2.11  install: all
    2.12  	rm -rf $(DESTDIR)$(pkgdocdir)
     3.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Jun 28 07:51:52 2006 -0600
     3.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c	Wed Jun 28 07:52:21 2006 -0600
     3.3 @@ -264,7 +264,7 @@ static void contiguous_bitmap_clear(
     3.4  }
     3.5  
     3.6  /* Protected by balloon_lock. */
     3.7 -#define MAX_CONTIG_ORDER 7
     3.8 +#define MAX_CONTIG_ORDER 9 /* 2MB */
     3.9  static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
    3.10  
    3.11  /* Ensure multi-page extents are contiguous in machine memory. */
     4.1 --- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c	Wed Jun 28 07:51:52 2006 -0600
     4.2 +++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c	Wed Jun 28 07:52:21 2006 -0600
     4.3 @@ -28,6 +28,7 @@
     4.4  
     4.5  #include <xen/interface/xen.h>
     4.6  #include <xen/interface/xenoprof.h>
     4.7 +#include <../../../drivers/oprofile/cpu_buffer.h>
     4.8  
     4.9  static int xenoprof_start(void);
    4.10  static void xenoprof_stop(void);
    4.11 @@ -50,6 +51,11 @@ int ovf_irq[NR_CPUS];
    4.12  /* cpu model type string - copied from Xen memory space on XENOPROF_init command */
    4.13  char cpu_type[XENOPROF_CPU_TYPE_SIZE];
    4.14  
    4.15 +/* Passive sample buffers shared with Xen */
    4.16 +xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS];
    4.17 +/* Passive shared buffer area */
    4.18 +char *p_shared_buffer[MAX_OPROF_DOMAINS];
    4.19 +
    4.20  #ifdef CONFIG_PM
    4.21  
    4.22  static int xenoprof_suspend(struct sys_device * dev, pm_message_t state)
    4.23 @@ -102,16 +108,14 @@ static void __exit exit_driverfs(void)
    4.24  #endif /* CONFIG_PM */
    4.25  
    4.26  unsigned long long oprofile_samples = 0;
    4.27 +unsigned long long p_oprofile_samples = 0;
    4.28  
    4.29 -static irqreturn_t 
    4.30 -xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
    4.31 +unsigned int pdomains;
    4.32 +struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS];
    4.33 +
    4.34 +static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive)
    4.35  {
    4.36  	int head, tail, size;
    4.37 -	struct xenoprof_buf * buf;
    4.38 -	int cpu;
    4.39 -
    4.40 -	cpu = smp_processor_id();
    4.41 -	buf = xenoprof_buf[cpu];
    4.42  
    4.43  	head = buf->event_head;
    4.44  	tail = buf->event_tail;
    4.45 @@ -122,7 +126,10 @@ xenoprof_ovf_interrupt(int irq, void * d
    4.46  			oprofile_add_pc(buf->event_log[tail].eip,
    4.47  					buf->event_log[tail].mode,
    4.48  					buf->event_log[tail].event);
    4.49 -			oprofile_samples++;
    4.50 +			if (!is_passive)
    4.51 +				oprofile_samples++;
    4.52 +			else
    4.53 +				p_oprofile_samples++;
    4.54  			tail++;
    4.55  		}
    4.56  		tail = 0;
    4.57 @@ -131,11 +138,47 @@ xenoprof_ovf_interrupt(int irq, void * d
    4.58  		oprofile_add_pc(buf->event_log[tail].eip,
    4.59  				buf->event_log[tail].mode,
    4.60  				buf->event_log[tail].event);
    4.61 -		oprofile_samples++;
    4.62 +		if (!is_passive)
    4.63 +			oprofile_samples++;
    4.64 +		else
    4.65 +			p_oprofile_samples++;
    4.66  		tail++;
    4.67  	}
    4.68  
    4.69  	buf->event_tail = tail;
    4.70 +}
    4.71 +
    4.72 +static void xenoprof_handle_passive(void)
    4.73 +{
    4.74 +	int i, j;
    4.75 +
    4.76 +	for (i = 0; i < pdomains; i++)
    4.77 +		for (j = 0; j < passive_domains[i].nbuf; j++) {
    4.78 +			xenoprof_buf_t *buf = p_xenoprof_buf[i][j];
    4.79 +			if (buf->event_head == buf->event_tail)
    4.80 +				continue;
    4.81 +                        oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_START, passive_domains[i].domain_id);
    4.82 +			xenoprof_add_pc(buf, 1);
    4.83 +                        oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_STOP, passive_domains[i].domain_id);
    4.84 +		}			
    4.85 +}
    4.86 +
    4.87 +static irqreturn_t 
    4.88 +xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
    4.89 +{
    4.90 +	struct xenoprof_buf * buf;
    4.91 +	int cpu;
    4.92 +	static unsigned long flag;
    4.93 +
    4.94 +	cpu = smp_processor_id();
    4.95 +	buf = xenoprof_buf[cpu];
    4.96 +
    4.97 +	xenoprof_add_pc(buf, 0);
    4.98 +
    4.99 +	if (is_primary && !test_and_set_bit(0, &flag)) {
   4.100 +		xenoprof_handle_passive();
   4.101 +		clear_bit(0, &flag);
   4.102 +	}
   4.103  
   4.104  	return IRQ_HANDLED;
   4.105  }
   4.106 @@ -312,6 +355,63 @@ out:
   4.107  	return ret;
   4.108  }
   4.109  
   4.110 +static int xenoprof_set_passive(int * p_domains,
   4.111 +                                unsigned int pdoms)
   4.112 +{
   4.113 +	int ret;
   4.114 +	int i, j;
   4.115 +	int vm_size;
   4.116 +	int npages;
   4.117 +	struct xenoprof_buf *buf;
   4.118 +	pgprot_t prot = __pgprot(_KERNPG_TABLE);
   4.119 +
   4.120 +	if (!is_primary)
   4.121 +        	return 0;
   4.122 +
   4.123 +	if (pdoms > MAX_OPROF_DOMAINS)
   4.124 +		return -E2BIG;
   4.125 +
   4.126 +	ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL);
   4.127 +	if (ret)
   4.128 +		return ret;
   4.129 +
   4.130 +	for (i = 0; i < pdoms; i++) {
   4.131 +		passive_domains[i].domain_id = p_domains[i];
   4.132 +		passive_domains[i].max_samples = 2048;
   4.133 +		ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, &passive_domains[i]);
   4.134 +		if (ret)
   4.135 +			return ret;
   4.136 +
   4.137 +		npages = (passive_domains[i].bufsize * passive_domains[i].nbuf - 1) / PAGE_SIZE + 1;
   4.138 +		vm_size = npages * PAGE_SIZE;
   4.139 +
   4.140 +		p_shared_buffer[i] = (char *)vm_map_xen_pages(passive_domains[i].buf_maddr,
   4.141 +							      vm_size, prot);
   4.142 +		if (!p_shared_buffer[i]) {
   4.143 +			ret = -ENOMEM;
   4.144 +			goto out;
   4.145 +		}
   4.146 +
   4.147 +		for (j = 0; j < passive_domains[i].nbuf; j++) {
   4.148 +			buf = (struct xenoprof_buf *)
   4.149 +				&p_shared_buffer[i][j * passive_domains[i].bufsize];
   4.150 +			BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
   4.151 +			p_xenoprof_buf[i][buf->vcpu_id] = buf;
   4.152 +		}
   4.153 +
   4.154 +	}
   4.155 +
   4.156 +	pdomains = pdoms;
   4.157 +	return 0;
   4.158 +
   4.159 +out:
   4.160 +	for (j = 0; j < i; j++) {
   4.161 +		vunmap(p_shared_buffer[j]);
   4.162 +		p_shared_buffer[j] = NULL;
   4.163 +	}
   4.164 +
   4.165 + 	return ret;
   4.166 +}
   4.167  
   4.168  struct op_counter_config counter_config[OP_MAX_COUNTER];
   4.169  
   4.170 @@ -346,6 +446,7 @@ static int xenoprof_create_files(struct 
   4.171  struct oprofile_operations xenoprof_ops = {
   4.172  	.create_files 	= xenoprof_create_files,
   4.173  	.set_active	= xenoprof_set_active,
   4.174 +	.set_passive    = xenoprof_set_passive,
   4.175  	.setup 		= xenoprof_setup,
   4.176  	.shutdown	= xenoprof_shutdown,
   4.177  	.start		= xenoprof_start,
   4.178 @@ -420,6 +521,8 @@ int __init oprofile_arch_init(struct opr
   4.179  
   4.180  void __exit oprofile_arch_exit(void)
   4.181  {
   4.182 +	int i;
   4.183 +
   4.184  	if (using_xenoprof)
   4.185  		exit_driverfs();
   4.186  
   4.187 @@ -427,6 +530,13 @@ void __exit oprofile_arch_exit(void)
   4.188  		vunmap(shared_buffer);
   4.189  		shared_buffer = NULL;
   4.190  	}
   4.191 -	if (is_primary)
   4.192 +	if (is_primary) {
   4.193 +		for (i = 0; i < pdomains; i++)
   4.194 +			if (p_shared_buffer[i]) {
   4.195 +		                vunmap(p_shared_buffer[i]);
   4.196 +                		p_shared_buffer[i] = NULL;
   4.197 +			}
   4.198  		HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL);
   4.199 +        }
   4.200 +
   4.201  }
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Wed Jun 28 07:51:52 2006 -0600
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Wed Jun 28 07:52:21 2006 -0600
     5.3 @@ -172,7 +172,7 @@ static unsigned long current_target(void
     5.4  
     5.5  static int increase_reservation(unsigned long nr_pages)
     5.6  {
     5.7 -	unsigned long *frame_list, pfn, i, flags;
     5.8 +	unsigned long *frame_list, frame, pfn, i, flags;
     5.9  	struct page   *page;
    5.10  	long           rc;
    5.11  	struct xen_memory_reservation reservation = {
    5.12 @@ -185,8 +185,11 @@ static int increase_reservation(unsigned
    5.13  		nr_pages = PAGE_SIZE / sizeof(unsigned long);
    5.14  
    5.15  	frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
    5.16 -	if (frame_list == NULL)
    5.17 -		return -ENOMEM;
    5.18 +	if (frame_list == NULL) {
    5.19 +		frame_list = &frame;
    5.20 +		if (nr_pages > 1)
    5.21 +			nr_pages = 1;
    5.22 +	}
    5.23  
    5.24  	balloon_lock(flags);
    5.25  
    5.26 @@ -202,14 +205,17 @@ static int increase_reservation(unsigned
    5.27  	rc = HYPERVISOR_memory_op(
    5.28  		XENMEM_populate_physmap, &reservation);
    5.29  	if (rc < nr_pages) {
    5.30 -		int ret;
    5.31 -		/* We hit the Xen hard limit: reprobe. */
    5.32 -		set_xen_guest_handle(reservation.extent_start, frame_list);
    5.33 -		reservation.nr_extents   = rc;
    5.34 -		ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
    5.35 -				&reservation);
    5.36 -		BUG_ON(ret != rc);
    5.37 -		hard_limit = current_pages + rc - driver_pages;
    5.38 +		if (rc > 0) {
    5.39 +			int ret;
    5.40 +
    5.41 +			/* We hit the Xen hard limit: reprobe. */
    5.42 +			reservation.nr_extents = rc;
    5.43 +			ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
    5.44 +					&reservation);
    5.45 +			BUG_ON(ret != rc);
    5.46 +		}
    5.47 +		if (rc >= 0)
    5.48 +			hard_limit = current_pages + rc - driver_pages;
    5.49  		goto out;
    5.50  	}
    5.51  
    5.52 @@ -247,14 +253,15 @@ static int increase_reservation(unsigned
    5.53   out:
    5.54  	balloon_unlock(flags);
    5.55  
    5.56 -	free_page((unsigned long)frame_list);
    5.57 +	if (frame_list != &frame)
    5.58 +		free_page((unsigned long)frame_list);
    5.59  
    5.60  	return 0;
    5.61  }
    5.62  
    5.63  static int decrease_reservation(unsigned long nr_pages)
    5.64  {
    5.65 -	unsigned long *frame_list, pfn, i, flags;
    5.66 +	unsigned long *frame_list, frame, pfn, i, flags;
    5.67  	struct page   *page;
    5.68  	void          *v;
    5.69  	int            need_sleep = 0;
    5.70 @@ -269,8 +276,11 @@ static int decrease_reservation(unsigned
    5.71  		nr_pages = PAGE_SIZE / sizeof(unsigned long);
    5.72  
    5.73  	frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
    5.74 -	if (frame_list == NULL)
    5.75 -		return -ENOMEM;
    5.76 +	if (frame_list == NULL) {
    5.77 +		frame_list = &frame;
    5.78 +		if (nr_pages > 1)
    5.79 +			nr_pages = 1;
    5.80 +	}
    5.81  
    5.82  	for (i = 0; i < nr_pages; i++) {
    5.83  		if ((page = alloc_page(GFP_HIGHUSER)) == NULL) {
    5.84 @@ -321,7 +331,8 @@ static int decrease_reservation(unsigned
    5.85  
    5.86  	balloon_unlock(flags);
    5.87  
    5.88 -	free_page((unsigned long)frame_list);
    5.89 +	if (frame_list != &frame)
    5.90 +		free_page((unsigned long)frame_list);
    5.91  
    5.92  	return need_sleep;
    5.93  }
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Wed Jun 28 07:51:52 2006 -0600
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Wed Jun 28 07:52:21 2006 -0600
     6.3 @@ -95,6 +95,7 @@ typedef struct blkif_st {
     6.4  } blkif_t;
     6.5  
     6.6  blkif_t *blkif_alloc(domid_t domid);
     6.7 +void blkif_disconnect(blkif_t *blkif);
     6.8  void blkif_free(blkif_t *blkif);
     6.9  int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
    6.10  
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Wed Jun 28 07:51:52 2006 -0600
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Wed Jun 28 07:52:21 2006 -0600
     7.3 @@ -32,6 +32,7 @@
     7.4  
     7.5  #include "common.h"
     7.6  #include <xen/evtchn.h>
     7.7 +#include <linux/kthread.h>
     7.8  
     7.9  static kmem_cache_t *blkif_cachep;
    7.10  
    7.11 @@ -139,22 +140,33 @@ int blkif_map(blkif_t *blkif, unsigned l
    7.12  	return 0;
    7.13  }
    7.14  
    7.15 -void blkif_free(blkif_t *blkif)
    7.16 +void blkif_disconnect(blkif_t *blkif)
    7.17  {
    7.18 +	if (blkif->xenblkd) {
    7.19 +		kthread_stop(blkif->xenblkd);
    7.20 +		blkif->xenblkd = NULL;
    7.21 +	}
    7.22 +
    7.23  	atomic_dec(&blkif->refcnt);
    7.24  	wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
    7.25 +	atomic_inc(&blkif->refcnt);
    7.26  
    7.27 -	/* Already disconnected? */
    7.28 -	if (blkif->irq)
    7.29 +	if (blkif->irq) {
    7.30  		unbind_from_irqhandler(blkif->irq, blkif);
    7.31 -
    7.32 -	vbd_free(&blkif->vbd);
    7.33 +		blkif->irq = 0;
    7.34 +	}
    7.35  
    7.36  	if (blkif->blk_ring.sring) {
    7.37  		unmap_frontend_page(blkif);
    7.38  		free_vm_area(blkif->blk_ring_area);
    7.39 +		blkif->blk_ring.sring = NULL;
    7.40  	}
    7.41 +}
    7.42  
    7.43 +void blkif_free(blkif_t *blkif)
    7.44 +{
    7.45 +	if (!atomic_dec_and_test(&blkif->refcnt))
    7.46 +		BUG();
    7.47  	kmem_cache_free(blkif_cachep, blkif);
    7.48  }
    7.49  
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Wed Jun 28 07:51:52 2006 -0600
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Wed Jun 28 07:52:21 2006 -0600
     8.3 @@ -43,7 +43,6 @@ static int connect_ring(struct backend_i
     8.4  static void backend_changed(struct xenbus_watch *, const char **,
     8.5  			    unsigned int);
     8.6  
     8.7 -
     8.8  static void update_blkif_status(blkif_t *blkif)
     8.9  { 
    8.10  	int err;
    8.11 @@ -73,6 +72,70 @@ static void update_blkif_status(blkif_t 
    8.12  }
    8.13  
    8.14  
    8.15 +/****************************************************************
    8.16 + *  sysfs interface for VBD I/O requests
    8.17 + */
    8.18 +
    8.19 +#ifdef CONFIG_SYSFS
    8.20 +
    8.21 +#define VBD_SHOW(name, format, args...)					\
    8.22 +	static ssize_t show_##name(struct device *_dev,			\
    8.23 +				   struct device_attribute *attr,	\
    8.24 +				   char *buf)				\
    8.25 +	{								\
    8.26 +		struct xenbus_device *dev = to_xenbus_device(_dev);	\
    8.27 +		struct backend_info *be = dev->dev.driver_data;		\
    8.28 +									\
    8.29 +		return sprintf(buf, format, ##args);			\
    8.30 +	}								\
    8.31 +	DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
    8.32 +
    8.33 +VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
    8.34 +VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
    8.35 +VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
    8.36 +
    8.37 +static struct attribute *vbdstat_attrs[] = {
    8.38 +	&dev_attr_oo_req.attr,
    8.39 +	&dev_attr_rd_req.attr,
    8.40 +	&dev_attr_wr_req.attr,
    8.41 +	NULL
    8.42 +};
    8.43 +
    8.44 +static struct attribute_group vbdstat_group = {
    8.45 +	.name = "statistics",
    8.46 +	.attrs = vbdstat_attrs,
    8.47 +};
    8.48 +
    8.49 +int xenvbd_sysfs_addif(struct xenbus_device *dev)
    8.50 +{
    8.51 +	int error = 0;
    8.52 +	
    8.53 +	error = sysfs_create_group(&dev->dev.kobj,
    8.54 +				   &vbdstat_group);
    8.55 +	if (error)
    8.56 +		goto fail;
    8.57 +	
    8.58 +	return 0;
    8.59 +	
    8.60 +fail:
    8.61 +	sysfs_remove_group(&dev->dev.kobj,
    8.62 +			   &vbdstat_group);
    8.63 +	return error;
    8.64 +}
    8.65 +
    8.66 +void xenvbd_sysfs_delif(struct xenbus_device *dev)
    8.67 +{
    8.68 +	sysfs_remove_group(&dev->dev.kobj,
    8.69 +			   &vbdstat_group);
    8.70 +}
    8.71 +
    8.72 +#else
    8.73 +
    8.74 +#define xenvbd_sysfs_addif(dev) (0)
    8.75 +#define xenvbd_sysfs_delif(dev) ((void)0)
    8.76 +
    8.77 +#endif /* CONFIG_SYSFS */
    8.78 +
    8.79  static ssize_t show_physical_device(struct device *_dev,
    8.80  				    struct device_attribute *attr, char *buf)
    8.81  {
    8.82 @@ -105,15 +168,17 @@ static int blkback_remove(struct xenbus_
    8.83  		kfree(be->backend_watch.node);
    8.84  		be->backend_watch.node = NULL;
    8.85  	}
    8.86 +
    8.87  	if (be->blkif) {
    8.88 -		if (be->blkif->xenblkd)
    8.89 -			kthread_stop(be->blkif->xenblkd);
    8.90 +		blkif_disconnect(be->blkif);
    8.91 +		vbd_free(&be->blkif->vbd);
    8.92  		blkif_free(be->blkif);
    8.93  		be->blkif = NULL;
    8.94  	}
    8.95  
    8.96  	device_remove_file(&dev->dev, &dev_attr_physical_device);
    8.97  	device_remove_file(&dev->dev, &dev_attr_mode);
    8.98 +	xenvbd_sysfs_delif(dev);
    8.99  
   8.100  	kfree(be);
   8.101  	dev->dev.driver_data = NULL;
   8.102 @@ -236,6 +301,7 @@ static void backend_changed(struct xenbu
   8.103  
   8.104  		device_create_file(&dev->dev, &dev_attr_physical_device);
   8.105  		device_create_file(&dev->dev, &dev_attr_mode);
   8.106 +		xenvbd_sysfs_addif(dev);
   8.107  
   8.108  		/* We're potentially connected now */
   8.109  		update_blkif_status(be->blkif); 
   8.110 @@ -273,6 +339,7 @@ static void frontend_changed(struct xenb
   8.111  		break;
   8.112  
   8.113  	case XenbusStateClosing:
   8.114 +		blkif_disconnect(be->blkif);
   8.115  		xenbus_switch_state(dev, XenbusStateClosing);
   8.116  		break;
   8.117  
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c	Wed Jun 28 07:51:52 2006 -0600
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c	Wed Jun 28 07:52:21 2006 -0600
     9.3 @@ -58,15 +58,17 @@ HYPERVISOR_ATTR_RO(minor);
     9.4  
     9.5  static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer)
     9.6  {
     9.7 -	int ret;
     9.8 -	char *extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
     9.9 +	int ret = -ENOMEM;
    9.10 +	char *extra;
    9.11 +
    9.12 +	extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
    9.13  	if (extra) {
    9.14  		ret = HYPERVISOR_xen_version(XENVER_extraversion, extra);
    9.15  		if (!ret)
    9.16 -			return sprintf(buffer, "%s\n", extra);
    9.17 +			ret = sprintf(buffer, "%s\n", extra);
    9.18  		kfree(extra);
    9.19 -	} else
    9.20 -		ret = -ENOMEM;
    9.21 +	}
    9.22 +
    9.23  	return ret;
    9.24  }
    9.25  
    9.26 @@ -86,7 +88,8 @@ static struct attribute_group version_gr
    9.27  
    9.28  static int __init xen_sysfs_version_init(void)
    9.29  {
    9.30 -	return sysfs_create_group(&hypervisor_subsys.kset.kobj, &version_group);
    9.31 +	return sysfs_create_group(&hypervisor_subsys.kset.kobj,
    9.32 +				  &version_group);
    9.33  }
    9.34  
    9.35  static void xen_sysfs_version_destroy(void)
    9.36 @@ -98,16 +101,16 @@ static void xen_sysfs_version_destroy(vo
    9.37  
    9.38  static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
    9.39  {
    9.40 -	int ret;
    9.41 -	struct xen_compile_info *info =
    9.42 -	    kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
    9.43 +	int ret = -ENOMEM;
    9.44 +	struct xen_compile_info *info;
    9.45 +
    9.46 +	info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
    9.47  	if (info) {
    9.48  		ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
    9.49  		if (!ret)
    9.50  			ret = sprintf(buffer, "%s\n", info->compiler);
    9.51  		kfree(info);
    9.52 -	} else
    9.53 -		ret = -ENOMEM;
    9.54 +	}
    9.55  
    9.56  	return ret;
    9.57  }
    9.58 @@ -116,7 +119,7 @@ HYPERVISOR_ATTR_RO(compiler);
    9.59  
    9.60  static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer)
    9.61  {
    9.62 -	int ret;
    9.63 +	int ret = -ENOMEM;
    9.64  	struct xen_compile_info *info;
    9.65  
    9.66  	info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
    9.67 @@ -125,8 +128,8 @@ static ssize_t compiled_by_show(struct h
    9.68  		if (!ret)
    9.69  			ret = sprintf(buffer, "%s\n", info->compile_by);
    9.70  		kfree(info);
    9.71 -	} else
    9.72 -		ret = -ENOMEM;
    9.73 +	}
    9.74 +
    9.75  	return ret;
    9.76  }
    9.77  
    9.78 @@ -134,7 +137,7 @@ HYPERVISOR_ATTR_RO(compiled_by);
    9.79  
    9.80  static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer)
    9.81  {
    9.82 -	int ret;
    9.83 +	int ret = -ENOMEM;
    9.84  	struct xen_compile_info *info;
    9.85  
    9.86  	info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
    9.87 @@ -143,8 +146,8 @@ static ssize_t compile_date_show(struct 
    9.88  		if (!ret)
    9.89  			ret = sprintf(buffer, "%s\n", info->compile_date);
    9.90  		kfree(info);
    9.91 -	} else
    9.92 -		ret = -ENOMEM;
    9.93 +	}
    9.94 +
    9.95  	return ret;
    9.96  }
    9.97  
    9.98 @@ -178,15 +181,17 @@ static void xen_compilation_destroy(void
    9.99  
   9.100  static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer)
   9.101  {
   9.102 -	int ret;
   9.103 -	char *caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
   9.104 +	int ret = -ENOMEM;
   9.105 +	char *caps;
   9.106 +
   9.107 +	caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
   9.108  	if (caps) {
   9.109  		ret = HYPERVISOR_xen_version(XENVER_capabilities, caps);
   9.110  		if (!ret)
   9.111  			ret = sprintf(buffer, "%s\n", caps);
   9.112  		kfree(caps);
   9.113 -	} else
   9.114 -		ret = -ENOMEM;
   9.115 +	}
   9.116 +
   9.117  	return ret;
   9.118  }
   9.119  
   9.120 @@ -194,15 +199,17 @@ HYPERVISOR_ATTR_RO(capabilities);
   9.121  
   9.122  static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer)
   9.123  {
   9.124 -	int ret;
   9.125 -	char *cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
   9.126 +	int ret = -ENOMEM;
   9.127 +	char *cset;
   9.128 +
   9.129 +	cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
   9.130  	if (cset) {
   9.131  		ret = HYPERVISOR_xen_version(XENVER_changeset, cset);
   9.132  		if (!ret)
   9.133  			ret = sprintf(buffer, "%s\n", cset);
   9.134  		kfree(cset);
   9.135 -	} else
   9.136 -		ret = -ENOMEM;
   9.137 +	}
   9.138 +
   9.139  	return ret;
   9.140  }
   9.141  
   9.142 @@ -210,36 +217,51 @@ HYPERVISOR_ATTR_RO(changeset);
   9.143  
   9.144  static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer)
   9.145  {
   9.146 -	int ret;
   9.147 -	struct xen_platform_parameters *parms =
   9.148 -	    kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
   9.149 +	int ret = -ENOMEM;
   9.150 +	struct xen_platform_parameters *parms;
   9.151 +
   9.152 +	parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
   9.153  	if (parms) {
   9.154 -		ret = HYPERVISOR_xen_version(XENVER_platform_parameters, parms);
   9.155 +		ret = HYPERVISOR_xen_version(XENVER_platform_parameters,
   9.156 +					     parms);
   9.157  		if (!ret)
   9.158  			ret = sprintf(buffer, "%lx\n", parms->virt_start);
   9.159  		kfree(parms);
   9.160 -	} else
   9.161 -		ret = -ENOMEM;
   9.162 +	}
   9.163 +
   9.164  	return ret;
   9.165  }
   9.166  
   9.167  HYPERVISOR_ATTR_RO(virtual_start);
   9.168  
   9.169 +static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer)
   9.170 +{
   9.171 +	int ret;
   9.172 +
   9.173 +	ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL);
   9.174 +	if (ret > 0)
   9.175 +		ret = sprintf(buffer, "%x\n", ret);
   9.176 +
   9.177 +	return ret;
   9.178 +}
   9.179 +
   9.180 +HYPERVISOR_ATTR_RO(pagesize);
   9.181 +
   9.182  /* eventually there will be several more features to export */
   9.183  static ssize_t xen_feature_show(int index, char *buffer)
   9.184  {
   9.185 -	int ret;
   9.186 +	int ret = -ENOMEM;
   9.187 +	struct xen_feature_info *info;
   9.188  
   9.189 -	struct xen_feature_info *info =
   9.190 -	    kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
   9.191 +	info = kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
   9.192  	if (info) {
   9.193  		info->submap_idx = index;
   9.194  		ret = HYPERVISOR_xen_version(XENVER_get_features, info);
   9.195  		if (!ret)
   9.196  			ret = sprintf(buffer, "%d\n", info->submap);
   9.197  		kfree(info);
   9.198 -	} else
   9.199 -		ret = -ENOMEM;
   9.200 +	}
   9.201 +
   9.202  	return ret;
   9.203  }
   9.204  
   9.205 @@ -254,6 +276,7 @@ static struct attribute *xen_properties_
   9.206  	&capabilities_attr.attr,
   9.207  	&changeset_attr.attr,
   9.208  	&virtual_start_attr.attr,
   9.209 +	&pagesize_attr.attr,
   9.210  	&writable_pt_attr.attr,
   9.211  	NULL
   9.212  };
   9.213 @@ -271,7 +294,8 @@ static int __init xen_properties_init(vo
   9.214  
   9.215  static void xen_properties_destroy(void)
   9.216  {
   9.217 -	sysfs_remove_group(&hypervisor_subsys.kset.kobj, &xen_properties_group);
   9.218 +	sysfs_remove_group(&hypervisor_subsys.kset.kobj,
   9.219 +			   &xen_properties_group);
   9.220  }
   9.221  
   9.222  static int __init hyper_sysfs_init(void)
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Wed Jun 28 07:51:52 2006 -0600
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Wed Jun 28 07:52:21 2006 -0600
    10.3 @@ -37,9 +37,9 @@
    10.4  static void __netif_up(netif_t *netif)
    10.5  {
    10.6  	struct net_device *dev = netif->dev;
    10.7 -	spin_lock_bh(&dev->xmit_lock);
    10.8 +	netif_tx_lock_bh(dev);
    10.9  	netif->active = 1;
   10.10 -	spin_unlock_bh(&dev->xmit_lock);
   10.11 +	netif_tx_unlock_bh(dev);
   10.12  	enable_irq(netif->irq);
   10.13  	netif_schedule_work(netif);
   10.14  }
   10.15 @@ -48,9 +48,9 @@ static void __netif_down(netif_t *netif)
   10.16  {
   10.17  	struct net_device *dev = netif->dev;
   10.18  	disable_irq(netif->irq);
   10.19 -	spin_lock_bh(&dev->xmit_lock);
   10.20 +	netif_tx_lock_bh(dev);
   10.21  	netif->active = 0;
   10.22 -	spin_unlock_bh(&dev->xmit_lock);
   10.23 +	netif_tx_unlock_bh(dev);
   10.24  	netif_deschedule_work(netif);
   10.25  }
   10.26  
    11.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Wed Jun 28 07:51:52 2006 -0600
    11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Wed Jun 28 07:52:21 2006 -0600
    11.3 @@ -125,6 +125,10 @@ static struct ethtool_ops network_ethtoo
    11.4  {
    11.5  	.get_tx_csum = ethtool_op_get_tx_csum,
    11.6  	.set_tx_csum = ethtool_op_set_tx_csum,
    11.7 +	.get_sg = ethtool_op_get_sg,
    11.8 +	.set_sg = ethtool_op_set_sg,
    11.9 +	.get_tso = ethtool_op_get_tso,
   11.10 +	.set_tso = ethtool_op_set_tso,
   11.11  };
   11.12  
   11.13  /*
   11.14 @@ -152,6 +156,7 @@ static void loopback_construct(struct ne
   11.15  
   11.16  	dev->features        = (NETIF_F_HIGHDMA |
   11.17  				NETIF_F_LLTX |
   11.18 +				NETIF_F_TSO |
   11.19  				NETIF_F_SG |
   11.20  				NETIF_F_IP_CSUM);
   11.21  
    12.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Jun 28 07:51:52 2006 -0600
    12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Wed Jun 28 07:52:21 2006 -0600
    12.3 @@ -43,7 +43,7 @@
    12.4  static void netif_idx_release(u16 pending_idx);
    12.5  static void netif_page_release(struct page *page);
    12.6  static void make_tx_response(netif_t *netif, 
    12.7 -			     u16      id,
    12.8 +			     netif_tx_request_t *txp,
    12.9  			     s8       st);
   12.10  static int  make_rx_response(netif_t *netif, 
   12.11  			     u16      id, 
   12.12 @@ -481,7 +481,7 @@ inline static void net_tx_action_dealloc
   12.13  
   12.14  		netif = pending_tx_info[pending_idx].netif;
   12.15  
   12.16 -		make_tx_response(netif, pending_tx_info[pending_idx].req.id, 
   12.17 +		make_tx_response(netif, &pending_tx_info[pending_idx].req, 
   12.18  				 NETIF_RSP_OKAY);
   12.19  
   12.20  		pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   12.21 @@ -490,14 +490,16 @@ inline static void net_tx_action_dealloc
   12.22  	}
   12.23  }
   12.24  
   12.25 -static void netbk_tx_err(netif_t *netif, RING_IDX end)
   12.26 +static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end)
   12.27  {
   12.28  	RING_IDX cons = netif->tx.req_cons;
   12.29  
   12.30  	do {
   12.31 -		netif_tx_request_t *txp = RING_GET_REQUEST(&netif->tx, cons);
   12.32 -		make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
   12.33 -	} while (++cons < end);
   12.34 +		make_tx_response(netif, txp, NETIF_RSP_ERROR);
   12.35 +		if (++cons >= end)
   12.36 +			break;
   12.37 +		txp = RING_GET_REQUEST(&netif->tx, cons);
   12.38 +	} while (1);
   12.39  	netif->tx.req_cons = cons;
   12.40  	netif_schedule_work(netif);
   12.41  	netif_put(netif);
   12.42 @@ -508,7 +510,7 @@ static int netbk_count_requests(netif_t 
   12.43  {
   12.44  	netif_tx_request_t *first = txp;
   12.45  	RING_IDX cons = netif->tx.req_cons;
   12.46 -	int frags = 1;
   12.47 +	int frags = 0;
   12.48  
   12.49  	while (txp->flags & NETTXF_more_data) {
   12.50  		if (frags >= work_to_do) {
   12.51 @@ -543,7 +545,7 @@ static gnttab_map_grant_ref_t *netbk_get
   12.52  	skb_frag_t *frags = shinfo->frags;
   12.53  	netif_tx_request_t *txp;
   12.54  	unsigned long pending_idx = *((u16 *)skb->data);
   12.55 -	RING_IDX cons = netif->tx.req_cons + 1;
   12.56 +	RING_IDX cons = netif->tx.req_cons;
   12.57  	int i, start;
   12.58  
   12.59  	/* Skip first skb fragment if it is on same page as header fragment. */
   12.60 @@ -581,7 +583,7 @@ static int netbk_tx_check_mop(struct sk_
   12.61  	err = mop->status;
   12.62  	if (unlikely(err)) {
   12.63  		txp = &pending_tx_info[pending_idx].req;
   12.64 -		make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
   12.65 +		make_tx_response(netif, txp, NETIF_RSP_ERROR);
   12.66  		pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   12.67  		netif_put(netif);
   12.68  	} else {
   12.69 @@ -614,7 +616,7 @@ static int netbk_tx_check_mop(struct sk_
   12.70  
   12.71  		/* Error on this fragment: respond to client with an error. */
   12.72  		txp = &pending_tx_info[pending_idx].req;
   12.73 -		make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
   12.74 +		make_tx_response(netif, txp, NETIF_RSP_ERROR);
   12.75  		pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   12.76  		netif_put(netif);
   12.77  
   12.78 @@ -668,6 +670,7 @@ static void net_tx_action(unsigned long 
   12.79  	struct sk_buff *skb;
   12.80  	netif_t *netif;
   12.81  	netif_tx_request_t txreq;
   12.82 +	struct netif_tx_extra txtra;
   12.83  	u16 pending_idx;
   12.84  	RING_IDX i;
   12.85  	gnttab_map_grant_ref_t *mop;
   12.86 @@ -726,22 +729,37 @@ static void net_tx_action(unsigned long 
   12.87  		}
   12.88  		netif->remaining_credit -= txreq.size;
   12.89  
   12.90 +		work_to_do--;
   12.91 +		netif->tx.req_cons = ++i;
   12.92 +
   12.93 +		if (txreq.flags & NETTXF_extra_info) {
   12.94 +			if (work_to_do-- <= 0) {
   12.95 +				DPRINTK("Missing extra info\n");
   12.96 +				netbk_tx_err(netif, &txreq, i);
   12.97 +				continue;
   12.98 +			}
   12.99 +
  12.100 +			memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i),
  12.101 +			       sizeof(txtra));
  12.102 +			netif->tx.req_cons = ++i;
  12.103 +		}
  12.104 +
  12.105  		ret = netbk_count_requests(netif, &txreq, work_to_do);
  12.106  		if (unlikely(ret < 0)) {
  12.107 -			netbk_tx_err(netif, i - ret);
  12.108 +			netbk_tx_err(netif, &txreq, i - ret);
  12.109  			continue;
  12.110  		}
  12.111  		i += ret;
  12.112  
  12.113  		if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
  12.114  			DPRINTK("Too many frags\n");
  12.115 -			netbk_tx_err(netif, i);
  12.116 +			netbk_tx_err(netif, &txreq, i);
  12.117  			continue;
  12.118  		}
  12.119  
  12.120  		if (unlikely(txreq.size < ETH_HLEN)) {
  12.121  			DPRINTK("Bad packet size: %d\n", txreq.size);
  12.122 -			netbk_tx_err(netif, i);
  12.123 +			netbk_tx_err(netif, &txreq, i);
  12.124  			continue; 
  12.125  		}
  12.126  
  12.127 @@ -750,26 +768,32 @@ static void net_tx_action(unsigned long 
  12.128  			DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", 
  12.129  				txreq.offset, txreq.size, 
  12.130  				(txreq.offset &~PAGE_MASK) + txreq.size);
  12.131 -			netbk_tx_err(netif, i);
  12.132 +			netbk_tx_err(netif, &txreq, i);
  12.133  			continue;
  12.134  		}
  12.135  
  12.136  		pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
  12.137  
  12.138  		data_len = (txreq.size > PKT_PROT_LEN &&
  12.139 -			    ret < MAX_SKB_FRAGS + 1) ?
  12.140 +			    ret < MAX_SKB_FRAGS) ?
  12.141  			PKT_PROT_LEN : txreq.size;
  12.142  
  12.143  		skb = alloc_skb(data_len+16, GFP_ATOMIC);
  12.144  		if (unlikely(skb == NULL)) {
  12.145  			DPRINTK("Can't allocate a skb in start_xmit.\n");
  12.146 -			netbk_tx_err(netif, i);
  12.147 +			netbk_tx_err(netif, &txreq, i);
  12.148  			break;
  12.149  		}
  12.150  
  12.151  		/* Packets passed to netif_rx() must have some headroom. */
  12.152  		skb_reserve(skb, 16);
  12.153  
  12.154 +		if (txreq.flags & NETTXF_gso) {
  12.155 +			skb_shinfo(skb)->gso_size = txtra.u.gso.size;
  12.156 +			skb_shinfo(skb)->gso_segs = txtra.u.gso.segs;
  12.157 +			skb_shinfo(skb)->gso_type = txtra.u.gso.type;
  12.158 +		}
  12.159 +
  12.160  		gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
  12.161  				  GNTMAP_host_map | GNTMAP_readonly,
  12.162  				  txreq.gref, netif->domid);
  12.163 @@ -782,7 +806,7 @@ static void net_tx_action(unsigned long 
  12.164  
  12.165  		__skb_put(skb, data_len);
  12.166  
  12.167 -		skb_shinfo(skb)->nr_frags = ret - 1;
  12.168 +		skb_shinfo(skb)->nr_frags = ret;
  12.169  		if (data_len < txreq.size) {
  12.170  			skb_shinfo(skb)->nr_frags++;
  12.171  			skb_shinfo(skb)->frags[0].page =
  12.172 @@ -898,7 +922,7 @@ irqreturn_t netif_be_int(int irq, void *
  12.173  }
  12.174  
  12.175  static void make_tx_response(netif_t *netif, 
  12.176 -			     u16      id,
  12.177 +			     netif_tx_request_t *txp,
  12.178  			     s8       st)
  12.179  {
  12.180  	RING_IDX i = netif->tx.rsp_prod_pvt;
  12.181 @@ -906,9 +930,12 @@ static void make_tx_response(netif_t *ne
  12.182  	int notify;
  12.183  
  12.184  	resp = RING_GET_RESPONSE(&netif->tx, i);
  12.185 -	resp->id     = id;
  12.186 +	resp->id     = txp->id;
  12.187  	resp->status = st;
  12.188  
  12.189 +	if (txp->flags & NETTXF_extra_info)
  12.190 +		RING_GET_RESPONSE(&netif->tx, ++i)->status = NETIF_RSP_NULL;
  12.191 +
  12.192  	netif->tx.rsp_prod_pvt = ++i;
  12.193  	RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->tx, notify);
  12.194  	if (notify)
    13.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Wed Jun 28 07:51:52 2006 -0600
    13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Wed Jun 28 07:52:21 2006 -0600
    13.3 @@ -101,6 +101,12 @@ static int netback_probe(struct xenbus_d
    13.4  			goto abort_transaction;
    13.5  		}
    13.6  
    13.7 +		err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
    13.8 +		if (err) {
    13.9 +			message = "writing feature-tso";
   13.10 +			goto abort_transaction;
   13.11 +		}
   13.12 +
   13.13  		err = xenbus_transaction_end(xbt, 0);
   13.14  	} while (err == -EAGAIN);
   13.15  
    14.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Wed Jun 28 07:51:52 2006 -0600
    14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Wed Jun 28 07:52:21 2006 -0600
    14.3 @@ -21,6 +21,8 @@
    14.4  	pr_debug("(file=%s, line=%d) " _f,	\
    14.5  		 __FILE__ , __LINE__ , ## _a )
    14.6  
    14.7 +struct backend_info;
    14.8 +
    14.9  typedef struct tpmif_st {
   14.10  	struct list_head tpmif_list;
   14.11  	/* Unique identifier for this interface. */
   14.12 @@ -43,7 +45,7 @@ typedef struct tpmif_st {
   14.13  	struct list_head list;	/* scheduling list */
   14.14  	atomic_t refcnt;
   14.15  
   14.16 -	long int tpm_instance;
   14.17 +	struct backend_info *bi;
   14.18  	unsigned long mmap_vstart;
   14.19  
   14.20  	grant_handle_t shmem_handle;
   14.21 @@ -54,7 +56,7 @@ typedef struct tpmif_st {
   14.22  } tpmif_t;
   14.23  
   14.24  void tpmif_disconnect_complete(tpmif_t * tpmif);
   14.25 -tpmif_t *tpmif_find(domid_t domid, long int instance);
   14.26 +tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi);
   14.27  void tpmif_interface_init(void);
   14.28  void tpmif_interface_exit(void);
   14.29  void tpmif_schedule_work(tpmif_t * tpmif);
   14.30 @@ -63,11 +65,12 @@ void tpmif_xenbus_init(void);
   14.31  void tpmif_xenbus_exit(void);
   14.32  int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
   14.33  irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
   14.34 -int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domain, u32 instance);
   14.35 -int tpmif_vtpm_close(u32 instance);
   14.36 +
   14.37 +long int tpmback_get_instance(struct backend_info *bi);
   14.38  
   14.39  int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
   14.40  
   14.41 +
   14.42  #define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
   14.43  #define tpmif_put(_b)					\
   14.44  	do {						\
    15.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Wed Jun 28 07:51:52 2006 -0600
    15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Wed Jun 28 07:52:21 2006 -0600
    15.3 @@ -20,7 +20,7 @@ int num_frontends = 0;
    15.4  
    15.5  LIST_HEAD(tpmif_list);
    15.6  
    15.7 -static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
    15.8 +static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi)
    15.9  {
   15.10  	tpmif_t *tpmif;
   15.11  
   15.12 @@ -31,7 +31,7 @@ static tpmif_t *alloc_tpmif(domid_t domi
   15.13  	memset(tpmif, 0, sizeof (*tpmif));
   15.14  	tpmif->domid = domid;
   15.15  	tpmif->status = DISCONNECTED;
   15.16 -	tpmif->tpm_instance = instance;
   15.17 +	tpmif->bi = bi;
   15.18  	snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
   15.19  	atomic_set(&tpmif->refcnt, 1);
   15.20  
   15.21 @@ -54,12 +54,12 @@ static void free_tpmif(tpmif_t * tpmif)
   15.22  	kmem_cache_free(tpmif_cachep, tpmif);
   15.23  }
   15.24  
   15.25 -tpmif_t *tpmif_find(domid_t domid, long int instance)
   15.26 +tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi)
   15.27  {
   15.28  	tpmif_t *tpmif;
   15.29  
   15.30  	list_for_each_entry(tpmif, &tpmif_list, tpmif_list) {
   15.31 -		if (tpmif->tpm_instance == instance) {
   15.32 +		if (tpmif->bi == bi) {
   15.33  			if (tpmif->domid == domid) {
   15.34  				tpmif_get(tpmif);
   15.35  				return tpmif;
   15.36 @@ -69,7 +69,7 @@ tpmif_t *tpmif_find(domid_t domid, long 
   15.37  		}
   15.38  	}
   15.39  
   15.40 -	return alloc_tpmif(domid, instance);
   15.41 +	return alloc_tpmif(domid, bi);
   15.42  }
   15.43  
   15.44  static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
    16.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Wed Jun 28 07:51:52 2006 -0600
    16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c	Wed Jun 28 07:52:21 2006 -0600
    16.3 @@ -161,7 +161,7 @@ static struct packet *packet_alloc(tpmif
    16.4  	if (NULL != pak) {
    16.5  		if (tpmif) {
    16.6  			pak->tpmif = tpmif;
    16.7 -			pak->tpm_instance = tpmif->tpm_instance;
    16.8 +			pak->tpm_instance = tpmback_get_instance(tpmif->bi);
    16.9  			tpmif_get(tpmif);
   16.10  		}
   16.11  		pak->data_len = size;
   16.12 @@ -685,95 +685,6 @@ static struct miscdevice vtpms_miscdevic
   16.13  };
   16.14  
   16.15  /***************************************************************
   16.16 - Virtual TPM functions and data stuctures
   16.17 -***************************************************************/
   16.18 -
   16.19 -static u8 create_cmd[] = {
   16.20 -	1, 193,			/* 0: TPM_TAG_RQU_COMMAMD */
   16.21 -	0, 0, 0, 19,		/* 2: length */
   16.22 -	0, 0, 0, 0x1,		/* 6: VTPM_ORD_OPEN */
   16.23 -	0,			/* 10: VTPM type */
   16.24 -	0, 0, 0, 0,		/* 11: domain id */
   16.25 -	0, 0, 0, 0		/* 15: instance id */
   16.26 -};
   16.27 -
   16.28 -int tpmif_vtpm_open(tpmif_t * tpmif, domid_t domid, u32 instance)
   16.29 -{
   16.30 -	int rc = 0;
   16.31 -	struct packet *pak;
   16.32 -
   16.33 -	pak = packet_alloc(tpmif,
   16.34 -			   sizeof (create_cmd),
   16.35 -			   create_cmd[1],
   16.36 -			   PACKET_FLAG_DISCARD_RESPONSE |
   16.37 -			   PACKET_FLAG_CHECK_RESPONSESTATUS);
   16.38 -	if (pak) {
   16.39 -		u8 buf[sizeof (create_cmd)];
   16.40 -		u32 domid_no = htonl((u32) domid);
   16.41 -		u32 instance_no = htonl(instance);
   16.42 -
   16.43 -		memcpy(buf, create_cmd, sizeof (create_cmd));
   16.44 -
   16.45 -		memcpy(&buf[11], &domid_no, sizeof (u32));
   16.46 -		memcpy(&buf[15], &instance_no, sizeof (u32));
   16.47 -
   16.48 -		/* copy the buffer into the packet */
   16.49 -		rc = packet_set(pak, buf, sizeof (buf));
   16.50 -
   16.51 -		if (rc == 0) {
   16.52 -			pak->tpm_instance = 0;
   16.53 -			rc = vtpm_queue_packet(pak);
   16.54 -		}
   16.55 -		if (rc < 0) {
   16.56 -			/* could not be queued or built */
   16.57 -			packet_free(pak);
   16.58 -		}
   16.59 -	} else {
   16.60 -		rc = -ENOMEM;
   16.61 -	}
   16.62 -	return rc;
   16.63 -}
   16.64 -
   16.65 -static u8 destroy_cmd[] = {
   16.66 -	1, 193,			/* 0: TPM_TAG_RQU_COMMAMD */
   16.67 -	0, 0, 0, 14,		/* 2: length */
   16.68 -	0, 0, 0, 0x2,		/* 6: VTPM_ORD_CLOSE */
   16.69 -	0, 0, 0, 0		/* 10: instance id */
   16.70 -};
   16.71 -
   16.72 -int tpmif_vtpm_close(u32 instid)
   16.73 -{
   16.74 -	int rc = 0;
   16.75 -	struct packet *pak;
   16.76 -
   16.77 -	pak = packet_alloc(NULL,
   16.78 -			   sizeof (destroy_cmd),
   16.79 -			   destroy_cmd[1], PACKET_FLAG_DISCARD_RESPONSE);
   16.80 -	if (pak) {
   16.81 -		u8 buf[sizeof (destroy_cmd)];
   16.82 -		u32 instid_no = htonl(instid);
   16.83 -
   16.84 -		memcpy(buf, destroy_cmd, sizeof (destroy_cmd));
   16.85 -		memcpy(&buf[10], &instid_no, sizeof (u32));
   16.86 -
   16.87 -		/* copy the buffer into the packet */
   16.88 -		rc = packet_set(pak, buf, sizeof (buf));
   16.89 -
   16.90 -		if (rc == 0) {
   16.91 -			pak->tpm_instance = 0;
   16.92 -			rc = vtpm_queue_packet(pak);
   16.93 -		}
   16.94 -		if (rc < 0) {
   16.95 -			/* could not be queued or built */
   16.96 -			packet_free(pak);
   16.97 -		}
   16.98 -	} else {
   16.99 -		rc = -ENOMEM;
  16.100 -	}
  16.101 -	return rc;
  16.102 -}
  16.103 -
  16.104 -/***************************************************************
  16.105   Utility functions
  16.106  ***************************************************************/
  16.107  
    17.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Wed Jun 28 07:51:52 2006 -0600
    17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Wed Jun 28 07:52:21 2006 -0600
    17.3 @@ -45,6 +45,14 @@ static void backend_changed(struct xenbu
    17.4  static void frontend_changed(struct xenbus_device *dev,
    17.5  			     enum xenbus_state frontend_state);
    17.6  
    17.7 +long int tpmback_get_instance(struct backend_info *bi)
    17.8 +{
    17.9 +	long int res = -1;
   17.10 +	if (bi && bi->is_instance_set)
   17.11 +		res = bi->instance;
   17.12 +	return res;
   17.13 +}
   17.14 +
   17.15  static int tpmback_remove(struct xenbus_device *dev)
   17.16  {
   17.17  	struct backend_info *be = dev->dev.driver_data;
   17.18 @@ -57,6 +65,7 @@ static int tpmback_remove(struct xenbus_
   17.19  		be->backend_watch.node = NULL;
   17.20  	}
   17.21  	if (be->tpmif) {
   17.22 +		be->tpmif->bi = NULL;
   17.23  		vtpm_release_packets(be->tpmif, 0);
   17.24  		tpmif_put(be->tpmif);
   17.25  		be->tpmif = NULL;
   17.26 @@ -150,15 +159,10 @@ static void frontend_changed(struct xenb
   17.27  		break;
   17.28  
   17.29  	case XenbusStateClosing:
   17.30 -		be->tpmif->tpm_instance = -1;
   17.31 +		be->instance = -1;
   17.32  		break;
   17.33  
   17.34  	case XenbusStateClosed:
   17.35 -		/*
   17.36 -		 * Notify the vTPM manager about the front-end
   17.37 -		 * having left.
   17.38 -		 */
   17.39 -		tpmif_vtpm_close(be->instance);
   17.40  		device_unregister(&be->dev->dev);
   17.41  		tpmback_remove(dev);
   17.42  		break;
   17.43 @@ -177,28 +181,10 @@ static void frontend_changed(struct xenb
   17.44  
   17.45  static void maybe_connect(struct backend_info *be)
   17.46  {
   17.47 -	int err;
   17.48 -
   17.49  	if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
   17.50  		return;
   17.51  
   17.52  	connect(be);
   17.53 -
   17.54 -	/*
   17.55 -	 * Notify the vTPM manager about a new front-end.
   17.56 -	 */
   17.57 -	err = tpmif_vtpm_open(be->tpmif,
   17.58 -			      be->frontend_id,
   17.59 -			      be->instance);
   17.60 -	if (err) {
   17.61 -		xenbus_dev_error(be->dev, err,
   17.62 -				 "queueing vtpm open packet");
   17.63 -		/*
   17.64 -		 * Should close down this device and notify FE
   17.65 -		 * about closure.
   17.66 -		 */
   17.67 -		return;
   17.68 -	}
   17.69  }
   17.70  
   17.71  
   17.72 @@ -256,8 +242,7 @@ static int connect_ring(struct backend_i
   17.73  	}
   17.74  
   17.75  	if (!be->tpmif) {
   17.76 -		be->tpmif = tpmif_find(dev->otherend_id,
   17.77 -				       be->instance);
   17.78 +		be->tpmif = tpmif_find(dev->otherend_id, be);
   17.79  		if (IS_ERR(be->tpmif)) {
   17.80  			err = PTR_ERR(be->tpmif);
   17.81  			be->tpmif = NULL;
    18.1 --- a/linux-2.6-xen-sparse/include/linux/skbuff.h	Wed Jun 28 07:51:52 2006 -0600
    18.2 +++ b/linux-2.6-xen-sparse/include/linux/skbuff.h	Wed Jun 28 07:52:21 2006 -0600
    18.3 @@ -134,9 +134,10 @@ struct skb_frag_struct {
    18.4  struct skb_shared_info {
    18.5  	atomic_t	dataref;
    18.6  	unsigned short	nr_frags;
    18.7 -	unsigned short	tso_size;
    18.8 -	unsigned short	tso_segs;
    18.9 -	unsigned short  ufo_size;
   18.10 +	unsigned short	gso_size;
   18.11 +	/* Warning: this field is not always filled in (UFO)! */
   18.12 +	unsigned short	gso_segs;
   18.13 +	unsigned short  gso_type;
   18.14  	unsigned int    ip6_frag_id;
   18.15  	struct sk_buff	*frag_list;
   18.16  	skb_frag_t	frags[MAX_SKB_FRAGS];
   18.17 @@ -168,6 +169,14 @@ enum {
   18.18  	SKB_FCLONE_CLONE,
   18.19  };
   18.20  
   18.21 +enum {
   18.22 +	SKB_GSO_TCPV4 = 1 << 0,
   18.23 +	SKB_GSO_UDPV4 = 1 << 1,
   18.24 +
   18.25 +	/* This indicates the skb is from an untrusted source. */
   18.26 +	SKB_GSO_DODGY = 1 << 2,
   18.27 +};
   18.28 +
   18.29  /** 
   18.30   *	struct sk_buff - socket buffer
   18.31   *	@next: Next buffer in list
   18.32 @@ -1157,18 +1166,34 @@ static inline int skb_can_coalesce(struc
   18.33  	return 0;
   18.34  }
   18.35  
   18.36 +static inline int __skb_linearize(struct sk_buff *skb)
   18.37 +{
   18.38 +	return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
   18.39 +}
   18.40 +
   18.41  /**
   18.42   *	skb_linearize - convert paged skb to linear one
   18.43   *	@skb: buffer to linarize
   18.44 - *	@gfp: allocation mode
   18.45   *
   18.46   *	If there is no free memory -ENOMEM is returned, otherwise zero
   18.47   *	is returned and the old skb data released.
   18.48   */
   18.49 -extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
   18.50 -static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
   18.51 +static inline int skb_linearize(struct sk_buff *skb)
   18.52  {
   18.53 -	return __skb_linearize(skb, gfp);
   18.54 +	return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
   18.55 +}
   18.56 +
   18.57 +/**
   18.58 + *	skb_linearize_cow - make sure skb is linear and writable
   18.59 + *	@skb: buffer to process
   18.60 + *
   18.61 + *	If there is no free memory -ENOMEM is returned, otherwise zero
   18.62 + *	is returned and the old skb data released.
   18.63 + */
   18.64 +static inline int skb_linearize_cow(struct sk_buff *skb)
   18.65 +{
   18.66 +	return skb_is_nonlinear(skb) || skb_cloned(skb) ?
   18.67 +	       __skb_linearize(skb) : 0;
   18.68  }
   18.69  
   18.70  /**
   18.71 @@ -1263,6 +1288,7 @@ extern void	       skb_split(struct sk_b
   18.72  				 struct sk_buff *skb1, const u32 len);
   18.73  
   18.74  extern void	       skb_release_data(struct sk_buff *skb);
   18.75 +extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
   18.76  
   18.77  static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
   18.78  				       int len, void *buffer)
    19.1 --- a/linux-2.6-xen-sparse/net/core/dev.c	Wed Jun 28 07:51:52 2006 -0600
    19.2 +++ b/linux-2.6-xen-sparse/net/core/dev.c	Wed Jun 28 07:52:21 2006 -0600
    19.3 @@ -115,6 +115,7 @@
    19.4  #include <net/iw_handler.h>
    19.5  #endif	/* CONFIG_NET_RADIO */
    19.6  #include <asm/current.h>
    19.7 +#include <linux/err.h>
    19.8  
    19.9  #ifdef CONFIG_XEN
   19.10  #include <net/ip.h>
   19.11 @@ -1038,7 +1039,7 @@ static inline void net_timestamp(struct 
   19.12   *	taps currently in use.
   19.13   */
   19.14  
   19.15 -void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
   19.16 +static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
   19.17  {
   19.18  	struct packet_type *ptype;
   19.19  
   19.20 @@ -1112,6 +1113,45 @@ out:
   19.21  	return ret;
   19.22  }
   19.23  
   19.24 +/**
   19.25 + *	skb_gso_segment - Perform segmentation on skb.
   19.26 + *	@skb: buffer to segment
   19.27 + *	@features: features for the output path (see dev->features)
   19.28 + *
   19.29 + *	This function segments the given skb and returns a list of segments.
   19.30 + *
   19.31 + *	It may return NULL if the skb requires no segmentation.  This is
   19.32 + *	only possible when GSO is used for verifying header integrity.
   19.33 + */
   19.34 +struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
   19.35 +{
   19.36 +	struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
   19.37 +	struct packet_type *ptype;
   19.38 +	int type = skb->protocol;
   19.39 +
   19.40 +	BUG_ON(skb_shinfo(skb)->frag_list);
   19.41 +	BUG_ON(skb->ip_summed != CHECKSUM_HW);
   19.42 +
   19.43 +	skb->mac.raw = skb->data;
   19.44 +	skb->mac_len = skb->nh.raw - skb->data;
   19.45 +	__skb_pull(skb, skb->mac_len);
   19.46 +
   19.47 +	rcu_read_lock();
   19.48 +	list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
   19.49 +		if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
   19.50 +			segs = ptype->gso_segment(skb, features);
   19.51 +			break;
   19.52 +		}
   19.53 +	}
   19.54 +	rcu_read_unlock();
   19.55 +
   19.56 +	__skb_push(skb, skb->data - skb->mac.raw);
   19.57 +
   19.58 +	return segs;
   19.59 +}
   19.60 +
   19.61 +EXPORT_SYMBOL(skb_gso_segment);
   19.62 +
   19.63  /* Take action when hardware reception checksum errors are detected. */
   19.64  #ifdef CONFIG_BUG
   19.65  void netdev_rx_csum_fault(struct net_device *dev)
   19.66 @@ -1148,75 +1188,108 @@ static inline int illegal_highdma(struct
   19.67  #define illegal_highdma(dev, skb)	(0)
   19.68  #endif
   19.69  
   19.70 -/* Keep head the same: replace data */
   19.71 -int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
   19.72 +struct dev_gso_cb {
   19.73 +	void (*destructor)(struct sk_buff *skb);
   19.74 +};
   19.75 +
   19.76 +#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
   19.77 +
   19.78 +static void dev_gso_skb_destructor(struct sk_buff *skb)
   19.79 +{
   19.80 +	struct dev_gso_cb *cb;
   19.81 +
   19.82 +	do {
   19.83 +		struct sk_buff *nskb = skb->next;
   19.84 +
   19.85 +		skb->next = nskb->next;
   19.86 +		nskb->next = NULL;
   19.87 +		kfree_skb(nskb);
   19.88 +	} while (skb->next);
   19.89 +
   19.90 +	cb = DEV_GSO_CB(skb);
   19.91 +	if (cb->destructor)
   19.92 +		cb->destructor(skb);
   19.93 +}
   19.94 +
   19.95 +/**
   19.96 + *	dev_gso_segment - Perform emulated hardware segmentation on skb.
   19.97 + *	@skb: buffer to segment
   19.98 + *
   19.99 + *	This function segments the given skb and stores the list of segments
  19.100 + *	in skb->next.
  19.101 + */
  19.102 +static int dev_gso_segment(struct sk_buff *skb)
  19.103  {
  19.104 -	unsigned int size;
  19.105 -	u8 *data;
  19.106 -	long offset;
  19.107 -	struct skb_shared_info *ninfo;
  19.108 -	int headerlen = skb->data - skb->head;
  19.109 -	int expand = (skb->tail + skb->data_len) - skb->end;
  19.110 -
  19.111 -	if (skb_shared(skb))
  19.112 -		BUG();
  19.113 -
  19.114 -	if (expand <= 0)
  19.115 -		expand = 0;
  19.116 -
  19.117 -	size = skb->end - skb->head + expand;
  19.118 -	size = SKB_DATA_ALIGN(size);
  19.119 -	data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
  19.120 -	if (!data)
  19.121 -		return -ENOMEM;
  19.122 -
  19.123 -	/* Copy entire thing */
  19.124 -	if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
  19.125 -		BUG();
  19.126 -
  19.127 -	/* Set up shinfo */
  19.128 -	ninfo = (struct skb_shared_info*)(data + size);
  19.129 -	atomic_set(&ninfo->dataref, 1);
  19.130 -	ninfo->tso_size = skb_shinfo(skb)->tso_size;
  19.131 -	ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
  19.132 -	ninfo->nr_frags = 0;
  19.133 -	ninfo->frag_list = NULL;
  19.134 -
  19.135 -	/* Offset between the two in bytes */
  19.136 -	offset = data - skb->head;
  19.137 -
  19.138 -	/* Free old data. */
  19.139 -	skb_release_data(skb);
  19.140 -
  19.141 -	skb->head = data;
  19.142 -	skb->end  = data + size;
  19.143 -
  19.144 -	/* Set up new pointers */
  19.145 -	skb->h.raw   += offset;
  19.146 -	skb->nh.raw  += offset;
  19.147 -	skb->mac.raw += offset;
  19.148 -	skb->tail    += offset;
  19.149 -	skb->data    += offset;
  19.150 -
  19.151 -	/* We are no longer a clone, even if we were. */
  19.152 -	skb->cloned    = 0;
  19.153 -
  19.154 -	skb->tail     += skb->data_len;
  19.155 -	skb->data_len  = 0;
  19.156 +	struct net_device *dev = skb->dev;
  19.157 +	struct sk_buff *segs;
  19.158 +	int features = dev->features & ~(illegal_highdma(dev, skb) ?
  19.159 +					 NETIF_F_SG : 0);
  19.160 +
  19.161 +	segs = skb_gso_segment(skb, features);
  19.162 +
  19.163 +	/* Verifying header integrity only. */
  19.164 +	if (!segs)
  19.165 +		return 0;
  19.166 +
  19.167 +	if (unlikely(IS_ERR(segs)))
  19.168 +		return PTR_ERR(segs);
  19.169 +
  19.170 +	skb->next = segs;
  19.171 +	DEV_GSO_CB(skb)->destructor = skb->destructor;
  19.172 +	skb->destructor = dev_gso_skb_destructor;
  19.173 +
  19.174 +	return 0;
  19.175 +}
  19.176 +
  19.177 +int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
  19.178 +{
  19.179 +	if (likely(!skb->next)) {
  19.180 +		if (netdev_nit)
  19.181 +			dev_queue_xmit_nit(skb, dev);
  19.182 +
  19.183 +		if (netif_needs_gso(dev, skb)) {
  19.184 +			if (unlikely(dev_gso_segment(skb)))
  19.185 +				goto out_kfree_skb;
  19.186 +			if (skb->next)
  19.187 +				goto gso;
  19.188 +		}
  19.189 +
  19.190 +		return dev->hard_start_xmit(skb, dev);
  19.191 +	}
  19.192 +
  19.193 +gso:
  19.194 +	do {
  19.195 +		struct sk_buff *nskb = skb->next;
  19.196 +		int rc;
  19.197 +
  19.198 +		skb->next = nskb->next;
  19.199 +		nskb->next = NULL;
  19.200 +		rc = dev->hard_start_xmit(nskb, dev);
  19.201 +		if (unlikely(rc)) {
  19.202 +			nskb->next = skb->next;
  19.203 +			skb->next = nskb;
  19.204 +			return rc;
  19.205 +		}
  19.206 +		if (unlikely(netif_queue_stopped(dev) && skb->next))
  19.207 +			return NETDEV_TX_BUSY;
  19.208 +	} while (skb->next);
  19.209 +	
  19.210 +	skb->destructor = DEV_GSO_CB(skb)->destructor;
  19.211 +
  19.212 +out_kfree_skb:
  19.213 +	kfree_skb(skb);
  19.214  	return 0;
  19.215  }
  19.216  
  19.217  #define HARD_TX_LOCK(dev, cpu) {			\
  19.218  	if ((dev->features & NETIF_F_LLTX) == 0) {	\
  19.219 -		spin_lock(&dev->xmit_lock);		\
  19.220 -		dev->xmit_lock_owner = cpu;		\
  19.221 +		netif_tx_lock(dev);			\
  19.222  	}						\
  19.223  }
  19.224  
  19.225  #define HARD_TX_UNLOCK(dev) {				\
  19.226  	if ((dev->features & NETIF_F_LLTX) == 0) {	\
  19.227 -		dev->xmit_lock_owner = -1;		\
  19.228 -		spin_unlock(&dev->xmit_lock);		\
  19.229 +		netif_tx_unlock(dev);			\
  19.230  	}						\
  19.231  }
  19.232  
  19.233 @@ -1289,9 +1362,19 @@ int dev_queue_xmit(struct sk_buff *skb)
  19.234  	struct Qdisc *q;
  19.235  	int rc = -ENOMEM;
  19.236  
  19.237 + 	/* If a checksum-deferred packet is forwarded to a device that needs a
  19.238 + 	 * checksum, correct the pointers and force checksumming.
  19.239 + 	 */
  19.240 + 	if (skb_checksum_setup(skb))
  19.241 + 		goto out_kfree_skb;
  19.242 +
  19.243 +	/* GSO will handle the following emulations directly. */
  19.244 +	if (netif_needs_gso(dev, skb))
  19.245 +		goto gso;
  19.246 +
  19.247  	if (skb_shinfo(skb)->frag_list &&
  19.248  	    !(dev->features & NETIF_F_FRAGLIST) &&
  19.249 -	    __skb_linearize(skb, GFP_ATOMIC))
  19.250 +	    __skb_linearize(skb))
  19.251  		goto out_kfree_skb;
  19.252  
  19.253  	/* Fragmented skb is linearized if device does not support SG,
  19.254 @@ -1300,31 +1383,26 @@ int dev_queue_xmit(struct sk_buff *skb)
  19.255  	 */
  19.256  	if (skb_shinfo(skb)->nr_frags &&
  19.257  	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
  19.258 -	    __skb_linearize(skb, GFP_ATOMIC))
  19.259 +	    __skb_linearize(skb))
  19.260  		goto out_kfree_skb;
  19.261  
  19.262 - 	/* If a checksum-deferred packet is forwarded to a device that needs a
  19.263 - 	 * checksum, correct the pointers and force checksumming.
  19.264 - 	 */
  19.265 - 	if(skb_checksum_setup(skb))
  19.266 - 		goto out_kfree_skb;
  19.267 -  
  19.268  	/* If packet is not checksummed and device does not support
  19.269  	 * checksumming for this protocol, complete checksumming here.
  19.270  	 */
  19.271  	if (skb->ip_summed == CHECKSUM_HW &&
  19.272 -	    (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
  19.273 +	    (!(dev->features & NETIF_F_GEN_CSUM) &&
  19.274  	     (!(dev->features & NETIF_F_IP_CSUM) ||
  19.275  	      skb->protocol != htons(ETH_P_IP))))
  19.276  	      	if (skb_checksum_help(skb, 0))
  19.277  	      		goto out_kfree_skb;
  19.278  
  19.279 +gso:
  19.280  	spin_lock_prefetch(&dev->queue_lock);
  19.281  
  19.282  	/* Disable soft irqs for various locks below. Also 
  19.283  	 * stops preemption for RCU. 
  19.284  	 */
  19.285 -	local_bh_disable(); 
  19.286 +	rcu_read_lock_bh(); 
  19.287  
  19.288  	/* Updates of qdisc are serialized by queue_lock. 
  19.289  	 * The struct Qdisc which is pointed to by qdisc is now a 
  19.290 @@ -1358,8 +1436,8 @@ int dev_queue_xmit(struct sk_buff *skb)
  19.291  	/* The device has no queue. Common case for software devices:
  19.292  	   loopback, all the sorts of tunnels...
  19.293  
  19.294 -	   Really, it is unlikely that xmit_lock protection is necessary here.
  19.295 -	   (f.e. loopback and IP tunnels are clean ignoring statistics
  19.296 +	   Really, it is unlikely that netif_tx_lock protection is necessary
  19.297 +	   here.  (f.e. loopback and IP tunnels are clean ignoring statistics
  19.298  	   counters.)
  19.299  	   However, it is possible, that they rely on protection
  19.300  	   made by us here.
  19.301 @@ -1375,11 +1453,8 @@ int dev_queue_xmit(struct sk_buff *skb)
  19.302  			HARD_TX_LOCK(dev, cpu);
  19.303  
  19.304  			if (!netif_queue_stopped(dev)) {
  19.305 -				if (netdev_nit)
  19.306 -					dev_queue_xmit_nit(skb, dev);
  19.307 -
  19.308  				rc = 0;
  19.309 -				if (!dev->hard_start_xmit(skb, dev)) {
  19.310 +				if (!dev_hard_start_xmit(skb, dev)) {
  19.311  					HARD_TX_UNLOCK(dev);
  19.312  					goto out;
  19.313  				}
  19.314 @@ -1398,13 +1473,13 @@ int dev_queue_xmit(struct sk_buff *skb)
  19.315  	}
  19.316  
  19.317  	rc = -ENETDOWN;
  19.318 -	local_bh_enable();
  19.319 +	rcu_read_unlock_bh();
  19.320  
  19.321  out_kfree_skb:
  19.322  	kfree_skb(skb);
  19.323  	return rc;
  19.324  out:
  19.325 -	local_bh_enable();
  19.326 +	rcu_read_unlock_bh();
  19.327  	return rc;
  19.328  }
  19.329  
  19.330 @@ -2732,7 +2807,7 @@ int register_netdevice(struct net_device
  19.331  	BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
  19.332  
  19.333  	spin_lock_init(&dev->queue_lock);
  19.334 -	spin_lock_init(&dev->xmit_lock);
  19.335 +	spin_lock_init(&dev->_xmit_lock);
  19.336  	dev->xmit_lock_owner = -1;
  19.337  #ifdef CONFIG_NET_CLS_ACT
  19.338  	spin_lock_init(&dev->ingress_lock);
  19.339 @@ -2776,9 +2851,7 @@ int register_netdevice(struct net_device
  19.340  
  19.341  	/* Fix illegal SG+CSUM combinations. */
  19.342  	if ((dev->features & NETIF_F_SG) &&
  19.343 -	    !(dev->features & (NETIF_F_IP_CSUM |
  19.344 -			       NETIF_F_NO_CSUM |
  19.345 -			       NETIF_F_HW_CSUM))) {
  19.346 +	    !(dev->features & NETIF_F_ALL_CSUM)) {
  19.347  		printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
  19.348  		       dev->name);
  19.349  		dev->features &= ~NETIF_F_SG;
  19.350 @@ -3330,7 +3403,6 @@ subsys_initcall(net_dev_init);
  19.351  EXPORT_SYMBOL(__dev_get_by_index);
  19.352  EXPORT_SYMBOL(__dev_get_by_name);
  19.353  EXPORT_SYMBOL(__dev_remove_pack);
  19.354 -EXPORT_SYMBOL(__skb_linearize);
  19.355  EXPORT_SYMBOL(dev_valid_name);
  19.356  EXPORT_SYMBOL(dev_add_pack);
  19.357  EXPORT_SYMBOL(dev_alloc_name);
    20.1 --- a/linux-2.6-xen-sparse/net/core/skbuff.c	Wed Jun 28 07:51:52 2006 -0600
    20.2 +++ b/linux-2.6-xen-sparse/net/core/skbuff.c	Wed Jun 28 07:52:21 2006 -0600
    20.3 @@ -165,9 +165,9 @@ struct sk_buff *__alloc_skb(unsigned int
    20.4  	shinfo = skb_shinfo(skb);
    20.5  	atomic_set(&shinfo->dataref, 1);
    20.6  	shinfo->nr_frags  = 0;
    20.7 -	shinfo->tso_size = 0;
    20.8 -	shinfo->tso_segs = 0;
    20.9 -	shinfo->ufo_size = 0;
   20.10 +	shinfo->gso_size = 0;
   20.11 +	shinfo->gso_segs = 0;
   20.12 +	shinfo->gso_type = 0;
   20.13  	shinfo->ip6_frag_id = 0;
   20.14  	shinfo->frag_list = NULL;
   20.15  
   20.16 @@ -237,9 +237,9 @@ struct sk_buff *alloc_skb_from_cache(kme
   20.17  	shinfo = skb_shinfo(skb);
   20.18  	atomic_set(&shinfo->dataref, 1);
   20.19  	shinfo->nr_frags  = 0;
   20.20 -	shinfo->tso_size = 0;
   20.21 -	shinfo->tso_segs = 0;
   20.22 -	shinfo->ufo_size = 0;
   20.23 +	shinfo->gso_size = 0;
   20.24 +	shinfo->gso_segs = 0;
   20.25 +	shinfo->gso_type = 0;
   20.26  	shinfo->ip6_frag_id = 0;
   20.27  	shinfo->frag_list = NULL;
   20.28  
   20.29 @@ -524,8 +524,9 @@ static void copy_skb_header(struct sk_bu
   20.30  	new->tc_index	= old->tc_index;
   20.31  #endif
   20.32  	atomic_set(&new->users, 1);
   20.33 -	skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
   20.34 -	skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
   20.35 +	skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
   20.36 +	skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
   20.37 +	skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
   20.38  }
   20.39  
   20.40  /**
   20.41 @@ -1800,6 +1801,133 @@ int skb_append_datato_frags(struct sock 
   20.42  	return 0;
   20.43  }
   20.44  
   20.45 +/**
   20.46 + *	skb_segment - Perform protocol segmentation on skb.
   20.47 + *	@skb: buffer to segment
   20.48 + *	@features: features for the output path (see dev->features)
   20.49 + *
   20.50 + *	This function performs segmentation on the given skb.  It returns
   20.51 + *	the segment at the given position.  It returns NULL if there are
   20.52 + *	no more segments to generate, or when an error is encountered.
   20.53 + */
   20.54 +struct sk_buff *skb_segment(struct sk_buff *skb, int features)
   20.55 +{
   20.56 +	struct sk_buff *segs = NULL;
   20.57 +	struct sk_buff *tail = NULL;
   20.58 +	unsigned int mss = skb_shinfo(skb)->gso_size;
   20.59 +	unsigned int doffset = skb->data - skb->mac.raw;
   20.60 +	unsigned int offset = doffset;
   20.61 +	unsigned int headroom;
   20.62 +	unsigned int len;
   20.63 +	int sg = features & NETIF_F_SG;
   20.64 +	int nfrags = skb_shinfo(skb)->nr_frags;
   20.65 +	int err = -ENOMEM;
   20.66 +	int i = 0;
   20.67 +	int pos;
   20.68 +
   20.69 +	__skb_push(skb, doffset);
   20.70 +	headroom = skb_headroom(skb);
   20.71 +	pos = skb_headlen(skb);
   20.72 +
   20.73 +	do {
   20.74 +		struct sk_buff *nskb;
   20.75 +		skb_frag_t *frag;
   20.76 +		int hsize, nsize;
   20.77 +		int k;
   20.78 +		int size;
   20.79 +
   20.80 +		len = skb->len - offset;
   20.81 +		if (len > mss)
   20.82 +			len = mss;
   20.83 +
   20.84 +		hsize = skb_headlen(skb) - offset;
   20.85 +		if (hsize < 0)
   20.86 +			hsize = 0;
   20.87 +		nsize = hsize + doffset;
   20.88 +		if (nsize > len + doffset || !sg)
   20.89 +			nsize = len + doffset;
   20.90 +
   20.91 +		nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
   20.92 +		if (unlikely(!nskb))
   20.93 +			goto err;
   20.94 +
   20.95 +		if (segs)
   20.96 +			tail->next = nskb;
   20.97 +		else
   20.98 +			segs = nskb;
   20.99 +		tail = nskb;
  20.100 +
  20.101 +		nskb->dev = skb->dev;
  20.102 +		nskb->priority = skb->priority;
  20.103 +		nskb->protocol = skb->protocol;
  20.104 +		nskb->dst = dst_clone(skb->dst);
  20.105 +		memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
  20.106 +		nskb->pkt_type = skb->pkt_type;
  20.107 +		nskb->mac_len = skb->mac_len;
  20.108 +
  20.109 +		skb_reserve(nskb, headroom);
  20.110 +		nskb->mac.raw = nskb->data;
  20.111 +		nskb->nh.raw = nskb->data + skb->mac_len;
  20.112 +		nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
  20.113 +		memcpy(skb_put(nskb, doffset), skb->data, doffset);
  20.114 +
  20.115 +		if (!sg) {
  20.116 +			nskb->csum = skb_copy_and_csum_bits(skb, offset,
  20.117 +							    skb_put(nskb, len),
  20.118 +							    len, 0);
  20.119 +			continue;
  20.120 +		}
  20.121 +
  20.122 +		frag = skb_shinfo(nskb)->frags;
  20.123 +		k = 0;
  20.124 +
  20.125 +		nskb->ip_summed = CHECKSUM_HW;
  20.126 +		nskb->csum = skb->csum;
  20.127 +		memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
  20.128 +
  20.129 +		while (pos < offset + len) {
  20.130 +			BUG_ON(i >= nfrags);
  20.131 +
  20.132 +			*frag = skb_shinfo(skb)->frags[i];
  20.133 +			get_page(frag->page);
  20.134 +			size = frag->size;
  20.135 +
  20.136 +			if (pos < offset) {
  20.137 +				frag->page_offset += offset - pos;
  20.138 +				frag->size -= offset - pos;
  20.139 +			}
  20.140 +
  20.141 +			k++;
  20.142 +
  20.143 +			if (pos + size <= offset + len) {
  20.144 +				i++;
  20.145 +				pos += size;
  20.146 +			} else {
  20.147 +				frag->size -= pos + size - (offset + len);
  20.148 +				break;
  20.149 +			}
  20.150 +
  20.151 +			frag++;
  20.152 +		}
  20.153 +
  20.154 +		skb_shinfo(nskb)->nr_frags = k;
  20.155 +		nskb->data_len = len - hsize;
  20.156 +		nskb->len += nskb->data_len;
  20.157 +		nskb->truesize += nskb->data_len;
  20.158 +	} while ((offset += len) < skb->len);
  20.159 +
  20.160 +	return segs;
  20.161 +
  20.162 +err:
  20.163 +	while ((skb = segs)) {
  20.164 +		segs = skb->next;
  20.165 +		kfree(skb);
  20.166 +	}
  20.167 +	return ERR_PTR(err);
  20.168 +}
  20.169 +
  20.170 +EXPORT_SYMBOL_GPL(skb_segment);
  20.171 +
  20.172  void __init skb_init(void)
  20.173  {
  20.174  	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/patches/linux-2.6.16.13/net-gso.patch	Wed Jun 28 07:52:21 2006 -0600
    21.3 @@ -0,0 +1,2907 @@
    21.4 +diff --git a/Documentation/networking/netdevices.txt b/Documentation/networking/netdevices.txt
    21.5 +index 3c0a5ba..847cedb 100644
    21.6 +--- a/Documentation/networking/netdevices.txt
    21.7 ++++ b/Documentation/networking/netdevices.txt
    21.8 +@@ -42,9 +42,9 @@ dev->get_stats:
    21.9 + 	Context: nominally process, but don't sleep inside an rwlock
   21.10 + 
   21.11 + dev->hard_start_xmit:
   21.12 +-	Synchronization: dev->xmit_lock spinlock.
   21.13 ++	Synchronization: netif_tx_lock spinlock.
   21.14 + 	When the driver sets NETIF_F_LLTX in dev->features this will be
   21.15 +-	called without holding xmit_lock. In this case the driver 
   21.16 ++	called without holding netif_tx_lock. In this case the driver
   21.17 + 	has to lock by itself when needed. It is recommended to use a try lock
   21.18 + 	for this and return -1 when the spin lock fails. 
   21.19 + 	The locking there should also properly protect against 
   21.20 +@@ -62,12 +62,12 @@ dev->hard_start_xmit:
   21.21 + 	  Only valid when NETIF_F_LLTX is set.
   21.22 + 
   21.23 + dev->tx_timeout:
   21.24 +-	Synchronization: dev->xmit_lock spinlock.
   21.25 ++	Synchronization: netif_tx_lock spinlock.
   21.26 + 	Context: BHs disabled
   21.27 + 	Notes: netif_queue_stopped() is guaranteed true
   21.28 + 
   21.29 + dev->set_multicast_list:
   21.30 +-	Synchronization: dev->xmit_lock spinlock.
   21.31 ++	Synchronization: netif_tx_lock spinlock.
   21.32 + 	Context: BHs disabled
   21.33 + 
   21.34 + dev->poll:
   21.35 +diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
   21.36 +index 4be9769..2e7cac7 100644
   21.37 +--- a/drivers/block/aoe/aoenet.c
   21.38 ++++ b/drivers/block/aoe/aoenet.c
   21.39 +@@ -95,9 +95,8 @@ mac_addr(char addr[6])
   21.40 + static struct sk_buff *
   21.41 + skb_check(struct sk_buff *skb)
   21.42 + {
   21.43 +-	if (skb_is_nonlinear(skb))
   21.44 + 	if ((skb = skb_share_check(skb, GFP_ATOMIC)))
   21.45 +-	if (skb_linearize(skb, GFP_ATOMIC) < 0) {
   21.46 ++	if (skb_linearize(skb)) {
   21.47 + 		dev_kfree_skb(skb);
   21.48 + 		return NULL;
   21.49 + 	}
   21.50 +diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
   21.51 +index a2408d7..c90e620 100644
   21.52 +--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
   21.53 ++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
   21.54 +@@ -821,7 +821,8 @@ void ipoib_mcast_restart_task(void *dev_
   21.55 + 
   21.56 + 	ipoib_mcast_stop_thread(dev, 0);
   21.57 + 
   21.58 +-	spin_lock_irqsave(&dev->xmit_lock, flags);
   21.59 ++	local_irq_save(flags);
   21.60 ++	netif_tx_lock(dev);
   21.61 + 	spin_lock(&priv->lock);
   21.62 + 
   21.63 + 	/*
   21.64 +@@ -896,7 +897,8 @@ void ipoib_mcast_restart_task(void *dev_
   21.65 + 	}
   21.66 + 
   21.67 + 	spin_unlock(&priv->lock);
   21.68 +-	spin_unlock_irqrestore(&dev->xmit_lock, flags);
   21.69 ++	netif_tx_unlock(dev);
   21.70 ++	local_irq_restore(flags);
   21.71 + 
   21.72 + 	/* We have to cancel outside of the spinlock */
   21.73 + 	list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
   21.74 +diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
   21.75 +index 6711eb6..8d2351f 100644
   21.76 +--- a/drivers/media/dvb/dvb-core/dvb_net.c
   21.77 ++++ b/drivers/media/dvb/dvb-core/dvb_net.c
   21.78 +@@ -1052,7 +1052,7 @@ static void wq_set_multicast_list (void 
   21.79 + 
   21.80 + 	dvb_net_feed_stop(dev);
   21.81 + 	priv->rx_mode = RX_MODE_UNI;
   21.82 +-	spin_lock_bh(&dev->xmit_lock);
   21.83 ++	netif_tx_lock_bh(dev);
   21.84 + 
   21.85 + 	if (dev->flags & IFF_PROMISC) {
   21.86 + 		dprintk("%s: promiscuous mode\n", dev->name);
   21.87 +@@ -1077,7 +1077,7 @@ static void wq_set_multicast_list (void 
   21.88 + 		}
   21.89 + 	}
   21.90 + 
   21.91 +-	spin_unlock_bh(&dev->xmit_lock);
   21.92 ++	netif_tx_unlock_bh(dev);
   21.93 + 	dvb_net_feed_start(dev);
   21.94 + }
   21.95 + 
   21.96 +diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
   21.97 +index dd41049..6615583 100644
   21.98 +--- a/drivers/net/8139cp.c
   21.99 ++++ b/drivers/net/8139cp.c
  21.100 +@@ -794,7 +794,7 @@ #endif
  21.101 + 	entry = cp->tx_head;
  21.102 + 	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
  21.103 + 	if (dev->features & NETIF_F_TSO)
  21.104 +-		mss = skb_shinfo(skb)->tso_size;
  21.105 ++		mss = skb_shinfo(skb)->gso_size;
  21.106 + 
  21.107 + 	if (skb_shinfo(skb)->nr_frags == 0) {
  21.108 + 		struct cp_desc *txd = &cp->tx_ring[entry];
  21.109 +diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
  21.110 +index a24200d..b5e39a1 100644
  21.111 +--- a/drivers/net/bnx2.c
  21.112 ++++ b/drivers/net/bnx2.c
  21.113 +@@ -1593,7 +1593,7 @@ bnx2_tx_int(struct bnx2 *bp)
  21.114 + 		skb = tx_buf->skb;
  21.115 + #ifdef BCM_TSO 
  21.116 + 		/* partial BD completions possible with TSO packets */
  21.117 +-		if (skb_shinfo(skb)->tso_size) {
  21.118 ++		if (skb_shinfo(skb)->gso_size) {
  21.119 + 			u16 last_idx, last_ring_idx;
  21.120 + 
  21.121 + 			last_idx = sw_cons +
  21.122 +@@ -1948,7 +1948,7 @@ bnx2_poll(struct net_device *dev, int *b
  21.123 + 	return 1;
  21.124 + }
  21.125 + 
  21.126 +-/* Called with rtnl_lock from vlan functions and also dev->xmit_lock
  21.127 ++/* Called with rtnl_lock from vlan functions and also netif_tx_lock
  21.128 +  * from set_multicast.
  21.129 +  */
  21.130 + static void
  21.131 +@@ -4403,7 +4403,7 @@ bnx2_vlan_rx_kill_vid(struct net_device 
  21.132 + }
  21.133 + #endif
  21.134 + 
  21.135 +-/* Called with dev->xmit_lock.
  21.136 ++/* Called with netif_tx_lock.
  21.137 +  * hard_start_xmit is pseudo-lockless - a lock is only required when
  21.138 +  * the tx queue is full. This way, we get the benefit of lockless
  21.139 +  * operations most of the time without the complexities to handle
  21.140 +@@ -4441,7 +4441,7 @@ bnx2_start_xmit(struct sk_buff *skb, str
  21.141 + 			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
  21.142 + 	}
  21.143 + #ifdef BCM_TSO 
  21.144 +-	if ((mss = skb_shinfo(skb)->tso_size) &&
  21.145 ++	if ((mss = skb_shinfo(skb)->gso_size) &&
  21.146 + 		(skb->len > (bp->dev->mtu + ETH_HLEN))) {
  21.147 + 		u32 tcp_opt_len, ip_tcp_len;
  21.148 + 
  21.149 +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
  21.150 +index bcf9f17..e970921 100644
  21.151 +--- a/drivers/net/bonding/bond_main.c
  21.152 ++++ b/drivers/net/bonding/bond_main.c
  21.153 +@@ -1145,8 +1145,7 @@ int bond_sethwaddr(struct net_device *bo
  21.154 + }
  21.155 + 
  21.156 + #define BOND_INTERSECT_FEATURES \
  21.157 +-	(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
  21.158 +-	NETIF_F_TSO|NETIF_F_UFO)
  21.159 ++	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
  21.160 + 
  21.161 + /* 
  21.162 +  * Compute the common dev->feature set available to all slaves.  Some
  21.163 +@@ -1164,9 +1163,7 @@ static int bond_compute_features(struct 
  21.164 + 		features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
  21.165 + 
  21.166 + 	if ((features & NETIF_F_SG) && 
  21.167 +-	    !(features & (NETIF_F_IP_CSUM |
  21.168 +-			  NETIF_F_NO_CSUM |
  21.169 +-			  NETIF_F_HW_CSUM)))
  21.170 ++	    !(features & NETIF_F_ALL_CSUM))
  21.171 + 		features &= ~NETIF_F_SG;
  21.172 + 
  21.173 + 	/* 
  21.174 +@@ -4147,7 +4144,7 @@ static int bond_init(struct net_device *
  21.175 + 	 */
  21.176 + 	bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
  21.177 + 
  21.178 +-	/* don't acquire bond device's xmit_lock when 
  21.179 ++	/* don't acquire bond device's netif_tx_lock when
  21.180 + 	 * transmitting */
  21.181 + 	bond_dev->features |= NETIF_F_LLTX;
  21.182 + 
  21.183 +diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
  21.184 +index 30ff8ea..7b7d360 100644
  21.185 +--- a/drivers/net/chelsio/sge.c
  21.186 ++++ b/drivers/net/chelsio/sge.c
  21.187 +@@ -1419,7 +1419,7 @@ int t1_start_xmit(struct sk_buff *skb, s
  21.188 + 	struct cpl_tx_pkt *cpl;
  21.189 + 
  21.190 + #ifdef NETIF_F_TSO
  21.191 +-	if (skb_shinfo(skb)->tso_size) {
  21.192 ++	if (skb_shinfo(skb)->gso_size) {
  21.193 + 		int eth_type;
  21.194 + 		struct cpl_tx_pkt_lso *hdr;
  21.195 + 
  21.196 +@@ -1434,7 +1434,7 @@ #ifdef NETIF_F_TSO
  21.197 + 		hdr->ip_hdr_words = skb->nh.iph->ihl;
  21.198 + 		hdr->tcp_hdr_words = skb->h.th->doff;
  21.199 + 		hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
  21.200 +-						skb_shinfo(skb)->tso_size));
  21.201 ++						skb_shinfo(skb)->gso_size));
  21.202 + 		hdr->len = htonl(skb->len - sizeof(*hdr));
  21.203 + 		cpl = (struct cpl_tx_pkt *)hdr;
  21.204 + 		sge->stats.tx_lso_pkts++;
  21.205 +diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
  21.206 +index fa29402..681d284 100644
  21.207 +--- a/drivers/net/e1000/e1000_main.c
  21.208 ++++ b/drivers/net/e1000/e1000_main.c
  21.209 +@@ -2526,7 +2526,7 @@ #ifdef NETIF_F_TSO
  21.210 + 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
  21.211 + 	int err;
  21.212 + 
  21.213 +-	if (skb_shinfo(skb)->tso_size) {
  21.214 ++	if (skb_shinfo(skb)->gso_size) {
  21.215 + 		if (skb_header_cloned(skb)) {
  21.216 + 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
  21.217 + 			if (err)
  21.218 +@@ -2534,7 +2534,7 @@ #ifdef NETIF_F_TSO
  21.219 + 		}
  21.220 + 
  21.221 + 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
  21.222 +-		mss = skb_shinfo(skb)->tso_size;
  21.223 ++		mss = skb_shinfo(skb)->gso_size;
  21.224 + 		if (skb->protocol == ntohs(ETH_P_IP)) {
  21.225 + 			skb->nh.iph->tot_len = 0;
  21.226 + 			skb->nh.iph->check = 0;
  21.227 +@@ -2651,7 +2651,7 @@ #ifdef NETIF_F_TSO
  21.228 + 		 * tso gets written back prematurely before the data is fully
  21.229 + 		 * DMAd to the controller */
  21.230 + 		if (!skb->data_len && tx_ring->last_tx_tso &&
  21.231 +-				!skb_shinfo(skb)->tso_size) {
  21.232 ++				!skb_shinfo(skb)->gso_size) {
  21.233 + 			tx_ring->last_tx_tso = 0;
  21.234 + 			size -= 4;
  21.235 + 		}
  21.236 +@@ -2893,7 +2893,7 @@ #endif
  21.237 + 	}
  21.238 + 
  21.239 + #ifdef NETIF_F_TSO
  21.240 +-	mss = skb_shinfo(skb)->tso_size;
  21.241 ++	mss = skb_shinfo(skb)->gso_size;
  21.242 + 	/* The controller does a simple calculation to 
  21.243 + 	 * make sure there is enough room in the FIFO before
  21.244 + 	 * initiating the DMA for each buffer.  The calc is:
  21.245 +@@ -2935,7 +2935,7 @@ #endif
  21.246 + #ifdef NETIF_F_TSO
  21.247 + 	/* Controller Erratum workaround */
  21.248 + 	if (!skb->data_len && tx_ring->last_tx_tso &&
  21.249 +-		!skb_shinfo(skb)->tso_size)
  21.250 ++		!skb_shinfo(skb)->gso_size)
  21.251 + 		count++;
  21.252 + #endif
  21.253 + 
  21.254 +diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
  21.255 +index 3682ec6..c35f16e 100644
  21.256 +--- a/drivers/net/forcedeth.c
  21.257 ++++ b/drivers/net/forcedeth.c
  21.258 +@@ -482,9 +482,9 @@ #define LPA_1000HALF	0x0400
  21.259 +  * critical parts:
  21.260 +  * - rx is (pseudo-) lockless: it relies on the single-threading provided
  21.261 +  *	by the arch code for interrupts.
  21.262 +- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
  21.263 ++ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission
  21.264 +  *	needs dev->priv->lock :-(
  21.265 +- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
  21.266 ++ * - set_multicast_list: preparation lockless, relies on netif_tx_lock.
  21.267 +  */
  21.268 + 
  21.269 + /* in dev: base, irq */
  21.270 +@@ -1016,7 +1016,7 @@ static void drain_ring(struct net_device
  21.271 + 
  21.272 + /*
  21.273 +  * nv_start_xmit: dev->hard_start_xmit function
  21.274 +- * Called with dev->xmit_lock held.
  21.275 ++ * Called with netif_tx_lock held.
  21.276 +  */
  21.277 + static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
  21.278 + {
  21.279 +@@ -1105,8 +1105,8 @@ static int nv_start_xmit(struct sk_buff 
  21.280 + 	np->tx_skbuff[nr] = skb;
  21.281 + 
  21.282 + #ifdef NETIF_F_TSO
  21.283 +-	if (skb_shinfo(skb)->tso_size)
  21.284 +-		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
  21.285 ++	if (skb_shinfo(skb)->gso_size)
  21.286 ++		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT);
  21.287 + 	else
  21.288 + #endif
  21.289 + 	tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
  21.290 +@@ -1203,7 +1203,7 @@ static void nv_tx_done(struct net_device
  21.291 + 
  21.292 + /*
  21.293 +  * nv_tx_timeout: dev->tx_timeout function
  21.294 +- * Called with dev->xmit_lock held.
  21.295 ++ * Called with netif_tx_lock held.
  21.296 +  */
  21.297 + static void nv_tx_timeout(struct net_device *dev)
  21.298 + {
  21.299 +@@ -1524,7 +1524,7 @@ static int nv_change_mtu(struct net_devi
  21.300 + 		 * Changing the MTU is a rare event, it shouldn't matter.
  21.301 + 		 */
  21.302 + 		disable_irq(dev->irq);
  21.303 +-		spin_lock_bh(&dev->xmit_lock);
  21.304 ++		netif_tx_lock_bh(dev);
  21.305 + 		spin_lock(&np->lock);
  21.306 + 		/* stop engines */
  21.307 + 		nv_stop_rx(dev);
  21.308 +@@ -1559,7 +1559,7 @@ static int nv_change_mtu(struct net_devi
  21.309 + 		nv_start_rx(dev);
  21.310 + 		nv_start_tx(dev);
  21.311 + 		spin_unlock(&np->lock);
  21.312 +-		spin_unlock_bh(&dev->xmit_lock);
  21.313 ++		netif_tx_unlock_bh(dev);
  21.314 + 		enable_irq(dev->irq);
  21.315 + 	}
  21.316 + 	return 0;
  21.317 +@@ -1594,7 +1594,7 @@ static int nv_set_mac_address(struct net
  21.318 + 	memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
  21.319 + 
  21.320 + 	if (netif_running(dev)) {
  21.321 +-		spin_lock_bh(&dev->xmit_lock);
  21.322 ++		netif_tx_lock_bh(dev);
  21.323 + 		spin_lock_irq(&np->lock);
  21.324 + 
  21.325 + 		/* stop rx engine */
  21.326 +@@ -1606,7 +1606,7 @@ static int nv_set_mac_address(struct net
  21.327 + 		/* restart rx engine */
  21.328 + 		nv_start_rx(dev);
  21.329 + 		spin_unlock_irq(&np->lock);
  21.330 +-		spin_unlock_bh(&dev->xmit_lock);
  21.331 ++		netif_tx_unlock_bh(dev);
  21.332 + 	} else {
  21.333 + 		nv_copy_mac_to_hw(dev);
  21.334 + 	}
  21.335 +@@ -1615,7 +1615,7 @@ static int nv_set_mac_address(struct net
  21.336 + 
  21.337 + /*
  21.338 +  * nv_set_multicast: dev->set_multicast function
  21.339 +- * Called with dev->xmit_lock held.
  21.340 ++ * Called with netif_tx_lock held.
  21.341 +  */
  21.342 + static void nv_set_multicast(struct net_device *dev)
  21.343 + {
  21.344 +diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
  21.345 +index 102c1f0..d12605f 100644
  21.346 +--- a/drivers/net/hamradio/6pack.c
  21.347 ++++ b/drivers/net/hamradio/6pack.c
  21.348 +@@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net
  21.349 + {
  21.350 + 	struct sockaddr_ax25 *sa = addr;
  21.351 + 
  21.352 +-	spin_lock_irq(&dev->xmit_lock);
  21.353 ++	netif_tx_lock_bh(dev);
  21.354 + 	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
  21.355 +-	spin_unlock_irq(&dev->xmit_lock);
  21.356 ++	netif_tx_unlock_bh(dev);
  21.357 + 
  21.358 + 	return 0;
  21.359 + }
  21.360 +@@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_stru
  21.361 + 			break;
  21.362 + 		}
  21.363 + 
  21.364 +-		spin_lock_irq(&dev->xmit_lock);
  21.365 ++		netif_tx_lock_bh(dev);
  21.366 + 		memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
  21.367 +-		spin_unlock_irq(&dev->xmit_lock);
  21.368 ++		netif_tx_unlock_bh(dev);
  21.369 + 
  21.370 + 		err = 0;
  21.371 + 		break;
  21.372 +diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
  21.373 +index dc5e9d5..5c66f5a 100644
  21.374 +--- a/drivers/net/hamradio/mkiss.c
  21.375 ++++ b/drivers/net/hamradio/mkiss.c
  21.376 +@@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net
  21.377 + {
  21.378 + 	struct sockaddr_ax25 *sa = addr;
  21.379 + 
  21.380 +-	spin_lock_irq(&dev->xmit_lock);
  21.381 ++	netif_tx_lock_bh(dev);
  21.382 + 	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
  21.383 +-	spin_unlock_irq(&dev->xmit_lock);
  21.384 ++	netif_tx_unlock_bh(dev);
  21.385 + 
  21.386 + 	return 0;
  21.387 + }
  21.388 +@@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct
  21.389 + 			break;
  21.390 + 		}
  21.391 + 
  21.392 +-		spin_lock_irq(&dev->xmit_lock);
  21.393 ++		netif_tx_lock_bh(dev);
  21.394 + 		memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
  21.395 +-		spin_unlock_irq(&dev->xmit_lock);
  21.396 ++		netif_tx_unlock_bh(dev);
  21.397 + 
  21.398 + 		err = 0;
  21.399 + 		break;
  21.400 +diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
  21.401 +index 31fb2d7..2e222ef 100644
  21.402 +--- a/drivers/net/ifb.c
  21.403 ++++ b/drivers/net/ifb.c
  21.404 +@@ -76,13 +76,13 @@ static void ri_tasklet(unsigned long dev
  21.405 + 	dp->st_task_enter++;
  21.406 + 	if ((skb = skb_peek(&dp->tq)) == NULL) {
  21.407 + 		dp->st_txq_refl_try++;
  21.408 +-		if (spin_trylock(&_dev->xmit_lock)) {
  21.409 ++		if (netif_tx_trylock(_dev)) {
  21.410 + 			dp->st_rxq_enter++;
  21.411 + 			while ((skb = skb_dequeue(&dp->rq)) != NULL) {
  21.412 + 				skb_queue_tail(&dp->tq, skb);
  21.413 + 				dp->st_rx2tx_tran++;
  21.414 + 			}
  21.415 +-			spin_unlock(&_dev->xmit_lock);
  21.416 ++			netif_tx_unlock(_dev);
  21.417 + 		} else {
  21.418 + 			/* reschedule */
  21.419 + 			dp->st_rxq_notenter++;
  21.420 +@@ -110,7 +110,7 @@ static void ri_tasklet(unsigned long dev
  21.421 + 		}
  21.422 + 	}
  21.423 + 
  21.424 +-	if (spin_trylock(&_dev->xmit_lock)) {
  21.425 ++	if (netif_tx_trylock(_dev)) {
  21.426 + 		dp->st_rxq_check++;
  21.427 + 		if ((skb = skb_peek(&dp->rq)) == NULL) {
  21.428 + 			dp->tasklet_pending = 0;
  21.429 +@@ -118,10 +118,10 @@ static void ri_tasklet(unsigned long dev
  21.430 + 				netif_wake_queue(_dev);
  21.431 + 		} else {
  21.432 + 			dp->st_rxq_rsch++;
  21.433 +-			spin_unlock(&_dev->xmit_lock);
  21.434 ++			netif_tx_unlock(_dev);
  21.435 + 			goto resched;
  21.436 + 		}
  21.437 +-		spin_unlock(&_dev->xmit_lock);
  21.438 ++		netif_tx_unlock(_dev);
  21.439 + 	} else {
  21.440 + resched:
  21.441 + 		dp->tasklet_pending = 1;
  21.442 +diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
  21.443 +index a9f49f0..339d4a7 100644
  21.444 +--- a/drivers/net/irda/vlsi_ir.c
  21.445 ++++ b/drivers/net/irda/vlsi_ir.c
  21.446 +@@ -959,7 +959,7 @@ static int vlsi_hard_start_xmit(struct s
  21.447 + 			    ||  (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec))
  21.448 + 			    	break;
  21.449 + 			udelay(100);
  21.450 +-			/* must not sleep here - we are called under xmit_lock! */
  21.451 ++			/* must not sleep here - called under netif_tx_lock! */
  21.452 + 		}
  21.453 + 	}
  21.454 + 
  21.455 +diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
  21.456 +index f9f77e4..bdab369 100644
  21.457 +--- a/drivers/net/ixgb/ixgb_main.c
  21.458 ++++ b/drivers/net/ixgb/ixgb_main.c
  21.459 +@@ -1163,7 +1163,7 @@ #ifdef NETIF_F_TSO
  21.460 + 	uint16_t ipcse, tucse, mss;
  21.461 + 	int err;
  21.462 + 
  21.463 +-	if(likely(skb_shinfo(skb)->tso_size)) {
  21.464 ++	if(likely(skb_shinfo(skb)->gso_size)) {
  21.465 + 		if (skb_header_cloned(skb)) {
  21.466 + 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
  21.467 + 			if (err)
  21.468 +@@ -1171,7 +1171,7 @@ #ifdef NETIF_F_TSO
  21.469 + 		}
  21.470 + 
  21.471 + 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
  21.472 +-		mss = skb_shinfo(skb)->tso_size;
  21.473 ++		mss = skb_shinfo(skb)->gso_size;
  21.474 + 		skb->nh.iph->tot_len = 0;
  21.475 + 		skb->nh.iph->check = 0;
  21.476 + 		skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
  21.477 +diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
  21.478 +index 690a1aa..9bcaa80 100644
  21.479 +--- a/drivers/net/loopback.c
  21.480 ++++ b/drivers/net/loopback.c
  21.481 +@@ -74,7 +74,7 @@ static void emulate_large_send_offload(s
  21.482 + 	struct iphdr *iph = skb->nh.iph;
  21.483 + 	struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
  21.484 + 	unsigned int doffset = (iph->ihl + th->doff) * 4;
  21.485 +-	unsigned int mtu = skb_shinfo(skb)->tso_size + doffset;
  21.486 ++	unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
  21.487 + 	unsigned int offset = 0;
  21.488 + 	u32 seq = ntohl(th->seq);
  21.489 + 	u16 id  = ntohs(iph->id);
  21.490 +@@ -139,7 +139,7 @@ #ifndef LOOPBACK_MUST_CHECKSUM
  21.491 + #endif
  21.492 + 
  21.493 + #ifdef LOOPBACK_TSO
  21.494 +-	if (skb_shinfo(skb)->tso_size) {
  21.495 ++	if (skb_shinfo(skb)->gso_size) {
  21.496 + 		BUG_ON(skb->protocol != htons(ETH_P_IP));
  21.497 + 		BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
  21.498 + 
  21.499 +diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
  21.500 +index c0998ef..0fac9d5 100644
  21.501 +--- a/drivers/net/mv643xx_eth.c
  21.502 ++++ b/drivers/net/mv643xx_eth.c
  21.503 +@@ -1107,7 +1107,7 @@ static int mv643xx_eth_start_xmit(struct
  21.504 + 
  21.505 + #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
  21.506 + 	if (has_tiny_unaligned_frags(skb)) {
  21.507 +-		if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
  21.508 ++		if (__skb_linearize(skb)) {
  21.509 + 			stats->tx_dropped++;
  21.510 + 			printk(KERN_DEBUG "%s: failed to linearize tiny "
  21.511 + 					"unaligned fragment\n", dev->name);
  21.512 +diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
  21.513 +index 9d6d254..c9ed624 100644
  21.514 +--- a/drivers/net/natsemi.c
  21.515 ++++ b/drivers/net/natsemi.c
  21.516 +@@ -323,12 +323,12 @@ performance critical codepaths:
  21.517 + The rx process only runs in the interrupt handler. Access from outside
  21.518 + the interrupt handler is only permitted after disable_irq().
  21.519 + 
  21.520 +-The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap
  21.521 ++The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap
  21.522 + is set, then access is permitted under spin_lock_irq(&np->lock).
  21.523 + 
  21.524 + Thus configuration functions that want to access everything must call
  21.525 + 	disable_irq(dev->irq);
  21.526 +-	spin_lock_bh(dev->xmit_lock);
  21.527 ++	netif_tx_lock_bh(dev);
  21.528 + 	spin_lock_irq(&np->lock);
  21.529 + 
  21.530 + IV. Notes
  21.531 +diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
  21.532 +index 8cc0d0b..e53b313 100644
  21.533 +--- a/drivers/net/r8169.c
  21.534 ++++ b/drivers/net/r8169.c
  21.535 +@@ -2171,7 +2171,7 @@ static int rtl8169_xmit_frags(struct rtl
  21.536 + static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
  21.537 + {
  21.538 + 	if (dev->features & NETIF_F_TSO) {
  21.539 +-		u32 mss = skb_shinfo(skb)->tso_size;
  21.540 ++		u32 mss = skb_shinfo(skb)->gso_size;
  21.541 + 
  21.542 + 		if (mss)
  21.543 + 			return LargeSend | ((mss & MSSMask) << MSSShift);
  21.544 +diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
  21.545 +index b7f00d6..439f45f 100644
  21.546 +--- a/drivers/net/s2io.c
  21.547 ++++ b/drivers/net/s2io.c
  21.548 +@@ -3522,8 +3522,8 @@ #endif
  21.549 + 	txdp->Control_1 = 0;
  21.550 + 	txdp->Control_2 = 0;
  21.551 + #ifdef NETIF_F_TSO
  21.552 +-	mss = skb_shinfo(skb)->tso_size;
  21.553 +-	if (mss) {
  21.554 ++	mss = skb_shinfo(skb)->gso_size;
  21.555 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) {
  21.556 + 		txdp->Control_1 |= TXD_TCP_LSO_EN;
  21.557 + 		txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
  21.558 + 	}
  21.559 +@@ -3543,10 +3543,10 @@ #endif
  21.560 + 	}
  21.561 + 
  21.562 + 	frg_len = skb->len - skb->data_len;
  21.563 +-	if (skb_shinfo(skb)->ufo_size) {
  21.564 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) {
  21.565 + 		int ufo_size;
  21.566 + 
  21.567 +-		ufo_size = skb_shinfo(skb)->ufo_size;
  21.568 ++		ufo_size = skb_shinfo(skb)->gso_size;
  21.569 + 		ufo_size &= ~7;
  21.570 + 		txdp->Control_1 |= TXD_UFO_EN;
  21.571 + 		txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
  21.572 +@@ -3572,7 +3572,7 @@ #endif
  21.573 + 	txdp->Host_Control = (unsigned long) skb;
  21.574 + 	txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
  21.575 + 
  21.576 +-	if (skb_shinfo(skb)->ufo_size)
  21.577 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  21.578 + 		txdp->Control_1 |= TXD_UFO_EN;
  21.579 + 
  21.580 + 	frg_cnt = skb_shinfo(skb)->nr_frags;
  21.581 +@@ -3587,12 +3587,12 @@ #endif
  21.582 + 		    (sp->pdev, frag->page, frag->page_offset,
  21.583 + 		     frag->size, PCI_DMA_TODEVICE);
  21.584 + 		txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
  21.585 +-		if (skb_shinfo(skb)->ufo_size)
  21.586 ++		if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  21.587 + 			txdp->Control_1 |= TXD_UFO_EN;
  21.588 + 	}
  21.589 + 	txdp->Control_1 |= TXD_GATHER_CODE_LAST;
  21.590 + 
  21.591 +-	if (skb_shinfo(skb)->ufo_size)
  21.592 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  21.593 + 		frg_cnt++; /* as Txd0 was used for inband header */
  21.594 + 
  21.595 + 	tx_fifo = mac_control->tx_FIFO_start[queue];
  21.596 +@@ -3606,7 +3606,7 @@ #ifdef NETIF_F_TSO
  21.597 + 	if (mss)
  21.598 + 		val64 |= TX_FIFO_SPECIAL_FUNC;
  21.599 + #endif
  21.600 +-	if (skb_shinfo(skb)->ufo_size)
  21.601 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  21.602 + 		val64 |= TX_FIFO_SPECIAL_FUNC;
  21.603 + 	writeq(val64, &tx_fifo->List_Control);
  21.604 + 
  21.605 +diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
  21.606 +index 0618cd5..2a55eb3 100644
  21.607 +--- a/drivers/net/sky2.c
  21.608 ++++ b/drivers/net/sky2.c
  21.609 +@@ -1125,7 +1125,7 @@ static unsigned tx_le_req(const struct s
  21.610 + 	count = sizeof(dma_addr_t) / sizeof(u32);
  21.611 + 	count += skb_shinfo(skb)->nr_frags * count;
  21.612 + 
  21.613 +-	if (skb_shinfo(skb)->tso_size)
  21.614 ++	if (skb_shinfo(skb)->gso_size)
  21.615 + 		++count;
  21.616 + 
  21.617 + 	if (skb->ip_summed == CHECKSUM_HW)
  21.618 +@@ -1197,7 +1197,7 @@ static int sky2_xmit_frame(struct sk_buf
  21.619 + 	}
  21.620 + 
  21.621 + 	/* Check for TCP Segmentation Offload */
  21.622 +-	mss = skb_shinfo(skb)->tso_size;
  21.623 ++	mss = skb_shinfo(skb)->gso_size;
  21.624 + 	if (mss != 0) {
  21.625 + 		/* just drop the packet if non-linear expansion fails */
  21.626 + 		if (skb_header_cloned(skb) &&
  21.627 +diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
  21.628 +index caf4102..fc9164a 100644
  21.629 +--- a/drivers/net/tg3.c
  21.630 ++++ b/drivers/net/tg3.c
  21.631 +@@ -3664,7 +3664,7 @@ static int tg3_start_xmit(struct sk_buff
  21.632 + #if TG3_TSO_SUPPORT != 0
  21.633 + 	mss = 0;
  21.634 + 	if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
  21.635 +-	    (mss = skb_shinfo(skb)->tso_size) != 0) {
  21.636 ++	    (mss = skb_shinfo(skb)->gso_size) != 0) {
  21.637 + 		int tcp_opt_len, ip_tcp_len;
  21.638 + 
  21.639 + 		if (skb_header_cloned(skb) &&
  21.640 +diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
  21.641 +index 5b1af39..11de5af 100644
  21.642 +--- a/drivers/net/tulip/winbond-840.c
  21.643 ++++ b/drivers/net/tulip/winbond-840.c
  21.644 +@@ -1605,11 +1605,11 @@ #ifdef CONFIG_PM
  21.645 +  * - get_stats:
  21.646 +  * 	spin_lock_irq(np->lock), doesn't touch hw if not present
  21.647 +  * - hard_start_xmit:
  21.648 +- * 	netif_stop_queue + spin_unlock_wait(&dev->xmit_lock);
  21.649 ++ * 	synchronize_irq + netif_tx_disable;
  21.650 +  * - tx_timeout:
  21.651 +- * 	netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
  21.652 ++ * 	netif_device_detach + netif_tx_disable;
  21.653 +  * - set_multicast_list
  21.654 +- * 	netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
  21.655 ++ * 	netif_device_detach + netif_tx_disable;
  21.656 +  * - interrupt handler
  21.657 +  * 	doesn't touch hw if not present, synchronize_irq waits for
  21.658 +  * 	running instances of the interrupt handler.
  21.659 +@@ -1635,11 +1635,10 @@ static int w840_suspend (struct pci_dev 
  21.660 + 		netif_device_detach(dev);
  21.661 + 		update_csr6(dev, 0);
  21.662 + 		iowrite32(0, ioaddr + IntrEnable);
  21.663 +-		netif_stop_queue(dev);
  21.664 + 		spin_unlock_irq(&np->lock);
  21.665 + 
  21.666 +-		spin_unlock_wait(&dev->xmit_lock);
  21.667 + 		synchronize_irq(dev->irq);
  21.668 ++		netif_tx_disable(dev);
  21.669 + 	
  21.670 + 		np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
  21.671 + 
  21.672 +diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
  21.673 +index 4c76cb7..30c48c9 100644
  21.674 +--- a/drivers/net/typhoon.c
  21.675 ++++ b/drivers/net/typhoon.c
  21.676 +@@ -340,7 +340,7 @@ #define typhoon_synchronize_irq(x) synch
  21.677 + #endif
  21.678 + 
  21.679 + #if defined(NETIF_F_TSO)
  21.680 +-#define skb_tso_size(x)		(skb_shinfo(x)->tso_size)
  21.681 ++#define skb_tso_size(x)		(skb_shinfo(x)->gso_size)
  21.682 + #define TSO_NUM_DESCRIPTORS	2
  21.683 + #define TSO_OFFLOAD_ON		TYPHOON_OFFLOAD_TCP_SEGMENT
  21.684 + #else
  21.685 +diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
  21.686 +index ed1f837..2eb6b5f 100644
  21.687 +--- a/drivers/net/via-velocity.c
  21.688 ++++ b/drivers/net/via-velocity.c
  21.689 +@@ -1899,6 +1899,13 @@ static int velocity_xmit(struct sk_buff 
  21.690 + 
  21.691 + 	int pktlen = skb->len;
  21.692 + 
  21.693 ++#ifdef VELOCITY_ZERO_COPY_SUPPORT
  21.694 ++	if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
  21.695 ++		kfree_skb(skb);
  21.696 ++		return 0;
  21.697 ++	}
  21.698 ++#endif
  21.699 ++
  21.700 + 	spin_lock_irqsave(&vptr->lock, flags);
  21.701 + 
  21.702 + 	index = vptr->td_curr[qnum];
  21.703 +@@ -1914,8 +1921,6 @@ static int velocity_xmit(struct sk_buff 
  21.704 + 	 */
  21.705 + 	if (pktlen < ETH_ZLEN) {
  21.706 + 		/* Cannot occur until ZC support */
  21.707 +-		if(skb_linearize(skb, GFP_ATOMIC))
  21.708 +-			return 0; 
  21.709 + 		pktlen = ETH_ZLEN;
  21.710 + 		memcpy(tdinfo->buf, skb->data, skb->len);
  21.711 + 		memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
  21.712 +@@ -1933,7 +1938,6 @@ #ifdef VELOCITY_ZERO_COPY_SUPPORT
  21.713 + 		int nfrags = skb_shinfo(skb)->nr_frags;
  21.714 + 		tdinfo->skb = skb;
  21.715 + 		if (nfrags > 6) {
  21.716 +-			skb_linearize(skb, GFP_ATOMIC);
  21.717 + 			memcpy(tdinfo->buf, skb->data, skb->len);
  21.718 + 			tdinfo->skb_dma[0] = tdinfo->buf_dma;
  21.719 + 			td_ptr->tdesc0.pktsize = 
  21.720 +diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
  21.721 +index 6fd0bf7..75237c1 100644
  21.722 +--- a/drivers/net/wireless/orinoco.c
  21.723 ++++ b/drivers/net/wireless/orinoco.c
  21.724 +@@ -1835,7 +1835,9 @@ static int __orinoco_program_rids(struct
  21.725 + 	/* Set promiscuity / multicast*/
  21.726 + 	priv->promiscuous = 0;
  21.727 + 	priv->mc_count = 0;
  21.728 +-	__orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
  21.729 ++
  21.730 ++	/* FIXME: what about netif_tx_lock */
  21.731 ++	__orinoco_set_multicast_list(dev);
  21.732 + 
  21.733 + 	return 0;
  21.734 + }
  21.735 +diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
  21.736 +index 82cb4af..57cec40 100644
  21.737 +--- a/drivers/s390/net/qeth_eddp.c
  21.738 ++++ b/drivers/s390/net/qeth_eddp.c
  21.739 +@@ -421,7 +421,7 @@ #endif /* CONFIG_QETH_VLAN */
  21.740 +        }
  21.741 + 	tcph = eddp->skb->h.th;
  21.742 + 	while (eddp->skb_offset < eddp->skb->len) {
  21.743 +-		data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
  21.744 ++		data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
  21.745 + 			       (int)(eddp->skb->len - eddp->skb_offset));
  21.746 + 		/* prepare qdio hdr */
  21.747 + 		if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
  21.748 +@@ -516,20 +516,20 @@ qeth_eddp_calc_num_pages(struct qeth_edd
  21.749 + 	
  21.750 + 	QETH_DBF_TEXT(trace, 5, "eddpcanp");
  21.751 + 	/* can we put multiple skbs in one page? */
  21.752 +-	skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
  21.753 ++	skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
  21.754 + 	if (skbs_per_page > 1){
  21.755 +-		ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
  21.756 ++		ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
  21.757 + 				 skbs_per_page + 1;
  21.758 + 		ctx->elements_per_skb = 1;
  21.759 + 	} else {
  21.760 + 		/* no -> how many elements per skb? */
  21.761 +-		ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
  21.762 ++		ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
  21.763 + 				     PAGE_SIZE) >> PAGE_SHIFT;
  21.764 + 		ctx->num_pages = ctx->elements_per_skb *
  21.765 +-				 (skb_shinfo(skb)->tso_segs + 1);
  21.766 ++				 (skb_shinfo(skb)->gso_segs + 1);
  21.767 + 	}
  21.768 + 	ctx->num_elements = ctx->elements_per_skb *
  21.769 +-			    (skb_shinfo(skb)->tso_segs + 1);
  21.770 ++			    (skb_shinfo(skb)->gso_segs + 1);
  21.771 + }
  21.772 + 
  21.773 + static inline struct qeth_eddp_context *
  21.774 +diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
  21.775 +index dba7f7f..d9cc997 100644
  21.776 +--- a/drivers/s390/net/qeth_main.c
  21.777 ++++ b/drivers/s390/net/qeth_main.c
  21.778 +@@ -4454,7 +4454,7 @@ qeth_send_packet(struct qeth_card *card,
  21.779 + 	queue = card->qdio.out_qs
  21.780 + 		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
  21.781 + 
  21.782 +-	if (skb_shinfo(skb)->tso_size)
  21.783 ++	if (skb_shinfo(skb)->gso_size)
  21.784 + 		large_send = card->options.large_send;
  21.785 + 
  21.786 + 	/*are we able to do TSO ? If so ,prepare and send it from here */
  21.787 +@@ -4501,7 +4501,7 @@ qeth_send_packet(struct qeth_card *card,
  21.788 + 		card->stats.tx_packets++;
  21.789 + 		card->stats.tx_bytes += skb->len;
  21.790 + #ifdef CONFIG_QETH_PERF_STATS
  21.791 +-		if (skb_shinfo(skb)->tso_size &&
  21.792 ++		if (skb_shinfo(skb)->gso_size &&
  21.793 + 		   !(large_send == QETH_LARGE_SEND_NO)) {
  21.794 + 			card->perf_stats.large_send_bytes += skb->len;
  21.795 + 			card->perf_stats.large_send_cnt++;
  21.796 +diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
  21.797 +index 1286dde..89cbf34 100644
  21.798 +--- a/drivers/s390/net/qeth_tso.h
  21.799 ++++ b/drivers/s390/net/qeth_tso.h
  21.800 +@@ -51,7 +51,7 @@ qeth_tso_fill_header(struct qeth_card *c
  21.801 + 	hdr->ext.hdr_version = 1;
  21.802 + 	hdr->ext.hdr_len     = 28;
  21.803 + 	/*insert non-fix values */
  21.804 +-	hdr->ext.mss = skb_shinfo(skb)->tso_size;
  21.805 ++	hdr->ext.mss = skb_shinfo(skb)->gso_size;
  21.806 + 	hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
  21.807 + 	hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
  21.808 + 				       sizeof(struct qeth_hdr_tso));
  21.809 +diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
  21.810 +index 93535f0..9269df7 100644
  21.811 +--- a/include/linux/ethtool.h
  21.812 ++++ b/include/linux/ethtool.h
  21.813 +@@ -408,6 +408,8 @@ #define ETHTOOL_STSO		0x0000001f /* Set 
  21.814 + #define ETHTOOL_GPERMADDR	0x00000020 /* Get permanent hardware address */
  21.815 + #define ETHTOOL_GUFO		0x00000021 /* Get UFO enable (ethtool_value) */
  21.816 + #define ETHTOOL_SUFO		0x00000022 /* Set UFO enable (ethtool_value) */
  21.817 ++#define ETHTOOL_GGSO		0x00000023 /* Get GSO enable (ethtool_value) */
  21.818 ++#define ETHTOOL_SGSO		0x00000024 /* Set GSO enable (ethtool_value) */
  21.819 + 
  21.820 + /* compatibility with older code */
  21.821 + #define SPARC_ETH_GSET		ETHTOOL_GSET
  21.822 +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
  21.823 +index 7fda03d..47b0965 100644
  21.824 +--- a/include/linux/netdevice.h
  21.825 ++++ b/include/linux/netdevice.h
  21.826 +@@ -230,7 +230,8 @@ enum netdev_state_t
  21.827 + 	__LINK_STATE_SCHED,
  21.828 + 	__LINK_STATE_NOCARRIER,
  21.829 + 	__LINK_STATE_RX_SCHED,
  21.830 +-	__LINK_STATE_LINKWATCH_PENDING
  21.831 ++	__LINK_STATE_LINKWATCH_PENDING,
  21.832 ++	__LINK_STATE_QDISC_RUNNING,
  21.833 + };
  21.834 + 
  21.835 + 
  21.836 +@@ -306,9 +307,17 @@ #define NETIF_F_HW_VLAN_TX	128	/* Transm
  21.837 + #define NETIF_F_HW_VLAN_RX	256	/* Receive VLAN hw acceleration */
  21.838 + #define NETIF_F_HW_VLAN_FILTER	512	/* Receive filtering on VLAN */
  21.839 + #define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
  21.840 +-#define NETIF_F_TSO		2048	/* Can offload TCP/IP segmentation */
  21.841 ++#define NETIF_F_GSO		2048	/* Enable software GSO. */
  21.842 + #define NETIF_F_LLTX		4096	/* LockLess TX */
  21.843 +-#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
  21.844 ++
  21.845 ++	/* Segmentation offload features */
  21.846 ++#define NETIF_F_GSO_SHIFT	16
  21.847 ++#define NETIF_F_TSO		(SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
  21.848 ++#define NETIF_F_UFO		(SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
  21.849 ++#define NETIF_F_GSO_ROBUST	(SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
  21.850 ++
  21.851 ++#define NETIF_F_GEN_CSUM	(NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
  21.852 ++#define NETIF_F_ALL_CSUM	(NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
  21.853 + 
  21.854 + 	struct net_device	*next_sched;
  21.855 + 
  21.856 +@@ -394,6 +403,9 @@ #define NETIF_F_UFO             8192    
  21.857 + 	struct list_head	qdisc_list;
  21.858 + 	unsigned long		tx_queue_len;	/* Max frames per queue allowed */
  21.859 + 
  21.860 ++	/* Partially transmitted GSO packet. */
  21.861 ++	struct sk_buff		*gso_skb;
  21.862 ++
  21.863 + 	/* ingress path synchronizer */
  21.864 + 	spinlock_t		ingress_lock;
  21.865 + 	struct Qdisc		*qdisc_ingress;
  21.866 +@@ -402,7 +414,7 @@ #define NETIF_F_UFO             8192    
  21.867 +  * One part is mostly used on xmit path (device)
  21.868 +  */
  21.869 + 	/* hard_start_xmit synchronizer */
  21.870 +-	spinlock_t		xmit_lock ____cacheline_aligned_in_smp;
  21.871 ++	spinlock_t		_xmit_lock ____cacheline_aligned_in_smp;
  21.872 + 	/* cpu id of processor entered to hard_start_xmit or -1,
  21.873 + 	   if nobody entered there.
  21.874 + 	 */
  21.875 +@@ -527,6 +539,8 @@ struct packet_type {
  21.876 + 					 struct net_device *,
  21.877 + 					 struct packet_type *,
  21.878 + 					 struct net_device *);
  21.879 ++	struct sk_buff		*(*gso_segment)(struct sk_buff *skb,
  21.880 ++						int features);
  21.881 + 	void			*af_packet_priv;
  21.882 + 	struct list_head	list;
  21.883 + };
  21.884 +@@ -693,7 +707,8 @@ extern int		dev_change_name(struct net_d
  21.885 + extern int		dev_set_mtu(struct net_device *, int);
  21.886 + extern int		dev_set_mac_address(struct net_device *,
  21.887 + 					    struct sockaddr *);
  21.888 +-extern void		dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
  21.889 ++extern int		dev_hard_start_xmit(struct sk_buff *skb,
  21.890 ++					    struct net_device *dev);
  21.891 + 
  21.892 + extern void		dev_init(void);
  21.893 + 
  21.894 +@@ -900,11 +915,43 @@ static inline void __netif_rx_complete(s
  21.895 + 	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
  21.896 + }
  21.897 + 
  21.898 ++static inline void netif_tx_lock(struct net_device *dev)
  21.899 ++{
  21.900 ++	spin_lock(&dev->_xmit_lock);
  21.901 ++	dev->xmit_lock_owner = smp_processor_id();
  21.902 ++}
  21.903 ++
  21.904 ++static inline void netif_tx_lock_bh(struct net_device *dev)
  21.905 ++{
  21.906 ++	spin_lock_bh(&dev->_xmit_lock);
  21.907 ++	dev->xmit_lock_owner = smp_processor_id();
  21.908 ++}
  21.909 ++
  21.910 ++static inline int netif_tx_trylock(struct net_device *dev)
  21.911 ++{
  21.912 ++	int err = spin_trylock(&dev->_xmit_lock);
  21.913 ++	if (!err)
  21.914 ++		dev->xmit_lock_owner = smp_processor_id();
  21.915 ++	return err;
  21.916 ++}
  21.917 ++
  21.918 ++static inline void netif_tx_unlock(struct net_device *dev)
  21.919 ++{
  21.920 ++	dev->xmit_lock_owner = -1;
  21.921 ++	spin_unlock(&dev->_xmit_lock);
  21.922 ++}
  21.923 ++
  21.924 ++static inline void netif_tx_unlock_bh(struct net_device *dev)
  21.925 ++{
  21.926 ++	dev->xmit_lock_owner = -1;
  21.927 ++	spin_unlock_bh(&dev->_xmit_lock);
  21.928 ++}
  21.929 ++
  21.930 + static inline void netif_tx_disable(struct net_device *dev)
  21.931 + {
  21.932 +-	spin_lock_bh(&dev->xmit_lock);
  21.933 ++	netif_tx_lock_bh(dev);
  21.934 + 	netif_stop_queue(dev);
  21.935 +-	spin_unlock_bh(&dev->xmit_lock);
  21.936 ++	netif_tx_unlock_bh(dev);
  21.937 + }
  21.938 + 
  21.939 + /* These functions live elsewhere (drivers/net/net_init.c, but related) */
  21.940 +@@ -932,6 +979,7 @@ extern int		netdev_max_backlog;
  21.941 + extern int		weight_p;
  21.942 + extern int		netdev_set_master(struct net_device *dev, struct net_device *master);
  21.943 + extern int skb_checksum_help(struct sk_buff *skb, int inward);
  21.944 ++extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
  21.945 + #ifdef CONFIG_BUG
  21.946 + extern void netdev_rx_csum_fault(struct net_device *dev);
  21.947 + #else
  21.948 +@@ -951,6 +999,18 @@ #endif
  21.949 + 
  21.950 + extern void linkwatch_run_queue(void);
  21.951 + 
  21.952 ++static inline int skb_gso_ok(struct sk_buff *skb, int features)
  21.953 ++{
  21.954 ++	int feature = skb_shinfo(skb)->gso_size ?
  21.955 ++		      skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
  21.956 ++	return (features & feature) == feature;
  21.957 ++}
  21.958 ++
  21.959 ++static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
  21.960 ++{
  21.961 ++	return !skb_gso_ok(skb, dev->features);
  21.962 ++}
  21.963 ++
  21.964 + #endif /* __KERNEL__ */
  21.965 + 
  21.966 + #endif	/* _LINUX_DEV_H */
  21.967 +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
  21.968 +index ad7cc22..b19d45d 100644
  21.969 +--- a/include/linux/skbuff.h
  21.970 ++++ b/include/linux/skbuff.h
  21.971 +@@ -134,9 +134,10 @@ struct skb_frag_struct {
  21.972 + struct skb_shared_info {
  21.973 + 	atomic_t	dataref;
  21.974 + 	unsigned short	nr_frags;
  21.975 +-	unsigned short	tso_size;
  21.976 +-	unsigned short	tso_segs;
  21.977 +-	unsigned short  ufo_size;
  21.978 ++	unsigned short	gso_size;
  21.979 ++	/* Warning: this field is not always filled in (UFO)! */
  21.980 ++	unsigned short	gso_segs;
  21.981 ++	unsigned short  gso_type;
  21.982 + 	unsigned int    ip6_frag_id;
  21.983 + 	struct sk_buff	*frag_list;
  21.984 + 	skb_frag_t	frags[MAX_SKB_FRAGS];
  21.985 +@@ -168,6 +169,14 @@ enum {
  21.986 + 	SKB_FCLONE_CLONE,
  21.987 + };
  21.988 + 
  21.989 ++enum {
  21.990 ++	SKB_GSO_TCPV4 = 1 << 0,
  21.991 ++	SKB_GSO_UDPV4 = 1 << 1,
  21.992 ++
  21.993 ++	/* This indicates the skb is from an untrusted source. */
  21.994 ++	SKB_GSO_DODGY = 1 << 2,
  21.995 ++};
  21.996 ++
  21.997 + /** 
  21.998 +  *	struct sk_buff - socket buffer
  21.999 +  *	@next: Next buffer in list
 21.1000 +@@ -1148,18 +1157,34 @@ static inline int skb_can_coalesce(struc
 21.1001 + 	return 0;
 21.1002 + }
 21.1003 + 
 21.1004 ++static inline int __skb_linearize(struct sk_buff *skb)
 21.1005 ++{
 21.1006 ++	return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
 21.1007 ++}
 21.1008 ++
 21.1009 + /**
 21.1010 +  *	skb_linearize - convert paged skb to linear one
 21.1011 +  *	@skb: buffer to linarize
 21.1012 +- *	@gfp: allocation mode
 21.1013 +  *
 21.1014 +  *	If there is no free memory -ENOMEM is returned, otherwise zero
 21.1015 +  *	is returned and the old skb data released.
 21.1016 +  */
 21.1017 +-extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
 21.1018 +-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
 21.1019 ++static inline int skb_linearize(struct sk_buff *skb)
 21.1020 ++{
 21.1021 ++	return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
 21.1022 ++}
 21.1023 ++
 21.1024 ++/**
 21.1025 ++ *	skb_linearize_cow - make sure skb is linear and writable
 21.1026 ++ *	@skb: buffer to process
 21.1027 ++ *
 21.1028 ++ *	If there is no free memory -ENOMEM is returned, otherwise zero
 21.1029 ++ *	is returned and the old skb data released.
 21.1030 ++ */
 21.1031 ++static inline int skb_linearize_cow(struct sk_buff *skb)
 21.1032 + {
 21.1033 +-	return __skb_linearize(skb, gfp);
 21.1034 ++	return skb_is_nonlinear(skb) || skb_cloned(skb) ?
 21.1035 ++	       __skb_linearize(skb) : 0;
 21.1036 + }
 21.1037 + 
 21.1038 + /**
 21.1039 +@@ -1254,6 +1279,7 @@ extern void	       skb_split(struct sk_b
 21.1040 + 				 struct sk_buff *skb1, const u32 len);
 21.1041 + 
 21.1042 + extern void	       skb_release_data(struct sk_buff *skb);
 21.1043 ++extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
 21.1044 + 
 21.1045 + static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
 21.1046 + 				       int len, void *buffer)
 21.1047 +diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
 21.1048 +index b94d1ad..75b5b93 100644
 21.1049 +--- a/include/net/pkt_sched.h
 21.1050 ++++ b/include/net/pkt_sched.h
 21.1051 +@@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_ge
 21.1052 + 		struct rtattr *tab);
 21.1053 + extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
 21.1054 + 
 21.1055 +-extern int qdisc_restart(struct net_device *dev);
 21.1056 ++extern void __qdisc_run(struct net_device *dev);
 21.1057 + 
 21.1058 + static inline void qdisc_run(struct net_device *dev)
 21.1059 + {
 21.1060 +-	while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
 21.1061 +-		/* NOTHING */;
 21.1062 ++	if (!netif_queue_stopped(dev) &&
 21.1063 ++	    !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
 21.1064 ++		__qdisc_run(dev);
 21.1065 + }
 21.1066 + 
 21.1067 + extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
 21.1068 +diff --git a/include/net/protocol.h b/include/net/protocol.h
 21.1069 +index 6dc5970..0d2dcdb 100644
 21.1070 +--- a/include/net/protocol.h
 21.1071 ++++ b/include/net/protocol.h
 21.1072 +@@ -37,6 +37,8 @@ #define MAX_INET_PROTOS	256		/* Must be 
 21.1073 + struct net_protocol {
 21.1074 + 	int			(*handler)(struct sk_buff *skb);
 21.1075 + 	void			(*err_handler)(struct sk_buff *skb, u32 info);
 21.1076 ++	struct sk_buff	       *(*gso_segment)(struct sk_buff *skb,
 21.1077 ++					       int features);
 21.1078 + 	int			no_policy;
 21.1079 + };
 21.1080 + 
 21.1081 +diff --git a/include/net/sock.h b/include/net/sock.h
 21.1082 +index f63d0d5..a8e8d21 100644
 21.1083 +--- a/include/net/sock.h
 21.1084 ++++ b/include/net/sock.h
 21.1085 +@@ -1064,9 +1064,13 @@ static inline void sk_setup_caps(struct 
 21.1086 + {
 21.1087 + 	__sk_dst_set(sk, dst);
 21.1088 + 	sk->sk_route_caps = dst->dev->features;
 21.1089 ++	if (sk->sk_route_caps & NETIF_F_GSO)
 21.1090 ++		sk->sk_route_caps |= NETIF_F_TSO;
 21.1091 + 	if (sk->sk_route_caps & NETIF_F_TSO) {
 21.1092 + 		if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
 21.1093 + 			sk->sk_route_caps &= ~NETIF_F_TSO;
 21.1094 ++		else 
 21.1095 ++			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
 21.1096 + 	}
 21.1097 + }
 21.1098 + 
 21.1099 +diff --git a/include/net/tcp.h b/include/net/tcp.h
 21.1100 +index 77f21c6..70e1d5f 100644
 21.1101 +--- a/include/net/tcp.h
 21.1102 ++++ b/include/net/tcp.h
 21.1103 +@@ -552,13 +552,13 @@ #include <net/tcp_ecn.h>
 21.1104 +  */
 21.1105 + static inline int tcp_skb_pcount(const struct sk_buff *skb)
 21.1106 + {
 21.1107 +-	return skb_shinfo(skb)->tso_segs;
 21.1108 ++	return skb_shinfo(skb)->gso_segs;
 21.1109 + }
 21.1110 + 
 21.1111 + /* This is valid iff tcp_skb_pcount() > 1. */
 21.1112 + static inline int tcp_skb_mss(const struct sk_buff *skb)
 21.1113 + {
 21.1114 +-	return skb_shinfo(skb)->tso_size;
 21.1115 ++	return skb_shinfo(skb)->gso_size;
 21.1116 + }
 21.1117 + 
 21.1118 + static inline void tcp_dec_pcount_approx(__u32 *count,
 21.1119 +@@ -1063,6 +1063,8 @@ extern struct request_sock_ops tcp_reque
 21.1120 + 
 21.1121 + extern int tcp_v4_destroy_sock(struct sock *sk);
 21.1122 + 
 21.1123 ++extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
 21.1124 ++
 21.1125 + #ifdef CONFIG_PROC_FS
 21.1126 + extern int  tcp4_proc_init(void);
 21.1127 + extern void tcp4_proc_exit(void);
 21.1128 +diff --git a/net/atm/clip.c b/net/atm/clip.c
 21.1129 +index 1842a4e..6dc21a7 100644
 21.1130 +--- a/net/atm/clip.c
 21.1131 ++++ b/net/atm/clip.c
 21.1132 +@@ -101,7 +101,7 @@ static void unlink_clip_vcc(struct clip_
 21.1133 + 		printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
 21.1134 + 		return;
 21.1135 + 	}
 21.1136 +-	spin_lock_bh(&entry->neigh->dev->xmit_lock);	/* block clip_start_xmit() */
 21.1137 ++	netif_tx_lock_bh(entry->neigh->dev);	/* block clip_start_xmit() */
 21.1138 + 	entry->neigh->used = jiffies;
 21.1139 + 	for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
 21.1140 + 		if (*walk == clip_vcc) {
 21.1141 +@@ -125,7 +125,7 @@ static void unlink_clip_vcc(struct clip_
 21.1142 + 	printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
 21.1143 + 	  "0x%p)\n",entry,clip_vcc);
 21.1144 + out:
 21.1145 +-	spin_unlock_bh(&entry->neigh->dev->xmit_lock);
 21.1146 ++	netif_tx_unlock_bh(entry->neigh->dev);
 21.1147 + }
 21.1148 + 
 21.1149 + /* The neighbour entry n->lock is held. */
 21.1150 +diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
 21.1151 +index 0b33a7b..180e79b 100644
 21.1152 +--- a/net/bridge/br_device.c
 21.1153 ++++ b/net/bridge/br_device.c
 21.1154 +@@ -146,9 +146,9 @@ static int br_set_tx_csum(struct net_dev
 21.1155 + 	struct net_bridge *br = netdev_priv(dev);
 21.1156 + 
 21.1157 + 	if (data)
 21.1158 +-		br->feature_mask |= NETIF_F_IP_CSUM;
 21.1159 ++		br->feature_mask |= NETIF_F_NO_CSUM;
 21.1160 + 	else
 21.1161 +-		br->feature_mask &= ~NETIF_F_IP_CSUM;
 21.1162 ++		br->feature_mask &= ~NETIF_F_ALL_CSUM;
 21.1163 + 
 21.1164 + 	br_features_recompute(br);
 21.1165 + 	return 0;
 21.1166 +@@ -185,6 +185,6 @@ void br_dev_setup(struct net_device *dev
 21.1167 + 	dev->set_mac_address = br_set_mac_address;
 21.1168 + 	dev->priv_flags = IFF_EBRIDGE;
 21.1169 + 
 21.1170 +- 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
 21.1171 +- 		| NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
 21.1172 ++ 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
 21.1173 ++ 			NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST;
 21.1174 + }
 21.1175 +diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
 21.1176 +index 2d24fb4..00b1128 100644
 21.1177 +--- a/net/bridge/br_forward.c
 21.1178 ++++ b/net/bridge/br_forward.c
 21.1179 +@@ -32,7 +32,7 @@ static inline int should_deliver(const s
 21.1180 + int br_dev_queue_push_xmit(struct sk_buff *skb)
 21.1181 + {
 21.1182 + 	/* drop mtu oversized packets except tso */
 21.1183 +-	if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
 21.1184 ++	if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size)
 21.1185 + 		kfree_skb(skb);
 21.1186 + 	else {
 21.1187 + #ifdef CONFIG_BRIDGE_NETFILTER
 21.1188 +diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
 21.1189 +index f36b35e..0617146 100644
 21.1190 +--- a/net/bridge/br_if.c
 21.1191 ++++ b/net/bridge/br_if.c
 21.1192 +@@ -385,17 +385,28 @@ void br_features_recompute(struct net_br
 21.1193 + 	struct net_bridge_port *p;
 21.1194 + 	unsigned long features, checksum;
 21.1195 + 
 21.1196 +-	features = br->feature_mask &~ NETIF_F_IP_CSUM;
 21.1197 +-	checksum = br->feature_mask & NETIF_F_IP_CSUM;
 21.1198 ++	checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
 21.1199 ++	features = br->feature_mask & ~NETIF_F_ALL_CSUM;
 21.1200 + 
 21.1201 + 	list_for_each_entry(p, &br->port_list, list) {
 21.1202 +-		if (!(p->dev->features 
 21.1203 +-		      & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
 21.1204 ++		unsigned long feature = p->dev->features;
 21.1205 ++
 21.1206 ++		if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
 21.1207 ++			checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
 21.1208 ++		if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
 21.1209 ++			checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
 21.1210 ++		if (!(feature & NETIF_F_IP_CSUM))
 21.1211 + 			checksum = 0;
 21.1212 +-		features &= p->dev->features;
 21.1213 ++
 21.1214 ++		if (feature & NETIF_F_GSO)
 21.1215 ++			feature |= NETIF_F_TSO;
 21.1216 ++		feature |= NETIF_F_GSO;
 21.1217 ++
 21.1218 ++		features &= feature;
 21.1219 + 	}
 21.1220 + 
 21.1221 +-	br->dev->features = features | checksum | NETIF_F_LLTX;
 21.1222 ++	br->dev->features = features | checksum | NETIF_F_LLTX |
 21.1223 ++			    NETIF_F_GSO_ROBUST;
 21.1224 + }
 21.1225 + 
 21.1226 + /* called with RTNL */
 21.1227 +diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
 21.1228 +index 9e27373..588207f 100644
 21.1229 +--- a/net/bridge/br_netfilter.c
 21.1230 ++++ b/net/bridge/br_netfilter.c
 21.1231 +@@ -743,7 +743,7 @@ static int br_nf_dev_queue_xmit(struct s
 21.1232 + {
 21.1233 + 	if (skb->protocol == htons(ETH_P_IP) &&
 21.1234 + 	    skb->len > skb->dev->mtu &&
 21.1235 +-	    !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
 21.1236 ++	    !skb_shinfo(skb)->gso_size)
 21.1237 + 		return ip_fragment(skb, br_dev_queue_push_xmit);
 21.1238 + 	else
 21.1239 + 		return br_dev_queue_push_xmit(skb);
 21.1240 +diff --git a/net/core/dev.c b/net/core/dev.c
 21.1241 +index 12a214c..32e1056 100644
 21.1242 +--- a/net/core/dev.c
 21.1243 ++++ b/net/core/dev.c
 21.1244 +@@ -115,6 +115,7 @@ #include <linux/wireless.h>		/* Note : w
 21.1245 + #include <net/iw_handler.h>
 21.1246 + #endif	/* CONFIG_NET_RADIO */
 21.1247 + #include <asm/current.h>
 21.1248 ++#include <linux/err.h>
 21.1249 + 
 21.1250 + /*
 21.1251 +  *	The list of packet types we will receive (as opposed to discard)
 21.1252 +@@ -1032,7 +1033,7 @@ static inline void net_timestamp(struct 
 21.1253 +  *	taps currently in use.
 21.1254 +  */
 21.1255 + 
 21.1256 +-void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 21.1257 ++static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 21.1258 + {
 21.1259 + 	struct packet_type *ptype;
 21.1260 + 
 21.1261 +@@ -1106,6 +1107,45 @@ out:	
 21.1262 + 	return ret;
 21.1263 + }
 21.1264 + 
 21.1265 ++/**
 21.1266 ++ *	skb_gso_segment - Perform segmentation on skb.
 21.1267 ++ *	@skb: buffer to segment
 21.1268 ++ *	@features: features for the output path (see dev->features)
 21.1269 ++ *
 21.1270 ++ *	This function segments the given skb and returns a list of segments.
 21.1271 ++ *
 21.1272 ++ *	It may return NULL if the skb requires no segmentation.  This is
 21.1273 ++ *	only possible when GSO is used for verifying header integrity.
 21.1274 ++ */
 21.1275 ++struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
 21.1276 ++{
 21.1277 ++	struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
 21.1278 ++	struct packet_type *ptype;
 21.1279 ++	int type = skb->protocol;
 21.1280 ++
 21.1281 ++	BUG_ON(skb_shinfo(skb)->frag_list);
 21.1282 ++	BUG_ON(skb->ip_summed != CHECKSUM_HW);
 21.1283 ++
 21.1284 ++	skb->mac.raw = skb->data;
 21.1285 ++	skb->mac_len = skb->nh.raw - skb->data;
 21.1286 ++	__skb_pull(skb, skb->mac_len);
 21.1287 ++
 21.1288 ++	rcu_read_lock();
 21.1289 ++	list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
 21.1290 ++		if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
 21.1291 ++			segs = ptype->gso_segment(skb, features);
 21.1292 ++			break;
 21.1293 ++		}
 21.1294 ++	}
 21.1295 ++	rcu_read_unlock();
 21.1296 ++
 21.1297 ++	__skb_push(skb, skb->data - skb->mac.raw);
 21.1298 ++
 21.1299 ++	return segs;
 21.1300 ++}
 21.1301 ++
 21.1302 ++EXPORT_SYMBOL(skb_gso_segment);
 21.1303 ++
 21.1304 + /* Take action when hardware reception checksum errors are detected. */
 21.1305 + #ifdef CONFIG_BUG
 21.1306 + void netdev_rx_csum_fault(struct net_device *dev)
 21.1307 +@@ -1142,75 +1182,108 @@ #else
 21.1308 + #define illegal_highdma(dev, skb)	(0)
 21.1309 + #endif
 21.1310 + 
 21.1311 +-/* Keep head the same: replace data */
 21.1312 +-int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
 21.1313 +-{
 21.1314 +-	unsigned int size;
 21.1315 +-	u8 *data;
 21.1316 +-	long offset;
 21.1317 +-	struct skb_shared_info *ninfo;
 21.1318 +-	int headerlen = skb->data - skb->head;
 21.1319 +-	int expand = (skb->tail + skb->data_len) - skb->end;
 21.1320 +-
 21.1321 +-	if (skb_shared(skb))
 21.1322 +-		BUG();
 21.1323 +-
 21.1324 +-	if (expand <= 0)
 21.1325 +-		expand = 0;
 21.1326 +-
 21.1327 +-	size = skb->end - skb->head + expand;
 21.1328 +-	size = SKB_DATA_ALIGN(size);
 21.1329 +-	data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
 21.1330 +-	if (!data)
 21.1331 +-		return -ENOMEM;
 21.1332 +-
 21.1333 +-	/* Copy entire thing */
 21.1334 +-	if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
 21.1335 +-		BUG();
 21.1336 +-
 21.1337 +-	/* Set up shinfo */
 21.1338 +-	ninfo = (struct skb_shared_info*)(data + size);
 21.1339 +-	atomic_set(&ninfo->dataref, 1);
 21.1340 +-	ninfo->tso_size = skb_shinfo(skb)->tso_size;
 21.1341 +-	ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
 21.1342 +-	ninfo->nr_frags = 0;
 21.1343 +-	ninfo->frag_list = NULL;
 21.1344 +-
 21.1345 +-	/* Offset between the two in bytes */
 21.1346 +-	offset = data - skb->head;
 21.1347 +-
 21.1348 +-	/* Free old data. */
 21.1349 +-	skb_release_data(skb);
 21.1350 +-
 21.1351 +-	skb->head = data;
 21.1352 +-	skb->end  = data + size;
 21.1353 +-
 21.1354 +-	/* Set up new pointers */
 21.1355 +-	skb->h.raw   += offset;
 21.1356 +-	skb->nh.raw  += offset;
 21.1357 +-	skb->mac.raw += offset;
 21.1358 +-	skb->tail    += offset;
 21.1359 +-	skb->data    += offset;
 21.1360 +-
 21.1361 +-	/* We are no longer a clone, even if we were. */
 21.1362 +-	skb->cloned    = 0;
 21.1363 +-
 21.1364 +-	skb->tail     += skb->data_len;
 21.1365 +-	skb->data_len  = 0;
 21.1366 ++struct dev_gso_cb {
 21.1367 ++	void (*destructor)(struct sk_buff *skb);
 21.1368 ++};
 21.1369 ++
 21.1370 ++#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
 21.1371 ++
 21.1372 ++static void dev_gso_skb_destructor(struct sk_buff *skb)
 21.1373 ++{
 21.1374 ++	struct dev_gso_cb *cb;
 21.1375 ++
 21.1376 ++	do {
 21.1377 ++		struct sk_buff *nskb = skb->next;
 21.1378 ++
 21.1379 ++		skb->next = nskb->next;
 21.1380 ++		nskb->next = NULL;
 21.1381 ++		kfree_skb(nskb);
 21.1382 ++	} while (skb->next);
 21.1383 ++
 21.1384 ++	cb = DEV_GSO_CB(skb);
 21.1385 ++	if (cb->destructor)
 21.1386 ++		cb->destructor(skb);
 21.1387 ++}
 21.1388 ++
 21.1389 ++/**
 21.1390 ++ *	dev_gso_segment - Perform emulated hardware segmentation on skb.
 21.1391 ++ *	@skb: buffer to segment
 21.1392 ++ *
 21.1393 ++ *	This function segments the given skb and stores the list of segments
 21.1394 ++ *	in skb->next.
 21.1395 ++ */
 21.1396 ++static int dev_gso_segment(struct sk_buff *skb)
 21.1397 ++{
 21.1398 ++	struct net_device *dev = skb->dev;
 21.1399 ++	struct sk_buff *segs;
 21.1400 ++	int features = dev->features & ~(illegal_highdma(dev, skb) ?
 21.1401 ++					 NETIF_F_SG : 0);
 21.1402 ++
 21.1403 ++	segs = skb_gso_segment(skb, features);
 21.1404 ++
 21.1405 ++	/* Verifying header integrity only. */
 21.1406 ++	if (!segs)
 21.1407 ++		return 0;
 21.1408 ++
 21.1409 ++	if (unlikely(IS_ERR(segs)))
 21.1410 ++		return PTR_ERR(segs);
 21.1411 ++
 21.1412 ++	skb->next = segs;
 21.1413 ++	DEV_GSO_CB(skb)->destructor = skb->destructor;
 21.1414 ++	skb->destructor = dev_gso_skb_destructor;
 21.1415 ++
 21.1416 ++	return 0;
 21.1417 ++}
 21.1418 ++
 21.1419 ++int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 21.1420 ++{
 21.1421 ++	if (likely(!skb->next)) {
 21.1422 ++		if (netdev_nit)
 21.1423 ++			dev_queue_xmit_nit(skb, dev);
 21.1424 ++
 21.1425 ++		if (netif_needs_gso(dev, skb)) {
 21.1426 ++			if (unlikely(dev_gso_segment(skb)))
 21.1427 ++				goto out_kfree_skb;
 21.1428 ++			if (skb->next)
 21.1429 ++				goto gso;
 21.1430 ++		}
 21.1431 ++
 21.1432 ++		return dev->hard_start_xmit(skb, dev);
 21.1433 ++	}
 21.1434 ++
 21.1435 ++gso:
 21.1436 ++	do {
 21.1437 ++		struct sk_buff *nskb = skb->next;
 21.1438 ++		int rc;
 21.1439 ++
 21.1440 ++		skb->next = nskb->next;
 21.1441 ++		nskb->next = NULL;
 21.1442 ++		rc = dev->hard_start_xmit(nskb, dev);
 21.1443 ++		if (unlikely(rc)) {
 21.1444 ++			nskb->next = skb->next;
 21.1445 ++			skb->next = nskb;
 21.1446 ++			return rc;
 21.1447 ++		}
 21.1448 ++		if (unlikely(netif_queue_stopped(dev) && skb->next))
 21.1449 ++			return NETDEV_TX_BUSY;
 21.1450 ++	} while (skb->next);
 21.1451 ++	
 21.1452 ++	skb->destructor = DEV_GSO_CB(skb)->destructor;
 21.1453 ++
 21.1454 ++out_kfree_skb:
 21.1455 ++	kfree_skb(skb);
 21.1456 + 	return 0;
 21.1457 + }
 21.1458 + 
 21.1459 + #define HARD_TX_LOCK(dev, cpu) {			\
 21.1460 + 	if ((dev->features & NETIF_F_LLTX) == 0) {	\
 21.1461 +-		spin_lock(&dev->xmit_lock);		\
 21.1462 +-		dev->xmit_lock_owner = cpu;		\
 21.1463 ++		netif_tx_lock(dev);			\
 21.1464 + 	}						\
 21.1465 + }
 21.1466 + 
 21.1467 + #define HARD_TX_UNLOCK(dev) {				\
 21.1468 + 	if ((dev->features & NETIF_F_LLTX) == 0) {	\
 21.1469 +-		dev->xmit_lock_owner = -1;		\
 21.1470 +-		spin_unlock(&dev->xmit_lock);		\
 21.1471 ++		netif_tx_unlock(dev);			\
 21.1472 + 	}						\
 21.1473 + }
 21.1474 + 
 21.1475 +@@ -1246,9 +1319,13 @@ int dev_queue_xmit(struct sk_buff *skb)
 21.1476 + 	struct Qdisc *q;
 21.1477 + 	int rc = -ENOMEM;
 21.1478 + 
 21.1479 ++	/* GSO will handle the following emulations directly. */
 21.1480 ++	if (netif_needs_gso(dev, skb))
 21.1481 ++		goto gso;
 21.1482 ++
 21.1483 + 	if (skb_shinfo(skb)->frag_list &&
 21.1484 + 	    !(dev->features & NETIF_F_FRAGLIST) &&
 21.1485 +-	    __skb_linearize(skb, GFP_ATOMIC))
 21.1486 ++	    __skb_linearize(skb))
 21.1487 + 		goto out_kfree_skb;
 21.1488 + 
 21.1489 + 	/* Fragmented skb is linearized if device does not support SG,
 21.1490 +@@ -1257,25 +1334,26 @@ int dev_queue_xmit(struct sk_buff *skb)
 21.1491 + 	 */
 21.1492 + 	if (skb_shinfo(skb)->nr_frags &&
 21.1493 + 	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
 21.1494 +-	    __skb_linearize(skb, GFP_ATOMIC))
 21.1495 ++	    __skb_linearize(skb))
 21.1496 + 		goto out_kfree_skb;
 21.1497 + 
 21.1498 + 	/* If packet is not checksummed and device does not support
 21.1499 + 	 * checksumming for this protocol, complete checksumming here.
 21.1500 + 	 */
 21.1501 + 	if (skb->ip_summed == CHECKSUM_HW &&
 21.1502 +-	    (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
 21.1503 ++	    (!(dev->features & NETIF_F_GEN_CSUM) &&
 21.1504 + 	     (!(dev->features & NETIF_F_IP_CSUM) ||
 21.1505 + 	      skb->protocol != htons(ETH_P_IP))))
 21.1506 + 	      	if (skb_checksum_help(skb, 0))
 21.1507 + 	      		goto out_kfree_skb;
 21.1508 + 
 21.1509 ++gso:
 21.1510 + 	spin_lock_prefetch(&dev->queue_lock);
 21.1511 + 
 21.1512 + 	/* Disable soft irqs for various locks below. Also 
 21.1513 + 	 * stops preemption for RCU. 
 21.1514 + 	 */
 21.1515 +-	local_bh_disable(); 
 21.1516 ++	rcu_read_lock_bh(); 
 21.1517 + 
 21.1518 + 	/* Updates of qdisc are serialized by queue_lock. 
 21.1519 + 	 * The struct Qdisc which is pointed to by qdisc is now a 
 21.1520 +@@ -1309,8 +1387,8 @@ #endif
 21.1521 + 	/* The device has no queue. Common case for software devices:
 21.1522 + 	   loopback, all the sorts of tunnels...
 21.1523 + 
 21.1524 +-	   Really, it is unlikely that xmit_lock protection is necessary here.
 21.1525 +-	   (f.e. loopback and IP tunnels are clean ignoring statistics
 21.1526 ++	   Really, it is unlikely that netif_tx_lock protection is necessary
 21.1527 ++	   here.  (f.e. loopback and IP tunnels are clean ignoring statistics
 21.1528 + 	   counters.)
 21.1529 + 	   However, it is possible, that they rely on protection
 21.1530 + 	   made by us here.
 21.1531 +@@ -1326,11 +1404,8 @@ #endif
 21.1532 + 			HARD_TX_LOCK(dev, cpu);
 21.1533 + 
 21.1534 + 			if (!netif_queue_stopped(dev)) {
 21.1535 +-				if (netdev_nit)
 21.1536 +-					dev_queue_xmit_nit(skb, dev);
 21.1537 +-
 21.1538 + 				rc = 0;
 21.1539 +-				if (!dev->hard_start_xmit(skb, dev)) {
 21.1540 ++				if (!dev_hard_start_xmit(skb, dev)) {
 21.1541 + 					HARD_TX_UNLOCK(dev);
 21.1542 + 					goto out;
 21.1543 + 				}
 21.1544 +@@ -1349,13 +1424,13 @@ #endif
 21.1545 + 	}
 21.1546 + 
 21.1547 + 	rc = -ENETDOWN;
 21.1548 +-	local_bh_enable();
 21.1549 ++	rcu_read_unlock_bh();
 21.1550 + 
 21.1551 + out_kfree_skb:
 21.1552 + 	kfree_skb(skb);
 21.1553 + 	return rc;
 21.1554 + out:
 21.1555 +-	local_bh_enable();
 21.1556 ++	rcu_read_unlock_bh();
 21.1557 + 	return rc;
 21.1558 + }
 21.1559 + 
 21.1560 +@@ -2670,7 +2745,7 @@ int register_netdevice(struct net_device
 21.1561 + 	BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
 21.1562 + 
 21.1563 + 	spin_lock_init(&dev->queue_lock);
 21.1564 +-	spin_lock_init(&dev->xmit_lock);
 21.1565 ++	spin_lock_init(&dev->_xmit_lock);
 21.1566 + 	dev->xmit_lock_owner = -1;
 21.1567 + #ifdef CONFIG_NET_CLS_ACT
 21.1568 + 	spin_lock_init(&dev->ingress_lock);
 21.1569 +@@ -2714,9 +2789,7 @@ #endif
 21.1570 + 
 21.1571 + 	/* Fix illegal SG+CSUM combinations. */
 21.1572 + 	if ((dev->features & NETIF_F_SG) &&
 21.1573 +-	    !(dev->features & (NETIF_F_IP_CSUM |
 21.1574 +-			       NETIF_F_NO_CSUM |
 21.1575 +-			       NETIF_F_HW_CSUM))) {
 21.1576 ++	    !(dev->features & NETIF_F_ALL_CSUM)) {
 21.1577 + 		printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
 21.1578 + 		       dev->name);
 21.1579 + 		dev->features &= ~NETIF_F_SG;
 21.1580 +@@ -3268,7 +3341,6 @@ subsys_initcall(net_dev_init);
 21.1581 + EXPORT_SYMBOL(__dev_get_by_index);
 21.1582 + EXPORT_SYMBOL(__dev_get_by_name);
 21.1583 + EXPORT_SYMBOL(__dev_remove_pack);
 21.1584 +-EXPORT_SYMBOL(__skb_linearize);
 21.1585 + EXPORT_SYMBOL(dev_valid_name);
 21.1586 + EXPORT_SYMBOL(dev_add_pack);
 21.1587 + EXPORT_SYMBOL(dev_alloc_name);
 21.1588 +diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
 21.1589 +index 05d6085..c57d887 100644
 21.1590 +--- a/net/core/dev_mcast.c
 21.1591 ++++ b/net/core/dev_mcast.c
 21.1592 +@@ -62,7 +62,7 @@ #include <net/arp.h>
 21.1593 +  *	Device mc lists are changed by bh at least if IPv6 is enabled,
 21.1594 +  *	so that it must be bh protected.
 21.1595 +  *
 21.1596 +- *	We block accesses to device mc filters with dev->xmit_lock.
 21.1597 ++ *	We block accesses to device mc filters with netif_tx_lock.
 21.1598 +  */
 21.1599 + 
 21.1600 + /*
 21.1601 +@@ -93,9 +93,9 @@ static void __dev_mc_upload(struct net_d
 21.1602 + 
 21.1603 + void dev_mc_upload(struct net_device *dev)
 21.1604 + {
 21.1605 +-	spin_lock_bh(&dev->xmit_lock);
 21.1606 ++	netif_tx_lock_bh(dev);
 21.1607 + 	__dev_mc_upload(dev);
 21.1608 +-	spin_unlock_bh(&dev->xmit_lock);
 21.1609 ++	netif_tx_unlock_bh(dev);
 21.1610 + }
 21.1611 + 
 21.1612 + /*
 21.1613 +@@ -107,7 +107,7 @@ int dev_mc_delete(struct net_device *dev
 21.1614 + 	int err = 0;
 21.1615 + 	struct dev_mc_list *dmi, **dmip;
 21.1616 + 
 21.1617 +-	spin_lock_bh(&dev->xmit_lock);
 21.1618 ++	netif_tx_lock_bh(dev);
 21.1619 + 
 21.1620 + 	for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
 21.1621 + 		/*
 21.1622 +@@ -139,13 +139,13 @@ int dev_mc_delete(struct net_device *dev
 21.1623 + 			 */
 21.1624 + 			__dev_mc_upload(dev);
 21.1625 + 			
 21.1626 +-			spin_unlock_bh(&dev->xmit_lock);
 21.1627 ++			netif_tx_unlock_bh(dev);
 21.1628 + 			return 0;
 21.1629 + 		}
 21.1630 + 	}
 21.1631 + 	err = -ENOENT;
 21.1632 + done:
 21.1633 +-	spin_unlock_bh(&dev->xmit_lock);
 21.1634 ++	netif_tx_unlock_bh(dev);
 21.1635 + 	return err;
 21.1636 + }
 21.1637 + 
 21.1638 +@@ -160,7 +160,7 @@ int dev_mc_add(struct net_device *dev, v
 21.1639 + 
 21.1640 + 	dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
 21.1641 + 
 21.1642 +-	spin_lock_bh(&dev->xmit_lock);
 21.1643 ++	netif_tx_lock_bh(dev);
 21.1644 + 	for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
 21.1645 + 		if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
 21.1646 + 		    dmi->dmi_addrlen == alen) {
 21.1647 +@@ -176,7 +176,7 @@ int dev_mc_add(struct net_device *dev, v
 21.1648 + 	}
 21.1649 + 
 21.1650 + 	if ((dmi = dmi1) == NULL) {
 21.1651 +-		spin_unlock_bh(&dev->xmit_lock);
 21.1652 ++		netif_tx_unlock_bh(dev);
 21.1653 + 		return -ENOMEM;
 21.1654 + 	}
 21.1655 + 	memcpy(dmi->dmi_addr, addr, alen);
 21.1656 +@@ -189,11 +189,11 @@ int dev_mc_add(struct net_device *dev, v
 21.1657 + 
 21.1658 + 	__dev_mc_upload(dev);
 21.1659 + 	
 21.1660 +-	spin_unlock_bh(&dev->xmit_lock);
 21.1661 ++	netif_tx_unlock_bh(dev);
 21.1662 + 	return 0;
 21.1663 + 
 21.1664 + done:
 21.1665 +-	spin_unlock_bh(&dev->xmit_lock);
 21.1666 ++	netif_tx_unlock_bh(dev);
 21.1667 + 	kfree(dmi1);
 21.1668 + 	return err;
 21.1669 + }
 21.1670 +@@ -204,7 +204,7 @@ done:
 21.1671 + 
 21.1672 + void dev_mc_discard(struct net_device *dev)
 21.1673 + {
 21.1674 +-	spin_lock_bh(&dev->xmit_lock);
 21.1675 ++	netif_tx_lock_bh(dev);
 21.1676 + 	
 21.1677 + 	while (dev->mc_list != NULL) {
 21.1678 + 		struct dev_mc_list *tmp = dev->mc_list;
 21.1679 +@@ -215,7 +215,7 @@ void dev_mc_discard(struct net_device *d
 21.1680 + 	}
 21.1681 + 	dev->mc_count = 0;
 21.1682 + 
 21.1683 +-	spin_unlock_bh(&dev->xmit_lock);
 21.1684 ++	netif_tx_unlock_bh(dev);
 21.1685 + }
 21.1686 + 
 21.1687 + #ifdef CONFIG_PROC_FS
 21.1688 +@@ -250,7 +250,7 @@ static int dev_mc_seq_show(struct seq_fi
 21.1689 + 	struct dev_mc_list *m;
 21.1690 + 	struct net_device *dev = v;
 21.1691 + 
 21.1692 +-	spin_lock_bh(&dev->xmit_lock);
 21.1693 ++	netif_tx_lock_bh(dev);
 21.1694 + 	for (m = dev->mc_list; m; m = m->next) {
 21.1695 + 		int i;
 21.1696 + 
 21.1697 +@@ -262,7 +262,7 @@ static int dev_mc_seq_show(struct seq_fi
 21.1698 + 
 21.1699 + 		seq_putc(seq, '\n');
 21.1700 + 	}
 21.1701 +-	spin_unlock_bh(&dev->xmit_lock);
 21.1702 ++	netif_tx_unlock_bh(dev);
 21.1703 + 	return 0;
 21.1704 + }
 21.1705 + 
 21.1706 +diff --git a/net/core/ethtool.c b/net/core/ethtool.c
 21.1707 +index e6f7610..27ce168 100644
 21.1708 +--- a/net/core/ethtool.c
 21.1709 ++++ b/net/core/ethtool.c
 21.1710 +@@ -30,7 +30,7 @@ u32 ethtool_op_get_link(struct net_devic
 21.1711 + 
 21.1712 + u32 ethtool_op_get_tx_csum(struct net_device *dev)
 21.1713 + {
 21.1714 +-	return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0;
 21.1715 ++	return (dev->features & NETIF_F_ALL_CSUM) != 0;
 21.1716 + }
 21.1717 + 
 21.1718 + int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
 21.1719 +@@ -551,9 +551,7 @@ static int ethtool_set_sg(struct net_dev
 21.1720 + 		return -EFAULT;
 21.1721 + 
 21.1722 + 	if (edata.data && 
 21.1723 +-	    !(dev->features & (NETIF_F_IP_CSUM |
 21.1724 +-			       NETIF_F_NO_CSUM |
 21.1725 +-			       NETIF_F_HW_CSUM)))
 21.1726 ++	    !(dev->features & NETIF_F_ALL_CSUM))
 21.1727 + 		return -EINVAL;
 21.1728 + 
 21.1729 + 	return __ethtool_set_sg(dev, edata.data);
 21.1730 +@@ -591,7 +589,7 @@ static int ethtool_set_tso(struct net_de
 21.1731 + 
 21.1732 + static int ethtool_get_ufo(struct net_device *dev, char __user *useraddr)
 21.1733 + {
 21.1734 +-	struct ethtool_value edata = { ETHTOOL_GTSO };
 21.1735 ++	struct ethtool_value edata = { ETHTOOL_GUFO };
 21.1736 + 
 21.1737 + 	if (!dev->ethtool_ops->get_ufo)
 21.1738 + 		return -EOPNOTSUPP;
 21.1739 +@@ -600,6 +598,7 @@ static int ethtool_get_ufo(struct net_de
 21.1740 + 		 return -EFAULT;
 21.1741 + 	return 0;
 21.1742 + }
 21.1743 ++
 21.1744 + static int ethtool_set_ufo(struct net_device *dev, char __user *useraddr)
 21.1745 + {
 21.1746 + 	struct ethtool_value edata;
 21.1747 +@@ -615,6 +614,29 @@ static int ethtool_set_ufo(struct net_de
 21.1748 + 	return dev->ethtool_ops->set_ufo(dev, edata.data);
 21.1749 + }
 21.1750 + 
 21.1751 ++static int ethtool_get_gso(struct net_device *dev, char __user *useraddr)
 21.1752 ++{
 21.1753 ++	struct ethtool_value edata = { ETHTOOL_GGSO };
 21.1754 ++
 21.1755 ++	edata.data = dev->features & NETIF_F_GSO;
 21.1756 ++	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 21.1757 ++		 return -EFAULT;
 21.1758 ++	return 0;
 21.1759 ++}
 21.1760 ++
 21.1761 ++static int ethtool_set_gso(struct net_device *dev, char __user *useraddr)
 21.1762 ++{
 21.1763 ++	struct ethtool_value edata;
 21.1764 ++
 21.1765 ++	if (copy_from_user(&edata, useraddr, sizeof(edata)))
 21.1766 ++		return -EFAULT;
 21.1767 ++	if (edata.data)
 21.1768 ++		dev->features |= NETIF_F_GSO;
 21.1769 ++	else
 21.1770 ++		dev->features &= ~NETIF_F_GSO;
 21.1771 ++	return 0;
 21.1772 ++}
 21.1773 ++
 21.1774 + static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
 21.1775 + {
 21.1776 + 	struct ethtool_test test;
 21.1777 +@@ -906,6 +928,12 @@ int dev_ethtool(struct ifreq *ifr)
 21.1778 + 	case ETHTOOL_SUFO:
 21.1779 + 		rc = ethtool_set_ufo(dev, useraddr);
 21.1780 + 		break;
 21.1781 ++	case ETHTOOL_GGSO:
 21.1782 ++		rc = ethtool_get_gso(dev, useraddr);
 21.1783 ++		break;
 21.1784 ++	case ETHTOOL_SGSO:
 21.1785 ++		rc = ethtool_set_gso(dev, useraddr);
 21.1786 ++		break;
 21.1787 + 	default:
 21.1788 + 		rc =  -EOPNOTSUPP;
 21.1789 + 	}
 21.1790 +diff --git a/net/core/netpoll.c b/net/core/netpoll.c
 21.1791 +index ea51f8d..ec28d3b 100644
 21.1792 +--- a/net/core/netpoll.c
 21.1793 ++++ b/net/core/netpoll.c
 21.1794 +@@ -273,24 +273,21 @@ static void netpoll_send_skb(struct netp
 21.1795 + 
 21.1796 + 	do {
 21.1797 + 		npinfo->tries--;
 21.1798 +-		spin_lock(&np->dev->xmit_lock);
 21.1799 +-		np->dev->xmit_lock_owner = smp_processor_id();
 21.1800 ++		netif_tx_lock(np->dev);
 21.1801 + 
 21.1802 + 		/*
 21.1803 + 		 * network drivers do not expect to be called if the queue is
 21.1804 + 		 * stopped.
 21.1805 + 		 */
 21.1806 + 		if (netif_queue_stopped(np->dev)) {
 21.1807 +-			np->dev->xmit_lock_owner = -1;
 21.1808 +-			spin_unlock(&np->dev->xmit_lock);
 21.1809 ++			netif_tx_unlock(np->dev);
 21.1810 + 			netpoll_poll(np);
 21.1811 + 			udelay(50);
 21.1812 + 			continue;
 21.1813 + 		}
 21.1814 + 
 21.1815 + 		status = np->dev->hard_start_xmit(skb, np->dev);
 21.1816 +-		np->dev->xmit_lock_owner = -1;
 21.1817 +-		spin_unlock(&np->dev->xmit_lock);
 21.1818 ++		netif_tx_unlock(np->dev);
 21.1819 + 
 21.1820 + 		/* success */
 21.1821 + 		if(!status) {
 21.1822 +diff --git a/net/core/pktgen.c b/net/core/pktgen.c
 21.1823 +index da16f8f..2380347 100644
 21.1824 +--- a/net/core/pktgen.c
 21.1825 ++++ b/net/core/pktgen.c
 21.1826 +@@ -2582,7 +2582,7 @@ static __inline__ void pktgen_xmit(struc
 21.1827 + 		}
 21.1828 + 	}
 21.1829 + 	
 21.1830 +-	spin_lock_bh(&odev->xmit_lock);
 21.1831 ++	netif_tx_lock_bh(odev);
 21.1832 + 	if (!netif_queue_stopped(odev)) {
 21.1833 + 
 21.1834 + 		atomic_inc(&(pkt_dev->skb->users));
 21.1835 +@@ -2627,7 +2627,7 @@ retry_now:
 21.1836 + 		pkt_dev->next_tx_ns = 0;
 21.1837 +         }
 21.1838 + 
 21.1839 +-	spin_unlock_bh(&odev->xmit_lock);
 21.1840 ++	netif_tx_unlock_bh(odev);
 21.1841 + 	
 21.1842 + 	/* If pkt_dev->count is zero, then run forever */
 21.1843 + 	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
 21.1844 +diff --git a/net/core/skbuff.c b/net/core/skbuff.c
 21.1845 +index 2144952..46f56af 100644
 21.1846 +--- a/net/core/skbuff.c
 21.1847 ++++ b/net/core/skbuff.c
 21.1848 +@@ -164,9 +164,9 @@ struct sk_buff *__alloc_skb(unsigned int
 21.1849 + 	shinfo = skb_shinfo(skb);
 21.1850 + 	atomic_set(&shinfo->dataref, 1);
 21.1851 + 	shinfo->nr_frags  = 0;
 21.1852 +-	shinfo->tso_size = 0;
 21.1853 +-	shinfo->tso_segs = 0;
 21.1854 +-	shinfo->ufo_size = 0;
 21.1855 ++	shinfo->gso_size = 0;
 21.1856 ++	shinfo->gso_segs = 0;
 21.1857 ++	shinfo->gso_type = 0;
 21.1858 + 	shinfo->ip6_frag_id = 0;
 21.1859 + 	shinfo->frag_list = NULL;
 21.1860 + 
 21.1861 +@@ -230,8 +230,9 @@ struct sk_buff *alloc_skb_from_cache(kme
 21.1862 + 
 21.1863 + 	atomic_set(&(skb_shinfo(skb)->dataref), 1);
 21.1864 + 	skb_shinfo(skb)->nr_frags  = 0;
 21.1865 +-	skb_shinfo(skb)->tso_size = 0;
 21.1866 +-	skb_shinfo(skb)->tso_segs = 0;
 21.1867 ++	skb_shinfo(skb)->gso_size = 0;
 21.1868 ++	skb_shinfo(skb)->gso_segs = 0;
 21.1869 ++	skb_shinfo(skb)->gso_type = 0;
 21.1870 + 	skb_shinfo(skb)->frag_list = NULL;
 21.1871 + out:
 21.1872 + 	return skb;
 21.1873 +@@ -501,8 +502,9 @@ #endif
 21.1874 + 	new->tc_index	= old->tc_index;
 21.1875 + #endif
 21.1876 + 	atomic_set(&new->users, 1);
 21.1877 +-	skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
 21.1878 +-	skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
 21.1879 ++	skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
 21.1880 ++	skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
 21.1881 ++	skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
 21.1882 + }
 21.1883 + 
 21.1884 + /**
 21.1885 +@@ -1777,6 +1779,133 @@ int skb_append_datato_frags(struct sock 
 21.1886 + 	return 0;
 21.1887 + }
 21.1888 + 
 21.1889 ++/**
 21.1890 ++ *	skb_segment - Perform protocol segmentation on skb.
 21.1891 ++ *	@skb: buffer to segment
 21.1892 ++ *	@features: features for the output path (see dev->features)
 21.1893 ++ *
 21.1894 ++ *	This function performs segmentation on the given skb.  It returns
 21.1895 ++ *	the segment at the given position.  It returns NULL if there are
 21.1896 ++ *	no more segments to generate, or when an error is encountered.
 21.1897 ++ */
 21.1898 ++struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 21.1899 ++{
 21.1900 ++	struct sk_buff *segs = NULL;
 21.1901 ++	struct sk_buff *tail = NULL;
 21.1902 ++	unsigned int mss = skb_shinfo(skb)->gso_size;
 21.1903 ++	unsigned int doffset = skb->data - skb->mac.raw;
 21.1904 ++	unsigned int offset = doffset;
 21.1905 ++	unsigned int headroom;
 21.1906 ++	unsigned int len;
 21.1907 ++	int sg = features & NETIF_F_SG;
 21.1908 ++	int nfrags = skb_shinfo(skb)->nr_frags;
 21.1909 ++	int err = -ENOMEM;
 21.1910 ++	int i = 0;
 21.1911 ++	int pos;
 21.1912 ++
 21.1913 ++	__skb_push(skb, doffset);
 21.1914 ++	headroom = skb_headroom(skb);
 21.1915 ++	pos = skb_headlen(skb);
 21.1916 ++
 21.1917 ++	do {
 21.1918 ++		struct sk_buff *nskb;
 21.1919 ++		skb_frag_t *frag;
 21.1920 ++		int hsize, nsize;
 21.1921 ++		int k;
 21.1922 ++		int size;
 21.1923 ++
 21.1924 ++		len = skb->len - offset;
 21.1925 ++		if (len > mss)
 21.1926 ++			len = mss;
 21.1927 ++
 21.1928 ++		hsize = skb_headlen(skb) - offset;
 21.1929 ++		if (hsize < 0)
 21.1930 ++			hsize = 0;
 21.1931 ++		nsize = hsize + doffset;
 21.1932 ++		if (nsize > len + doffset || !sg)
 21.1933 ++			nsize = len + doffset;
 21.1934 ++
 21.1935 ++		nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
 21.1936 ++		if (unlikely(!nskb))
 21.1937 ++			goto err;
 21.1938 ++
 21.1939 ++		if (segs)
 21.1940 ++			tail->next = nskb;
 21.1941 ++		else
 21.1942 ++			segs = nskb;
 21.1943 ++		tail = nskb;
 21.1944 ++
 21.1945 ++		nskb->dev = skb->dev;
 21.1946 ++		nskb->priority = skb->priority;
 21.1947 ++		nskb->protocol = skb->protocol;
 21.1948 ++		nskb->dst = dst_clone(skb->dst);
 21.1949 ++		memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
 21.1950 ++		nskb->pkt_type = skb->pkt_type;
 21.1951 ++		nskb->mac_len = skb->mac_len;
 21.1952 ++
 21.1953 ++		skb_reserve(nskb, headroom);
 21.1954 ++		nskb->mac.raw = nskb->data;
 21.1955 ++		nskb->nh.raw = nskb->data + skb->mac_len;
 21.1956 ++		nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
 21.1957 ++		memcpy(skb_put(nskb, doffset), skb->data, doffset);
 21.1958 ++
 21.1959 ++		if (!sg) {
 21.1960 ++			nskb->csum = skb_copy_and_csum_bits(skb, offset,
 21.1961 ++							    skb_put(nskb, len),
 21.1962 ++							    len, 0);
 21.1963 ++			continue;
 21.1964 ++		}
 21.1965 ++
 21.1966 ++		frag = skb_shinfo(nskb)->frags;
 21.1967 ++		k = 0;
 21.1968 ++
 21.1969 ++		nskb->ip_summed = CHECKSUM_HW;
 21.1970 ++		nskb->csum = skb->csum;
 21.1971 ++		memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
 21.1972 ++
 21.1973 ++		while (pos < offset + len) {
 21.1974 ++			BUG_ON(i >= nfrags);
 21.1975 ++
 21.1976 ++			*frag = skb_shinfo(skb)->frags[i];
 21.1977 ++			get_page(frag->page);
 21.1978 ++			size = frag->size;
 21.1979 ++
 21.1980 ++			if (pos < offset) {
 21.1981 ++				frag->page_offset += offset - pos;
 21.1982 ++				frag->size -= offset - pos;
 21.1983 ++			}
 21.1984 ++
 21.1985 ++			k++;
 21.1986 ++
 21.1987 ++			if (pos + size <= offset + len) {
 21.1988 ++				i++;
 21.1989 ++				pos += size;
 21.1990 ++			} else {
 21.1991 ++				frag->size -= pos + size - (offset + len);
 21.1992 ++				break;
 21.1993 ++			}
 21.1994 ++
 21.1995 ++			frag++;
 21.1996 ++		}
 21.1997 ++
 21.1998 ++		skb_shinfo(nskb)->nr_frags = k;
 21.1999 ++		nskb->data_len = len - hsize;
 21.2000 ++		nskb->len += nskb->data_len;
 21.2001 ++		nskb->truesize += nskb->data_len;
 21.2002 ++	} while ((offset += len) < skb->len);
 21.2003 ++
 21.2004 ++	return segs;
 21.2005 ++
 21.2006 ++err:
 21.2007 ++	while ((skb = segs)) {
 21.2008 ++		segs = skb->next;
 21.2009 ++		kfree(skb);
 21.2010 ++	}
 21.2011 ++	return ERR_PTR(err);
 21.2012 ++}
 21.2013 ++
 21.2014 ++EXPORT_SYMBOL_GPL(skb_segment);
 21.2015 ++
 21.2016 + void __init skb_init(void)
 21.2017 + {
 21.2018 + 	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
 21.2019 +diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
 21.2020 +index 44bda85..2e3323a 100644
 21.2021 +--- a/net/decnet/dn_nsp_in.c
 21.2022 ++++ b/net/decnet/dn_nsp_in.c
 21.2023 +@@ -801,8 +801,7 @@ got_it:
 21.2024 + 		 * We linearize everything except data segments here.
 21.2025 + 		 */
 21.2026 + 		if (cb->nsp_flags & ~0x60) {
 21.2027 +-			if (unlikely(skb_is_nonlinear(skb)) &&
 21.2028 +-			    skb_linearize(skb, GFP_ATOMIC) != 0)
 21.2029 ++			if (unlikely(skb_linearize(skb)))
 21.2030 + 				goto free_out;
 21.2031 + 		}
 21.2032 + 
 21.2033 +diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
 21.2034 +index 3407f19..a0a25e0 100644
 21.2035 +--- a/net/decnet/dn_route.c
 21.2036 ++++ b/net/decnet/dn_route.c
 21.2037 +@@ -629,8 +629,7 @@ int dn_route_rcv(struct sk_buff *skb, st
 21.2038 + 			padlen);
 21.2039 + 
 21.2040 +         if (flags & DN_RT_PKT_CNTL) {
 21.2041 +-		if (unlikely(skb_is_nonlinear(skb)) &&
 21.2042 +-		    skb_linearize(skb, GFP_ATOMIC) != 0)
 21.2043 ++		if (unlikely(skb_linearize(skb)))
 21.2044 + 			goto dump_it;
 21.2045 + 
 21.2046 +                 switch(flags & DN_RT_CNTL_MSK) {
 21.2047 +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
 21.2048 +index 97c276f..5ba719e 100644
 21.2049 +--- a/net/ipv4/af_inet.c
 21.2050 ++++ b/net/ipv4/af_inet.c
 21.2051 +@@ -68,6 +68,7 @@
 21.2052 +  */
 21.2053 + 
 21.2054 + #include <linux/config.h>
 21.2055 ++#include <linux/err.h>
 21.2056 + #include <linux/errno.h>
 21.2057 + #include <linux/types.h>
 21.2058 + #include <linux/socket.h>
 21.2059 +@@ -1084,6 +1085,54 @@ int inet_sk_rebuild_header(struct sock *
 21.2060 + 
 21.2061 + EXPORT_SYMBOL(inet_sk_rebuild_header);
 21.2062 + 
 21.2063 ++static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
 21.2064 ++{
 21.2065 ++	struct sk_buff *segs = ERR_PTR(-EINVAL);
 21.2066 ++	struct iphdr *iph;
 21.2067 ++	struct net_protocol *ops;
 21.2068 ++	int proto;
 21.2069 ++	int ihl;
 21.2070 ++	int id;
 21.2071 ++
 21.2072 ++	if (!pskb_may_pull(skb, sizeof(*iph)))
 21.2073 ++		goto out;
 21.2074 ++
 21.2075 ++	iph = skb->nh.iph;
 21.2076 ++	ihl = iph->ihl * 4;
 21.2077 ++	if (ihl < sizeof(*iph))
 21.2078 ++		goto out;
 21.2079 ++
 21.2080 ++	if (!pskb_may_pull(skb, ihl))
 21.2081 ++		goto out;
 21.2082 ++
 21.2083 ++	skb->h.raw = __skb_pull(skb, ihl);
 21.2084 ++	iph = skb->nh.iph;
 21.2085 ++	id = ntohs(iph->id);
 21.2086 ++	proto = iph->protocol & (MAX_INET_PROTOS - 1);
 21.2087 ++	segs = ERR_PTR(-EPROTONOSUPPORT);
 21.2088 ++
 21.2089 ++	rcu_read_lock();
 21.2090 ++	ops = rcu_dereference(inet_protos[proto]);
 21.2091 ++	if (ops && ops->gso_segment)
 21.2092 ++		segs = ops->gso_segment(skb, features);
 21.2093 ++	rcu_read_unlock();
 21.2094 ++
 21.2095 ++	if (!segs || unlikely(IS_ERR(segs)))
 21.2096 ++		goto out;
 21.2097 ++
 21.2098 ++	skb = segs;
 21.2099 ++	do {
 21.2100 ++		iph = skb->nh.iph;
 21.2101 ++		iph->id = htons(id++);
 21.2102 ++		iph->tot_len = htons(skb->len - skb->mac_len);
 21.2103 ++		iph->check = 0;
 21.2104 ++		iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
 21.2105 ++	} while ((skb = skb->next));
 21.2106 ++
 21.2107 ++out:
 21.2108 ++	return segs;
 21.2109 ++}
 21.2110 ++
 21.2111 + #ifdef CONFIG_IP_MULTICAST
 21.2112 + static struct net_protocol igmp_protocol = {
 21.2113 + 	.handler =	igmp_rcv,
 21.2114 +@@ -1093,6 +1142,7 @@ #endif
 21.2115 + static struct net_protocol tcp_protocol = {
 21.2116 + 	.handler =	tcp_v4_rcv,
 21.2117 + 	.err_handler =	tcp_v4_err,
 21.2118 ++	.gso_segment =	tcp_tso_segment,
 21.2119 + 	.no_policy =	1,
 21.2120 + };
 21.2121 + 
 21.2122 +@@ -1138,6 +1188,7 @@ static int ipv4_proc_init(void);
 21.2123 + static struct packet_type ip_packet_type = {
 21.2124 + 	.type = __constant_htons(ETH_P_IP),
 21.2125 + 	.func = ip_rcv,
 21.2126 ++	.gso_segment = inet_gso_segment,
 21.2127 + };
 21.2128 + 
 21.2129 + static int __init inet_init(void)
 21.2130 +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
 21.2131 +index 8dcba38..19c3c73 100644
 21.2132 +--- a/net/ipv4/ip_output.c
 21.2133 ++++ b/net/ipv4/ip_output.c
 21.2134 +@@ -210,8 +210,7 @@ #if defined(CONFIG_NETFILTER) && defined
 21.2135 + 		return dst_output(skb);
 21.2136 + 	}
 21.2137 + #endif
 21.2138 +-	if (skb->len > dst_mtu(skb->dst) &&
 21.2139 +-	    !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
 21.2140 ++	if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size)
 21.2141 + 		return ip_fragment(skb, ip_finish_output2);
 21.2142 + 	else
 21.2143 + 		return ip_finish_output2(skb);
 21.2144 +@@ -362,7 +361,7 @@ packet_routed:
 21.2145 + 	}
 21.2146 + 
 21.2147 + 	ip_select_ident_more(iph, &rt->u.dst, sk,
 21.2148 +-			     (skb_shinfo(skb)->tso_segs ?: 1) - 1);
 21.2149 ++			     (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 21.2150 + 
 21.2151 + 	/* Add an IP checksum. */
 21.2152 + 	ip_send_check(iph);
 21.2153 +@@ -743,7 +742,8 @@ static inline int ip_ufo_append_data(str
 21.2154 + 			       (length - transhdrlen));
 21.2155 + 	if (!err) {
 21.2156 + 		/* specify the length of each IP datagram fragment*/
 21.2157 +-		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
 21.2158 ++		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
 21.2159 ++		skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
 21.2160 + 		__skb_queue_tail(&sk->sk_write_queue, skb);
 21.2161 + 
 21.2162 + 		return 0;
 21.2163 +@@ -839,7 +839,7 @@ int ip_append_data(struct sock *sk,
 21.2164 + 	 */
 21.2165 + 	if (transhdrlen &&
 21.2166 + 	    length + fragheaderlen <= mtu &&
 21.2167 +-	    rt->u.dst.dev->features&(NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) &&
 21.2168 ++	    rt->u.dst.dev->features & NETIF_F_ALL_CSUM &&
 21.2169 + 	    !exthdrlen)
 21.2170 + 		csummode = CHECKSUM_HW;
 21.2171 + 
 21.2172 +@@ -1086,14 +1086,16 @@ ssize_t	ip_append_page(struct sock *sk, 
 21.2173 + 
 21.2174 + 	inet->cork.length += size;
 21.2175 + 	if ((sk->sk_protocol == IPPROTO_UDP) &&
 21.2176 +-	    (rt->u.dst.dev->features & NETIF_F_UFO))
 21.2177 +-		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
 21.2178 ++	    (rt->u.dst.dev->features & NETIF_F_UFO)) {
 21.2179 ++		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
 21.2180 ++		skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
 21.2181 ++	}
 21.2182 + 
 21.2183 + 
 21.2184 + 	while (size > 0) {
 21.2185 + 		int i;
 21.2186 + 
 21.2187 +-		if (skb_shinfo(skb)->ufo_size)
 21.2188 ++		if (skb_shinfo(skb)->gso_size)
 21.2189 + 			len = size;
 21.2190 + 		else {
 21.2191 + 
 21.2192 +diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
 21.2193 +index d64e2ec..7494823 100644
 21.2194 +--- a/net/ipv4/ipcomp.c
 21.2195 ++++ b/net/ipv4/ipcomp.c
 21.2196 +@@ -84,7 +84,7 @@ static int ipcomp_input(struct xfrm_stat
 21.2197 +                         struct xfrm_decap_state *decap, struct sk_buff *skb)
 21.2198 + {
 21.2199 + 	u8 nexthdr;
 21.2200 +-	int err = 0;
 21.2201 ++	int err = -ENOMEM;
 21.2202 + 	struct iphdr *iph;
 21.2203 + 	union {
 21.2204 + 		struct iphdr	iph;
 21.2205 +@@ -92,11 +92,8 @@ static int ipcomp_input(struct xfrm_stat
 21.2206 + 	} tmp_iph;
 21.2207 + 
 21.2208 + 
 21.2209 +-	if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
 21.2210 +-	    skb_linearize(skb, GFP_ATOMIC) != 0) {
 21.2211 +-	    	err = -ENOMEM;
 21.2212 ++	if (skb_linearize_cow(skb))
 21.2213 + 	    	goto out;
 21.2214 +-	}
 21.2215 + 
 21.2216 + 	skb->ip_summed = CHECKSUM_NONE;
 21.2217 + 
 21.2218 +@@ -171,10 +168,8 @@ static int ipcomp_output(struct xfrm_sta
 21.2219 + 		goto out_ok;
 21.2220 + 	}
 21.2221 + 
 21.2222 +-	if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
 21.2223 +-	    skb_linearize(skb, GFP_ATOMIC) != 0) {
 21.2224 ++	if (skb_linearize_cow(skb))
 21.2225 + 		goto out_ok;
 21.2226 +-	}
 21.2227 + 	
 21.2228 + 	err = ipcomp_compress(x, skb);
 21.2229 + 	iph = skb->nh.iph;
 21.2230 +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
 21.2231 +index 00aa80e..84130c9 100644
 21.2232 +--- a/net/ipv4/tcp.c
 21.2233 ++++ b/net/ipv4/tcp.c
 21.2234 +@@ -257,6 +257,7 @@ #include <linux/smp_lock.h>
 21.2235 + #include <linux/fs.h>
 21.2236 + #include <linux/random.h>
 21.2237 + #include <linux/bootmem.h>
 21.2238 ++#include <linux/err.h>
 21.2239 + 
 21.2240 + #include <net/icmp.h>
 21.2241 + #include <net/tcp.h>
 21.2242 +@@ -570,7 +571,7 @@ new_segment:
 21.2243 + 		skb->ip_summed = CHECKSUM_HW;
 21.2244 + 		tp->write_seq += copy;
 21.2245 + 		TCP_SKB_CB(skb)->end_seq += copy;
 21.2246 +-		skb_shinfo(skb)->tso_segs = 0;
 21.2247 ++		skb_shinfo(skb)->gso_segs = 0;
 21.2248 + 
 21.2249 + 		if (!copied)
 21.2250 + 			TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;
 21.2251 +@@ -621,14 +622,10 @@ ssize_t tcp_sendpage(struct socket *sock
 21.2252 + 	ssize_t res;
 21.2253 + 	struct sock *sk = sock->sk;
 21.2254 + 
 21.2255 +-#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
 21.2256 +-
 21.2257 + 	if (!(sk->sk_route_caps & NETIF_F_SG) ||
 21.2258 +-	    !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS))
 21.2259 ++	    !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
 21.2260 + 		return sock_no_sendpage(sock, page, offset, size, flags);
 21.2261 + 
 21.2262 +-#undef TCP_ZC_CSUM_FLAGS
 21.2263 +-
 21.2264 + 	lock_sock(sk);
 21.2265 + 	TCP_CHECK_TIMER(sk);
 21.2266 + 	res = do_tcp_sendpages(sk, &page, offset, size, flags);
 21.2267 +@@ -725,9 +722,7 @@ new_segment:
 21.2268 + 				/*
 21.2269 + 				 * Check whether we can use HW checksum.
 21.2270 + 				 */
 21.2271 +-				if (sk->sk_route_caps &
 21.2272 +-				    (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM |
 21.2273 +-				     NETIF_F_HW_CSUM))
 21.2274 ++				if (sk->sk_route_caps & NETIF_F_ALL_CSUM)
 21.2275 + 					skb->ip_summed = CHECKSUM_HW;
 21.2276 + 
 21.2277 + 				skb_entail(sk, tp, skb);
 21.2278 +@@ -823,7 +818,7 @@ new_segment:
 21.2279 + 
 21.2280 + 			tp->write_seq += copy;
 21.2281 + 			TCP_SKB_CB(skb)->end_seq += copy;
 21.2282 +-			skb_shinfo(skb)->tso_segs = 0;
 21.2283 ++			skb_shinfo(skb)->gso_segs = 0;
 21.2284 + 
 21.2285 + 			from += copy;
 21.2286 + 			copied += copy;
 21.2287 +@@ -2026,6 +2021,71 @@ int tcp_getsockopt(struct sock *sk, int 
 21.2288 + }
 21.2289 + 
 21.2290 + 
 21.2291 ++struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
 21.2292 ++{
 21.2293 ++	struct sk_buff *segs = ERR_PTR(-EINVAL);
 21.2294 ++	struct tcphdr *th;
 21.2295 ++	unsigned thlen;
 21.2296 ++	unsigned int seq;
 21.2297 ++	unsigned int delta;
 21.2298 ++	unsigned int oldlen;
 21.2299 ++	unsigned int len;
 21.2300 ++
 21.2301 ++	if (!pskb_may_pull(skb, sizeof(*th)))
 21.2302 ++		goto out;
 21.2303 ++
 21.2304 ++	th = skb->h.th;
 21.2305 ++	thlen = th->doff * 4;
 21.2306 ++	if (thlen < sizeof(*th))
 21.2307 ++		goto out;
 21.2308 ++
 21.2309 ++	if (!pskb_may_pull(skb, thlen))
 21.2310 ++		goto out;
 21.2311 ++
 21.2312 ++	segs = NULL;
 21.2313 ++	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
 21.2314 ++		goto out;
 21.2315 ++
 21.2316 ++	oldlen = (u16)~skb->len;
 21.2317 ++	__skb_pull(skb, thlen);
 21.2318 ++
 21.2319 ++	segs = skb_segment(skb, features);
 21.2320 ++	if (IS_ERR(segs))
 21.2321 ++		goto out;
 21.2322 ++
 21.2323 ++	len = skb_shinfo(skb)->gso_size;
 21.2324 ++	delta = htonl(oldlen + (thlen + len));
 21.2325 ++
 21.2326 ++	skb = segs;
 21.2327 ++	th = skb->h.th;
 21.2328 ++	seq = ntohl(th->seq);
 21.2329 ++
 21.2330 ++	do {
 21.2331 ++		th->fin = th->psh = 0;
 21.2332 ++
 21.2333 ++		th->check = ~csum_fold(th->check + delta);
 21.2334 ++		if (skb->ip_summed != CHECKSUM_HW)
 21.2335 ++			th->check = csum_fold(csum_partial(skb->h.raw, thlen,
 21.2336 ++							   skb->csum));
 21.2337 ++
 21.2338 ++		seq += len;
 21.2339 ++		skb = skb->next;
 21.2340 ++		th = skb->h.th;
 21.2341 ++
 21.2342 ++		th->seq = htonl(seq);
 21.2343 ++		th->cwr = 0;
 21.2344 ++	} while (skb->next);
 21.2345 ++
 21.2346 ++	delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len);
 21.2347 ++	th->check = ~csum_fold(th->check + delta);
 21.2348 ++	if (skb->ip_summed != CHECKSUM_HW)
 21.2349 ++		th->check = csum_fold(csum_partial(skb->h.raw, thlen,
 21.2350 ++						   skb->csum));
 21.2351 ++
 21.2352 ++out:
 21.2353 ++	return segs;
 21.2354 ++}
 21.2355 ++
 21.2356 + extern void __skb_cb_too_small_for_tcp(int, int);
 21.2357 + extern struct tcp_congestion_ops tcp_reno;
 21.2358 + 
 21.2359 +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
 21.2360 +index e9a54ae..defe77a 100644
 21.2361 +--- a/net/ipv4/tcp_input.c
 21.2362 ++++ b/net/ipv4/tcp_input.c
 21.2363 +@@ -1072,7 +1072,7 @@ tcp_sacktag_write_queue(struct sock *sk,
 21.2364 + 				else
 21.2365 + 					pkt_len = (end_seq -
 21.2366 + 						   TCP_SKB_CB(skb)->seq);
 21.2367 +-				if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->tso_size))
 21.2368 ++				if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->gso_size))
 21.2369 + 					break;
 21.2370 + 				pcount = tcp_skb_pcount(skb);
 21.2371 + 			}
 21.2372 +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
 21.2373 +index 310f2e6..ee01f69 100644
 21.2374 +--- a/net/ipv4/tcp_output.c
 21.2375 ++++ b/net/ipv4/tcp_output.c
 21.2376 +@@ -497,15 +497,17 @@ static void tcp_set_skb_tso_segs(struct 
 21.2377 + 		/* Avoid the costly divide in the normal
 21.2378 + 		 * non-TSO case.
 21.2379 + 		 */
 21.2380 +-		skb_shinfo(skb)->tso_segs = 1;
 21.2381 +-		skb_shinfo(skb)->tso_size = 0;
 21.2382 ++		skb_shinfo(skb)->gso_segs = 1;
 21.2383 ++		skb_shinfo(skb)->gso_size = 0;
 21.2384 ++		skb_shinfo(skb)->gso_type = 0;
 21.2385 + 	} else {
 21.2386 + 		unsigned int factor;
 21.2387 + 
 21.2388 + 		factor = skb->len + (mss_now - 1);
 21.2389 + 		factor /= mss_now;
 21.2390 +-		skb_shinfo(skb)->tso_segs = factor;
 21.2391 +-		skb_shinfo(skb)->tso_size = mss_now;
 21.2392 ++		skb_shinfo(skb)->gso_segs = factor;
 21.2393 ++		skb_shinfo(skb)->gso_size = mss_now;
 21.2394 ++		skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
 21.2395 + 	}
 21.2396 + }
 21.2397 + 
 21.2398 +@@ -850,7 +852,7 @@ static int tcp_init_tso_segs(struct sock
 21.2399 + 
 21.2400 + 	if (!tso_segs ||
 21.2401 + 	    (tso_segs > 1 &&
 21.2402 +-	     skb_shinfo(skb)->tso_size != mss_now)) {
 21.2403 ++	     tcp_skb_mss(skb) != mss_now)) {
 21.2404 + 		tcp_set_skb_tso_segs(sk, skb, mss_now);
 21.2405 + 		tso_segs = tcp_skb_pcount(skb);
 21.2406 + 	}
 21.2407 +@@ -1510,8 +1512,9 @@ int tcp_retransmit_skb(struct sock *sk, 
 21.2408 + 	   tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
 21.2409 + 		if (!pskb_trim(skb, 0)) {
 21.2410 + 			TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1;
 21.2411 +-			skb_shinfo(skb)->tso_segs = 1;
 21.2412 +-			skb_shinfo(skb)->tso_size = 0;
 21.2413 ++			skb_shinfo(skb)->gso_segs = 1;
 21.2414 ++			skb_shinfo(skb)->gso_size = 0;
 21.2415 ++			skb_shinfo(skb)->gso_type = 0;
 21.2416 + 			skb->ip_summed = CHECKSUM_NONE;
 21.2417 + 			skb->csum = 0;
 21.2418 + 		}
 21.2419 +@@ -1716,8 +1719,9 @@ void tcp_send_fin(struct sock *sk)
 21.2420 + 		skb->csum = 0;
 21.2421 + 		TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
 21.2422 + 		TCP_SKB_CB(skb)->sacked = 0;
 21.2423 +-		skb_shinfo(skb)->tso_segs = 1;
 21.2424 +-		skb_shinfo(skb)->tso_size = 0;
 21.2425 ++		skb_shinfo(skb)->gso_segs = 1;
 21.2426 ++		skb_shinfo(skb)->gso_size = 0;
 21.2427 ++		skb_shinfo(skb)->gso_type = 0;
 21.2428 + 
 21.2429 + 		/* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
 21.2430 + 		TCP_SKB_CB(skb)->seq = tp->write_seq;
 21.2431 +@@ -1749,8 +1753,9 @@ void tcp_send_active_reset(struct sock *
 21.2432 + 	skb->csum = 0;
 21.2433 + 	TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
 21.2434 + 	TCP_SKB_CB(skb)->sacked = 0;
 21.2435 +-	skb_shinfo(skb)->tso_segs = 1;
 21.2436 +-	skb_shinfo(skb)->tso_size = 0;
 21.2437 ++	skb_shinfo(skb)->gso_segs = 1;
 21.2438 ++	skb_shinfo(skb)->gso_size = 0;
 21.2439 ++	skb_shinfo(skb)->gso_type = 0;
 21.2440 + 
 21.2441 + 	/* Send it off. */
 21.2442 + 	TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp);
 21.2443 +@@ -1833,8 +1838,9 @@ struct sk_buff * tcp_make_synack(struct 
 21.2444 + 	TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn;
 21.2445 + 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
 21.2446 + 	TCP_SKB_CB(skb)->sacked = 0;
 21.2447 +-	skb_shinfo(skb)->tso_segs = 1;
 21.2448 +-	skb_shinfo(skb)->tso_size = 0;
 21.2449 ++	skb_shinfo(skb)->gso_segs = 1;
 21.2450 ++	skb_shinfo(skb)->gso_size = 0;
 21.2451 ++	skb_shinfo(skb)->gso_type = 0;
 21.2452 + 	th->seq = htonl(TCP_SKB_CB(skb)->seq);
 21.2453 + 	th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1);
 21.2454 + 	if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
 21.2455 +@@ -1937,8 +1943,9 @@ int tcp_connect(struct sock *sk)
 21.2456 + 	TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN;
 21.2457 + 	TCP_ECN_send_syn(sk, tp, buff);
 21.2458 + 	TCP_SKB_CB(buff)->sacked = 0;
 21.2459 +-	skb_shinfo(buff)->tso_segs = 1;
 21.2460 +-	skb_shinfo(buff)->tso_size = 0;
 21.2461 ++	skb_shinfo(buff)->gso_segs = 1;
 21.2462 ++	skb_shinfo(buff)->gso_size = 0;
 21.2463 ++	skb_shinfo(buff)->gso_type = 0;
 21.2464 + 	buff->csum = 0;
 21.2465 + 	TCP_SKB_CB(buff)->seq = tp->write_seq++;
 21.2466 + 	TCP_SKB_CB(buff)->end_seq = tp->write_seq;
 21.2467 +@@ -2042,8 +2049,9 @@ void tcp_send_ack(struct sock *sk)
 21.2468 + 		buff->csum = 0;
 21.2469 + 		TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK;
 21.2470 + 		TCP_SKB_CB(buff)->sacked = 0;
 21.2471 +-		skb_shinfo(buff)->tso_segs = 1;
 21.2472 +-		skb_shinfo(buff)->tso_size = 0;
 21.2473 ++		skb_shinfo(buff)->gso_segs = 1;
 21.2474 ++		skb_shinfo(buff)->gso_size = 0;
 21.2475 ++		skb_shinfo(buff)->gso_type = 0;
 21.2476 + 
 21.2477 + 		/* Send it off, this clears delayed acks for us. */
 21.2478 + 		TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk, tp);
 21.2479 +@@ -2078,8 +2086,9 @@ static int tcp_xmit_probe_skb(struct soc
 21.2480 + 	skb->csum = 0;
 21.2481 + 	TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
 21.2482 + 	TCP_SKB_CB(skb)->sacked = urgent;
 21.2483 +-	skb_shinfo(skb)->tso_segs = 1;
 21.2484 +-	skb_shinfo(skb)->tso_size = 0;
 21.2485 ++	skb_shinfo(skb)->gso_segs = 1;
 21.2486 ++	skb_shinfo(skb)->gso_size = 0;
 21.2487 ++	skb_shinfo(skb)->gso_type = 0;
 21.2488 + 
 21.2489 + 	/* Use a previous sequence.  This should cause the other
 21.2490 + 	 * end to send an ack.  Don't queue or clone SKB, just
 21.2491 +diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
 21.2492 +index 32ad229..737c1db 100644
 21.2493 +--- a/net/ipv4/xfrm4_output.c
 21.2494 ++++ b/net/ipv4/xfrm4_output.c
 21.2495 +@@ -9,6 +9,8 @@
 21.2496 +  */
 21.2497 + 
 21.2498 + #include <linux/compiler.h>
 21.2499 ++#include <linux/if_ether.h>
 21.2500 ++#include <linux/kernel.h>
 21.2501 + #include <linux/skbuff.h>
 21.2502 + #include <linux/spinlock.h>
 21.2503 + #include <linux/netfilter_ipv4.h>
 21.2504 +@@ -152,16 +154,10 @@ error_nolock:
 21.2505 + 	goto out_exit;
 21.2506 + }
 21.2507 + 
 21.2508 +-static int xfrm4_output_finish(struct sk_buff *skb)
 21.2509 ++static int xfrm4_output_finish2(struct sk_buff *skb)
 21.2510 + {
 21.2511 + 	int err;
 21.2512 + 
 21.2513 +-#ifdef CONFIG_NETFILTER
 21.2514 +-	if (!skb->dst->xfrm) {
 21.2515 +-		IPCB(skb)->flags |= IPSKB_REROUTED;
 21.2516 +-		return dst_output(skb);
 21.2517 +-	}
 21.2518 +-#endif
 21.2519 + 	while (likely((err = xfrm4_output_one(skb)) == 0)) {
 21.2520 + 		nf_reset(skb);
 21.2521 + 
 21.2522 +@@ -174,7 +170,7 @@ #endif
 21.2523 + 			return dst_output(skb);
 21.2524 + 
 21.2525 + 		err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL,
 21.2526 +-			      skb->dst->dev, xfrm4_output_finish);
 21.2527 ++			      skb->dst->dev, xfrm4_output_finish2);
 21.2528 + 		if (unlikely(err != 1))
 21.2529 + 			break;
 21.2530 + 	}
 21.2531 +@@ -182,6 +178,48 @@ #endif
 21.2532 + 	return err;
 21.2533 + }
 21.2534 + 
 21.2535 ++static int xfrm4_output_finish(struct sk_buff *skb)
 21.2536 ++{
 21.2537 ++	struct sk_buff *segs;
 21.2538 ++
 21.2539 ++#ifdef CONFIG_NETFILTER
 21.2540 ++	if (!skb->dst->xfrm) {
 21.2541 ++		IPCB(skb)->flags |= IPSKB_REROUTED;
 21.2542 ++		return dst_output(skb);
 21.2543 ++	}
 21.2544 ++#endif
 21.2545 ++
 21.2546 ++	if (!skb_shinfo(skb)->gso_size)
 21.2547 ++		return xfrm4_output_finish2(skb);
 21.2548 ++
 21.2549 ++	skb->protocol = htons(ETH_P_IP);
 21.2550 ++	segs = skb_gso_segment(skb, 0);
 21.2551 ++	kfree_skb(skb);
 21.2552 ++	if (unlikely(IS_ERR(segs)))
 21.2553 ++		return PTR_ERR(segs);
 21.2554 ++
 21.2555 ++	do {
 21.2556 ++		struct sk_buff *nskb = segs->next;
 21.2557 ++		int err;
 21.2558 ++
 21.2559 ++		segs->next = NULL;
 21.2560 ++		err = xfrm4_output_finish2(segs);
 21.2561 ++
 21.2562 ++		if (unlikely(err)) {
 21.2563 ++			while ((segs = nskb)) {
 21.2564 ++				nskb = segs->next;
 21.2565 ++				segs->next = NULL;
 21.2566 ++				kfree_skb(segs);
 21.2567 ++			}
 21.2568 ++			return err;
 21.2569 ++		}
 21.2570 ++
 21.2571 ++		segs = nskb;
 21.2572 ++	} while (segs);
 21.2573 ++
 21.2574 ++	return 0;
 21.2575 ++}
 21.2576 ++
 21.2577 + int xfrm4_output(struct sk_buff *skb)
 21.2578 + {
 21.2579 + 	return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
 21.2580 +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
 21.2581 +index 5bf70b1..cf5d17e 100644
 21.2582 +--- a/net/ipv6/ip6_output.c
 21.2583 ++++ b/net/ipv6/ip6_output.c
 21.2584 +@@ -147,7 +147,7 @@ static int ip6_output2(struct sk_buff *s
 21.2585 + 
 21.2586 + int ip6_output(struct sk_buff *skb)
 21.2587 + {
 21.2588 +-	if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) ||
 21.2589 ++	if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) ||
 21.2590 + 				dst_allfrag(skb->dst))
 21.2591 + 		return ip6_fragment(skb, ip6_output2);
 21.2592 + 	else
 21.2593 +@@ -829,8 +829,9 @@ static inline int ip6_ufo_append_data(st
 21.2594 + 		struct frag_hdr fhdr;
 21.2595 + 
 21.2596 + 		/* specify the length of each IP datagram fragment*/
 21.2597 +-		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - 
 21.2598 +-						sizeof(struct frag_hdr);
 21.2599 ++		skb_shinfo(skb)->gso_size = mtu - fragheaderlen - 
 21.2600 ++					    sizeof(struct frag_hdr);
 21.2601 ++		skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
 21.2602 + 		ipv6_select_ident(skb, &fhdr);
 21.2603 + 		skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
 21.2604 + 		__skb_queue_tail(&sk->sk_write_queue, skb);
 21.2605 +diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
 21.2606 +index d511a88..ef56d5d 100644
 21.2607 +--- a/net/ipv6/ipcomp6.c
 21.2608 ++++ b/net/ipv6/ipcomp6.c
 21.2609 +@@ -64,7 +64,7 @@ static LIST_HEAD(ipcomp6_tfms_list);
 21.2610 + 
 21.2611 + static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
 21.2612 + {
 21.2613 +-	int err = 0;
 21.2614 ++	int err = -ENOMEM;
 21.2615 + 	u8 nexthdr = 0;
 21.2616 + 	int hdr_len = skb->h.raw - skb->nh.raw;
 21.2617 + 	unsigned char *tmp_hdr = NULL;
 21.2618 +@@ -75,11 +75,8 @@ static int ipcomp6_input(struct xfrm_sta
 21.2619 + 	struct crypto_tfm *tfm;
 21.2620 + 	int cpu;
 21.2621 + 
 21.2622 +-	if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
 21.2623 +-		skb_linearize(skb, GFP_ATOMIC) != 0) {
 21.2624 +-		err = -ENOMEM;
 21.2625 ++	if (skb_linearize_cow(skb))
 21.2626 + 		goto out;
 21.2627 +-	}
 21.2628 + 
 21.2629 + 	skb->ip_summed = CHECKSUM_NONE;
 21.2630 + 
 21.2631 +@@ -158,10 +155,8 @@ static int ipcomp6_output(struct xfrm_st
 21.2632 + 		goto out_ok;
 21.2633 + 	}
 21.2634 + 
 21.2635 +-	if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
 21.2636 +-		skb_linearize(skb, GFP_ATOMIC) != 0) {
 21.2637 ++	if (skb_linearize_cow(skb))
 21.2638 + 		goto out_ok;
 21.2639 +-	}
 21.2640 + 
 21.2641 + 	/* compression */
 21.2642 + 	plen = skb->len - hdr_len;
 21.2643 +diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
 21.2644 +index 8024217..39bdeec 100644
 21.2645 +--- a/net/ipv6/xfrm6_output.c
 21.2646 ++++ b/net/ipv6/xfrm6_output.c
 21.2647 +@@ -151,7 +151,7 @@ error_nolock:
 21.2648 + 	goto out_exit;
 21.2649 + }
 21.2650 + 
 21.2651 +-static int xfrm6_output_finish(struct sk_buff *skb)
 21.2652 ++static int xfrm6_output_finish2(struct sk_buff *skb)
 21.2653 + {
 21.2654 + 	int err;
 21.2655 + 
 21.2656 +@@ -167,7 +167,7 @@ static int xfrm6_output_finish(struct sk
 21.2657 + 			return dst_output(skb);
 21.2658 + 
 21.2659 + 		err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL,
 21.2660 +-			      skb->dst->dev, xfrm6_output_finish);
 21.2661 ++			      skb->dst->dev, xfrm6_output_finish2);
 21.2662 + 		if (unlikely(err != 1))
 21.2663 + 			break;
 21.2664 + 	}
 21.2665 +@@ -175,6 +175,41 @@ static int xfrm6_output_finish(struct sk
 21.2666 + 	return err;
 21.2667 + }
 21.2668 + 
 21.2669 ++static int xfrm6_output_finish(struct sk_buff *skb)
 21.2670 ++{
 21.2671 ++	struct sk_buff *segs;
 21.2672 ++
 21.2673 ++	if (!skb_shinfo(skb)->gso_size)
 21.2674 ++		return xfrm6_output_finish2(skb);
 21.2675 ++
 21.2676 ++	skb->protocol = htons(ETH_P_IP);
 21.2677 ++	segs = skb_gso_segment(skb, 0);
 21.2678 ++	kfree_skb(skb);
 21.2679 ++	if (unlikely(IS_ERR(segs)))
 21.2680 ++		return PTR_ERR(segs);
 21.2681 ++
 21.2682 ++	do {
 21.2683 ++		struct sk_buff *nskb = segs->next;
 21.2684 ++		int err;
 21.2685 ++
 21.2686 ++		segs->next = NULL;
 21.2687 ++		err = xfrm6_output_finish2(segs);
 21.2688 ++
 21.2689 ++		if (unlikely(err)) {
 21.2690 ++			while ((segs = nskb)) {
 21.2691 ++				nskb = segs->next;
 21.2692 ++				segs->next = NULL;
 21.2693 ++				kfree_skb(segs);
 21.2694 ++			}
 21.2695 ++			return err;
 21.2696 ++		}
 21.2697 ++
 21.2698 ++		segs = nskb;
 21.2699 ++	} while (segs);
 21.2700 ++
 21.2701 ++	return 0;
 21.2702 ++}
 21.2703 ++
 21.2704 + int xfrm6_output(struct sk_buff *skb)
 21.2705 + {
 21.2706 + 	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
 21.2707 +diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
 21.2708 +index 99ceb91..28c9efd 100644
 21.2709 +--- a/net/sched/sch_generic.c
 21.2710 ++++ b/net/sched/sch_generic.c
 21.2711 +@@ -72,9 +72,9 @@ void qdisc_unlock_tree(struct net_device
 21.2712 +    dev->queue_lock serializes queue accesses for this device
 21.2713 +    AND dev->qdisc pointer itself.
 21.2714 + 
 21.2715 +-   dev->xmit_lock serializes accesses to device driver.
 21.2716 ++   netif_tx_lock serializes accesses to device driver.
 21.2717 + 
 21.2718 +-   dev->queue_lock and dev->xmit_lock are mutually exclusive,
 21.2719 ++   dev->queue_lock and netif_tx_lock are mutually exclusive,
 21.2720 +    if one is grabbed, another must be free.
 21.2721 +  */
 21.2722 + 
 21.2723 +@@ -90,14 +90,17 @@ void qdisc_unlock_tree(struct net_device
 21.2724 +    NOTE: Called under dev->queue_lock with locally disabled BH.
 21.2725 + */
 21.2726 + 
 21.2727 +-int qdisc_restart(struct net_device *dev)
 21.2728 ++static inline int qdisc_restart(struct net_device *dev)
 21.2729 + {
 21.2730 + 	struct Qdisc *q = dev->qdisc;
 21.2731 + 	struct sk_buff *skb;
 21.2732 + 
 21.2733 + 	/* Dequeue packet */
 21.2734 +-	if ((skb = q->dequeue(q)) != NULL) {
 21.2735 ++	if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
 21.2736 + 		unsigned nolock = (dev->features & NETIF_F_LLTX);
 21.2737 ++
 21.2738 ++		dev->gso_skb = NULL;
 21.2739 ++
 21.2740 + 		/*
 21.2741 + 		 * When the driver has LLTX set it does its own locking
 21.2742 + 		 * in start_xmit. No need to add additional overhead by
 21.2743 +@@ -108,7 +111,7 @@ int qdisc_restart(struct net_device *dev
 21.2744 + 		 * will be requeued.
 21.2745 + 		 */
 21.2746 + 		if (!nolock) {
 21.2747 +-			if (!spin_trylock(&dev->xmit_lock)) {
 21.2748 ++			if (!netif_tx_trylock(dev)) {
 21.2749 + 			collision:
 21.2750 + 				/* So, someone grabbed the driver. */
 21.2751 + 				
 21.2752 +@@ -126,8 +129,6 @@ int qdisc_restart(struct net_device *dev
 21.2753 + 				__get_cpu_var(netdev_rx_stat).cpu_collision++;
 21.2754 + 				goto requeue;
 21.2755 + 			}
 21.2756 +-			/* Remember that the driver is grabbed by us. */
 21.2757 +-			dev->xmit_lock_owner = smp_processor_id();
 21.2758 + 		}
 21.2759 + 		
 21.2760 + 		{
 21.2761 +@@ -136,14 +137,11 @@ int qdisc_restart(struct net_device *dev
 21.2762 + 
 21.2763 + 			if (!netif_queue_stopped(dev)) {
 21.2764 + 				int ret;
 21.2765 +-				if (netdev_nit)
 21.2766 +-					dev_queue_xmit_nit(skb, dev);
 21.2767 + 
 21.2768 +-				ret = dev->hard_start_xmit(skb, dev);
 21.2769 ++				ret = dev_hard_start_xmit(skb, dev);
 21.2770 + 				if (ret == NETDEV_TX_OK) { 
 21.2771 + 					if (!nolock) {
 21.2772 +-						dev->xmit_lock_owner = -1;
 21.2773 +-						spin_unlock(&dev->xmit_lock);
 21.2774 ++						netif_tx_unlock(dev);
 21.2775 + 					}
 21.2776 + 					spin_lock(&dev->queue_lock);
 21.2777 + 					return -1;
 21.2778 +@@ -157,8 +155,7 @@ int qdisc_restart(struct net_device *dev
 21.2779 + 			/* NETDEV_TX_BUSY - we need to requeue */
 21.2780 + 			/* Release the driver */
 21.2781 + 			if (!nolock) { 
 21.2782 +-				dev->xmit_lock_owner = -1;
 21.2783 +-				spin_unlock(&dev->xmit_lock);
 21.2784 ++				netif_tx_unlock(dev);
 21.2785 + 			} 
 21.2786 + 			spin_lock(&dev->queue_lock);
 21.2787 + 			q = dev->qdisc;
 21.2788 +@@ -175,7 +172,10 @@ int qdisc_restart(struct net_device *dev
 21.2789 + 		 */
 21.2790 + 
 21.2791 + requeue:
 21.2792 +-		q->ops->requeue(skb, q);
 21.2793 ++		if (skb->next)
 21.2794 ++			dev->gso_skb = skb;
 21.2795 ++		else
 21.2796 ++			q->ops->requeue(skb, q);
 21.2797 + 		netif_schedule(dev);
 21.2798 + 		return 1;
 21.2799 + 	}
 21.2800 +@@ -183,11 +183,23 @@ requeue:
 21.2801 + 	return q->q.qlen;
 21.2802 + }
 21.2803 + 
 21.2804 ++void __qdisc_run(struct net_device *dev)
 21.2805 ++{
 21.2806 ++	if (unlikely(dev->qdisc == &noop_qdisc))
 21.2807 ++		goto out;
 21.2808 ++
 21.2809 ++	while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
 21.2810 ++		/* NOTHING */;
 21.2811 ++
 21.2812 ++out:
 21.2813 ++	clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
 21.2814 ++}
 21.2815 ++
 21.2816 + static void dev_watchdog(unsigned long arg)
 21.2817 + {
 21.2818 + 	struct net_device *dev = (struct net_device *)arg;
 21.2819 + 
 21.2820 +-	spin_lock(&dev->xmit_lock);
 21.2821 ++	netif_tx_lock(dev);
 21.2822 + 	if (dev->qdisc != &noop_qdisc) {
 21.2823 + 		if (netif_device_present(dev) &&
 21.2824 + 		    netif_running(dev) &&
 21.2825 +@@ -201,7 +213,7 @@ static void dev_watchdog(unsigned long a
 21.2826 + 				dev_hold(dev);
 21.2827 + 		}
 21.2828 + 	}
 21.2829 +-	spin_unlock(&dev->xmit_lock);
 21.2830 ++	netif_tx_unlock(dev);
 21.2831 + 
 21.2832 + 	dev_put(dev);
 21.2833 + }
 21.2834 +@@ -225,17 +237,17 @@ void __netdev_watchdog_up(struct net_dev
 21.2835 + 
 21.2836 + static void dev_watchdog_up(struct net_device *dev)
 21.2837 + {
 21.2838 +-	spin_lock_bh(&dev->xmit_lock);
 21.2839 ++	netif_tx_lock_bh(dev);
 21.2840 + 	__netdev_watchdog_up(dev);
 21.2841 +-	spin_unlock_bh(&dev->xmit_lock);
 21.2842 ++	netif_tx_unlock_bh(dev);
 21.2843 + }
 21.2844 + 
 21.2845 + static void dev_watchdog_down(struct net_device *dev)
 21.2846 + {
 21.2847 +-	spin_lock_bh(&dev->xmit_lock);
 21.2848 ++	netif_tx_lock_bh(dev);
 21.2849 + 	if (del_timer(&dev->watchdog_timer))
 21.2850 + 		__dev_put(dev);
 21.2851 +-	spin_unlock_bh(&dev->xmit_lock);
 21.2852 ++	netif_tx_unlock_bh(dev);
 21.2853 + }
 21.2854 + 
 21.2855 + void netif_carrier_on(struct net_device *dev)
 21.2856 +@@ -577,10 +589,17 @@ void dev_deactivate(struct net_device *d
 21.2857 + 
 21.2858 + 	dev_watchdog_down(dev);
 21.2859 + 
 21.2860 +-	while (test_bit(__LINK_STATE_SCHED, &dev->state))
 21.2861 ++	/* Wait for outstanding dev_queue_xmit calls. */
 21.2862 ++	synchronize_rcu();
 21.2863 ++
 21.2864 ++	/* Wait for outstanding qdisc_run calls. */
 21.2865 ++	while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
 21.2866 + 		yield();
 21.2867 + 
 21.2868 +-	spin_unlock_wait(&dev->xmit_lock);
 21.2869 ++	if (dev->gso_skb) {
 21.2870 ++		kfree_skb(dev->gso_skb);
 21.2871 ++		dev->gso_skb = NULL;
 21.2872 ++	}
 21.2873 + }
 21.2874 + 
 21.2875 + void dev_init_scheduler(struct net_device *dev)
 21.2876 +@@ -622,6 +641,5 @@ EXPORT_SYMBOL(qdisc_create_dflt);
 21.2877 + EXPORT_SYMBOL(qdisc_alloc);
 21.2878 + EXPORT_SYMBOL(qdisc_destroy);
 21.2879 + EXPORT_SYMBOL(qdisc_reset);
 21.2880 +-EXPORT_SYMBOL(qdisc_restart);
 21.2881 + EXPORT_SYMBOL(qdisc_lock_tree);
 21.2882 + EXPORT_SYMBOL(qdisc_unlock_tree);
 21.2883 +diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
 21.2884 +index 79b8ef3..4c16ad5 100644
 21.2885 +--- a/net/sched/sch_teql.c
 21.2886 ++++ b/net/sched/sch_teql.c
 21.2887 +@@ -302,20 +302,17 @@ restart:
 21.2888 + 
 21.2889 + 		switch (teql_resolve(skb, skb_res, slave)) {
 21.2890 + 		case 0:
 21.2891 +-			if (spin_trylock(&slave->xmit_lock)) {
 21.2892 +-				slave->xmit_lock_owner = smp_processor_id();
 21.2893 ++			if (netif_tx_trylock(slave)) {
 21.2894 + 				if (!netif_queue_stopped(slave) &&
 21.2895 + 				    slave->hard_start_xmit(skb, slave) == 0) {
 21.2896 +-					slave->xmit_lock_owner = -1;
 21.2897 +-					spin_unlock(&slave->xmit_lock);
 21.2898 ++					netif_tx_unlock(slave);
 21.2899 + 					master->slaves = NEXT_SLAVE(q);
 21.2900 + 					netif_wake_queue(dev);
 21.2901 + 					master->stats.tx_packets++;
 21.2902 + 					master->stats.tx_bytes += len;
 21.2903 + 					return 0;
 21.2904 + 				}
 21.2905 +-				slave->xmit_lock_owner = -1;
 21.2906 +-				spin_unlock(&slave->xmit_lock);
 21.2907 ++				netif_tx_unlock(slave);
 21.2908 + 			}
 21.2909 + 			if (netif_queue_stopped(dev))
 21.2910 + 				busy = 1;
    22.1 --- a/patches/linux-2.6.16.13/xenoprof-generic.patch	Wed Jun 28 07:51:52 2006 -0600
    22.2 +++ b/patches/linux-2.6.16.13/xenoprof-generic.patch	Wed Jun 28 07:52:21 2006 -0600
    22.3 @@ -1,6 +1,6 @@
    22.4 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
    22.5 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c	2006-05-02 22:38:44.000000000 +0100
    22.6 -+++ ./drivers/oprofile/buffer_sync.c	2006-05-04 17:41:51.000000000 +0100
    22.7 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
    22.8 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c	2006-05-03 05:38:44.000000000 +0800
    22.9 ++++ ./drivers/oprofile/buffer_sync.c	2006-06-27 12:14:53.000000000 +0800
   22.10  @@ -6,6 +6,10 @@
   22.11    *
   22.12    * @author John Levon <levon@movementarian.org>
   22.13 @@ -12,7 +12,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
   22.14    * This is the core of the buffer management. Each
   22.15    * CPU buffer is processed and entered into the
   22.16    * global event buffer. Such processing is necessary
   22.17 -@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
   22.18 +@@ -275,15 +279,30 @@ static void add_cpu_switch(int i)
   22.19   	last_cookie = INVALID_COOKIE;
   22.20   }
   22.21   
   22.22 @@ -33,7 +33,13 @@ diff -pruN ../pristine-linux-2.6.16.13/d
   22.23  +		break;
   22.24  +	case CPU_MODE_XEN:
   22.25  +		add_event_entry(XEN_ENTER_SWITCH_CODE);
   22.26 -+		break;
   22.27 ++	  	break;
   22.28 ++        case CPU_MODE_PASSIVE_START:
   22.29 ++                add_event_entry(PASSIVE_START_CODE);
   22.30 ++                break;
   22.31 ++        case CPU_MODE_PASSIVE_STOP:
   22.32 ++                add_event_entry(PASSIVE_STOP_CODE);
   22.33 ++                break;
   22.34  +	default:
   22.35  +		break;
   22.36  +	}
   22.37 @@ -43,7 +49,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
   22.38   static void
   22.39   add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
   22.40   {
   22.41 -@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
   22.42 +@@ -348,9 +367,9 @@ static int add_us_sample(struct mm_struc
   22.43    * for later lookup from userspace.
   22.44    */
   22.45   static int
   22.46 @@ -55,7 +61,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
   22.47   		add_sample_entry(s->eip, s->event);
   22.48   		return 1;
   22.49   	} else if (mm) {
   22.50 -@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
   22.51 +@@ -496,10 +515,11 @@ void sync_buffer(int cpu)
   22.52   	struct mm_struct *mm = NULL;
   22.53   	struct task_struct * new;
   22.54   	unsigned long cookie = 0;
   22.55 @@ -64,34 +70,62 @@ diff -pruN ../pristine-linux-2.6.16.13/d
   22.56   	unsigned int i;
   22.57   	sync_buffer_state state = sb_buffer_start;
   22.58   	unsigned long available;
   22.59 -@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
   22.60 ++	int domain_switch = NO_DOMAIN_SWITCH;
   22.61 + 
   22.62 + 	down(&buffer_sem);
   22.63 +  
   22.64 +@@ -513,12 +533,19 @@ void sync_buffer(int cpu)
   22.65   		struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
   22.66    
   22.67   		if (is_code(s->eip)) {
   22.68  -			if (s->event <= CPU_IS_KERNEL) {
   22.69 -+			if (s->event <= CPU_MODE_XEN) {
   22.70 ++			if (s->event < CPU_TRACE_BEGIN) {
   22.71   				/* kernel/userspace switch */
   22.72  -				in_kernel = s->event;
   22.73  +				cpu_mode = s->event;
   22.74   				if (state == sb_buffer_start)
   22.75   					state = sb_sample_start;
   22.76  -				add_kernel_ctx_switch(s->event);
   22.77 -+				add_cpu_mode_switch(s->event);
   22.78 ++
   22.79 ++				if (s->event == CPU_MODE_PASSIVE_START)
   22.80 ++					domain_switch = DOMAIN_SWITCH_START_EVENT1;
   22.81 ++				else if (s->event == CPU_MODE_PASSIVE_STOP)
   22.82 ++					domain_switch = DOMAIN_SWITCH_STOP_EVENT1;
   22.83 ++
   22.84 ++				if (domain_switch != DOMAIN_SWITCH_START_EVENT2)
   22.85 ++					add_cpu_mode_switch(s->event);
   22.86   			} else if (s->event == CPU_TRACE_BEGIN) {
   22.87   				state = sb_bt_start;
   22.88   				add_trace_begin();
   22.89 -@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
   22.90 +@@ -535,11 +562,20 @@ void sync_buffer(int cpu)
   22.91 + 				add_user_ctx_switch(new, cookie);
   22.92   			}
   22.93   		} else {
   22.94 - 			if (state >= sb_bt_start &&
   22.95 +-			if (state >= sb_bt_start &&
   22.96  -			    !add_sample(mm, s, in_kernel)) {
   22.97 -+			    !add_sample(mm, s, cpu_mode)) {
   22.98 - 				if (state == sb_bt_start) {
   22.99 - 					state = sb_bt_ignore;
  22.100 - 					atomic_inc(&oprofile_stats.bt_lost_no_mapping);
  22.101 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
  22.102 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c	2006-05-02 22:38:44.000000000 +0100
  22.103 -+++ ./drivers/oprofile/cpu_buffer.c	2006-05-04 17:41:51.000000000 +0100
  22.104 +-				if (state == sb_bt_start) {
  22.105 +-					state = sb_bt_ignore;
  22.106 +-					atomic_inc(&oprofile_stats.bt_lost_no_mapping);
  22.107 ++			if (domain_switch == DOMAIN_SWITCH_START_EVENT1) {
  22.108 ++			        add_event_entry(s->event);
  22.109 ++				domain_switch = DOMAIN_SWITCH_START_EVENT2;
  22.110 ++			} else if (domain_switch == DOMAIN_SWITCH_START_EVENT1) {
  22.111 ++				add_sample_entry(s->eip, s->event);
  22.112 ++			} else if (domain_switch == DOMAIN_SWITCH_STOP_EVENT1) {
  22.113 ++				domain_switch = NO_DOMAIN_SWITCH;
  22.114 ++			} else {
  22.115 ++				if (state >= sb_bt_start &&
  22.116 ++				    !add_sample(mm, s, cpu_mode)) {
  22.117 ++					if (state == sb_bt_start) {
  22.118 ++						state = sb_bt_ignore;
  22.119 ++						atomic_inc(&oprofile_stats.bt_lost_no_mapping);
  22.120 ++					}
  22.121 + 				}
  22.122 + 			}
  22.123 + 		}
  22.124 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
  22.125 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c	2006-05-03 05:38:44.000000000 +0800
  22.126 ++++ ./drivers/oprofile/cpu_buffer.c	2006-06-19 22:43:53.000000000 +0800
  22.127  @@ -6,6 +6,10 @@
  22.128    *
  22.129    * @author John Levon <levon@movementarian.org>
  22.130 @@ -139,13 +173,12 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  22.131   {
  22.132   	struct task_struct * task;
  22.133   
  22.134 -@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
  22.135 +@@ -181,16 +185,14 @@ static int log_sample(struct oprofile_cp
  22.136   		return 0;
  22.137   	}
  22.138   
  22.139  -	is_kernel = !!is_kernel;
  22.140 -+	WARN_ON(cpu_mode > CPU_MODE_XEN);
  22.141 - 
  22.142 +-
  22.143   	task = current;
  22.144   
  22.145   	/* notice a switch from user->kernel or vice versa */
  22.146 @@ -161,9 +194,9 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  22.147   	/* notice a task switch */
  22.148   	if (cpu_buf->last_task != task) {
  22.149   		cpu_buf->last_task = task;
  22.150 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
  22.151 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h	2006-05-02 22:38:44.000000000 +0100
  22.152 -+++ ./drivers/oprofile/cpu_buffer.h	2006-05-04 17:41:51.000000000 +0100
  22.153 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
  22.154 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h	2006-05-03 05:38:44.000000000 +0800
  22.155 ++++ ./drivers/oprofile/cpu_buffer.h	2006-06-27 10:38:08.000000000 +0800
  22.156  @@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
  22.157   	volatile unsigned long tail_pos;
  22.158   	unsigned long buffer_size;
  22.159 @@ -173,22 +206,26 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  22.160   	int tracing;
  22.161   	struct op_sample * buffer;
  22.162   	unsigned long sample_received;
  22.163 -@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
  22.164 +@@ -51,7 +51,13 @@ extern struct oprofile_cpu_buffer cpu_bu
  22.165   void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
  22.166   
  22.167   /* transient events for the CPU buffer -> event buffer */
  22.168  -#define CPU_IS_KERNEL 1
  22.169  -#define CPU_TRACE_BEGIN 2
  22.170 -+#define CPU_MODE_USER    0
  22.171 -+#define CPU_MODE_KERNEL  1
  22.172 -+#define CPU_MODE_XEN     2
  22.173 -+#define CPU_TRACE_BEGIN  3
  22.174 ++#define CPU_MODE_USER           0
  22.175 ++#define CPU_MODE_KERNEL         1
  22.176 ++#define CPU_MODE_XEN            2
  22.177 ++#define CPU_MODE_PASSIVE_START  3
  22.178 ++#define CPU_MODE_PASSIVE_STOP   4
  22.179 ++#define CPU_TRACE_BEGIN         5
  22.180 ++
  22.181 ++#define IGNORED_PC              0
  22.182   
  22.183   #endif /* OPROFILE_CPU_BUFFER_H */
  22.184 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
  22.185 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h	2006-05-02 22:38:44.000000000 +0100
  22.186 -+++ ./drivers/oprofile/event_buffer.h	2006-05-04 17:41:51.000000000 +0100
  22.187 -@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
  22.188 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
  22.189 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h	2006-05-03 05:38:44.000000000 +0800
  22.190 ++++ ./drivers/oprofile/event_buffer.h	2006-06-19 22:43:53.000000000 +0800
  22.191 +@@ -29,11 +29,14 @@ void wake_up_buffer_waiter(void);
  22.192   #define CPU_SWITCH_CODE 		2
  22.193   #define COOKIE_SWITCH_CODE 		3
  22.194   #define KERNEL_ENTER_SWITCH_CODE	4
  22.195 @@ -199,12 +236,14 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  22.196   #define TRACE_BEGIN_CODE		8
  22.197   #define TRACE_END_CODE			9
  22.198  +#define XEN_ENTER_SWITCH_CODE		10
  22.199 ++#define PASSIVE_START_CODE		11
  22.200 ++#define PASSIVE_STOP_CODE		12
  22.201    
  22.202   #define INVALID_COOKIE ~0UL
  22.203   #define NO_COOKIE 0UL
  22.204 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
  22.205 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c	2006-05-02 22:38:44.000000000 +0100
  22.206 -+++ ./drivers/oprofile/oprof.c	2006-05-04 17:41:51.000000000 +0100
  22.207 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
  22.208 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c	2006-05-03 05:38:44.000000000 +0800
  22.209 ++++ ./drivers/oprofile/oprof.c	2006-06-19 23:45:17.000000000 +0800
  22.210  @@ -5,6 +5,10 @@
  22.211    * @remark Read the file COPYING
  22.212    *
  22.213 @@ -225,7 +264,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  22.214   struct oprofile_operations oprofile_ops;
  22.215   
  22.216   unsigned long oprofile_started;
  22.217 -@@ -33,6 +37,19 @@ static DECLARE_MUTEX(start_sem);
  22.218 +@@ -33,6 +37,32 @@ static DECLARE_MUTEX(start_sem);
  22.219    */
  22.220   static int timer = 0;
  22.221   
  22.222 @@ -242,23 +281,37 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  22.223  +	return err;
  22.224  +}
  22.225  +
  22.226 ++int oprofile_set_passive(int passive_domains[], unsigned int pdomains)
  22.227 ++{
  22.228 ++	int err;
  22.229 ++
  22.230 ++	if (!oprofile_ops.set_passive)
  22.231 ++		return -EINVAL;
  22.232 ++
  22.233 ++	down(&start_sem);
  22.234 ++	err = oprofile_ops.set_passive(passive_domains, pdomains);
  22.235 ++	up(&start_sem);
  22.236 ++	return err;
  22.237 ++}
  22.238 ++
  22.239   int oprofile_setup(void)
  22.240   {
  22.241   	int err;
  22.242 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
  22.243 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h	2006-05-02 22:38:44.000000000 +0100
  22.244 -+++ ./drivers/oprofile/oprof.h	2006-05-04 17:41:51.000000000 +0100
  22.245 -@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
  22.246 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
  22.247 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h	2006-05-03 05:38:44.000000000 +0800
  22.248 ++++ ./drivers/oprofile/oprof.h	2006-06-19 23:42:36.000000000 +0800
  22.249 +@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
  22.250   void oprofile_timer_init(struct oprofile_operations * ops);
  22.251   
  22.252   int oprofile_set_backtrace(unsigned long depth);
  22.253  +
  22.254  +int oprofile_set_active(int active_domains[], unsigned int adomains);
  22.255 ++int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
  22.256    
  22.257   #endif /* OPROF_H */
  22.258 -diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
  22.259 ---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c	2006-05-02 22:38:44.000000000 +0100
  22.260 -+++ ./drivers/oprofile/oprofile_files.c	2006-05-04 17:41:51.000000000 +0100
  22.261 +diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
  22.262 +--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c	2006-05-03 05:38:44.000000000 +0800
  22.263 ++++ ./drivers/oprofile/oprofile_files.c	2006-06-19 23:29:07.000000000 +0800
  22.264  @@ -5,15 +5,21 @@
  22.265    * @remark Read the file COPYING
  22.266    *
  22.267 @@ -282,7 +335,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  22.268   unsigned long fs_buffer_size = 131072;
  22.269   unsigned long fs_cpu_buffer_size = 8192;
  22.270   unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
  22.271 -@@ -117,11 +123,108 @@ static ssize_t dump_write(struct file * 
  22.272 +@@ -117,11 +123,202 @@ static ssize_t dump_write(struct file * 
  22.273   static struct file_operations dump_fops = {
  22.274   	.write		= dump_write,
  22.275   };
  22.276 @@ -384,17 +437,110 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  22.277  +	.write		= adomain_write,
  22.278  +};
  22.279  +
  22.280 ++static unsigned int pdomains = 0;
  22.281 ++static int passive_domains[MAX_OPROF_DOMAINS];
  22.282 ++static DEFINE_MUTEX(pdom_mutex);
  22.283 ++
  22.284 ++static ssize_t pdomain_write(struct file * file, char const __user * buf, 
  22.285 ++			     size_t count, loff_t * offset)
  22.286 ++{
  22.287 ++	char *tmpbuf;
  22.288 ++	char *startp, *endp;
  22.289 ++	int i;
  22.290 ++	unsigned long val;
  22.291 ++	ssize_t retval = count;
  22.292 ++	
  22.293 ++	if (*offset)
  22.294 ++		return -EINVAL;	
  22.295 ++	if (count > TMPBUFSIZE - 1)
  22.296 ++		return -EINVAL;
  22.297 ++
  22.298 ++	if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
  22.299 ++		return -ENOMEM;
  22.300 ++
  22.301 ++	if (copy_from_user(tmpbuf, buf, count)) {
  22.302 ++		kfree(tmpbuf);
  22.303 ++		return -EFAULT;
  22.304 ++	}
  22.305 ++	tmpbuf[count] = 0;
  22.306 ++
  22.307 ++	mutex_lock(&pdom_mutex);
  22.308 ++
  22.309 ++	startp = tmpbuf;
  22.310 ++	/* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
  22.311 ++	for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
  22.312 ++		val = simple_strtoul(startp, &endp, 0);
  22.313 ++		if (endp == startp)
  22.314 ++			break;
  22.315 ++		while (ispunct(*endp) || isspace(*endp))
  22.316 ++			endp++;
  22.317 ++		passive_domains[i] = val;
  22.318 ++		if (passive_domains[i] != val)
  22.319 ++			/* Overflow, force error below */
  22.320 ++			i = MAX_OPROF_DOMAINS + 1;
  22.321 ++		startp = endp;
  22.322 ++	}
  22.323 ++	/* Force error on trailing junk */
  22.324 ++	pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
  22.325 ++
  22.326 ++	kfree(tmpbuf);
  22.327 ++
  22.328 ++	if (pdomains > MAX_OPROF_DOMAINS
  22.329 ++	    || oprofile_set_passive(passive_domains, pdomains)) {
  22.330 ++		pdomains = 0;
  22.331 ++		retval = -EINVAL;
  22.332 ++	}
  22.333 ++
  22.334 ++	mutex_unlock(&pdom_mutex);
  22.335 ++	return retval;
  22.336 ++}
  22.337 ++
  22.338 ++static ssize_t pdomain_read(struct file * file, char __user * buf, 
  22.339 ++			    size_t count, loff_t * offset)
  22.340 ++{
  22.341 ++	char * tmpbuf;
  22.342 ++	size_t len;
  22.343 ++	int i;
  22.344 ++	ssize_t retval;
  22.345 ++
  22.346 ++	if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
  22.347 ++		return -ENOMEM;
  22.348 ++
  22.349 ++	mutex_lock(&pdom_mutex);
  22.350 ++
  22.351 ++	len = 0;
  22.352 ++	for (i = 0; i < pdomains; i++)
  22.353 ++		len += snprintf(tmpbuf + len,
  22.354 ++				len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
  22.355 ++				"%u ", passive_domains[i]);
  22.356 ++	WARN_ON(len > TMPBUFSIZE);
  22.357 ++	if (len != 0 && len <= TMPBUFSIZE)
  22.358 ++		tmpbuf[len-1] = '\n';
  22.359 ++
  22.360 ++	mutex_unlock(&pdom_mutex);
  22.361 ++
  22.362 ++	retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
  22.363 ++
  22.364 ++	kfree(tmpbuf);
  22.365 ++	return retval;
  22.366 ++}
  22.367 ++
  22.368 ++static struct file_operations passive_domain_ops = {
  22.369 ++	.read		= pdomain_read,
  22.370 ++	.write		= pdomain_write,
  22.371 ++};
  22.372 ++
  22.373   void oprofile_create_files(struct super_block * sb, struct dentry * root)
  22.374   {
  22.375   	oprofilefs_create_file(sb, root, "enable", &enable_fops);
  22.376   	oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
  22.377  +	oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
  22.378 ++	oprofilefs_create_file(sb, root, "passive_domains", &passive_domain_ops);
  22.379   	oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
  22.380   	oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
  22.381   	oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
  22.382 -diff -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h ./include/linux/oprofile.h
  22.383 ---- ../pristine-linux-2.6.16.13/include/linux/oprofile.h	2006-05-02 22:38:44.000000000 +0100
  22.384 -+++ ./include/linux/oprofile.h	2006-05-04 17:41:51.000000000 +0100
  22.385 +--- ../pristine-linux-2.6.16.13/include/linux/oprofile.h	2006-05-03 05:38:44.000000000 +0800
  22.386 ++++ ./include/linux/oprofile.h	2006-06-19 23:52:00.000000000 +0800
  22.387  @@ -16,6 +16,8 @@
  22.388   #include <linux/types.h>
  22.389   #include <linux/spinlock.h>
  22.390 @@ -404,12 +550,15 @@ diff -pruN ../pristine-linux-2.6.16.13/i
  22.391    
  22.392   struct super_block;
  22.393   struct dentry;
  22.394 -@@ -27,6 +29,8 @@ struct oprofile_operations {
  22.395 +@@ -27,6 +29,11 @@ struct oprofile_operations {
  22.396   	/* create any necessary configuration files in the oprofile fs.
  22.397   	 * Optional. */
  22.398   	int (*create_files)(struct super_block * sb, struct dentry * root);
  22.399  +	/* setup active domains with Xen */
  22.400  +	int (*set_active)(int *active_domains, unsigned int adomains);
  22.401 ++        /* setup passive domains with Xen */
  22.402 ++        int (*set_passive)(int *passive_domains, unsigned int pdomains);
  22.403 ++	
  22.404   	/* Do any necessary interrupt setup. Optional. */
  22.405   	int (*setup)(void);
  22.406   	/* Do any necessary interrupt shutdown. Optional. */
    23.1 --- a/tools/Makefile	Wed Jun 28 07:51:52 2006 -0600
    23.2 +++ b/tools/Makefile	Wed Jun 28 07:52:21 2006 -0600
    23.3 @@ -45,6 +45,9 @@ clean: check_clean
    23.4  	done
    23.5  	$(MAKE) ioemuclean
    23.6  
    23.7 +.PHONY: distclean
    23.8 +distclean: clean
    23.9 +
   23.10  .PHONY: check
   23.11  check:
   23.12  	$(MAKE) -C check
    24.1 --- a/tools/examples/Makefile	Wed Jun 28 07:51:52 2006 -0600
    24.2 +++ b/tools/examples/Makefile	Wed Jun 28 07:52:21 2006 -0600
    24.3 @@ -32,7 +32,7 @@ XEN_SCRIPTS += external-device-migrate
    24.4  XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
    24.5  XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
    24.6  XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
    24.7 -XEN_SCRIPT_DATA += vtpm-migration.sh
    24.8 +XEN_SCRIPT_DATA += vtpm-migration.sh vtpm-impl
    24.9  
   24.10  XEN_HOTPLUG_DIR = /etc/hotplug
   24.11  XEN_HOTPLUG_SCRIPTS = xen-backend.agent
    25.1 --- a/tools/examples/vtpm	Wed Jun 28 07:51:52 2006 -0600
    25.2 +++ b/tools/examples/vtpm	Wed Jun 28 07:52:21 2006 -0600
    25.3 @@ -9,15 +9,9 @@ case "$command" in
    25.4    add)
    25.5      vtpm_create_instance
    25.6    ;;
    25.7 -  online)
    25.8 -    vtpm_create_instance
    25.9 -  ;;
   25.10    remove)
   25.11      vtpm_remove_instance
   25.12    ;;
   25.13 -  offline)
   25.14 -    vtpm_remove_instance
   25.15 -  ;;
   25.16  esac
   25.17  
   25.18  if [ $vtpm_fatal_error -eq 0 ]; then
    26.1 --- a/tools/examples/vtpm-common.sh	Wed Jun 28 07:51:52 2006 -0600
    26.2 +++ b/tools/examples/vtpm-common.sh	Wed Jun 28 07:52:21 2006 -0600
    26.3 @@ -23,7 +23,7 @@ dir=$(dirname "$0")
    26.4  VTPMDB="/etc/xen/vtpm.db"
    26.5  
    26.6  #In the vtpm-impl file some commands should be defined:
    26.7 -#      vtpm_create, vtpm_setup, vtpm_reset, etc. (see below)
    26.8 +#      vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
    26.9  #This should be indicated by setting VTPM_IMPL_DEFINED.
   26.10  if [ -r "$dir/vtpm-impl" ]; then
   26.11  	. "$dir/vtpm-impl"
   26.12 @@ -36,7 +36,7 @@ if [ -z "$VTPM_IMPL_DEFINED" ]; then
   26.13  	function vtpm_setup() {
   26.14  		true
   26.15  	}
   26.16 -	function vtpm_reset() {
   26.17 +	function vtpm_start() {
   26.18  		true
   26.19  	}
   26.20  	function vtpm_suspend() {
   26.21 @@ -256,22 +256,22 @@ function vtpm_create_instance () {
   26.22  		else
   26.23  			instance=$(vtpmdb_get_free_instancenum)
   26.24  		fi
   26.25 -		if [ "$reason" == "create" ]; then
   26.26 -			vtpm_create $instance
   26.27 -		else
   26.28 -			vtpm_resume $instance $domname
   26.29 -		fi
   26.30 +
   26.31 +		vtpm_create $instance
   26.32 +
   26.33  		if [ $vtpm_fatal_error -eq 0 ]; then
   26.34  			vtpmdb_add_instance $domname $instance
   26.35  		fi
   26.36 +	else
   26.37 +		if [ "$reason" == "resume" ]; then
   26.38 +			vtpm_resume $instance
   26.39 +		else
   26.40 +			vtpm_start $instance
   26.41 +		fi
   26.42  	fi
   26.43  
   26.44  	release_lock vtpmdb
   26.45  
   26.46 -	if [ $vtpm_fatal_error -eq 0 -a \
   26.47 -	     "$reason" == "create" ]; then
   26.48 -		vtpm_reset $instance
   26.49 -	fi
   26.50  	xenstore_write $XENBUS_PATH/instance $instance
   26.51  }
   26.52  
   26.53 @@ -283,19 +283,17 @@ function vtpm_remove_instance () {
   26.54  	local instance reason domname
   26.55  	domname=$(xenstore_read "$XENBUS_PATH"/domain)
   26.56  
   26.57 -	if [ "$doname" != "" ]; then
   26.58 +	if [ "$domname" != "" ]; then
   26.59  		claim_lock vtpmdb
   26.60  
   26.61  		instance=$(vtpmdb_find_instance $domname)
   26.62  
   26.63  		if [ "$instance" != "0" ]; then
   26.64 -			if [ "$reason" == "suspend" ]; then
   26.65 -				vtpm_suspend $instance
   26.66 -			fi
   26.67 +			vtpm_suspend $instance
   26.68  		fi
   26.69 +
   26.70 +		release_lock vtpmdb
   26.71  	fi
   26.72 -
   26.73 -	release_lock vtpmdb
   26.74  }
   26.75  
   26.76  
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/tools/examples/vtpm-impl	Wed Jun 28 07:52:21 2006 -0600
    27.3 @@ -0,0 +1,136 @@
    27.4 +#!/bin/bash
    27.5 +# ===================================================================
    27.6 +# 
    27.7 +# Copyright (c) 2005, Intel Corp.
    27.8 +# All rights reserved.
    27.9 +#
   27.10 +# Redistribution and use in source and binary forms, with or without 
   27.11 +# modification, are permitted provided that the following conditions 
   27.12 +# are met:
   27.13 +#
   27.14 +#   * Redistributions of source code must retain the above copyright 
   27.15 +#     notice, this list of conditions and the following disclaimer.
   27.16 +#   * Redistributions in binary form must reproduce the above 
   27.17 +#     copyright notice, this list of conditions and the following 
   27.18 +#     disclaimer in the documentation and/or other materials provided 
   27.19 +#     with the distribution.
   27.20 +#   * Neither the name of Intel Corporation nor the names of its 
   27.21 +#     contributors may be used to endorse or promote products derived
   27.22 +#     from this software without specific prior written permission.
   27.23 +#
   27.24 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
   27.25 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
   27.26 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
   27.27 +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
   27.28 +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   27.29 +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   27.30 +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
   27.31 +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27.32 +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   27.33 +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   27.34 +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   27.35 +# OF THE POSSIBILITY OF SUCH DAMAGE.
   27.36 +# ===================================================================
   27.37 +
   27.38 +VTPM_IMPL_DEFINED=1
   27.39 +
   27.40 +#            |        SRC        |    TAG  |      CMD SIZE     |        ORD       | type| mode
   27.41 +TPM_CMD_OPEN=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x01
   27.42 +TPM_CMD_RESM=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x02
   27.43 +TPM_CMD_CLOS=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x02
   27.44 +TPM_CMD_DELE=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x03
   27.45 +
   27.46 +TPM_SUCCESS=00000000
   27.47 +
   27.48 +TX_VTPM_MANAGER=/var/vtpm/fifos/from_console.fifo
   27.49 +RX_VTPM_MANAGER=/var/vtpm/fifos/to_console.fifo
   27.50 +
   27.51 +# -------------------- Helpers for binary streams -----------
   27.52 +
   27.53 +function str_to_hex32() {
   27.54 + printf "%0.8x" $1
   27.55 +}
   27.56 +
   27.57 +function hex32_to_bin() {
   27.58 + local inst=$(str_to_hex32 $1);
   27.59 + 
   27.60 + local n1=`echo $inst | sed 's/\(..\)....../\\\\x\1/'`
   27.61 + local n2=`echo $inst | sed 's/..\(..\)..../\\\\x\1/'`
   27.62 + local n3=`echo $inst | sed 's/....\(..\)../\\\\x\1/'`
   27.63 + local n4=`echo $inst | sed 's/......\(..\)/\\\\x\1/'`
   27.64 +
   27.65 + echo "$n1$n2$n3$n4"
   27.66 +}
   27.67 +
   27.68 +function vtpm_manager_cmd() {
   27.69 + local cmd=$1;
   27.70 + local inst=$2;
   27.71 + local inst_bin=$(hex32_to_bin $inst);
   27.72 +
   27.73 + #send cmd to vtpm_manager
   27.74 + printf "$cmd$inst_bin" > $TX_VTPM_MANAGER
   27.75 +
   27.76 + #recv response
   27.77 + local resp_hex=`dd skip=10 bs=1 count=4 if=$RX_VTPM_MANAGER 2> /dev/null | xxd -ps`
   27.78 +
   27.79 + #return whether the command was successful
   27.80 + if [ $resp_hex != $TPM_SUCCESS ]; then
   27.81 +   vtpm_fatal_error=1
   27.82 +   false
   27.83 +  else
   27.84 +   true
   27.85 + fi
   27.86 +}
   27.87 +
   27.88 +# ------------------ Command handlers -----------------
   27.89 +
   27.90 +# Create new vtpm instance & set it up for use
   27.91 +function vtpm_create () {
   27.92 + # Creation is handled implicitly by the manager on first setup
   27.93 + # so just set it up for use
   27.94 + $(vtpm_start $1)
   27.95 +}
   27.96 +
   27.97 +# Setup vtpm instance for use.
   27.98 +function vtpm_start() {
   27.99 + $(vtpm_manager_cmd $TPM_CMD_OPEN $1)
  27.100 +}
  27.101 +
  27.102 +function vtpm_resume() {
  27.103 + $(vtpm_manager_cmd $TPM_CMD_RESM $1)
  27.104 +}
  27.105 +
  27.106 +# Reset the vtpm AKA clear PCRs
  27.107 +function vtpm_reset() {
  27.108 + #not used by current implemenation
  27.109 + true
  27.110 +}
  27.111 +
  27.112 +# Shutdown the vtpm while the vm is down
  27.113 +# This could be a suspend of shutdown
  27.114 +# we cannot distinquish, so save the state
  27.115 +# and decide on startup if we should keep is
  27.116 +function vtpm_suspend() {
  27.117 + $(vtpm_manager_cmd $TPM_CMD_CLOS $1)
  27.118 +}
  27.119 +
  27.120 +
  27.121 +function vtpm_delete() {
  27.122 + local inst=$1
  27.123 + if $(vtpm_manager_cmd $TPM_CMD_DELE $inst); then
  27.124 +   rm -f /var/vtpm/vtpm_dm_$1.data
  27.125 +   true
  27.126 + else 
  27.127 +   vtpm_fatal_error=1
  27.128 +   false
  27.129 + fi
  27.130 +}
  27.131 +
  27.132 +function vtpm_migrate() {
  27.133 + echo "Error: vTPM migration accross machines not implemented."
  27.134 +}
  27.135 +
  27.136 +function vtpm_migrate_recover() {
  27.137 + true
  27.138 +}
  27.139 +
    28.1 --- a/tools/libxc/Makefile	Wed Jun 28 07:51:52 2006 -0600
    28.2 +++ b/tools/libxc/Makefile	Wed Jun 28 07:52:21 2006 -0600
    28.3 @@ -31,7 +31,6 @@ GUEST_SRCS-y += xc_load_bin.c
    28.4  GUEST_SRCS-y += xc_load_elf.c
    28.5  GUEST_SRCS-y += xg_private.c
    28.6  GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c
    28.7 -GUEST_SRCS-$(CONFIG_PLAN9) += xc_load_aout9.c
    28.8  GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
    28.9  GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
   28.10  
    29.1 --- a/tools/libxc/xc_aout9.h	Wed Jun 28 07:51:52 2006 -0600
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,30 +0,0 @@
    29.4 -
    29.5 -typedef struct	Exec
    29.6 -{
    29.7 -	long	magic;		/* magic number */
    29.8 -	long	text;	 	/* size of text segment */
    29.9 -	long	data;	 	/* size of initialized data */
   29.10 -	long	bss;	  	/* size of uninitialized data */
   29.11 -	long	syms;	 	/* size of symbol table */
   29.12 -	long	entry;	 	/* entry point */
   29.13 -	long	spsz;		/* size of pc/sp offset table */
   29.14 -	long	pcsz;		/* size of pc/line number table */
   29.15 -} Exec;
   29.16 -
   29.17 -#define	_MAGIC(b)	((((4*b)+0)*b)+7)
   29.18 -#define	A_MAGIC		_MAGIC(8)	/* 68020 */
   29.19 -#define	I_MAGIC		_MAGIC(11)	/* intel 386 */
   29.20 -#define	J_MAGIC		_MAGIC(12)	/* intel 960 (retired) */
   29.21 -#define	K_MAGIC		_MAGIC(13)	/* sparc */
   29.22 -#define	V_MAGIC		_MAGIC(16)	/* mips 3000 BE */
   29.23 -#define	X_MAGIC		_MAGIC(17)	/* att dsp 3210 (retired) */
   29.24 -#define	M_MAGIC		_MAGIC(18)	/* mips 4000 BE */
   29.25 -#define	D_MAGIC		_MAGIC(19)	/* amd 29000 (retired) */
   29.26 -#define	E_MAGIC		_MAGIC(20)	/* arm */
   29.27 -#define	Q_MAGIC		_MAGIC(21)	/* powerpc */
   29.28 -#define	N_MAGIC		_MAGIC(22)	/* mips 4000 LE */
   29.29 -#define	L_MAGIC		_MAGIC(23)	/* dec alpha */
   29.30 -#define	P_MAGIC		_MAGIC(24)	/* mips 3000 LE */
   29.31 -#define	U_MAGIC		_MAGIC(25)	/* sparc64 */
   29.32 -#define	S_MAGIC		_MAGIC(26)	/* amd64 */
   29.33 -
    30.1 --- a/tools/libxc/xc_ia64_stubs.c	Wed Jun 28 07:51:52 2006 -0600
    30.2 +++ b/tools/libxc/xc_ia64_stubs.c	Wed Jun 28 07:52:21 2006 -0600
    30.3 @@ -38,23 +38,12 @@ int xc_linux_restore(int xc_handle, int 
    30.4      return -1;
    30.5  }
    30.6  
    30.7 -int
    30.8 -xc_plan9_build(int xc_handle,
    30.9 -               uint32_t domid,
   30.10 -               const char *image_name,
   30.11 -               const char *cmdline,
   30.12 -               unsigned int control_evtchn, unsigned long flags)
   30.13 -{
   30.14 -    PERROR("xc_plan9_build not implemented\n");
   30.15 -    return -1;
   30.16 -}
   30.17  /*  
   30.18      VMM uses put_user to copy pfn_list to guest buffer, this maybe fail,
   30.19      VMM doesn't handle this now.
   30.20      This method will touch guest buffer to make sure the buffer's mapping
   30.21      is tracked by VMM,
   30.22   */
   30.23 -
   30.24  int xc_ia64_get_pfn_list(int xc_handle,
   30.25                           uint32_t domid,
   30.26                           xen_pfn_t *pfn_buf,
    31.1 --- a/tools/libxc/xc_linux_build.c	Wed Jun 28 07:51:52 2006 -0600
    31.2 +++ b/tools/libxc/xc_linux_build.c	Wed Jun 28 07:52:21 2006 -0600
    31.3 @@ -7,7 +7,6 @@
    31.4  #include <xenctrl.h>
    31.5  
    31.6  #include "xc_elf.h"
    31.7 -#include "xc_aout9.h"
    31.8  #include <stdlib.h>
    31.9  #include <unistd.h>
   31.10  #include <inttypes.h>
   31.11 @@ -35,10 +34,6 @@
   31.12  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   31.13  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
   31.14  
   31.15 -#ifdef __ia64__
   31.16 -#define probe_aout9(image,image_size,load_funcs) 1
   31.17 -#endif
   31.18 -
   31.19  struct initrd_info {
   31.20      enum { INITRD_none, INITRD_file, INITRD_mem } type;
   31.21      unsigned long len;
   31.22 @@ -124,8 +119,7 @@ static int probeimageformat(const char *
   31.23                              struct load_funcs *load_funcs)
   31.24  {
   31.25      if ( probe_elf(image, image_size, load_funcs) &&
   31.26 -         probe_bin(image, image_size, load_funcs) &&
   31.27 -         probe_aout9(image, image_size, load_funcs) )
   31.28 +         probe_bin(image, image_size, load_funcs) )
   31.29      {
   31.30          ERROR( "Unrecognized image format" );
   31.31          return -EINVAL;
    32.1 --- a/tools/libxc/xc_load_aout9.c	Wed Jun 28 07:51:52 2006 -0600
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,178 +0,0 @@
    32.4 -
    32.5 -#include "xg_private.h"
    32.6 -#include "xc_aout9.h"
    32.7 -
    32.8 -#if defined(__i386__)
    32.9 -  #define A9_MAGIC I_MAGIC
   32.10 -#elif defined(__x86_64__)
   32.11 -  #define A9_MAGIC S_MAGIC
   32.12 -#elif defined(__ia64__)
   32.13 -  #define A9_MAGIC 0
   32.14 -#else
   32.15 -#error "Unsupported architecture"
   32.16 -#endif
   32.17 -
   32.18 -#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   32.19 -#define KZERO             0x80000000
   32.20 -#define KOFFSET(_p)       ((_p)&~KZERO)
   32.21 -
   32.22 -static int parseaout9image(const char *, unsigned long, struct domain_setup_info *);
   32.23 -static int loadaout9image(const char *, unsigned long, int, uint32_t, xen_pfn_t *, struct domain_setup_info *);
   32.24 -static void copyout(int, uint32_t, unsigned long *, unsigned long, const char *, int);
   32.25 -struct Exec *get_header(const char *, unsigned long, struct Exec *);
   32.26 -
   32.27 -
   32.28 -int
   32.29 -probe_aout9(
   32.30 -    const char *image,
   32.31 -    unsigned long image_size,
   32.32 -    struct load_funcs *load_funcs)
   32.33 -{
   32.34 -    struct Exec ehdr;
   32.35 -
   32.36 -    if (!get_header(image, image_size, &ehdr)) {
   32.37 -        ERROR("Kernel image does not have a a.out9 header.");
   32.38 -        return -EINVAL;
   32.39 -    }
   32.40 -
   32.41 -    load_funcs->parseimage = parseaout9image;
   32.42 -    load_funcs->loadimage = loadaout9image;
   32.43 -    return 0;
   32.44 -}
   32.45 -
   32.46 -static int
   32.47 -parseaout9image(
   32.48 -    const char *image,
   32.49 -    unsigned long image_size,
   32.50 -    struct domain_setup_info *dsi)
   32.51 -{
   32.52 -    struct Exec ehdr;
   32.53 -    unsigned long start, dstart, end;
   32.54 -
   32.55 -    if (!get_header(image, image_size, &ehdr)) {
   32.56 -        ERROR("Kernel image does not have a a.out9 header.");
   32.57 -        return -EINVAL;
   32.58 -    }
   32.59 -
   32.60 -    if (sizeof ehdr + ehdr.text + ehdr.data > image_size) {
   32.61 -        ERROR("a.out program extends past end of image.");
   32.62 -        return -EINVAL;
   32.63 -    }
   32.64 -
   32.65 -    start = ehdr.entry;
   32.66 -    dstart = round_pgup(start + ehdr.text);
   32.67 -    end = dstart + ehdr.data + ehdr.bss;
   32.68 -
   32.69 -    dsi->v_start     = KZERO;
   32.70 -    dsi->v_kernstart = start;
   32.71 -    dsi->v_kernend   = end;
   32.72 -    dsi->v_kernentry = ehdr.entry;
   32.73 -    dsi->v_end       = end;
   32.74 -
   32.75 -    /* XXX load symbols */
   32.76 -
   32.77 -    return 0;
   32.78 -}
   32.79 -
   32.80 -static int
   32.81 -loadaout9image(
   32.82 -    const char *image,
   32.83 -    unsigned long image_size,
   32.84 -    int xch, uint32_t dom,
   32.85 -    xen_pfn_t *parray,
   32.86 -    struct domain_setup_info *dsi)
   32.87 -{
   32.88 -    struct Exec ehdr;
   32.89 -    unsigned long start, dstart;
   32.90 -
   32.91 -    if (!get_header(image, image_size, &ehdr)) {
   32.92 -        ERROR("Kernel image does not have a a.out9 header.");
   32.93 -        return -EINVAL;
   32.94 -    }
   32.95 -
   32.96 -    start = ehdr.entry;
   32.97 -    dstart = round_pgup(start + ehdr.text);
   32.98 -    copyout(xch, dom, parray, start, image + sizeof ehdr, ehdr.text);
   32.99 -    copyout(xch, dom, parray, dstart,
  32.100 -            image + sizeof ehdr + ehdr.text, ehdr.data);
  32.101 -
  32.102 -    /* XXX load symbols */
  32.103 -
  32.104 -    return 0;
  32.105 -}
  32.106 -
  32.107 -/*
  32.108 - * copyout data to the domain given an offset to the start
  32.109 - * of its memory region described by parray.
  32.110 - */
  32.111 -static void
  32.112 -copyout(
  32.113 -    int xch, uint32_t dom,
  32.114 -    unsigned long *parray,
  32.115 -    unsigned long addr,
  32.116 -    const char *buf,
  32.117 -    int sz)
  32.118 -{
  32.119 -    unsigned long pgoff, chunksz, off;
  32.120 -    void *pg;
  32.121 -
  32.122 -    off = KOFFSET(addr);
  32.123 -    while (sz > 0) {
  32.124 -        pgoff = off & (PAGE_SIZE-1);
  32.125 -        chunksz = sz;
  32.126 -        if(chunksz > PAGE_SIZE - pgoff)
  32.127 -            chunksz = PAGE_SIZE - pgoff;
  32.128 -
  32.129 -        pg = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_WRITE,
  32.130 -                                  parray[off>>PAGE_SHIFT]);
  32.131 -        memcpy(pg + pgoff, buf, chunksz);
  32.132 -        munmap(pg, PAGE_SIZE);
  32.133 -
  32.134 -        off += chunksz;
  32.135 -        buf += chunksz;
  32.136 -        sz -= chunksz;
  32.137 -    }
  32.138 -}
  32.139 -
  32.140 -#define swap16(_v) ((((uint16_t)(_v)>>8)&0xff)|(((uint16_t)(_v)&0xff)<<8))
  32.141 -#define swap32(_v) (((uint32_t)swap16((uint16_t)(_v))<<16)|(uint32_t)swap16((uint32_t)((_v)>>16)))
  32.142 -
  32.143 -/*
  32.144 - * Decode the header from the start of image and return it.
  32.145 - */
  32.146 -struct Exec *
  32.147 -get_header(
  32.148 -    const char *image,
  32.149 -    unsigned long image_size,
  32.150 -    struct Exec *ehdr)
  32.151 -{
  32.152 -    uint32_t *v, x;
  32.153 -    int i;
  32.154 -
  32.155 -    if (A9_MAGIC == 0)
  32.156 -        return 0;
  32.157 -
  32.158 -    if (image_size < sizeof ehdr)
  32.159 -        return 0;
  32.160 -
  32.161 -    /* ... all big endian words */
  32.162 -    v = (uint32_t *)ehdr;
  32.163 -    for (i = 0; i < sizeof(*ehdr); i += 4) {
  32.164 -        x = *(uint32_t *)&image[i];
  32.165 -        v[i/4] = swap32(x);
  32.166 -    }
  32.167 -
  32.168 -    if(ehdr->magic != A9_MAGIC)
  32.169 -        return 0;
  32.170 -    return ehdr;
  32.171 -}
  32.172 -
  32.173 -/*
  32.174 - * Local variables:
  32.175 - * mode: C
  32.176 - * c-set-style: "BSD"
  32.177 - * c-basic-offset: 4
  32.178 - * tab-width: 4
  32.179 - * indent-tabs-mode: nil
  32.180 - * End:
  32.181 - */
    33.1 --- a/tools/libxc/xg_private.h	Wed Jun 28 07:51:52 2006 -0600
    33.2 +++ b/tools/libxc/xg_private.h	Wed Jun 28 07:52:21 2006 -0600
    33.3 @@ -196,8 +196,5 @@ int probe_elf(const char *image, unsigne
    33.4                struct load_funcs *funcs);
    33.5  int probe_bin(const char *image, unsigned long image_size,
    33.6                struct load_funcs *funcs);
    33.7 -int probe_aout9(const char *image, unsigned long image_size,
    33.8 -                struct load_funcs *funcs);
    33.9  
   33.10 -#endif
   33.11 -
   33.12 +#endif /* XG_PRIVATE_H */
    34.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Wed Jun 28 07:51:52 2006 -0600
    34.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Jun 28 07:52:21 2006 -0600
    34.3 @@ -582,6 +582,12 @@ static PyObject *pyxc_readconsolering(Xc
    34.4  }
    34.5  
    34.6  
    34.7 +static unsigned long pages_to_kib(unsigned long pages)
    34.8 +{
    34.9 +    return pages * (XC_PAGE_SIZE / 1024);
   34.10 +}
   34.11 +
   34.12 +
   34.13  static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
   34.14  {
   34.15      unsigned long pages;
   34.16 @@ -589,13 +595,7 @@ static PyObject *pyxc_pages_to_kib(XcObj
   34.17      if (!PyArg_ParseTuple(args, "l", &pages))
   34.18          return NULL;
   34.19  
   34.20 -    return PyLong_FromUnsignedLong(pages * (XC_PAGE_SIZE / 1024));
   34.21 -}
   34.22 -
   34.23 -
   34.24 -static unsigned long pages_to_mb(unsigned long pages)
   34.25 -{
   34.26 -    return (pages * (XC_PAGE_SIZE / 1024) + 1023) / 1024;
   34.27 +    return PyLong_FromUnsignedLong(pages_to_kib(pages));
   34.28  }
   34.29  
   34.30  
   34.31 @@ -618,13 +618,14 @@ static PyObject *pyxc_physinfo(XcObject 
   34.32      if(q>cpu_cap)
   34.33          *(q-1)=0;
   34.34  
   34.35 -    return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i,s:s}",
   34.36 +    return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
   34.37                           "threads_per_core", info.threads_per_core,
   34.38                           "cores_per_socket", info.cores_per_socket,
   34.39                           "sockets_per_node", info.sockets_per_node,
   34.40                           "nr_nodes",         info.nr_nodes,
   34.41 -                         "total_memory",     pages_to_mb(info.total_pages),
   34.42 -                         "free_memory",      pages_to_mb(info.free_pages),
   34.43 +                         "total_memory",     pages_to_kib(info.total_pages),
   34.44 +                         "free_memory",      pages_to_kib(info.free_pages),
   34.45 +                         "scrub_memory",     pages_to_kib(info.scrub_pages),
   34.46                           "cpu_khz",          info.cpu_khz,
   34.47                           "hw_caps",          cpu_cap);
   34.48  }
   34.49 @@ -637,6 +638,7 @@ static PyObject *pyxc_xeninfo(XcObject *
   34.50      xen_capabilities_info_t xen_caps;
   34.51      xen_platform_parameters_t p_parms;
   34.52      long xen_version;
   34.53 +    long xen_pagesize;
   34.54      char str[128];
   34.55  
   34.56      xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
   34.57 @@ -658,11 +660,16 @@ static PyObject *pyxc_xeninfo(XcObject *
   34.58  
   34.59      sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
   34.60  
   34.61 -    return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}",
   34.62 +    xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
   34.63 +    if (xen_pagesize < 0 )
   34.64 +        return PyErr_SetFromErrno(xc_error);
   34.65 +
   34.66 +    return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
   34.67                           "xen_major", xen_version >> 16,
   34.68                           "xen_minor", (xen_version & 0xffff),
   34.69                           "xen_extra", xen_extra,
   34.70                           "xen_caps",  xen_caps,
   34.71 +                         "xen_pagesize", xen_pagesize,
   34.72                           "platform_params", str,
   34.73                           "xen_changeset", xen_chgset,
   34.74                           "cc_compiler", xen_cc.compiler,
    35.1 --- a/tools/python/xen/xend/XendNode.py	Wed Jun 28 07:51:52 2006 -0600
    35.2 +++ b/tools/python/xen/xend/XendNode.py	Wed Jun 28 07:52:21 2006 -0600
    35.3 @@ -64,6 +64,9 @@ class XendNode:
    35.4                             info['cores_per_socket'] *
    35.5                             info['threads_per_core'])
    35.6          info['cpu_mhz'] = info['cpu_khz'] / 1000
    35.7 +        # physinfo is in KiB
    35.8 +        info['total_memory'] = info['total_memory'] / 1024
    35.9 +        info['free_memory']  = info['free_memory'] / 1024
   35.10  
   35.11          ITEM_ORDER = ['nr_cpus',
   35.12                        'nr_nodes',
   35.13 @@ -86,6 +89,7 @@ class XendNode:
   35.14                        'xen_minor',
   35.15                        'xen_extra',
   35.16                        'xen_caps',
   35.17 +                      'xen_pagesize',
   35.18                        'platform_params',
   35.19                        'xen_changeset',
   35.20                        'cc_compiler',
    36.1 --- a/tools/python/xen/xend/balloon.py	Wed Jun 28 07:51:52 2006 -0600
    36.2 +++ b/tools/python/xen/xend/balloon.py	Wed Jun 28 07:52:21 2006 -0600
    36.3 @@ -29,9 +29,7 @@ from XendError import VmError
    36.4  
    36.5  PROC_XEN_BALLOON = '/proc/xen/balloon'
    36.6  
    36.7 -BALLOON_OUT_SLACK = 1 # MiB.  We need this because the physinfo details are
    36.8 -                      # rounded.
    36.9 -RETRY_LIMIT = 10
   36.10 +RETRY_LIMIT = 20
   36.11  RETRY_LIMIT_INCR = 5
   36.12  ##
   36.13  # The time to sleep between retries grows linearly, using this value (in
   36.14 @@ -68,22 +66,22 @@ def _get_proc_balloon(label):
   36.15          f.close()
   36.16  
   36.17  def get_dom0_current_alloc():
   36.18 -    """Returns the current memory allocation (in MiB) of dom0."""
   36.19 +    """Returns the current memory allocation (in KiB) of dom0."""
   36.20  
   36.21      kb = _get_proc_balloon(labels['current'])
   36.22      if kb == None:
   36.23          raise VmError('Failed to query current memory allocation of dom0.')
   36.24 -    return kb / 1024
   36.25 +    return kb
   36.26  
   36.27  def get_dom0_target_alloc():
   36.28 -    """Returns the target memory allocation (in MiB) of dom0."""
   36.29 +    """Returns the target memory allocation (in KiB) of dom0."""
   36.30  
   36.31      kb = _get_proc_balloon(labels['target'])
   36.32      if kb == None:
   36.33          raise VmError('Failed to query target memory allocation of dom0.')
   36.34 -    return kb / 1024
   36.35 +    return kb
   36.36  
   36.37 -def free(required):
   36.38 +def free(need_mem):
   36.39      """Balloon out memory from the privileged domain so that there is the
   36.40      specified required amount (in KiB) free.
   36.41      """
   36.42 @@ -92,9 +90,10 @@ def free(required):
   36.43      # to balloon out to free some up.  Memory freed by a destroyed domain may
   36.44      # not appear in the free_memory field immediately, because it needs to be
   36.45      # scrubbed before it can be released to the free list, which is done
   36.46 -    # asynchronously by Xen; ballooning is asynchronous also.  No matter where
   36.47 -    # we expect the free memory to come from, therefore, we need to wait for
   36.48 -    # it to become available.
   36.49 +    # asynchronously by Xen; ballooning is asynchronous also.  Such memory
   36.50 +    # does, however, need to be accounted for when calculating how much dom0
   36.51 +    # needs to balloon.  No matter where we expect the free memory to come
   36.52 +    # from, we need to wait for it to become available.
   36.53      #
   36.54      # We are not allowed to balloon below dom0_min_mem, or if dom0_min_mem
   36.55      # is 0, we cannot balloon at all.  Memory can still become available
   36.56 @@ -108,43 +107,49 @@ def free(required):
   36.57      # usage, so we recheck the required alloc each time around the loop, but
   36.58      # track the last used value so that we don't trigger too many watches.
   36.59  
   36.60 -    need_mem = (required + 1023) / 1024 + BALLOON_OUT_SLACK
   36.61 -
   36.62      xroot = XendRoot.instance()
   36.63      xc = xen.lowlevel.xc.xc()
   36.64  
   36.65      try:
   36.66 -        dom0_min_mem = xroot.get_dom0_min_mem()
   36.67 +        dom0_min_mem = xroot.get_dom0_min_mem() * 1024
   36.68  
   36.69          retries = 0
   36.70          sleep_time = SLEEP_TIME_GROWTH
   36.71          last_new_alloc = None
   36.72          rlimit = RETRY_LIMIT
   36.73          while retries < rlimit:
   36.74 -            free_mem = xc.physinfo()['free_memory']
   36.75 +            physinfo = xc.physinfo()
   36.76 +            free_mem = physinfo['free_memory']
   36.77 +            scrub_mem = physinfo['scrub_memory']
   36.78  
   36.79              if free_mem >= need_mem:
   36.80 -                log.debug("Balloon: free %d; need %d; done.", free_mem,
   36.81 -                          need_mem)
   36.82 +                log.debug("Balloon: %d KiB free; need %d; done.",
   36.83 +                          free_mem, need_mem)
   36.84                  return
   36.85  
   36.86              if retries == 0:
   36.87 -                rlimit += ((need_mem - free_mem)/1024) * RETRY_LIMIT_INCR
   36.88 -                log.debug("Balloon: free %d; need %d; retries: %d.", 
   36.89 -                          free_mem, need_mem, rlimit)
   36.90 +                rlimit += ((need_mem - free_mem)/1024/1024) * RETRY_LIMIT_INCR
   36.91 +                log.debug("Balloon: %d KiB free; %d to scrub; need %d; retries: %d.",
   36.92 +                          free_mem, scrub_mem, need_mem, rlimit)
   36.93  
   36.94              if dom0_min_mem > 0:
   36.95                  dom0_alloc = get_dom0_current_alloc()
   36.96 -                new_alloc = dom0_alloc - (need_mem - free_mem)
   36.97 +                new_alloc = dom0_alloc - (need_mem - free_mem - scrub_mem)
   36.98  
   36.99 -                if (new_alloc >= dom0_min_mem and
  36.100 -                    new_alloc != last_new_alloc):
  36.101 -                    log.debug("Balloon: setting dom0 target to %d.",
  36.102 -                              new_alloc)
  36.103 -                    dom0 = XendDomain.instance().privilegedDomain()
  36.104 -                    dom0.setMemoryTarget(new_alloc)
  36.105 -                    last_new_alloc = new_alloc
  36.106 -                    # Continue to retry, waiting for ballooning.
  36.107 +                if free_mem + scrub_mem >= need_mem:
  36.108 +                    if last_new_alloc == None:
  36.109 +                        log.debug("Balloon: waiting on scrubbing")
  36.110 +                        last_new_alloc = dom0_alloc
  36.111 +                else:
  36.112 +                    if (new_alloc >= dom0_min_mem and
  36.113 +                        new_alloc != last_new_alloc):
  36.114 +                        new_alloc_mb = new_alloc / 1024  # Round down
  36.115 +                        log.debug("Balloon: setting dom0 target to %d MiB.",
  36.116 +                                  new_alloc_mb)
  36.117 +                        dom0 = XendDomain.instance().privilegedDomain()
  36.118 +                        dom0.setMemoryTarget(new_alloc_mb)
  36.119 +                        last_new_alloc = new_alloc
  36.120 +                # Continue to retry, waiting for ballooning or scrubbing.
  36.121  
  36.122              time.sleep(sleep_time)
  36.123              if retries < 2 * RETRY_LIMIT:
  36.124 @@ -154,15 +159,15 @@ def free(required):
  36.125          # Not enough memory; diagnose the problem.
  36.126          if dom0_min_mem == 0:
  36.127              raise VmError(('Not enough free memory and dom0_min_mem is 0, so '
  36.128 -                           'I cannot release any more.  I need %d MiB but '
  36.129 +                           'I cannot release any more.  I need %d KiB but '
  36.130                             'only have %d.') %
  36.131                            (need_mem, free_mem))
  36.132          elif new_alloc < dom0_min_mem:
  36.133              raise VmError(
  36.134 -                ('I need %d MiB, but dom0_min_mem is %d and shrinking to '
  36.135 -                 '%d MiB would leave only %d MiB free.') %
  36.136 +                ('I need %d KiB, but dom0_min_mem is %d and shrinking to '
  36.137 +                 '%d KiB would leave only %d KiB free.') %
  36.138                  (need_mem, dom0_min_mem, dom0_min_mem,
  36.139 -                 free_mem + dom0_alloc - dom0_min_mem))
  36.140 +                 free_mem + scrub_mem + dom0_alloc - dom0_min_mem))
  36.141          else:
  36.142              raise VmError('The privileged domain did not balloon!')
  36.143  
    37.1 --- a/tools/python/xen/xm/main.py	Wed Jun 28 07:51:52 2006 -0600
    37.2 +++ b/tools/python/xen/xm/main.py	Wed Jun 28 07:52:21 2006 -0600
    37.3 @@ -887,7 +887,7 @@ def parse_dev_info(info):
    37.4          'ring-ref'   : get_info('ring-ref',     int,   -1),
    37.5          }
    37.6  
    37.7 -def has_long_option(args):
    37.8 +def arg_check_for_resource_list(args, name):
    37.9      use_long = 0
   37.10      try:
   37.11          (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
   37.12 @@ -898,16 +898,19 @@ def has_long_option(args):
   37.13      for (k, v) in options:
   37.14          if k in ['-l', '--long']:
   37.15              use_long = 1
   37.16 +
   37.17 +    if len(params) == 0:
   37.18 +        print 'No domain parameter given'
   37.19 +        usage(name)
   37.20 +    if len(params) > 1:
   37.21 +        print 'No multiple domain parameters allowed'
   37.22 +        usage(name)
   37.23 +    
   37.24      return (use_long, params)
   37.25  
   37.26  def xm_network_list(args):
   37.27 -    arg_check(args, "network-list", 1, 2)
   37.28 -
   37.29 -    (use_long, params) = has_long_option(args)
   37.30 +    (use_long, params) = arg_check_for_resource_list(args, "network-list")
   37.31  
   37.32 -    if len(params) == 0:
   37.33 -        print 'No domain parameter given'
   37.34 -        sys.exit(1)
   37.35      dom = params[0]
   37.36      if use_long:
   37.37          devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
   37.38 @@ -931,13 +934,8 @@ def xm_network_list(args):
   37.39                     % ni)
   37.40  
   37.41  def xm_block_list(args):
   37.42 -    arg_check(args, "block-list", 1, 2)
   37.43 -
   37.44 -    (use_long, params) = has_long_option(args)
   37.45 +    (use_long, params) = arg_check_for_resource_list(args, "block-list")
   37.46  
   37.47 -    if len(params) == 0:
   37.48 -        print 'No domain parameter given'
   37.49 -        sys.exit(1)
   37.50      dom = params[0]
   37.51      if use_long:
   37.52          devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
   37.53 @@ -960,13 +958,8 @@ def xm_block_list(args):
   37.54                     % ni)
   37.55  
   37.56  def xm_vtpm_list(args):
   37.57 -    arg_check(args, "vtpm-list", 1, 2)
   37.58 -
   37.59 -    (use_long, params) = has_long_option(args)
   37.60 +    (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
   37.61  
   37.62 -    if len(params) == 0:
   37.63 -        print 'No domain parameter given'
   37.64 -        sys.exit(1)
   37.65      dom = params[0]
   37.66      if use_long:
   37.67          devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
    38.1 --- a/tools/vtpm/Rules.mk	Wed Jun 28 07:51:52 2006 -0600
    38.2 +++ b/tools/vtpm/Rules.mk	Wed Jun 28 07:52:21 2006 -0600
    38.3 @@ -33,8 +33,7 @@ OBJS	= $(patsubst %.c,%.o,$(SRCS))
    38.4  
    38.5  -include $(DEP_FILES)
    38.6  
    38.7 -# Emulator does not work on 64-bit systems, and may be broken on 32 right now
    38.8 -BUILD_EMULATOR = n
    38.9 +BUILD_EMULATOR = y
   38.10  
   38.11  # Make sure these are just rules
   38.12  .PHONY : all build install clean
    39.1 --- a/tools/vtpm/tpm_emulator-0.3-x86_64.patch	Wed Jun 28 07:51:52 2006 -0600
    39.2 +++ b/tools/vtpm/tpm_emulator-0.3-x86_64.patch	Wed Jun 28 07:52:21 2006 -0600
    39.3 @@ -1,62 +1,6 @@
    39.4 -diff -uprN tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
    39.5 ---- tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c	2006-01-10 04:21:45.000000000 -0800
    39.6 -+++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c	2006-05-26 11:26:02.000000000 -0700
    39.7 -@@ -79,7 +79,7 @@ void __attribute__ ((regparm(0))) *kerne
    39.8 - {
    39.9 -   void *ret  = (void*)kmalloc(size, GFP_KERNEL);
   39.10 -   if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 
   39.11 --    "GMP: cannot allocate memory (size=%u)\n", size);
   39.12 -+    "GMP: cannot allocate memory (size=%Zu)\n", size);
   39.13 -   return ret;
   39.14 - }
   39.15 - 
   39.16 -@@ -88,7 +88,7 @@ void __attribute__ ((regparm(0))) *kerne
   39.17 - {
   39.18 -   void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
   39.19 -   if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
   39.20 --    "(old_size=%u new_size=%u)\n", old_size, new_size);
   39.21 -+    "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
   39.22 -   memcpy(ret, oldptr, old_size);
   39.23 -   kfree(oldptr);
   39.24 -   return ret;
   39.25 -diff -uprN tpm_emulator-0.3/linux_module.c tpm_emulator-0.3-x86_64/linux_module.c
   39.26 ---- tpm_emulator-0.3/linux_module.c	2006-01-10 04:21:45.000000000 -0800
   39.27 -+++ tpm_emulator-0.3-x86_64/linux_module.c	2006-05-26 11:26:02.000000000 -0700
   39.28 -@@ -72,7 +72,7 @@ static int tpm_release(struct inode *ino
   39.29 - 
   39.30 - static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos)
   39.31 - {
   39.32 --  debug("%s(%d)", __FUNCTION__, count);
   39.33 -+  debug("%s(%Zu)", __FUNCTION__, count);
   39.34 -   down(&tpm_mutex);
   39.35 -   if (tpm_response.data != NULL) {
   39.36 -     count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
   39.37 -@@ -91,7 +91,7 @@ static ssize_t tpm_read(struct file *fil
   39.38 - 
   39.39 - static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
   39.40 - {
   39.41 --  debug("%s(%d)", __FUNCTION__, count);
   39.42 -+  debug("%s(%Zu)", __FUNCTION__, count);
   39.43 -   down(&tpm_mutex);
   39.44 -   *ppos = 0;
   39.45 -   if (tpm_response.data != NULL) kfree(tpm_response.data);
   39.46 -diff -uprN tpm_emulator-0.3/linux_module.h tpm_emulator-0.3-x86_64/linux_module.h
   39.47 ---- tpm_emulator-0.3/linux_module.h	2006-01-10 04:21:45.000000000 -0800
   39.48 -+++ tpm_emulator-0.3-x86_64/linux_module.h	2006-05-26 11:26:02.000000000 -0700
   39.49 -@@ -28,8 +28,10 @@
   39.50 - 
   39.51 - /* module settings */
   39.52 - 
   39.53 -+#ifndef STR
   39.54 - #define STR(s) __STR__(s)
   39.55 - #define __STR__(s) #s
   39.56 -+#endif
   39.57 - #include "tpm_version.h"
   39.58 - 
   39.59 - #define TPM_DEVICE_MINOR	224
   39.60 -diff -uprN tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile
   39.61 ---- tpm_emulator-0.3/Makefile	2006-01-10 04:21:45.000000000 -0800
   39.62 -+++ tpm_emulator-0.3-x86_64/Makefile	2006-05-26 11:26:02.000000000 -0700
   39.63 +diff -uprN orig/tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile
   39.64 +--- orig/tpm_emulator-0.3/Makefile	2006-01-10 04:21:45.000000000 -0800
   39.65 ++++ tpm_emulator-0.3-x86_64/Makefile	2006-08-29 15:08:20.532342768 -0700
   39.66  @@ -7,6 +7,7 @@
   39.67   KERNEL_RELEASE := $(shell uname -r)
   39.68   KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
   39.69 @@ -81,9 +25,9 @@ diff -uprN tpm_emulator-0.3/Makefile tpm
   39.70   GMP_HEADER     := /usr/include/gmp.h
   39.71   
   39.72   # sources and objects
   39.73 -diff -uprN tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README
   39.74 ---- tpm_emulator-0.3/README	2006-01-10 04:21:45.000000000 -0800
   39.75 -+++ tpm_emulator-0.3-x86_64/README	2006-05-26 11:26:02.000000000 -0700
   39.76 +diff -uprN orig/tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README
   39.77 +--- orig/tpm_emulator-0.3/README	2006-01-10 04:21:45.000000000 -0800
   39.78 ++++ tpm_emulator-0.3-x86_64/README	2006-08-29 15:07:43.530967832 -0700
   39.79  @@ -43,6 +43,12 @@ Example:
   39.80   GMP_LIB        := /usr/lib/libgmp.a
   39.81   GMP_HEADER     := /usr/include/gmp.h
   39.82 @@ -97,9 +41,65 @@ diff -uprN tpm_emulator-0.3/README tpm_e
   39.83   Installation
   39.84   --------------------------------------------------------------------------
   39.85   The compilation and installation process uses the build environment for 
   39.86 -diff -uprN tpm_emulator-0.3/tpm/tpm_credentials.c tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c
   39.87 ---- tpm_emulator-0.3/tpm/tpm_credentials.c	2006-01-10 04:21:45.000000000 -0800
   39.88 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c	2006-05-26 11:26:02.000000000 -0700
   39.89 +diff -uprN orig/tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
   39.90 +--- orig/tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c	2006-01-10 04:21:45.000000000 -0800
   39.91 ++++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c	2006-08-29 15:07:43.525968592 -0700
   39.92 +@@ -79,7 +79,7 @@ void __attribute__ ((regparm(0))) *kerne
   39.93 + {
   39.94 +   void *ret  = (void*)kmalloc(size, GFP_KERNEL);
   39.95 +   if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 
   39.96 +-    "GMP: cannot allocate memory (size=%u)\n", size);
   39.97 ++    "GMP: cannot allocate memory (size=%Zu)\n", size);
   39.98 +   return ret;
   39.99 + }
  39.100 + 
  39.101 +@@ -88,7 +88,7 @@ void __attribute__ ((regparm(0))) *kerne
  39.102 + {
  39.103 +   void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
  39.104 +   if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
  39.105 +-    "(old_size=%u new_size=%u)\n", old_size, new_size);
  39.106 ++    "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
  39.107 +   memcpy(ret, oldptr, old_size);
  39.108 +   kfree(oldptr);
  39.109 +   return ret;
  39.110 +diff -uprN orig/tpm_emulator-0.3/linux_module.c tpm_emulator-0.3-x86_64/linux_module.c
  39.111 +--- orig/tpm_emulator-0.3/linux_module.c	2006-01-10 04:21:45.000000000 -0800
  39.112 ++++ tpm_emulator-0.3-x86_64/linux_module.c	2006-08-29 15:07:43.526968440 -0700
  39.113 +@@ -72,7 +72,7 @@ static int tpm_release(struct inode *ino
  39.114 + 
  39.115 + static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos)
  39.116 + {
  39.117 +-  debug("%s(%d)", __FUNCTION__, count);
  39.118 ++  debug("%s(%Zu)", __FUNCTION__, count);
  39.119 +   down(&tpm_mutex);
  39.120 +   if (tpm_response.data != NULL) {
  39.121 +     count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
  39.122 +@@ -91,7 +91,7 @@ static ssize_t tpm_read(struct file *fil
  39.123 + 
  39.124 + static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
  39.125 + {
  39.126 +-  debug("%s(%d)", __FUNCTION__, count);
  39.127 ++  debug("%s(%Zu)", __FUNCTION__, count);
  39.128 +   down(&tpm_mutex);
  39.129 +   *ppos = 0;
  39.130 +   if (tpm_response.data != NULL) kfree(tpm_response.data);
  39.131 +diff -uprN orig/tpm_emulator-0.3/linux_module.h tpm_emulator-0.3-x86_64/linux_module.h
  39.132 +--- orig/tpm_emulator-0.3/linux_module.h	2006-01-10 04:21:45.000000000 -0800
  39.133 ++++ tpm_emulator-0.3-x86_64/linux_module.h	2006-08-29 15:07:43.527968288 -0700
  39.134 +@@ -28,8 +28,10 @@
  39.135 + 
  39.136 + /* module settings */
  39.137 + 
  39.138 ++#ifndef STR
  39.139 + #define STR(s) __STR__(s)
  39.140 + #define __STR__(s) #s
  39.141 ++#endif
  39.142 + #include "tpm_version.h"
  39.143 + 
  39.144 + #define TPM_DEVICE_MINOR	224
  39.145 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_credentials.c tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c
  39.146 +--- orig/tpm_emulator-0.3/tpm/tpm_credentials.c	2006-01-10 04:21:45.000000000 -0800
  39.147 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c	2006-08-29 15:07:43.530967832 -0700
  39.148  @@ -47,16 +47,16 @@ int tpm_compute_pubkey_checksum(TPM_NONC
  39.149   
  39.150   TPM_RESULT tpm_get_pubek(TPM_PUBKEY *pubEndorsementKey)
  39.151 @@ -140,9 +140,9 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_cred
  39.152       publicPortion->algorithmParms.algorithmID = TPM_ALG_RSA;
  39.153       publicPortion->algorithmParms.encScheme = srk->encScheme;
  39.154       publicPortion->algorithmParms.sigScheme = srk->sigScheme;
  39.155 -diff -uprN tpm_emulator-0.3/tpm/tpm_crypto.c tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c
  39.156 ---- tpm_emulator-0.3/tpm/tpm_crypto.c	2006-01-10 04:21:45.000000000 -0800
  39.157 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c	2006-05-26 11:26:02.000000000 -0700
  39.158 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_crypto.c tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c
  39.159 +--- orig/tpm_emulator-0.3/tpm/tpm_crypto.c	2006-01-10 04:21:45.000000000 -0800
  39.160 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c	2006-08-29 15:07:43.531967680 -0700
  39.161  @@ -182,7 +182,8 @@ TPM_RESULT TPM_CertifyKey(TPM_KEY_HANDLE
  39.162     TPM_KEY_DATA *cert, *key;
  39.163     sha1_ctx_t sha1_ctx;
  39.164 @@ -192,10 +192,10 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_cryp
  39.165       free_TPM_KEY_PARMS(certifyInfo->algorithmParms);
  39.166       return TPM_FAIL;
  39.167     }
  39.168 -diff -uprN tpm_emulator-0.3/tpm/tpm_data.c tpm_emulator-0.3-x86_64/tpm/tpm_data.c
  39.169 ---- tpm_emulator-0.3/tpm/tpm_data.c	2006-01-10 04:21:45.000000000 -0800
  39.170 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c	2006-05-26 11:26:02.000000000 -0700
  39.171 -@@ -214,7 +214,7 @@ static int read_from_file(uint8_t **data
  39.172 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_data.c tpm_emulator-0.3-x86_64/tpm/tpm_data.c
  39.173 +--- orig/tpm_emulator-0.3/tpm/tpm_data.c	2006-01-10 04:21:45.000000000 -0800
  39.174 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c	2006-08-29 15:08:20.535342312 -0700
  39.175 +@@ -214,23 +214,30 @@ static int read_from_file(uint8_t **data
  39.176   int tpm_store_permanent_data(void)
  39.177   {
  39.178     uint8_t *buf, *ptr;
  39.179 @@ -203,8 +203,35 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_data
  39.180  +  UINT32 buf_length, len;
  39.181   
  39.182     /* marshal data */
  39.183 -   buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
  39.184 -@@ -242,13 +242,14 @@ int tpm_store_permanent_data(void)
  39.185 +-  buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
  39.186 +-    + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) + 2
  39.187 +-    + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data);
  39.188 ++  buf_length = len = 4 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
  39.189 ++    + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) 
  39.190 ++    + sizeof_TPM_STANY_FLAGS(tpmData.stany.flags) + 2
  39.191 ++    + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data) 
  39.192 ++    + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data)
  39.193 ++    + sizeof_TPM_STANY_DATA(tpmData.stany.data);
  39.194 +   buf = ptr = tpm_malloc(buf_length);
  39.195 +   if (buf == NULL
  39.196 +       || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version)
  39.197 +       || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
  39.198 +       || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)
  39.199 ++      || tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
  39.200 +       || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.selfTestSucceeded)
  39.201 +       || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned)
  39.202 +-      || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)) {
  39.203 ++      || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
  39.204 ++      || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
  39.205 ++      || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
  39.206 +     tpm_free(buf);
  39.207 +     return -1;
  39.208 +   }
  39.209 ++
  39.210 +   if (write_to_file(buf, buf_length - len)) {
  39.211 +     tpm_free(buf);
  39.212 +     return -1; 
  39.213 +@@ -242,24 +249,29 @@ int tpm_store_permanent_data(void)
  39.214   int tpm_restore_permanent_data(void)
  39.215   {
  39.216     uint8_t *buf, *ptr;
  39.217 @@ -221,9 +248,25 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_data
  39.218     /* unmarshal data */
  39.219     if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
  39.220         || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION))
  39.221 -diff -uprN tpm_emulator-0.3/tpm/tpm_marshalling.c tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c
  39.222 ---- tpm_emulator-0.3/tpm/tpm_marshalling.c	2006-01-10 04:21:45.000000000 -0800
  39.223 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c	2006-05-26 11:26:02.000000000 -0700
  39.224 +       || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
  39.225 +       || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)
  39.226 ++      || tpm_unmarshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
  39.227 +       || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.selfTestSucceeded)
  39.228 +       || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned)
  39.229 +-      || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)) {
  39.230 ++      || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
  39.231 ++      || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
  39.232 ++      || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
  39.233 +     tpm_free(buf);
  39.234 +     return -1;
  39.235 +   }
  39.236 ++
  39.237 +   tpm_free(buf);
  39.238 +   return 0;
  39.239 + }
  39.240 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_marshalling.c tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c
  39.241 +--- orig/tpm_emulator-0.3/tpm/tpm_marshalling.c	2006-01-10 04:21:45.000000000 -0800
  39.242 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c	2006-08-29 15:08:20.537342008 -0700
  39.243  @@ -1212,7 +1212,7 @@ int tpm_unmarshal_TPM_STANY_FLAGS(BYTE *
  39.244   
  39.245   int tpm_marshal_RSA(BYTE **ptr, UINT32 *length, rsa_private_key_t *v)
  39.246 @@ -233,9 +276,92 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_mars
  39.247     if (*length < sizeof_RSA((*v))) return -1;
  39.248     if (v->size > 0) {
  39.249       rsa_export_modulus(v, &(*ptr)[6], &m_len);
  39.250 -diff -uprN tpm_emulator-0.3/tpm/tpm_owner.c tpm_emulator-0.3-x86_64/tpm/tpm_owner.c
  39.251 ---- tpm_emulator-0.3/tpm/tpm_owner.c	2006-01-10 04:21:45.000000000 -0800
  39.252 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c	2006-05-26 11:26:02.000000000 -0700
  39.253 +@@ -1356,6 +1356,66 @@ int tpm_unmarshal_TPM_PERMANENT_DATA(BYT
  39.254 +   return 0;
  39.255 + }
  39.256 + 
  39.257 ++int tpm_marshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA *v)
  39.258 ++{
  39.259 ++  if (tpm_marshal_TPM_STRUCTURE_TAG(ptr, length, v->tag)
  39.260 ++    || tpm_marshal_TPM_NONCE(ptr, length, &v->contextNonceKey)
  39.261 ++    || tpm_marshal_TPM_COUNT_ID(ptr, length, v->countID) ) return -1;
  39.262 ++
  39.263 ++  return 0;
  39.264 ++}
  39.265 ++
  39.266 ++int tpm_unmarshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA *v)
  39.267 ++{
  39.268 ++  if (tpm_unmarshal_TPM_STRUCTURE_TAG(ptr, length, &v->tag)
  39.269 ++    || tpm_unmarshal_TPM_NONCE(ptr, length, &v->contextNonceKey)
  39.270 ++    || tpm_unmarshal_TPM_COUNT_ID(ptr, length, &v->countID) ) return -1;
  39.271 ++
  39.272 ++  return 0;
  39.273 ++}
  39.274 ++
  39.275 ++int tpm_marshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v)
  39.276 ++{
  39.277 ++  UINT32 i;
  39.278 ++  if (tpm_marshal_TPM_STRUCTURE_TAG(ptr, length, v->tag)
  39.279 ++    || tpm_marshal_TPM_NONCE(ptr, length, &v->contextNonceSession)
  39.280 ++    || tpm_marshal_TPM_DIGEST(ptr, length, &v->auditDigest)
  39.281 ++    || tpm_marshal_BOOL(ptr, length, v->auditSession)
  39.282 ++    || tpm_marshal_TPM_CURRENT_TICKS(ptr, length, &v->currentTicks)
  39.283 ++    || tpm_marshal_UINT32(ptr, length, v->contextCount)
  39.284 ++    || tpm_marshal_UINT32_ARRAY(ptr, length, v->contextList, TPM_MAX_SESSION_LIST)) return -1;
  39.285 ++  for (i = 0; i < TPM_MAX_SESSIONS; i++) {
  39.286 ++    if (tpm_marshal_TPM_SESSION_DATA(ptr, length, &v->sessions[i])) return -1;
  39.287 ++  }
  39.288 ++  for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) {
  39.289 ++    if (tpm_marshal_TPM_DAA_SESSION_DATA(ptr, length, &v->sessionsDAA[i])) return -1;
  39.290 ++  }
  39.291 ++  if (tpm_marshal_TPM_TRANSHANDLE(ptr, length, v->transExclusive)) return -1;
  39.292 ++
  39.293 ++  return 0;
  39.294 ++}
  39.295 ++
  39.296 ++int tpm_unmarshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v)
  39.297 ++{
  39.298 ++  UINT32 i;
  39.299 ++  if (tpm_unmarshal_TPM_STRUCTURE_TAG(ptr, length, &v->tag)
  39.300 ++    || tpm_unmarshal_TPM_NONCE(ptr, length, &v->contextNonceSession)
  39.301 ++    || tpm_unmarshal_TPM_DIGEST(ptr, length, &v->auditDigest)
  39.302 ++    || tpm_unmarshal_BOOL(ptr, length, &v->auditSession)
  39.303 ++    || tpm_unmarshal_TPM_CURRENT_TICKS(ptr, length, &v->currentTicks)
  39.304 ++    || tpm_unmarshal_UINT32(ptr, length, &v->contextCount)
  39.305 ++    || tpm_unmarshal_UINT32_ARRAY(ptr, length, v->contextList, TPM_MAX_SESSION_LIST)) return -1;
  39.306 ++  for (i = 0; i < TPM_MAX_SESSIONS; i++) {
  39.307 ++    if (tpm_unmarshal_TPM_SESSION_DATA(ptr, length, &v->sessions[i])) return -1;
  39.308 ++  }
  39.309 ++  for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) {
  39.310 ++    if (tpm_unmarshal_TPM_DAA_SESSION_DATA(ptr, length, &v->sessionsDAA[i])) return -1;
  39.311 ++  }
  39.312 ++  if (tpm_unmarshal_TPM_TRANSHANDLE(ptr, length, &v->transExclusive)) return -1;
  39.313 ++
  39.314 ++  return 0;
  39.315 ++}
  39.316 ++
  39.317 + int tpm_marshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA *v)
  39.318 + {
  39.319 +   if (tpm_marshal_BYTE(ptr, length, v->type)
  39.320 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_marshalling.h tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.h
  39.321 +--- orig/tpm_emulator-0.3/tpm/tpm_marshalling.h	2006-01-10 04:21:45.000000000 -0800
  39.322 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.h	2006-08-29 15:08:20.538341856 -0700
  39.323 +@@ -420,6 +420,12 @@ int tpm_unmarshal_TPM_KEY_DATA(BYTE **pt
  39.324 + int tpm_marshal_TPM_PERMANENT_DATA(BYTE **ptr, UINT32 *length, TPM_PERMANENT_DATA *);
  39.325 + int tpm_unmarshal_TPM_PERMANENT_DATA(BYTE **ptr, UINT32 *length, TPM_PERMANENT_DATA *);
  39.326 + 
  39.327 ++int tpm_marshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA *v);
  39.328 ++int tpm_unmarshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA *v);
  39.329 ++
  39.330 ++int tpm_marshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v);
  39.331 ++int tpm_unmarshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v);
  39.332 ++
  39.333 + int tpm_marshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA *v);
  39.334 + int tpm_unmarshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA *v);
  39.335 + 
  39.336 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_owner.c tpm_emulator-0.3-x86_64/tpm/tpm_owner.c
  39.337 +--- orig/tpm_emulator-0.3/tpm/tpm_owner.c	2006-01-10 04:21:45.000000000 -0800
  39.338 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c	2006-08-29 15:07:43.535967072 -0700
  39.339  @@ -108,7 +108,7 @@ TPM_RESULT TPM_TakeOwnership(TPM_PROTOCO
  39.340     TPM_RESULT res;
  39.341     rsa_private_key_t *ek = &tpmData.permanent.data.endorsementKey;
  39.342 @@ -255,9 +381,63 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_owne
  39.343     /* setup tpmProof and set state to owned */
  39.344     tpm_get_random_bytes(tpmData.permanent.data.tpmProof.nonce, 
  39.345       sizeof(tpmData.permanent.data.tpmProof.nonce));
  39.346 -diff -uprN tpm_emulator-0.3/tpm/tpm_storage.c tpm_emulator-0.3-x86_64/tpm/tpm_storage.c
  39.347 ---- tpm_emulator-0.3/tpm/tpm_storage.c	2006-01-10 04:21:45.000000000 -0800
  39.348 -+++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c	2006-05-26 14:33:18.000000000 -0700
  39.349 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_startup.c tpm_emulator-0.3-x86_64/tpm/tpm_startup.c
  39.350 +--- orig/tpm_emulator-0.3/tpm/tpm_startup.c	2006-01-10 04:21:45.000000000 -0800
  39.351 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_startup.c	2006-08-29 15:08:20.538341856 -0700
  39.352 +@@ -41,24 +41,29 @@ void TPM_Init(TPM_STARTUP_TYPE startupTy
  39.353 + TPM_RESULT TPM_Startup(TPM_STARTUP_TYPE startupType)
  39.354 + {
  39.355 +   int i;
  39.356 ++  int restore_fail;
  39.357 +   info("TPM_Startup(%d)", startupType);
  39.358 +   if (tpmData.stany.flags.postInitialise == FALSE) return TPM_INVALID_POSTINIT;
  39.359 +-  /* reset STANY_FLAGS */
  39.360 +-  SET_TO_ZERO(&tpmData.stany.flags);
  39.361 +-  tpmData.stany.flags.tag = TPM_TAG_STANY_FLAGS;
  39.362 +-  /* reset STANY_DATA (invalidates ALL sessions) */
  39.363 +-  SET_TO_ZERO(&tpmData.stany.data);
  39.364 +-  tpmData.stany.data.tag = TPM_TAG_STANY_DATA;
  39.365 +-  /* init session-context nonce */
  39.366 +-  SET_TO_RAND(&tpmData.stany.data.contextNonceSession);
  39.367 ++
  39.368 ++  /* try and restore state to get EK, SRK, etc */
  39.369 ++  restore_fail = tpm_restore_permanent_data();
  39.370 ++
  39.371 +   /* set data and flags according to the given startup type */
  39.372 +   if (startupType == TPM_ST_CLEAR) {
  39.373 ++    /* reset STANY_FLAGS */
  39.374 ++    SET_TO_ZERO(&tpmData.stany.flags);
  39.375 ++    tpmData.stany.flags.tag = TPM_TAG_STANY_FLAGS;
  39.376 ++    /* reset STANY_DATA (invalidates ALL sessions) */
  39.377 ++    SET_TO_ZERO(&tpmData.stany.data);
  39.378 ++    tpmData.stany.data.tag = TPM_TAG_STANY_DATA;
  39.379 ++    /* init session-context nonce */
  39.380 ++    SET_TO_RAND(&tpmData.stany.data.contextNonceSession);
  39.381 +     /* reset PCR values */
  39.382 +     for (i = 0; i < TPM_NUM_PCR; i++) {
  39.383 +-      if (tpmData.permanent.data.pcrAttrib[i].pcrReset)
  39.384 +-        SET_TO_ZERO(tpmData.permanent.data.pcrValue[i].digest);
  39.385 ++      if (!tpmData.permanent.data.pcrAttrib[i].pcrReset)
  39.386 ++        SET_TO_ZERO(&tpmData.permanent.data.pcrValue[i].digest);
  39.387 +       else
  39.388 +-        SET_TO_0xFF(tpmData.permanent.data.pcrValue[i].digest);
  39.389 ++        SET_TO_0xFF(&tpmData.permanent.data.pcrValue[i].digest);
  39.390 +     }
  39.391 +     /* reset STCLEAR_FLAGS */
  39.392 +     SET_TO_ZERO(&tpmData.stclear.flags);
  39.393 +@@ -77,7 +82,8 @@ TPM_RESULT TPM_Startup(TPM_STARTUP_TYPE 
  39.394 +     /* init key-context nonce */
  39.395 +     SET_TO_RAND(&tpmData.stclear.data.contextNonceKey);
  39.396 +   } else if (startupType == TPM_ST_STATE) {
  39.397 +-    if (tpm_restore_permanent_data()) {
  39.398 ++    /* restore must have been successful for TPM_ST_STATE */
  39.399 ++    if (restore_fail) {
  39.400 +       error("restoring permanent data failed");
  39.401 +       tpmData.permanent.data.testResult = "tpm_restore_permanent_data() failed";
  39.402 +       tpmData.permanent.flags.selfTestSucceeded = FALSE;
  39.403 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_storage.c tpm_emulator-0.3-x86_64/tpm/tpm_storage.c
  39.404 +--- orig/tpm_emulator-0.3/tpm/tpm_storage.c	2006-01-10 04:21:45.000000000 -0800
  39.405 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c	2006-08-29 15:07:43.537966768 -0700
  39.406  @@ -58,6 +58,7 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
  39.407                           BYTE *enc, UINT32 *enc_size)
  39.408   {
  39.409 @@ -482,3 +662,76 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_stor
  39.410     if (tpm_setup_key_parms(key, &pubKey->algorithmParms) != 0) {
  39.411       tpm_free(pubKey->pubKey.key);
  39.412       return TPM_FAIL;
  39.413 +diff -uprN orig/tpm_emulator-0.3/tpm/tpm_structures.h tpm_emulator-0.3-x86_64/tpm/tpm_structures.h
  39.414 +--- orig/tpm_emulator-0.3/tpm/tpm_structures.h	2006-01-10 04:21:45.000000000 -0800
  39.415 ++++ tpm_emulator-0.3-x86_64/tpm/tpm_structures.h	2006-08-29 15:08:20.545340792 -0700
  39.416 +@@ -1723,6 +1723,7 @@ typedef struct tdTPM_DAA_ISSUER {
  39.417 +   TPM_DIGEST DAA_digest_gamma;
  39.418 +   BYTE DAA_generic_q[26];
  39.419 + } TPM_DAA_ISSUER;
  39.420 ++#define sizeof_TPM_DAA_ISSUER(s) (2 + (20 * 6) + 26 )
  39.421 + 
  39.422 + /*
  39.423 +  * TPM_DAA_TPM ([TPM_Part2], Section 22.8)
  39.424 +@@ -1738,6 +1739,7 @@ typedef struct tdTPM_DAA_TPM {
  39.425 +   TPM_DIGEST DAA_rekey;
  39.426 +   UINT32 DAA_count;
  39.427 + } TPM_DAA_TPM;
  39.428 ++#define sizeof_TPM_DAA_TPM(s) (2 + (4 * 20) + 4)
  39.429 + 
  39.430 + /*
  39.431 +  * TPM_DAA_CONTEXT ([TPM_Part2], Section 22.9)
  39.432 +@@ -1752,6 +1754,7 @@ typedef struct tdTPM_DAA_CONTEXT {
  39.433 +   BYTE DAA_scratch[256];
  39.434 +   BYTE DAA_stage;
  39.435 + } TPM_DAA_CONTEXT;
  39.436 ++#define sizeof_TPM_DAA_CONTEXT(s) (2 + (3 * 20) + 256 + 1)
  39.437 + 
  39.438 + /*
  39.439 +  * TPM_DAA_JOINDATA ([TPM_Part2], Section 22.10)
  39.440 +@@ -1763,6 +1766,7 @@ typedef struct tdTPM_DAA_JOINDATA {
  39.441 +   BYTE DAA_join_u1[138]; /* WATCH: 138 (v1.2 rev 85) */
  39.442 +   TPM_DIGEST DAA_digest_n0;
  39.443 + } TPM_DAA_JOINDATA;
  39.444 ++#define sizeof_TPM_DAA_JOINDATA(s) (1 + 1 + 20)
  39.445 + 
  39.446 + /*
  39.447 +  * TPM_DAA_BLOB ([TPM_Part2], Section 22.12)
  39.448 +@@ -2033,6 +2037,7 @@ typedef struct tdTPM_STCLEAR_DATA {
  39.449 +   TPM_COUNT_ID countID;
  39.450 +   //UINT32 ownerReference;
  39.451 + } TPM_STCLEAR_DATA;
  39.452 ++#define sizeof_TPM_STCLEAR_DATA(s) (2 + 20 + 4)
  39.453 + 
  39.454 + /*
  39.455 +  * TPM_SESSION_DATA
  39.456 +@@ -2069,6 +2074,11 @@ typedef struct tdTPM_DAA_SESSION_DATA {
  39.457 +   TPM_DAA_JOINDATA DAA_joinSession;
  39.458 +   TPM_HANDLE handle;
  39.459 + } TPM_DAA_SESSION_DATA;
  39.460 ++#define sizeof_TPM_DAA_SESSION_DATA(s) ( 1 \
  39.461 ++  + sizeof_TPM_DAA_ISSUER(s.DAA_issuerSettings) \
  39.462 ++  + sizeof_TPM_DAA_TPM(s.DAA_tpmSpecific) \
  39.463 ++  + sizeof_TPM_DAA_CONTEXT(s.DAA_session) \
  39.464 ++  + sizeof_TPM_DAA_JOINDATA(s.DAA_joinSession) + 4)
  39.465 + 
  39.466 + /*
  39.467 +  * TPM_STANY_DATA ([TPM_Part2], Section 7.6)
  39.468 +@@ -2095,6 +2105,17 @@ typedef struct tdTPM_STANY_DATA {
  39.469 +   TPM_DAA_SESSION_DATA sessionsDAA[TPM_MAX_SESSIONS_DAA];
  39.470 +   TPM_TRANSHANDLE transExclusive;
  39.471 + } TPM_STANY_DATA;
  39.472 ++#define sizeof_TPM_STANY_DATA(s) (2 + 20 + 20 + 1 \
  39.473 ++  + sizeof_TPM_CURRENT_TICKS(s.currentTicks) \
  39.474 ++  + 4 + (4 * TPM_MAX_SESSION_LIST) \
  39.475 ++  + (sizeof_TPM_SESSION_DATA(s.sessions[0]) * TPM_MAX_SESSION_LIST) \
  39.476 ++  + (sizeof_TPM_DAA_SESSION_DATA(s.sessionsDAA[0]) * TPM_MAX_SESSIONS_DAA) + 4)
  39.477 ++
  39.478 ++#define sizeof_TPM_PERMANENT_DATA(s) (2 + 4 + 4*20 \
  39.479 ++  + sizeof_RSA(s.endorsementKey) + TPM_ORD_MAX/8 \
  39.480 ++  + (1+TPM_MAX_KEYS)*sizeof_TPM_KEY_DATA(s.srk) \
  39.481 ++  + TPM_NUM_PCR*(sizeof_TPM_PCR_ATTRIBUTES(x)+20) \
  39.482 ++  + TPM_MAX_COUNTERS*sizeof_TPM_COUNTER_VALUE2(x) + 1 + 4 + 20)
  39.483 + 
  39.484 + /*
  39.485 +  * TPM_DATA
    40.1 --- a/tools/vtpm/tpm_emulator.patch	Wed Jun 28 07:51:52 2006 -0600
    40.2 +++ b/tools/vtpm/tpm_emulator.patch	Wed Jun 28 07:52:21 2006 -0600
    40.3 @@ -1,68 +1,63 @@
    40.4 -diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS tpm_emulator/AUTHORS
    40.5 ---- orig/tpm_emulator-0.2-x86_64/AUTHORS	2005-08-15 00:58:57.000000000 -0700
    40.6 -+++ tpm_emulator/AUTHORS	2005-09-14 20:27:22.000000000 -0700
    40.7 -@@ -1 +1,2 @@
    40.8 +diff -uprN tpm_emulator-0.3-x86_64/AUTHORS tpm_emulator/AUTHORS
    40.9 +--- tpm_emulator-0.3-x86_64/AUTHORS	2006-08-29 15:07:21.618299064 -0700
   40.10 ++++ tpm_emulator/AUTHORS	2006-08-29 15:26:17.099679656 -0700
   40.11 +@@ -1,2 +1,3 @@
   40.12   Mario Strasser <mast@gmx.net>
   40.13 -+INTEL Corp <>
   40.14 -diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog tpm_emulator/ChangeLog
   40.15 ---- orig/tpm_emulator-0.2-x86_64/ChangeLog	2005-08-15 00:58:57.000000000 -0700
   40.16 -+++ tpm_emulator/ChangeLog	2005-09-14 20:27:22.000000000 -0700
   40.17 -@@ -1,3 +1,7 @@
   40.18 -+2005-08-16: INTEL Corp
   40.19 -+	* Set default permissions to PCRs
   40.20 -+	* Changed device to /dev/tpm0
   40.21 + Heiko Stamer <stamer@gaos.org> [DAA]
   40.22 ++INTEL Corp <> [Dropped to Ring3]
   40.23 +diff -uprN tpm_emulator-0.3-x86_64/ChangeLog tpm_emulator/ChangeLog
   40.24 +--- tpm_emulator-0.3-x86_64/ChangeLog	2006-08-29 15:07:21.618299064 -0700
   40.25 ++++ tpm_emulator/ChangeLog	2006-08-29 15:26:17.100679504 -0700
   40.26 +@@ -1,3 +1,6 @@
   40.27 ++2005-08-16 Intel Corp
   40.28 ++	* Moved module out of kernel to run as a ring 3 app
   40.29  +
   40.30 - 2005-08-15  Mario Strasser <mast@gmx.net>
   40.31 - 	* all: some typos corrected
   40.32 - 	* tpm_integrity.c: bug in TPM_Extend fixed
   40.33 -diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h tpm_emulator/linux_module.h
   40.34 ---- orig/tpm_emulator-0.2-x86_64/linux_module.h	2005-09-15 19:21:14.844078720 -0700
   40.35 -+++ tpm_emulator/linux_module.h	2005-09-14 20:27:22.000000000 -0700
   40.36 -@@ -1,5 +1,6 @@
   40.37 - /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   40.38 -  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
   40.39 -+ * Copyright (C) 2005 INTEL Corp.
   40.40 -  *
   40.41 -  * This module is free software; you can redistribute it and/or modify
   40.42 -  * it under the terms of the GNU General Public License as published
   40.43 -@@ -35,7 +36,7 @@
   40.44 - #include "tpm_version.h"
   40.45 - 
   40.46 - #define TPM_DEVICE_MINOR	224
   40.47 --#define TPM_DEVICE_NAME         "tpm"
   40.48 -+#define TPM_DEVICE_NAME         "tpm0"
   40.49 - #define TPM_MODULE_NAME 	"tpm_emulator"
   40.50 - 
   40.51 - /* debug and log output functions */
   40.52 -diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile tpm_emulator/Makefile
   40.53 ---- orig/tpm_emulator-0.2-x86_64/Makefile	2005-09-15 19:21:14.845078568 -0700
   40.54 -+++ tpm_emulator/Makefile	2005-09-14 20:27:22.000000000 -0700
   40.55 -@@ -1,16 +1,22 @@
   40.56 + 2005-12-24  Mario Strasser <mast@gmx.net>
   40.57 + 	* tpm_transport.c, tpm_marshalling.c, tpm_structures.h:
   40.58 + 		Transport session functionality added
   40.59 +diff -uprN tpm_emulator-0.3-x86_64/Makefile tpm_emulator/Makefile
   40.60 +--- tpm_emulator-0.3-x86_64/Makefile	2006-08-29 15:08:20.532342768 -0700
   40.61 ++++ tpm_emulator/Makefile	2006-08-29 15:27:39.559143912 -0700
   40.62 +@@ -1,22 +1,31 @@
   40.63   # Software-Based Trusted Platform Module (TPM) Emulator for Linux
   40.64   # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
   40.65 -+# Copyright (C) 2005 INTEL Corp.
   40.66 ++# Copyright (C) 2006 INTEL Corp.
   40.67   #
   40.68 - # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
   40.69 + # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
   40.70   
   40.71 -+XEN_ROOT       := ../../..
   40.72 -+EUID           := $(shell id -u)
   40.73 -+
   40.74 - # kernel settings
   40.75 - KERNEL_RELEASE := $(shell uname -r)
   40.76 +-# kernel settings
   40.77 +-KERNEL_RELEASE := $(shell uname -r)
   40.78  -KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
   40.79 -+CUR_DIR        := $(shell pwd)
   40.80 -+LINUX_VERSION  := $(shell cat $(CUR_DIR)/$(XEN_ROOT)/buildconfigs/mk.linux-2.6-xen | grep "LINUX_VER" | grep "2.6" | gawk '{ print $$3 }' )
   40.81 -+KERNEL_BUILD   := $(XEN_ROOT)/linux-$(LINUX_VERSION)-xen
   40.82 - MOD_SUBDIR     := misc
   40.83 +-MOD_SUBDIR     := misc
   40.84   COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
   40.85   
   40.86   # module settings
   40.87  -MODULE_NAME    := tpm_emulator
   40.88  +BIN            := tpm_emulator
   40.89   VERSION_MAJOR  := 0
   40.90 - VERSION_MINOR  := 2
   40.91 + VERSION_MINOR  := 3
   40.92   VERSION_BUILD  := $(shell date +"%s")
   40.93 -@@ -34,11 +38,9 @@ DIRS           := . crypto tpm 
   40.94 + 
   40.95 +-# enable/disable DEBUG messages
   40.96 +-EXTRA_CFLAGS   += -Wall -DDEBUG -g  
   40.97 ++# Installation program and options
   40.98 ++INSTALL         = install
   40.99 ++INSTALL_PROG    = $(INSTALL) -m0755
  40.100 ++INSTALL_DIR     = $(INSTALL) -d -m0755
  40.101 ++
  40.102 ++# Xen tools installation directory
  40.103 ++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
  40.104 ++
  40.105 ++CC      := gcc
  40.106 ++CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
  40.107 ++CFLAGS  += -I. -Itpm
  40.108 ++
  40.109 ++# Is the simulator running in it's own vm?
  40.110 ++#CFLAGS += -DVTPM_MULTI_VM
  40.111 + 
  40.112 + ifeq ($(COMPILE_ARCH),x86_64)
  40.113 + LIBDIR = lib64
  40.114 +@@ -34,38 +43,31 @@ DIRS           := . crypto tpm 
  40.115   SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
  40.116   OBJS           := $(patsubst %.c, %.o, $(SRCS))
  40.117   SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
  40.118 @@ -71,29 +66,37 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  40.119   
  40.120  -obj-m               := $(MODULE_NAME).o
  40.121  -$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  40.122 -+obj-m               := $(BIN).o
  40.123 ++obj-m               := $(BIN)
  40.124  +$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  40.125   
  40.126   EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
  40.127   
  40.128 -@@ -49,23 +51,17 @@ all:	$(src)/crypto/gmp.h $(src)/crypto/l
  40.129 - 	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
  40.130 + # do not print "Entering directory ..."
  40.131 + MAKEFLAGS      += --no-print-directory
  40.132   
  40.133 - install:
  40.134 +-all:	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
  40.135 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
  40.136 ++all: $(BIN)
  40.137 ++
  40.138 ++$(BIN):	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS)
  40.139 ++	$(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
  40.140 ++
  40.141 ++%.o: %.c
  40.142 ++	$(CC) $(CFLAGS) -c $< -o $@
  40.143 + 
  40.144 +-install:
  40.145  -	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
  40.146  -	test -d /var/tpm || mkdir /var/tpm
  40.147  -	test -c /dev/tpm || mknod /dev/tpm c 10 224
  40.148  -	chmod 666 /dev/tpm
  40.149  -	depmod -a
  40.150 -+	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) INSTALL_MOD_PATH=$(DESTDIR) modules_install
  40.151 -+	test -d $(DESTDIR)/var/tpm || mkdir $(DESTDIR)/var/tpm
  40.152 -+	test -d $(DESTDIR)/dev || mkdir $(DESTDIR)/dev
  40.153 -+	test -c $(DESTDIR)/dev/tpm0 || [ $(EUID) -ne 0 ] || mknod $(DESTDIR)/dev/tpm0 c 10 224
  40.154 -+	[ $(EUID) -ne 0 ] || chmod 666 $(DESTDIR)/dev/tpm0
  40.155 ++install: $(BIN)
  40.156 ++	$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
  40.157   
  40.158   clean:
  40.159 - 	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
  40.160 - 	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
  40.161 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
  40.162 +-	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
  40.163 ++	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
  40.164   
  40.165  -dist:	$(DISTSRC)
  40.166  -	rm -rf $(DISTDIR)
  40.167 @@ -103,25 +106,591 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  40.168  -	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
  40.169  -	rm -rf $(DISTDIR)
  40.170  +mrproper: clean
  40.171 ++	rm -f $(BIN) tpm_version.h
  40.172   
  40.173   $(src)/crypto/libgmp.a:
  40.174   	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
  40.175 -diff -uprN orig/tpm_emulator-0.2-x86_64/README tpm_emulator/README
  40.176 ---- orig/tpm_emulator-0.2-x86_64/README	2005-08-15 00:58:57.000000000 -0700
  40.177 -+++ tpm_emulator/README	2005-09-14 20:27:22.000000000 -0700
  40.178 -@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
  40.179 +diff -uprN tpm_emulator-0.3-x86_64/README tpm_emulator/README
  40.180 +--- tpm_emulator-0.3-x86_64/README	2006-08-29 15:07:43.530967832 -0700
  40.181 ++++ tpm_emulator/README	2006-08-29 15:26:17.105678744 -0700
  40.182 +@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
  40.183   Copyright
  40.184   --------------------------------------------------------------------------
  40.185   Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
  40.186  -Institute of Technology (ETH) Zurich.
  40.187  +                   Institute of Technology (ETH) Zurich.
  40.188 -+Copyright (C) 2005 
  40.189 ++Copyright (C) 2005 INTEL Corp 
  40.190                 
  40.191   This program is free software; you can redistribute it and/or modify
  40.192   it under the terms of the GNU General Public License as published by
  40.193 -diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c tpm_emulator/tpm/tpm_data.c
  40.194 ---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c	2005-09-15 19:21:14.847078264 -0700
  40.195 -+++ tpm_emulator/tpm/tpm_data.c	2005-09-14 20:27:22.000000000 -0700
  40.196 +diff -uprN tpm_emulator-0.3-x86_64/README.1st tpm_emulator/README.1st
  40.197 +--- tpm_emulator-0.3-x86_64/README.1st	1969-12-31 16:00:00.000000000 -0800
  40.198 ++++ tpm_emulator/README.1st	2006-08-29 15:26:17.105678744 -0700
  40.199 +@@ -0,0 +1 @@
  40.200 ++Note that you must manually create /tmp/tpm_in.fifo and /tmp/tpm_out.fifo for this emulator to work.
  40.201 +diff -uprN tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c tpm_emulator/crypto/gmp_kernel_wrapper.c
  40.202 +--- tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c	2006-08-29 15:07:43.525968592 -0700
  40.203 ++++ tpm_emulator/crypto/gmp_kernel_wrapper.c	2006-08-29 15:26:17.101679352 -0700
  40.204 +@@ -1,5 +1,6 @@
  40.205 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  40.206 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.207 ++ * Copyright (C) 2005 INTEL Corp
  40.208 +  *
  40.209 +  * This module is free software; you can redistribute it and/or modify
  40.210 +  * it under the terms of the GNU General Public License as published
  40.211 +@@ -24,15 +25,10 @@ int __gmp_junk;
  40.212 + void __attribute__ ((regparm(0))) __gmp_assert_fail(const char *filename, 
  40.213 +   int linenum, const char *expr) 
  40.214 + {
  40.215 +-  panic(KERN_CRIT TPM_MODULE_NAME "%s:%d: GNU MP assertion failed: %s\n", 
  40.216 ++  error("%s:%d: GNU MP assertion failed: %s\n", 
  40.217 +     filename, linenum, expr);
  40.218 + }
  40.219 + 
  40.220 +-void __attribute__ ((regparm(0))) abort(void)
  40.221 +-{
  40.222 +-  panic(KERN_CRIT TPM_MODULE_NAME "GNU MP abort() was called\n");
  40.223 +-}
  40.224 +-
  40.225 + /* overwrite GNU MP random functions (used by mpz/millerrabin.c) */ 
  40.226 + 
  40.227 + void __attribute__ ((regparm(0))) gmp_randinit(gmp_randstate_t rstate, 
  40.228 +@@ -77,20 +73,19 @@ void __attribute__ ((regparm(0))) mpz_ur
  40.229 + 
  40.230 + void __attribute__ ((regparm(0))) *kernel_allocate(size_t size)
  40.231 + {
  40.232 +-  void *ret  = (void*)kmalloc(size, GFP_KERNEL);
  40.233 +-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 
  40.234 +-    "GMP: cannot allocate memory (size=%Zu)\n", size);
  40.235 ++  void *ret  = (void*)malloc(size);
  40.236 ++  if (!ret) error("GMP: cannot allocate memory (size=%Zu)\n", size);
  40.237 +   return ret;
  40.238 + }
  40.239 + 
  40.240 + void __attribute__ ((regparm(0))) *kernel_reallocate(void *oldptr, 
  40.241 +   size_t old_size, size_t new_size)
  40.242 + {
  40.243 +-  void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
  40.244 +-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
  40.245 ++  void *ret = (void*)malloc(new_size);
  40.246 ++  if (!ret) error("GMP: Cannot reallocate memory "
  40.247 +     "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
  40.248 +   memcpy(ret, oldptr, old_size);
  40.249 +-  kfree(oldptr);
  40.250 ++  free(oldptr);
  40.251 +   return ret;
  40.252 + }
  40.253 + 
  40.254 +@@ -99,7 +94,7 @@ void __attribute__ ((regparm(0))) kernel
  40.255 +   /* overwrite used memory */
  40.256 +   if (blk_ptr != NULL) { 
  40.257 +     memset(blk_ptr, 0, blk_size);
  40.258 +-    kfree(blk_ptr);
  40.259 ++    free(blk_ptr);
  40.260 +   }
  40.261 + }
  40.262 + 
  40.263 +diff -uprN tpm_emulator-0.3-x86_64/crypto/rsa.c tpm_emulator/crypto/rsa.c
  40.264 +--- tpm_emulator-0.3-x86_64/crypto/rsa.c	2006-08-29 15:07:21.618299064 -0700
  40.265 ++++ tpm_emulator/crypto/rsa.c	2006-08-29 15:26:17.102679200 -0700
  40.266 +@@ -1,5 +1,6 @@
  40.267 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  40.268 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.269 ++ * Copyright (C) 2005 INTEL Corp
  40.270 +  *
  40.271 +  * This module is free software; you can redistribute it and/or modify
  40.272 +  * it under the terms of the GNU General Public License as published
  40.273 +@@ -381,7 +382,7 @@ static int encode_message(int type, uint
  40.274 +       msg[0] = 0x00;
  40.275 +       get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
  40.276 +       sha1_init(&ctx);
  40.277 +-      sha1_update(&ctx, "TCPA", 4);
  40.278 ++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
  40.279 +       sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
  40.280 +       memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00, 
  40.281 +         msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
  40.282 +@@ -429,7 +430,7 @@ static int decode_message(int type, uint
  40.283 +       mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
  40.284 +         &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
  40.285 +       sha1_init(&ctx);
  40.286 +-      sha1_update(&ctx, "TCPA", 4);
  40.287 ++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
  40.288 +       sha1_final(&ctx, &msg[1]);
  40.289 +       if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
  40.290 +           SHA1_DIGEST_LENGTH) != 0) return -1;
  40.291 +diff -uprN tpm_emulator-0.3-x86_64/linux_module.c tpm_emulator/linux_module.c
  40.292 +--- tpm_emulator-0.3-x86_64/linux_module.c	2006-08-29 15:07:43.526968440 -0700
  40.293 ++++ tpm_emulator/linux_module.c	1969-12-31 16:00:00.000000000 -0800
  40.294 +@@ -1,194 +0,0 @@
  40.295 +-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
  40.296 +- * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.297 +- *
  40.298 +- * This module is free software; you can redistribute it and/or modify 
  40.299 +- * it under the terms of the GNU General Public License as published 
  40.300 +- * by the Free Software Foundation; either version 2 of the License, 
  40.301 +- * or (at your option) any later version.  
  40.302 +- *
  40.303 +- * This module is distributed in the hope that it will be useful, 
  40.304 +- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  40.305 +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  40.306 +- * GNU General Public License for more details.
  40.307 +- *
  40.308 +- * $Id: linux_module.c 76 2006-01-02 22:17:58Z hstamer $
  40.309 +- */
  40.310 +-
  40.311 +-#include <linux/module.h>
  40.312 +-#include <linux/kernel.h>
  40.313 +-#include <linux/init.h>
  40.314 +-#include <linux/miscdevice.h>
  40.315 +-#include <linux/poll.h>
  40.316 +-#include "linux_module.h"
  40.317 +-#include "tpm/tpm_emulator.h"
  40.318 +-
  40.319 +-MODULE_LICENSE("GPL");
  40.320 +-MODULE_AUTHOR("Mario Strasser <mast@gmx.net>");
  40.321 +-MODULE_DESCRIPTION("Trusted Platform Module (TPM) Emulator");
  40.322 +-MODULE_SUPPORTED_DEVICE(TPM_DEVICE_NAME);
  40.323 +-
  40.324 +-/* module startup parameters */
  40.325 +-char *startup = "save";
  40.326 +-module_param(startup, charp, 0444);
  40.327 +-MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. "
  40.328 +-  "Possible values are 'clear', 'save' (default) and 'deactivated.");
  40.329 +-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.2";
  40.330 +-module_param(storage_file, charp, 0644);
  40.331 +-MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage " 
  40.332 +-  "file of the TPM.");
  40.333 +-
  40.334 +-/* TPM lock */
  40.335 +-static struct semaphore tpm_mutex;
  40.336 +-
  40.337 +-/* TPM command response */
  40.338 +-static struct {
  40.339 +-  uint8_t *data;
  40.340 +-  uint32_t size;
  40.341 +-} tpm_response;
  40.342 +-
  40.343 +-/* module state */
  40.344 +-#define STATE_IS_OPEN 0
  40.345 +-static uint32_t module_state;
  40.346 +-
  40.347 +-static int tpm_open(struct inode *inode, struct file *file)
  40.348 +-{
  40.349 +-  debug("%s()", __FUNCTION__);
  40.350 +-  if (test_and_set_bit(STATE_IS_OPEN, (void*)&module_state)) return -EBUSY;
  40.351 +-  return 0;
  40.352 +-}
  40.353 +-
  40.354 +-static int tpm_release(struct inode *inode, struct file *file)
  40.355 +-{
  40.356 +-  debug("%s()", __FUNCTION__);
  40.357 +-  clear_bit(STATE_IS_OPEN, (void*)&module_state);
  40.358 +-  down(&tpm_mutex);
  40.359 +-  if (tpm_response.data != NULL) {
  40.360 +-    kfree(tpm_response.data);
  40.361 +-    tpm_response.data = NULL;
  40.362 +-  }
  40.363 +-  up(&tpm_mutex);
  40.364 +-  return 0;
  40.365 +-}
  40.366 +-
  40.367 +-static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t *ppos)
  40.368 +-{
  40.369 +-  debug("%s(%Zu)", __FUNCTION__, count);
  40.370 +-  down(&tpm_mutex);
  40.371 +-  if (tpm_response.data != NULL) {
  40.372 +-    count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
  40.373 +-    count -= copy_to_user(buf, &tpm_response.data[*ppos], count);
  40.374 +-    *ppos += count;
  40.375 +-    if ((size_t)tpm_response.size == (size_t)*ppos) {
  40.376 +-      kfree(tpm_response.data);
  40.377 +-      tpm_response.data = NULL;
  40.378 +-    }
  40.379 +-  } else {
  40.380 +-    count = 0;
  40.381 +-  }
  40.382 +-  up(&tpm_mutex);
  40.383 +-  return count;
  40.384 +-}
  40.385 +-
  40.386 +-static ssize_t tpm_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
  40.387 +-{
  40.388 +-  debug("%s(%Zu)", __FUNCTION__, count);
  40.389 +-  down(&tpm_mutex);
  40.390 +-  *ppos = 0;
  40.391 +-  if (tpm_response.data != NULL) kfree(tpm_response.data);
  40.392 +-  if (tpm_handle_command(buf, count, &tpm_response.data, 
  40.393 +-                         &tpm_response.size) != 0) { 
  40.394 +-    count = -EILSEQ;
  40.395 +-    tpm_response.data = NULL;
  40.396 +-  }
  40.397 +-  up(&tpm_mutex);
  40.398 +-  return count;
  40.399 +-}
  40.400 +-
  40.401 +-#define TPMIOC_CANCEL   _IO('T', 0x00)
  40.402 +-#define TPMIOC_TRANSMIT _IO('T', 0x01)
  40.403 +-
  40.404 +-static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  40.405 +-{
  40.406 +-  debug("%s(%d, %p)", __FUNCTION__, cmd, (char*)arg);
  40.407 +-  if (cmd == TPMIOC_TRANSMIT) {
  40.408 +-    uint32_t count = ntohl(*(uint32_t*)(arg + 2));
  40.409 +-    down(&tpm_mutex);
  40.410 +-    if (tpm_response.data != NULL) kfree(tpm_response.data);
  40.411 +-    if (tpm_handle_command((char*)arg, count, &tpm_response.data,
  40.412 +-                           &tpm_response.size) == 0) {
  40.413 +-      tpm_response.size -= copy_to_user((char*)arg, tpm_response.data,
  40.414 +-                            tpm_response.size);
  40.415 +-      kfree(tpm_response.data);
  40.416 +-      tpm_response.data = NULL;
  40.417 +-    } else {
  40.418 +-      tpm_response.size = 0;
  40.419 +-      tpm_response.data = NULL;
  40.420 +-    }
  40.421 +-    up(&tpm_mutex);
  40.422 +-    return tpm_response.size;
  40.423 +-  }
  40.424 +-  return -1;
  40.425 +-}
  40.426 +-
  40.427 +-struct file_operations fops = {
  40.428 +-  .owner   = THIS_MODULE,
  40.429 +-  .open    = tpm_open,
  40.430 +-  .release = tpm_release,
  40.431 +-  .read    = tpm_read,
  40.432 +-  .write   = tpm_write,
  40.433 +-  .ioctl   = tpm_ioctl,
  40.434 +-};
  40.435 +-
  40.436 +-static struct miscdevice tpm_dev = {
  40.437 +-  .minor      = TPM_DEVICE_MINOR, 
  40.438 +-  .name       = TPM_DEVICE_NAME, 
  40.439 +-  .fops       = &fops,
  40.440 +-};
  40.441 +-
  40.442 +-int __init init_tpm_module(void)
  40.443 +-{
  40.444 +-  int res = misc_register(&tpm_dev);
  40.445 +-  if (res != 0) {
  40.446 +-    error("misc_register() failed for minor %d\n", TPM_DEVICE_MINOR);
  40.447 +-    return res;
  40.448 +-  }
  40.449 +-  /* initialize variables */
  40.450 +-  sema_init(&tpm_mutex, 1);
  40.451 +-  module_state = 0;
  40.452 +-  tpm_response.data = NULL;    
  40.453 +-  /* initialize TPM emulator */
  40.454 +-  if (!strcmp(startup, "clear")) {
  40.455 +-    tpm_emulator_init(1);
  40.456 +-  } else if (!strcmp(startup, "save")) {
  40.457 +-    tpm_emulator_init(2);
  40.458 +-  } else if (!strcmp(startup, "deactivated")) {
  40.459 +-    tpm_emulator_init(3);
  40.460 +-  } else {
  40.461 +-    error("invalid startup mode '%s'; must be 'clear', "
  40.462 +-      "'save' (default) or 'deactivated", startup);
  40.463 +-    misc_deregister(&tpm_dev);
  40.464 +-    return -EINVAL;
  40.465 +-  }
  40.466 +-  return 0;
  40.467 +-}
  40.468 +-
  40.469 +-void __exit cleanup_tpm_module(void)
  40.470 +-{
  40.471 +-  tpm_emulator_shutdown();
  40.472 +-  misc_deregister(&tpm_dev);
  40.473 +-  if (tpm_response.data != NULL) kfree(tpm_response.data);
  40.474 +-}
  40.475 +-
  40.476 +-module_init(init_tpm_module);
  40.477 +-module_exit(cleanup_tpm_module);
  40.478 +-
  40.479 +-uint64_t tpm_get_ticks(void)
  40.480 +-{
  40.481 +-  static struct timespec old_time = {0, 0};
  40.482 +-  struct timespec new_time = current_kernel_time();
  40.483 +-  uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000
  40.484 +-                   + (old_time.tv_nsec - new_time.tv_nsec) / 1000;
  40.485 +-  old_time = new_time;
  40.486 +-  return (ticks > 0) ? ticks : 1;
  40.487 +-}
  40.488 +-
  40.489 +diff -uprN tpm_emulator-0.3-x86_64/linux_module.h tpm_emulator/linux_module.h
  40.490 +--- tpm_emulator-0.3-x86_64/linux_module.h	2006-08-29 15:07:43.527968288 -0700
  40.491 ++++ tpm_emulator/linux_module.h	2006-08-29 15:26:17.103679048 -0700
  40.492 +@@ -1,5 +1,6 @@
  40.493 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  40.494 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.495 ++ * Copyright (C) 2005 INTEL Corp
  40.496 +  *
  40.497 +  * This module is free software; you can redistribute it and/or modify
  40.498 +  * it under the terms of the GNU General Public License as published
  40.499 +@@ -17,17 +18,22 @@
  40.500 + #ifndef _LINUX_MODULE_H_
  40.501 + #define _LINUX_MODULE_H_
  40.502 + 
  40.503 +-#include <linux/version.h>
  40.504 +-#include <linux/kernel.h>
  40.505 +-#include <linux/slab.h>
  40.506 ++#include <malloc.h>
  40.507 ++#include <stdint.h>
  40.508 ++#include <stdio.h>
  40.509 ++#include <string.h>
  40.510 + #include <linux/types.h>
  40.511 +-#include <linux/string.h>
  40.512 +-#include <linux/random.h>
  40.513 +-#include <linux/time.h>
  40.514 +-#include <asm/byteorder.h>
  40.515 + 
  40.516 +-/* module settings */
  40.517 ++#include <endian.h>
  40.518 ++#define __BYTEORDER_HAS_U64__
  40.519 ++#ifdef LITTLE_ENDIAN
  40.520 ++ #include <linux/byteorder/little_endian.h>
  40.521 ++#else
  40.522 ++ #include <linux/byteorder/big_endian.h>
  40.523 ++#endif
  40.524 + 
  40.525 ++/* module settings */
  40.526 ++#define min(A,B) ((A)<(B)?(A):(B))
  40.527 + #ifndef STR
  40.528 + #define STR(s) __STR__(s)
  40.529 + #define __STR__(s) #s
  40.530 +@@ -38,35 +44,36 @@
  40.531 + #define TPM_DEVICE_NAME         "tpm"
  40.532 + #define TPM_MODULE_NAME 	"tpm_emulator"
  40.533 + 
  40.534 +-/* debug and log output functions */
  40.535 +-
  40.536 + #ifdef DEBUG
  40.537 +-#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \
  40.538 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
  40.539 ++#define debug(fmt, ...) printf("TPMD: %s:%d: Debug: " fmt "\n", \
  40.540 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
  40.541 + #else
  40.542 + #define debug(fmt, ...) 
  40.543 + #endif
  40.544 +-#define info(fmt, ...)  printk(KERN_INFO "%s %s:%d: Info: " fmt "\n", \
  40.545 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
  40.546 +-#define error(fmt, ...) printk(KERN_ERR "%s %s:%d: Error: " fmt "\n", \
  40.547 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
  40.548 +-#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \
  40.549 +-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
  40.550 ++#define info(fmt, ...)  printf("TPMD: %s:%d: Info: " fmt "\n", \
  40.551 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
  40.552 ++#define error(fmt, ...) printf("TPMD: %s:%d: Error: " fmt "\n", \
  40.553 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
  40.554 ++#define alert(fmt, ...) printf("TPMD: %s:%d: Alert: " fmt "\n", \
  40.555 ++                        __FILE__, __LINE__, ## __VA_ARGS__)
  40.556 + 
  40.557 + /* memory allocation */
  40.558 + 
  40.559 + static inline void *tpm_malloc(size_t size) 
  40.560 + {
  40.561 +-  return kmalloc(size, GFP_KERNEL);  
  40.562 ++  return malloc(size);  
  40.563 + }
  40.564 + 
  40.565 + static inline void tpm_free(const void *ptr)
  40.566 + {
  40.567 +-  if (ptr != NULL) kfree(ptr);
  40.568 ++  if (ptr != NULL) free( (void *) ptr);
  40.569 + }
  40.570 + 
  40.571 + /* random numbers */
  40.572 + 
  40.573 ++//FIXME;
  40.574 ++void get_random_bytes(void *buf, int nbytes);
  40.575 ++
  40.576 + static inline void tpm_get_random_bytes(void *buf, int nbytes)
  40.577 + {
  40.578 +   get_random_bytes(buf, nbytes);
  40.579 +@@ -86,9 +93,9 @@ uint64_t tpm_get_ticks(void);
  40.580 + #define CPU_TO_LE16(x) __cpu_to_le16(x)
  40.581 + 
  40.582 + #define BE64_TO_CPU(x) __be64_to_cpu(x)
  40.583 +-#define LE64_TO_CPU(x) __be64_to_cpu(x)
  40.584 ++#define LE64_TO_CPU(x) __le64_to_cpu(x)
  40.585 + #define BE32_TO_CPU(x) __be32_to_cpu(x)
  40.586 +-#define LE32_TO_CPU(x) __be32_to_cpu(x)
  40.587 ++#define LE32_TO_CPU(x) __le32_to_cpu(x)
  40.588 + #define BE16_TO_CPU(x) __be16_to_cpu(x)
  40.589 + #define LE16_TO_CPU(x) __le16_to_cpu(x)
  40.590 + 
  40.591 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_audit.c tpm_emulator/tpm/tpm_audit.c
  40.592 +--- tpm_emulator-0.3-x86_64/tpm/tpm_audit.c	2006-08-29 15:07:21.620298760 -0700
  40.593 ++++ tpm_emulator/tpm/tpm_audit.c	2006-08-29 15:26:17.107678440 -0700
  40.594 +@@ -1,6 +1,7 @@
  40.595 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  40.596 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.597 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  40.598 ++ * Copyright (C) 2005 INTEL Corp
  40.599 +  *
  40.600 +  * This module is free software; you can redistribute it and/or modify
  40.601 +  * it under the terms of the GNU General Public License as published
  40.602 +@@ -45,14 +46,14 @@ void tpm_audit_request(TPM_COMMAND_CODE 
  40.603 +       tpmData.permanent.data.auditMonotonicCounter++;
  40.604 +     }
  40.605 +     /* update audit digest */
  40.606 +-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_IN);
  40.607 +-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
  40.608 ++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_IN);
  40.609 ++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
  40.610 +     sha1_init(&sha1_ctx);
  40.611 +     sha1_update(&sha1_ctx, req->param, req->paramSize);
  40.612 +     sha1_final(&sha1_ctx, &buf[6]);
  40.613 +-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
  40.614 ++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
  40.615 +     memset(&buf[30], 0, 4);
  40.616 +-    *((UINT32*)&buf[34]) = cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
  40.617 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
  40.618 +     sha1_init(&sha1_ctx);
  40.619 +     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
  40.620 +       sizeof(TPM_DIGEST));
  40.621 +@@ -70,15 +71,15 @@ void tpm_audit_response(TPM_COMMAND_CODE
  40.622 +       && (AUDIT_STATUS[ord / 8] & (1 << (ord & 0x07)))) {
  40.623 +     info("tpm_audit_response()");
  40.624 +     /* update audit digest */
  40.625 +-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_OUT);
  40.626 +-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
  40.627 ++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_OUT);
  40.628 ++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
  40.629 +     sha1_init(&sha1_ctx);
  40.630 +     sha1_update(&sha1_ctx, rsp->param, rsp->paramSize);
  40.631 +     sha1_final(&sha1_ctx, &buf[6]);
  40.632 +-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
  40.633 ++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
  40.634 +     memset(&buf[30], 0, 4);
  40.635 +-    *((UINT32*)&buf[34]) = cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
  40.636 +-    *((UINT32*)&buf[34]) = cpu_to_be32(rsp->result);
  40.637 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
  40.638 ++    *((UINT32*)&buf[34]) = CPU_TO_BE32(rsp->result);
  40.639 +     sha1_init(&sha1_ctx);
  40.640 +     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
  40.641 +       sizeof(TPM_DIGEST));
  40.642 +@@ -158,7 +159,7 @@ TPM_RESULT TPM_GetAuditDigestSigned(TPM_
  40.643 +   }
  40.644 +   memcpy(&buf[0], "\x05\x00ADIG", 6);
  40.645 +   memcpy(&buf[6], antiReplay->nonce, 20);
  40.646 +-  *(UINT32*)&buf[26] = cpu_to_be32(buf_size - 30);
  40.647 ++  *(UINT32*)&buf[26] = CPU_TO_BE32(buf_size - 30);
  40.648 +   memcpy(&buf[30], auditDigest->digest, 20);
  40.649 +   ptr = &buf[50];
  40.650 +   len = buf_size - 50;
  40.651 +@@ -198,4 +199,3 @@ TPM_RESULT TPM_SetOrdinalAuditStatus(TPM
  40.652 +   }
  40.653 +   return TPM_SUCCESS;
  40.654 + }
  40.655 +-
  40.656 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c tpm_emulator/tpm/tpm_authorization.c
  40.657 +--- tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c	2006-08-29 15:07:21.620298760 -0700
  40.658 ++++ tpm_emulator/tpm/tpm_authorization.c	2006-08-29 15:26:17.108678288 -0700
  40.659 +@@ -1,6 +1,7 @@
  40.660 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  40.661 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.662 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  40.663 ++ * Copyright (C) 2005 INTEL Corp
  40.664 +  *
  40.665 +  * This module is free software; you can redistribute it and/or modify
  40.666 +  * it under the terms of the GNU General Public License as published
  40.667 +@@ -279,7 +280,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
  40.668 + {
  40.669 +   hmac_ctx_t ctx;
  40.670 +   TPM_SESSION_DATA *session;
  40.671 +-  UINT32 auth_handle = cpu_to_be32(auth->authHandle);
  40.672 ++  UINT32 auth_handle = CPU_TO_BE32(auth->authHandle);
  40.673 +   
  40.674 +   info("tpm_verify_auth(%08x)", auth->authHandle);
  40.675 +   /* get dedicated authorization or transport session */
  40.676 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_capability.c tpm_emulator/tpm/tpm_capability.c
  40.677 +--- tpm_emulator-0.3-x86_64/tpm/tpm_capability.c	2006-08-29 15:07:21.620298760 -0700
  40.678 ++++ tpm_emulator/tpm/tpm_capability.c	2006-08-29 15:26:17.109678136 -0700
  40.679 +@@ -1,6 +1,7 @@
  40.680 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  40.681 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.682 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  40.683 ++ * Copyright (C) 2005 INTEL Corp
  40.684 +  *
  40.685 +  * This module is free software; you can redistribute it and/or modify
  40.686 +  * it under the terms of the GNU General Public License as published
  40.687 +@@ -406,7 +407,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
  40.688 + 
  40.689 +     case TPM_CAP_KEY_HANDLE:
  40.690 +       debug("[TPM_CAP_KEY_HANDLE]");
  40.691 +-      subCapSize = cpu_to_be32(TPM_RT_KEY);
  40.692 ++      subCapSize = CPU_TO_BE32(TPM_RT_KEY);
  40.693 +       return cap_handle(4, (BYTE*)&subCapSize, respSize, resp);
  40.694 + 
  40.695 +     case TPM_CAP_CHECK_LOADED:
  40.696 +@@ -480,4 +481,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
  40.697 +       return TPM_BAD_MODE;
  40.698 +   }
  40.699 + }
  40.700 +-
  40.701 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c tpm_emulator/tpm/tpm_cmd_handler.c
  40.702 +--- tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c	2006-08-29 15:07:21.621298608 -0700
  40.703 ++++ tpm_emulator/tpm/tpm_cmd_handler.c	2006-08-29 15:26:17.113677528 -0700
  40.704 +@@ -1,6 +1,7 @@
  40.705 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  40.706 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.707 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
  40.708 ++ * Copyright (C) 2005 INTEL Corp
  40.709 +  *
  40.710 +  * This module is free software; you can redistribute it and/or modify
  40.711 +  * it under the terms of the GNU General Public License as published
  40.712 +@@ -73,7 +74,7 @@ void tpm_compute_in_param_digest(TPM_REQ
  40.713 + {
  40.714 +   sha1_ctx_t sha1;
  40.715 +   UINT32 offset = tpm_get_param_offset(req->ordinal);
  40.716 +-  UINT32 ord = cpu_to_be32(req->ordinal);
  40.717 ++  UINT32 ord = CPU_TO_BE32(req->ordinal);
  40.718 + 
  40.719 +   /* compute SHA1 hash */
  40.720 +   if (offset <= req->paramSize) {
  40.721 +@@ -89,8 +90,8 @@ void tpm_compute_in_param_digest(TPM_REQ
  40.722 + void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
  40.723 + {
  40.724 +   sha1_ctx_t sha1;
  40.725 +-  UINT32 res = cpu_to_be32(rsp->result);
  40.726 +-  UINT32 ord = cpu_to_be32(ordinal);
  40.727 ++  UINT32 res = CPU_TO_BE32(rsp->result);
  40.728 ++  UINT32 ord = CPU_TO_BE32(ordinal);
  40.729 + 
  40.730 +   /* compute SHA1 hash */
  40.731 +   sha1_init(&sha1);
  40.732 +@@ -3123,7 +3124,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
  40.733 +       hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
  40.734 + #if 0
  40.735 +       if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) {
  40.736 +-        UINT32 handle = cpu_to_be32(rsp->auth2->authHandle);
  40.737 ++        UINT32 handle = CPU_TO_BE32(rsp->auth2->authHandle);
  40.738 +         hmac_update(&hmac, (BYTE*)&handle, 4);
  40.739 +       }
  40.740 + #endif
  40.741 +@@ -3138,7 +3139,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
  40.742 +       hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
  40.743 + #if 0
  40.744 +       if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) {
  40.745 +-        UINT32 handle = cpu_to_be32(rsp->auth1->authHandle);
  40.746 ++        UINT32 handle = CPU_TO_BE32(rsp->auth1->authHandle);
  40.747 +         hmac_update(&hmac, (BYTE*)&handle, 4);
  40.748 +       }
  40.749 + #endif
  40.750 +@@ -3221,7 +3222,9 @@ extern const char *tpm_error_to_string(T
  40.751 + void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
  40.752 + {
  40.753 +   TPM_RESULT res;
  40.754 +-  
  40.755 ++
  40.756 ++  req->tag = (BYTE) req->tag;  // FIXME: Why is this here
  40.757 ++
  40.758 +   /* setup authorisation as well as response tag and size */
  40.759 +   memset(rsp, 0, sizeof(*rsp));
  40.760 +   switch (req->tag) {
  40.761 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c tpm_emulator/tpm/tpm_crypto.c
  40.762 +--- tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c	2006-08-29 15:07:43.531967680 -0700
  40.763 ++++ tpm_emulator/tpm/tpm_crypto.c	2006-08-29 15:26:17.114677376 -0700
  40.764  @@ -1,6 +1,7 @@
  40.765   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  40.766    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  40.767 @@ -130,15 +699,1043 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  40.768    *
  40.769    * This module is free software; you can redistribute it and/or modify
  40.770    * it under the terms of the GNU General Public License as published
  40.771 -@@ -85,6 +86,11 @@ void tpm_init_data(void)
  40.772 -   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
  40.773 -   /* setup PCR attributes */
  40.774 -   for (i = 0; i < TPM_NUM_PCR; i++) {
  40.775 -+    int j;
  40.776 -+    for (j=0; j < TPM_NUM_LOCALITY; j++) {
  40.777 -+      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
  40.778 +@@ -106,7 +107,7 @@ TPM_RESULT tpm_sign(TPM_KEY_DATA *key, T
  40.779 +     /* setup TPM_SIGN_INFO structure */
  40.780 +     memcpy(&buf[0], "\x05\x00SIGN", 6);
  40.781 +     memcpy(&buf[6], auth->nonceOdd.nonce, 20);
  40.782 +-    *(UINT32*)&buf[26] = cpu_to_be32(areaToSignSize);
  40.783 ++    *(UINT32*)&buf[26] = CPU_TO_BE32(areaToSignSize);
  40.784 +     memcpy(&buf[30], areaToSign, areaToSignSize);
  40.785 +     if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, 
  40.786 +         buf, areaToSignSize + 30, *sig)) {
  40.787 +@@ -383,4 +384,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
  40.788 +   }
  40.789 +   return TPM_SUCCESS;
  40.790 + }
  40.791 +-
  40.792 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_daa.c tpm_emulator/tpm/tpm_daa.c
  40.793 +--- tpm_emulator-0.3-x86_64/tpm/tpm_daa.c	2006-08-29 15:07:21.622298456 -0700
  40.794 ++++ tpm_emulator/tpm/tpm_daa.c	2006-08-29 15:26:17.119676616 -0700
  40.795 +@@ -700,14 +700,14 @@ info("tested until here");
  40.796 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.797 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.798 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.799 +-      sha1_update(&sha1, "\x00", 1);
  40.800 ++      sha1_update(&sha1, (BYTE *) "\x00", 1);
  40.801 +       sha1_final(&sha1, scratch);
  40.802 +       sha1_init(&sha1);
  40.803 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
  40.804 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.805 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.806 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.807 +-      sha1_update(&sha1, "\x01", 1);
  40.808 ++      sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.809 +       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  40.810 +       mpz_init(f), mpz_init(q);
  40.811 +       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  40.812 +@@ -787,14 +787,14 @@ info("tested until here");
  40.813 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.814 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.815 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.816 +-      sha1_update(&sha1, "\x00", 1);
  40.817 ++      sha1_update(&sha1, (BYTE *) "\x00", 1);
  40.818 +       sha1_final(&sha1, scratch);
  40.819 +       sha1_init(&sha1);
  40.820 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
  40.821 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.822 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.823 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.824 +-      sha1_update(&sha1, "\x01", 1);
  40.825 ++      sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.826 +       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  40.827 +       mpz_init(f), mpz_init(q);
  40.828 +       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  40.829 +@@ -1440,14 +1440,14 @@ info("tested until here");
  40.830 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.831 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.832 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.833 +-      sha1_update(&sha1, "\x00", 1);
  40.834 ++      sha1_update(&sha1, (BYTE *) "\x00", 1);
  40.835 +       sha1_final(&sha1, scratch);
  40.836 +       sha1_init(&sha1);
  40.837 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
  40.838 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.839 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.840 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.841 +-      sha1_update(&sha1, "\x01", 1);
  40.842 ++      sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.843 +       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  40.844 +       mpz_init(f), mpz_init(q);
  40.845 +       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  40.846 +@@ -1660,14 +1660,14 @@ info("tested until here");
  40.847 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.848 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.849 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.850 +-      sha1_update(&sha1, "\x00", 1);
  40.851 ++      sha1_update(&sha1, (BYTE *) "\x00", 1);
  40.852 +       sha1_final(&sha1, scratch);
  40.853 +       sha1_init(&sha1);
  40.854 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
  40.855 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.856 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.857 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.858 +-      sha1_update(&sha1, "\x01", 1);
  40.859 ++      sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.860 +       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  40.861 +       mpz_init(f), mpz_init(q);
  40.862 +       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  40.863 +@@ -1740,14 +1740,14 @@ info("tested until here");
  40.864 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.865 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.866 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.867 +-      sha1_update(&sha1, "\x00", 1);
  40.868 ++      sha1_update(&sha1, (BYTE *) "\x00", 1);
  40.869 +       sha1_final(&sha1, scratch);
  40.870 +       sha1_init(&sha1);
  40.871 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
  40.872 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.873 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.874 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.875 +-      sha1_update(&sha1, "\x01", 1);
  40.876 ++      sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.877 +       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  40.878 +       mpz_init(f), mpz_init(q);
  40.879 +       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  40.880 +@@ -2828,14 +2828,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
  40.881 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.882 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.883 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.884 +-      sha1_update(&sha1, "\x00", 1);
  40.885 ++      sha1_update(&sha1, (BYTE *) "\x00", 1);
  40.886 +       sha1_final(&sha1, scratch);
  40.887 +       sha1_init(&sha1);
  40.888 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
  40.889 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.890 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.891 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.892 +-      sha1_update(&sha1, "\x01", 1);
  40.893 ++      sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.894 +       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  40.895 +       mpz_init(f), mpz_init(q);
  40.896 +       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  40.897 +@@ -3050,7 +3050,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
  40.898 +         sha1_init(&sha1);
  40.899 +         sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest, 
  40.900 +           sizeof(session->DAA_session.DAA_digest));
  40.901 +-        sha1_update(&sha1, "\x01", 1);
  40.902 ++        sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.903 +         sha1_update(&sha1, inputData1, inputSize1);
  40.904 +         sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
  40.905 +       }
  40.906 +@@ -3078,7 +3078,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
  40.907 +         sha1_init(&sha1);
  40.908 +         sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest, 
  40.909 +           sizeof(session->DAA_session.DAA_digest));
  40.910 +-        sha1_update(&sha1, "\x01", 1);
  40.911 ++        sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.912 +         rsa_export_modulus(&aikData->key, scratch, &size);
  40.913 +         sha1_update(&sha1, scratch, size);
  40.914 +         sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
  40.915 +@@ -3134,14 +3134,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
  40.916 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.917 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.918 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.919 +-      sha1_update(&sha1, "\x00", 1);
  40.920 ++      sha1_update(&sha1, (BYTE *) "\x00", 1);
  40.921 +       sha1_final(&sha1, scratch);
  40.922 +       sha1_init(&sha1);
  40.923 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
  40.924 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.925 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.926 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.927 +-      sha1_update(&sha1, "\x01", 1);
  40.928 ++      sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.929 +       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  40.930 +       mpz_init(f), mpz_init(q);
  40.931 +       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  40.932 +@@ -3213,14 +3213,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
  40.933 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.934 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.935 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.936 +-      sha1_update(&sha1, "\x00", 1);
  40.937 ++      sha1_update(&sha1, (BYTE *) "\x00", 1);
  40.938 +       sha1_final(&sha1, scratch);
  40.939 +       sha1_init(&sha1);
  40.940 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
  40.941 +           sizeof(session->DAA_tpmSpecific.DAA_rekey));
  40.942 +       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  40.943 +           sizeof(session->DAA_tpmSpecific.DAA_count));
  40.944 +-      sha1_update(&sha1, "\x01", 1);
  40.945 ++      sha1_update(&sha1, (BYTE *) "\x01", 1);
  40.946 +       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  40.947 +       mpz_init(f), mpz_init(q);
  40.948 +       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  40.949 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c tpm_emulator/tpm/tpm_data.c
  40.950 +--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c	2006-08-29 15:08:20.535342312 -0700
  40.951 ++++ tpm_emulator/tpm/tpm_data.c	2006-08-29 15:26:17.121676312 -0700
  40.952 +@@ -150,44 +150,43 @@ void tpm_release_data(void)
  40.953 + 
  40.954 + #ifdef TPM_STORE_TO_FILE
  40.955 + 
  40.956 +-#include <linux/fs.h>
  40.957 +-#include <linux/unistd.h>
  40.958 +-#include <asm/uaccess.h>
  40.959 ++#include <sys/types.h>
  40.960 ++#include <sys/stat.h>
  40.961 ++#include <fcntl.h>
  40.962 ++#include <unistd.h>
  40.963 + 
  40.964 + #define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR) 
  40.965 + 
  40.966 + static int write_to_file(uint8_t *data, size_t data_length)
  40.967 + {
  40.968 +   int res;
  40.969 +-  struct file *fp;
  40.970 +-  mm_segment_t old_fs = get_fs();
  40.971 +-  fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
  40.972 +-  if (IS_ERR(fp)) return -1;
  40.973 +-  set_fs(get_ds());
  40.974 +-  res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
  40.975 +-  set_fs(old_fs);
  40.976 +-  filp_close(fp, NULL);
  40.977 ++  int fp;
  40.978 ++  fp = open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
  40.979 ++  res = write(fp, data, data_length);
  40.980 ++  close(fp);
  40.981 +   return (res == data_length) ? 0 : -1;
  40.982 + }
  40.983 + 
  40.984 + static int read_from_file(uint8_t **data, size_t *data_length)
  40.985 + {
  40.986 +   int res;
  40.987 +-  struct file *fp;
  40.988 +-  mm_segment_t old_fs = get_fs();
  40.989 +-  fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
  40.990 +-  if (IS_ERR(fp)) return -1;
  40.991 +-  *data_length = (size_t)fp->f_dentry->d_inode->i_size;
  40.992 +-  /* *data_length = i_size_read(fp->f_dentry->d_inode); */
  40.993 ++  int fp, file_status;
  40.994 ++  struct stat file_info;
  40.995 ++  fp = open(TPM_STORAGE_FILE, O_RDONLY, 0);
  40.996 ++  file_status = fstat(fp, &file_info);
  40.997 ++  if (file_status < 0) {
  40.998 ++    close(fp);
  40.999 ++    return -1;
 40.1000 ++  } 
 40.1001 ++
 40.1002 ++  *data_length = file_info.st_size; 
 40.1003 +   *data = tpm_malloc(*data_length);
 40.1004 +   if (*data == NULL) {
 40.1005 +-    filp_close(fp, NULL);
 40.1006 ++    close(fp);
 40.1007 +     return -1;
 40.1008 +   }
 40.1009 +-  set_fs(get_ds());
 40.1010 +-  res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
 40.1011 +-  set_fs(old_fs);
 40.1012 +-  filp_close(fp, NULL);
 40.1013 ++  res = read(fp, *data, *data_length);
 40.1014 ++  close(fp);
 40.1015 +   if (res != *data_length) {
 40.1016 +     tpm_free(*data);
 40.1017 +     return -1;
 40.1018 +@@ -278,7 +277,7 @@ int tpm_restore_permanent_data(void)
 40.1019 + 
 40.1020 + int tpm_erase_permanent_data(void)
 40.1021 + {
 40.1022 +-  int res = write_to_file("", 0);
 40.1023 ++  int res = write_to_file((uint8_t *) "", 0);
 40.1024 +   return res;
 40.1025 + }
 40.1026 + 
 40.1027 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c.orig tpm_emulator/tpm/tpm_data.c.orig
 40.1028 +--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c.orig	1969-12-31 16:00:00.000000000 -0800
 40.1029 ++++ tpm_emulator/tpm/tpm_data.c.orig	2006-08-29 15:26:08.469991568 -0700
 40.1030 +@@ -0,0 +1,284 @@
 40.1031 ++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 40.1032 ++ * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 40.1033 ++ *                    Swiss Federal Institute of Technology (ETH) Zurich
 40.1034 ++ *
 40.1035 ++ * This module is free software; you can redistribute it and/or modify
 40.1036 ++ * it under the terms of the GNU General Public License as published
 40.1037 ++ * by the Free Software Foundation; either version 2 of the License,
 40.1038 ++ * or (at your option) any later version.
 40.1039 ++ *
 40.1040 ++ * This module is distributed in the hope that it will be useful,
 40.1041 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 40.1042 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 40.1043 ++ * GNU General Public License for more details.
 40.1044 ++ *
 40.1045 ++ * $Id: tpm_data.c 36 2005-10-26 20:31:19Z hstamer $
 40.1046 ++ */
 40.1047 ++
 40.1048 ++#include "tpm_emulator.h"
 40.1049 ++#include "tpm_structures.h"
 40.1050 ++#include "tpm_marshalling.h"
 40.1051 ++#include "linux_module.h"
 40.1052 ++
 40.1053 ++TPM_DATA tpmData;
 40.1054 ++
 40.1055 ++BOOL tpm_get_physical_presence(void)
 40.1056 ++{
 40.1057 ++  return (tpmData.stclear.flags.physicalPresence || TRUE);
 40.1058 ++}
 40.1059 ++
 40.1060 ++static inline void init_pcr_attr(int pcr, BOOL reset, BYTE rl, BYTE el)
 40.1061 ++{
 40.1062 ++  int i;
 40.1063 ++  tpmData.permanent.data.pcrAttrib[pcr].pcrReset = reset;
 40.1064 ++  for (i = 0; i < TPM_NUM_LOCALITY; i++) {
 40.1065 ++    tpmData.permanent.data.pcrAttrib[pcr].pcrResetLocal[i] = (rl & (1 << i));
 40.1066 ++    tpmData.permanent.data.pcrAttrib[pcr].pcrExtendLocal[i] = (el & (1 << i));
 40.1067 ++  }
 40.1068 ++}
 40.1069 ++
 40.1070 ++void tpm_init_data(void)
 40.1071 ++{
 40.1072 ++  /* endorsement key */
 40.1073 ++  uint8_t ek_n[] =  "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7"
 40.1074 ++    "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93"
 40.1075 ++    "\x92\xeb\xd1\x96\x2b\x72\x18\x81\x79\x12\x9d\x9c\x40\xd7\x1a"
 40.1076 ++    "\x21\xda\x5f\x56\xe0\xc9\x48\x31\xdd\x96\xdc\xbb\x45\xc6\x8e"
 40.1077 ++    "\xad\x58\x23\xcb\xbe\xbb\x13\x2d\x6b\x86\xc5\x57\xf5\xdd\x48"
 40.1078 ++    "\xc1\x3d\xcd\x4d\xda\x81\xc4\x43\x17\xaa\x05\x40\x33\x62\x0a"
 40.1079 ++    "\x59\xdb\x28\xcd\xb5\x08\x31\xbb\x06\xf5\xf7\x71\xae\x21\xa8"
 40.1080 ++    "\xf2\x2f\x0e\x17\x80\x5d\x9c\xdf\xaa\xe9\x89\x09\x54\x65\x2b"
 40.1081 ++    "\x46\xfb\x9d\xb2\x00\x70\x63\x0d\x9a\x6d\x3d\x5e\x11\x78\x65"
 40.1082 ++    "\x90\xe6\x26\xee\x77\xbe\x08\xff\x07\x60\x5a\xcc\xf1\x0a\xbd"
 40.1083 ++    "\x44\x92\x6b\xca\xb6\xce\x66\xf9\x93\x40\xae\xf3\x3e\x53\x02"
 40.1084 ++    "\x3c\xa6\x81\xb3\xbe\xad\x6e\x6c\xa6\xf0\xeb\xdf\xe9\xa2\x83"
 40.1085 ++    "\x36\x0e\x52\x0d\x64\x17\xd9\xff\xa1\x74\x7c\x2b\xbc\x6a\xcc"
 40.1086 ++    "\xe5\x4e\xb4\x52\xd9\xec\x43\xbd\x26\x6a\x2b\x19\x19\x6e\x97"
 40.1087 ++    "\xb8\x1d\x9f\x7b\xe7\x32\x2d\xdd\x7c\x51\xc8\xe4\xf3\x02\xd4"
 40.1088 ++    "\x7c\x90\x44\xa0\x33\x72\x81\x75\xa9\x16\x27\x5c\x00\x1d\x07"
 40.1089 ++    "\x81\xd4\xf7\xac\xcb\xfe\xd6\x60\x03\x6f\x7a\xcc\x00\xd1\xc4"
 40.1090 ++    "\x85\x37";
 40.1091 ++  uint8_t ek_e[] = "\x01\x00\x01";
 40.1092 ++  uint8_t ek_p[] = "\xd7\xea\x61\x15\x8b\xa3\x71\xdf\xa8\x74\x77\xca\x88\x95"
 40.1093 ++    "\xd0\x76\x17\x43\x2c\xf6\x23\x27\x44\xb9\x0e\x18\x35\x7e\xe4"
 40.1094 ++    "\xc3\xcb\x13\x6e\xfc\x38\x02\x1e\x77\x26\x40\x9d\x17\xb2\x39"
 40.1095 ++    "\x9c\x7f\x5f\x98\xe6\xf2\x55\x0c\x12\x05\x4c\xb3\x51\xae\x29"
 40.1096 ++    "\xe7\xcd\xce\x41\x0b\x28\x4d\x97\x13\x4b\x60\xc8\xd8\x70\x81"
 40.1097 ++    "\xf9\x1c\x12\x44\xdf\x53\x0a\x87\x9d\x33\x92\x4a\x34\x69\xf0"
 40.1098 ++    "\x70\x5e\x1b\x5d\x65\xc7\x84\x90\xa2\x62\xdf\x83\x14\x10\x69"
 40.1099 ++    "\xe2\xa7\x18\x43\xd7\x1f\x60\xc9\x03\x8f\xd6\xa4\xce\xb2\x9d"
 40.1100 ++    "\x40\x37\x70\x17\x4c\xe3\x69\xd4\x59";
 40.1101 ++  uint8_t ek_q[] = "\xc8\x34\xd2\xd0\x7c\xfa\xdc\x68\xe2\x72\xd7\x92\xe2\x50"
 40.1102 ++    "\x93\xfc\xbb\x72\x55\x4d\x6b\x7a\x0c\x0b\xcf\x87\x66\x1f\x81"
 40.1103 ++    "\x71\xf3\x50\xcb\xaa\xe6\x43\x7e\xbe\x11\xc4\xec\x00\x53\xf4"
 40.1104 ++    "\x78\x13\x2b\x59\x26\x4a\x9f\x91\x61\x8f\xa7\x07\x64\x11\x5a"
 40.1105 ++    "\xf4\xaf\x9c\x9b\x5a\x5d\x69\x20\x17\x55\x74\xba\xd8\xe4\x59"
 40.1106 ++    "\x39\x1a\x0a\x7b\x4a\x30\xf0\xc8\x7f\xd9\xaf\x72\xc5\xb6\x71"
 40.1107 ++    "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b"
 40.1108 ++    "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47"
 40.1109 ++    "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f";
 40.1110 ++  int i;
 40.1111 ++  /* reset all data to NULL, FALSE or 0 */
 40.1112 ++  memset(&tpmData, 0, sizeof(tpmData));
 40.1113 ++  tpmData.permanent.data.tag = TPM_TAG_PERMANENT_DATA;
 40.1114 ++  /* set permanent flags */
 40.1115 ++  tpmData.permanent.flags.tag = TPM_TAG_PERMANENT_FLAGS;
 40.1116 ++  tpmData.permanent.flags.disable = FALSE;
 40.1117 ++  tpmData.permanent.flags.deactivated = FALSE;
 40.1118 ++  tpmData.permanent.flags.ownership = TRUE;
 40.1119 ++  tpmData.permanent.flags.readPubek = TRUE;
 40.1120 ++  tpmData.permanent.flags.allowMaintenance = TRUE;
 40.1121 ++  tpmData.permanent.flags.enableRevokeEK = TRUE;
 40.1122 ++  /* set TPM vision */
 40.1123 ++  tpmData.permanent.data.version.major = 1;
 40.1124 ++  tpmData.permanent.data.version.minor = 2;
 40.1125 ++  tpmData.permanent.data.version.revMajor = VERSION_MAJOR;
 40.1126 ++  tpmData.permanent.data.version.revMinor = VERSION_MINOR;
 40.1127 ++  /* setup PCR attributes */
 40.1128 ++  for (i = 0; i < min(16, TPM_NUM_PCR); i++) {
 40.1129 ++    init_pcr_attr(i, FALSE, 0x00, 0x1f);
 40.1130 ++  }
 40.1131 ++  if (TPM_NUM_PCR >= 24) {
 40.1132 ++    init_pcr_attr(16, TRUE, 0x1f, 0x1f);
 40.1133 ++    init_pcr_attr(17, TRUE, 0x10, 0x1c);
 40.1134 ++    init_pcr_attr(18, TRUE, 0x10, 0x1c);
 40.1135 ++    init_pcr_attr(19, TRUE, 0x10, 0x0c);
 40.1136 ++    init_pcr_attr(20, TRUE, 0x14, 0x0e);
 40.1137 ++    init_pcr_attr(21, TRUE, 0x04, 0x04);
 40.1138 ++    init_pcr_attr(22, TRUE, 0x04, 0x04);
 40.1139 ++    init_pcr_attr(23, TRUE, 0x1f, 0x1f);
 40.1140 ++  }
 40.1141 ++  for (i = 24; i < TPM_NUM_PCR; i++) {
 40.1142 ++    init_pcr_attr(i, TRUE, 0x00, 0x00);
 40.1143 ++  }
 40.1144 ++  /* set tick type */
 40.1145 ++  tpmData.permanent.data.tickType = TICK_INC;
 40.1146 ++#ifdef TPM_GENERATE_EK
 40.1147 ++  /* generate a new endorsement key */
 40.1148 ++  rsa_generate_key(&tpmData.permanent.data.endorsementKey, 2048);
 40.1149 ++#else
 40.1150 ++  /* setup endorsement key */
 40.1151 ++  rsa_import_key(&tpmData.permanent.data.endorsementKey, 
 40.1152 ++    RSA_MSB_FIRST, ek_n, 256, ek_e, 3, ek_p, ek_q);
 40.1153 ++#endif
 40.1154 ++#ifdef TPM_GENERATE_SEED_DAA
 40.1155 ++  /* generate the DAA seed (cf. [TPM_Part2], v1.2 rev 85, Section 7.4) */
 40.1156 ++  tpm_get_random_bytes(tpmData.permanent.data.tpmDAASeed.digest, 
 40.1157 ++    sizeof(tpmData.permanent.data.tpmDAASeed.digest));
 40.1158 ++#else
 40.1159 ++  /* FIXME: setup DAA seed */
 40.1160 ++  memcpy(tpmData.permanent.data.tpmDAASeed.digest, 
 40.1161 ++    "\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
 40.1162 ++    "\x00\x00\x00\x77", 20);
 40.1163 ++#endif
 40.1164 ++
 40.1165 ++  memcpy(tpmData.permanent.data.ekReset.nonce, "\xde\xad\xbe\xef", 4);
 40.1166 ++}
 40.1167 ++
 40.1168 ++void tpm_release_data(void)
 40.1169 ++{
 40.1170 ++  int i;
 40.1171 ++  /* release the EK, SRK as well as all other rsa keys */
 40.1172 ++  if (tpmData.permanent.data.endorsementKey.size > 0)
 40.1173 ++    rsa_release_private_key(&tpmData.permanent.data.endorsementKey);
 40.1174 ++  if (tpmData.permanent.data.srk.valid)
 40.1175 ++    rsa_release_private_key(&tpmData.permanent.data.srk.key);
 40.1176 ++  for (i = 0; i < TPM_MAX_KEYS; i++)
 40.1177 ++    if (tpmData.permanent.data.keys[i].valid)
 40.1178 ++      rsa_release_private_key(&tpmData.permanent.data.keys[i].key);
 40.1179 ++}
 40.1180 ++
 40.1181 ++#ifdef TPM_STORE_TO_FILE
 40.1182 ++
 40.1183 ++#include <linux/fs.h>
 40.1184 ++#include <linux/unistd.h>
 40.1185 ++#include <asm/uaccess.h>
 40.1186 ++
 40.1187 ++#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR) 
 40.1188 ++
 40.1189 ++static int write_to_file(uint8_t *data, size_t data_length)
 40.1190 ++{
 40.1191 ++  int res;
 40.1192 ++  struct file *fp;
 40.1193 ++  mm_segment_t old_fs = get_fs();
 40.1194 ++  fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
 40.1195 ++  if (IS_ERR(fp)) return -1;
 40.1196 ++  set_fs(get_ds());
 40.1197 ++  res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
 40.1198 ++  set_fs(old_fs);
 40.1199 ++  filp_close(fp, NULL);
 40.1200 ++  return (res == data_length) ? 0 : -1;
 40.1201 ++}
 40.1202 ++
 40.1203 ++static int read_from_file(uint8_t **data, size_t *data_length)
 40.1204 ++{
 40.1205 ++  int res;
 40.1206 ++  struct file *fp;
 40.1207 ++  mm_segment_t old_fs = get_fs();
 40.1208 ++  fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
 40.1209 ++  if (IS_ERR(fp)) return -1;
 40.1210 ++  *data_length = (size_t)fp->f_dentry->d_inode->i_size;
 40.1211 ++  /* *data_length = i_size_read(fp->f_dentry->d_inode); */
 40.1212 ++  *data = tpm_malloc(*data_length);
 40.1213 ++  if (*data == NULL) {
 40.1214 ++    filp_close(fp, NULL);
 40.1215 ++    return -1;
 40.1216 ++  }
 40.1217 ++  set_fs(get_ds());
 40.1218 ++  res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
 40.1219 ++  set_fs(old_fs);
 40.1220 ++  filp_close(fp, NULL);
 40.1221 ++  if (res != *data_length) {
 40.1222 ++    tpm_free(*data);
 40.1223 ++    return -1;
 40.1224 ++  }
 40.1225 ++  return 0;
 40.1226 ++}
 40.1227 ++
 40.1228 ++#else
 40.1229 ++
 40.1230 ++static int write_to_file(uint8_t *data, size_t data_length)
 40.1231 ++{
 40.1232 ++  info("TPM_STORE_TO_FILE disabled, no data written");
 40.1233 ++  return 0;
 40.1234 ++}
 40.1235 ++
 40.1236 ++static int read_from_file(uint8_t **data, size_t *data_length)
 40.1237 ++{
 40.1238 ++  info("TPM_STORE_TO_FILE disabled, no data read");
 40.1239 ++  return 0;
 40.1240 ++}
 40.1241 ++
 40.1242 ++#endif /* TPM_STORE_TO_FILE */
 40.1243 ++
 40.1244 ++int tpm_store_permanent_data(void)
 40.1245 ++{
 40.1246 ++  uint8_t *buf, *ptr;
 40.1247 ++  UINT32 buf_length, len;
 40.1248 ++
 40.1249 ++  /* marshal data */
 40.1250 ++  buf_length = len = 4 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
 40.1251 ++    + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) 
 40.1252 ++    + sizeof_TPM_STANY_FLAGS(tpmData.stany.flags) + 2
 40.1253 ++    + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data) 
 40.1254 ++    + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data)
 40.1255 ++    + sizeof_TPM_STANY_DATA(tpmData.stany.data);
 40.1256 ++  buf = ptr = tpm_malloc(buf_length);
 40.1257 ++  if (buf == NULL
 40.1258 ++      || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version)
 40.1259 ++      || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
 40.1260 ++      || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)
 40.1261 ++      || tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
 40.1262 ++      || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.selfTestSucceeded)
 40.1263 ++      || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned)
 40.1264 ++      || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
 40.1265 ++      || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
 40.1266 ++      || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
 40.1267 ++    tpm_free(buf);
 40.1268 ++    return -1;
 40.1269 ++  }
 40.1270 ++
 40.1271 ++  if (write_to_file(buf, buf_length - len)) {
 40.1272 ++    tpm_free(buf);
 40.1273 ++    return -1; 
 40.1274 ++  }
 40.1275 ++  tpm_free(buf);
 40.1276 ++  return 0;
 40.1277 ++}
 40.1278 ++
 40.1279 ++int tpm_restore_permanent_data(void)
 40.1280 ++{
 40.1281 ++  uint8_t *buf, *ptr;
 40.1282 ++  size_t buf_length;
 40.1283 ++  UINT32 len;
 40.1284 ++  TPM_VERSION ver;
 40.1285 ++
 40.1286 ++  /* read data */
 40.1287 ++  if (read_from_file(&buf, &buf_length)) return -1;
 40.1288 ++  ptr = buf;
 40.1289 ++  len = (uint32_t) buf_length;
 40.1290 ++  /* unmarshal data */
 40.1291 ++  if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
 40.1292 ++      || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION))
 40.1293 ++      || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
 40.1294 ++      || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)
 40.1295 ++      || tpm_unmarshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
 40.1296 ++      || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.selfTestSucceeded)
 40.1297 ++      || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned)
 40.1298 ++      || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
 40.1299 ++      || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
 40.1300 ++      || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
 40.1301 ++    tpm_free(buf);
 40.1302 ++    return -1;
 40.1303 ++  }
 40.1304 ++
 40.1305 ++  tpm_free(buf);
 40.1306 ++  return 0;
 40.1307 ++}
 40.1308 ++
 40.1309 ++int tpm_erase_permanent_data(void)
 40.1310 ++{
 40.1311 ++  int res = write_to_file("", 0);
 40.1312 ++  return res;
 40.1313 ++}
 40.1314 ++
 40.1315 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c tpm_emulator/tpm/tpm_deprecated.c
 40.1316 +--- tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c	2006-08-29 15:07:21.622298456 -0700
 40.1317 ++++ tpm_emulator/tpm/tpm_deprecated.c	2006-08-29 15:26:17.122676160 -0700
 40.1318 +@@ -1,6 +1,7 @@
 40.1319 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 40.1320 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 40.1321 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 40.1322 ++ * Copyright (C) 2005 INTEL Corp
 40.1323 +  *
 40.1324 +  * This module is free software; you can redistribute it and/or modify
 40.1325 +  * it under the terms of the GNU General Public License as published
 40.1326 +@@ -50,7 +51,7 @@ TPM_RESULT TPM_SaveKeyContext(TPM_KEY_HA
 40.1327 +   BYTE *ptr;
 40.1328 +   UINT32 len;
 40.1329 +   info("TPM_SaveKeyContext()");
 40.1330 +-  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, "SaveKeyContext..", 
 40.1331 ++  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, (BYTE*)"SaveKeyContext..", 
 40.1332 +                         keyContextSize, &contextBlob);
 40.1333 +   if (res != TPM_SUCCESS) return res;
 40.1334 +   len = *keyContextSize;
 40.1335 +@@ -82,7 +83,7 @@ TPM_RESULT TPM_SaveAuthContext(TPM_AUTHH
 40.1336 +   BYTE *ptr;
 40.1337 +   UINT32 len;
 40.1338 +   info("TPM_SaveAuthContext()");
 40.1339 +-  res = TPM_SaveContext(authHandle, TPM_RT_KEY, "SaveAuthContext.", 
 40.1340 ++  res = TPM_SaveContext(authHandle, TPM_RT_KEY, (BYTE*)"SaveAuthContext.", 
 40.1341 +                         authContextSize, &contextBlob);
 40.1342 +   if (res != TPM_SUCCESS) return res;
 40.1343 +   len = *authContextSize;
 40.1344 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h tpm_emulator/tpm/tpm_emulator.h
 40.1345 +--- tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h	2006-08-29 15:07:21.648294504 -0700
 40.1346 ++++ tpm_emulator/tpm/tpm_emulator.h	2006-08-29 15:26:17.122676160 -0700
 40.1347 +@@ -1,5 +1,6 @@
 40.1348 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 40.1349 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 40.1350 ++ * Copyright (C) 2005 INTEL Corp
 40.1351 +  *
 40.1352 +  * This module is free software; you can redistribute it and/or modify
 40.1353 +  * it under the terms of the GNU General Public License as published
 40.1354 +@@ -22,7 +23,8 @@
 40.1355 + /* TPM configuration */
 40.1356 + #define TPM_STORE_TO_FILE       1
 40.1357 + #undef  TPM_STRONG_PERSISTENCE
 40.1358 +-#undef  TPM_GENERATE_EK
 40.1359 ++//#undef  TPM_GENERATE_EK
 40.1360 ++#define  TPM_GENERATE_EK
 40.1361 + #undef  TPM_GENERATE_SEED_DAA
 40.1362 + 
 40.1363 + #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */        
 40.1364 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c tpm_emulator/tpm/tpm_integrity.c
 40.1365 +--- tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c	2006-08-29 15:07:21.645294960 -0700
 40.1366 ++++ tpm_emulator/tpm/tpm_integrity.c	2006-08-29 15:26:17.123676008 -0700
 40.1367 +@@ -1,6 +1,7 @@
 40.1368 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 40.1369 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 40.1370 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 40.1371 ++ * Copyright (C) 2005 INTEL Corp
 40.1372 +  *
 40.1373 +  * This module is free software; you can redistribute it and/or modify
 40.1374 +  * it under the terms of the GNU General Public License as published
 40.1375 +@@ -194,4 +195,3 @@ TPM_RESULT tpm_verify_pcr(TPM_KEY_DATA *
 40.1376 +   }
 40.1377 +   return TPM_SUCCESS;
 40.1378 + }
 40.1379 +-
 40.1380 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_structures.h tpm_emulator/tpm/tpm_structures.h
 40.1381 +--- tpm_emulator-0.3-x86_64/tpm/tpm_structures.h	2006-08-29 15:08:20.545340792 -0700
 40.1382 ++++ tpm_emulator/tpm/tpm_structures.h	2006-08-29 15:26:17.125675704 -0700
 40.1383 +@@ -1,6 +1,7 @@
 40.1384 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 40.1385 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 40.1386 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 40.1387 ++ * Copyright (C) 2005 INTEL Corp
 40.1388 +  *
 40.1389 +  * This module is free software; you can redistribute it and/or modify
 40.1390 +  * it under the terms of the GNU General Public License as published
 40.1391 +@@ -18,7 +19,7 @@
 40.1392 + #ifndef _TPM_STRUCTURES_H_
 40.1393 + #define _TPM_STRUCTURES_H_
 40.1394 + 
 40.1395 +-#include <linux/types.h>
 40.1396 ++//#include <linux/types.h>
 40.1397 + #include "crypto/rsa.h"
 40.1398 + 
 40.1399 + /*
 40.1400 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_testing.c tpm_emulator/tpm/tpm_testing.c
 40.1401 +--- tpm_emulator-0.3-x86_64/tpm/tpm_testing.c	2006-08-29 15:07:21.646294808 -0700
 40.1402 ++++ tpm_emulator/tpm/tpm_testing.c	2006-08-29 15:26:17.127675400 -0700
 40.1403 +@@ -1,6 +1,7 @@
 40.1404 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 40.1405 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 40.1406 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 40.1407 ++ * Copyright (C) 2005 INTEL Corp
 40.1408 +  *
 40.1409 +  * This module is free software; you can redistribute it and/or modify
 40.1410 +  * it under the terms of the GNU General Public License as published
 40.1411 +@@ -95,24 +96,24 @@ static int tpm_test_sha1(void)
 40.1412 +   struct {
 40.1413 +     uint8_t *data; uint32_t repetitions; uint8_t *digest;
 40.1414 +   } test_cases[] =  {{
 40.1415 +-    "abc", 1,
 40.1416 +-    "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
 40.1417 ++	(uint8_t*)"abc", 1,
 40.1418 ++    (uint8_t*)"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
 40.1419 +   }, {
 40.1420 +-    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
 40.1421 +-    "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
 40.1422 ++    (uint8_t*)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
 40.1423 ++    (uint8_t*)"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
 40.1424 +   }, {
 40.1425 +-    "a", 1000000,
 40.1426 +-    "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
 40.1427 ++    (uint8_t*)"a", 1000000,
 40.1428 ++    (uint8_t*)"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
 40.1429 +   }, {
 40.1430 +-    "0123456701234567012345670123456701234567012345670123456701234567", 10,
 40.1431 +-    "\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
 40.1432 ++    (uint8_t*)"0123456701234567012345670123456701234567012345670123456701234567", 10,
 40.1433 ++    (uint8_t*)"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
 40.1434 +   }};
 40.1435 + 
 40.1436 +   debug("tpm_test_sha1()");
 40.1437 +   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
 40.1438 +     sha1_init(&ctx);
 40.1439 +     for (j = 0; j < test_cases[i].repetitions; j++)
 40.1440 +-      sha1_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
 40.1441 ++      sha1_update(&ctx, test_cases[i].data, strlen((char*)test_cases[i].data));
 40.1442 +     sha1_final(&ctx, digest);
 40.1443 +     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return -1;
 40.1444 +   }
 40.1445 +@@ -128,41 +129,41 @@ static int tpm_test_hmac(void)
 40.1446 +   struct {
 40.1447 +     uint8_t *key, key_len, *data, data_len, *digest;
 40.1448 +   } test_cases[] = {{
 40.1449 +-    "\x0b", 20, "Hi There", 8,
 40.1450 +-    "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
 40.1451 ++    (uint8_t*)"\x0b", 20, (uint8_t*)"Hi There", 8,
 40.1452 ++    (uint8_t*)"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
 40.1453 +   }, {
 40.1454 +-    "Jefe", 4, "what do ya want for nothing?", 28,
 40.1455 +-    "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
 40.1456 ++    (uint8_t*)"Jefe", 4, (uint8_t*)"what do ya want for nothing?", 28,
 40.1457 ++    (uint8_t*)"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
 40.1458 +   }, {
 40.1459 +-    "\xaa", 20, "\xdd", 50,
 40.1460 +-    "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
 40.1461 ++    (uint8_t*)"\xaa", 20, (uint8_t*)"\xdd", 50,
 40.1462 ++    (uint8_t*)"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
 40.1463 +   }, {
 40.1464 +-    "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
 40.1465 +-    "\x15\x16\x17\x18\x19", 25, "\xcd", 50,
 40.1466 +-    "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
 40.1467 ++    (uint8_t*)"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
 40.1468 ++    "\x15\x16\x17\x18\x19", 25, (uint8_t*)"\xcd", 50,
 40.1469 ++    (uint8_t*)"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
 40.1470 +   }, {
 40.1471 +-    "\x0c", 20, "Test With Truncation", 20,
 40.1472 +-    "\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
 40.1473 ++    (uint8_t*)"\x0c", 20, (uint8_t*)"Test With Truncation", 20,
 40.1474 ++    (uint8_t*)"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
 40.1475 +   }, {
 40.1476 +-    "\xaa", 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54,
 40.1477 +-    "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
 40.1478 ++    (uint8_t*)"\xaa", 80, (uint8_t*)"Test Using Larger Than Block-Size Key - Hash Key First", 54,
 40.1479 ++    (uint8_t*)"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
 40.1480 +   }, {
 40.1481 +-    "\xaa", 80,
 40.1482 +-    "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
 40.1483 +-    "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
 40.1484 ++    (uint8_t*)"\xaa", 80,
 40.1485 ++    (uint8_t*)"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
 40.1486 ++    (uint8_t*)"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
 40.1487 +   }};
 40.1488 + 
 40.1489 +   debug("tpm_test_hmac()");
 40.1490 +   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
 40.1491 +-    if (strlen(test_cases[i].key) < test_cases[i].key_len) {
 40.1492 ++    if (strlen((char*)test_cases[i].key) < test_cases[i].key_len) {
 40.1493 +       uint8_t key[test_cases[i].key_len];
 40.1494 +       memset(key, test_cases[i].key[0], test_cases[i].key_len);
 40.1495 +       hmac_init(&ctx, key, test_cases[i].key_len);
 40.1496 +     } else {
 40.1497 +       hmac_init(&ctx, test_cases[i].key, test_cases[i].key_len);
 40.1498 +     }
 40.1499 +-    for (j = 0; j < test_cases[i].data_len; j += strlen(test_cases[i].data)) {
 40.1500 +-      hmac_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
 40.1501 ++    for (j = 0; j < test_cases[i].data_len; j += strlen((char*)test_cases[i].data)) {
 40.1502 ++      hmac_update(&ctx, test_cases[i].data, strlen((char*)test_cases[i].data));
 40.1503 +     }
 40.1504 +     hmac_final(&ctx, digest);
 40.1505 +     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return -1;
 40.1506 +@@ -173,9 +174,9 @@ static int tpm_test_hmac(void)
 40.1507 + static int tpm_test_rsa_EK(void)
 40.1508 + {
 40.1509 +   int res = 0;
 40.1510 +-  char *data = "RSA PKCS #1 v1.5 Test-String";
 40.1511 ++  uint8_t *data = (uint8_t*)"RSA PKCS #1 v1.5 Test-String";
 40.1512 +   uint8_t buf[256];
 40.1513 +-  size_t buf_len, data_len = strlen(data);
 40.1514 ++  size_t buf_len, data_len = strlen((char*)data);
 40.1515 +   rsa_private_key_t priv_key;
 40.1516 +   rsa_public_key_t pub_key;
 40.1517 + 
 40.1518 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c tpm_emulator/tpm/tpm_ticks.c
 40.1519 +--- tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c	2006-08-29 15:07:21.646294808 -0700
 40.1520 ++++ tpm_emulator/tpm/tpm_ticks.c	2006-08-29 15:26:17.128675248 -0700
 40.1521 +@@ -1,6 +1,7 @@
 40.1522 + /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 40.1523 +  * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
 40.1524 +  *                    Swiss Federal Institute of Technology (ETH) Zurich
 40.1525 ++ * Copyright (C) 2005 INTEL Corp
 40.1526 +  *
 40.1527 +  * This module is free software; you can redistribute it and/or modify
 40.1528 +  * it under the terms of the GNU General Public License as published
 40.1529 +@@ -37,9 +38,7 @@ TPM_RESULT TPM_SetTickType(TPM_TICKTYPE 
 40.1530 + TPM_RESULT TPM_GetTicks(TPM_CURRENT_TICKS *currentTime)
 40.1531 + {
 40.1532 +   info("TPM_GetTicks()");
 40.1533 +-  memcpy(currentTime, &tpmData.stany.data.currentTicks, 
 40.1534 +-    sizeof(TPM_CURRENT_TICKS));
 40.1535 +-  return TPM_SUCCESS;
 40.1536 ++  return TPM_DISABLED_CMD;
 40.1537 + }
 40.1538 + 
 40.1539 + TPM_RESULT TPM_TickStampBlob(TPM_KEY_HANDLE keyHandle, TPM_NONCE *antiReplay,
 40.1540 +@@ -47,61 +46,12 @@ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HAN
 40.1541 +                              TPM_CURRENT_TICKS *currentTicks, 
 40.1542 +                              UINT32 *sigSize, BYTE **sig)
 40.1543 + {
 40.1544 +-  TPM_RESULT res;
 40.1545 +-  TPM_KEY_DATA *key;
 40.1546 +-  BYTE *info, *p;
 40.1547 +-  UINT32 info_length, length;
 40.1548 +   info("TPM_TickStampBlob()");
 40.1549 +-  /* get key */
 40.1550 +-  key = tpm_get_key(keyHandle);
 40.1551 +-  if (key == NULL) return TPM_INVALID_KEYHANDLE;
 40.1552 +-  /* verify authorization */ 
 40.1553 +-  res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
 40.1554 +-  if (res != TPM_SUCCESS) return res;
 40.1555 +-  if (key->keyUsage != TPM_KEY_SIGNING && key->keyUsage != TPM_KEY_LEGACY
 40.1556 +-      && key->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE;
 40.1557 +-  /* get current ticks */
 40.1558 +-  TPM_GetTicks(currentTicks);
 40.1559 +-  /* sign data using signature scheme PKCS1_SHA1 and TPM_SIGN_INFO container */
 40.1560 +-  *sigSize = key->key.size >> 3;
 40.1561 +-  *sig = tpm_malloc(*sigSize);
 40.1562 +-  if (*sig == NULL) return TPM_FAIL; 
 40.1563 +-  /* setup TPM_SIGN_INFO structure */
 40.1564 +-  info_length = 30 + sizeof(TPM_DIGEST) + sizeof_TPM_CURRENT_TICKS(currentTicks);
 40.1565 +-  info = tpm_malloc(info_length);
 40.1566 +-  if (info == NULL) {
 40.1567 +-    tpm_free(*sig);
 40.1568 +-    return TPM_FAIL;
 40.1569 +-  }
 40.1570 +-  memcpy(&info[0], "\x05\x00TSTP", 6);
 40.1571 +-  memcpy(&info[6], antiReplay->nonce, 20);
 40.1572 +-  *(UINT32*)&info[26] = cpu_to_be32(20
 40.1573 +-                        + sizeof_TPM_CURRENT_TICKS(currentTicks));
 40.1574 +-  memcpy(&info[30], digestToStamp->digest, sizeof(TPM_DIGEST));
 40.1575 +-  p = &info[30 + sizeof(TPM_DIGEST)]; 
 40.1576 +-  length = sizeof_TPM_CURRENT_TICKS(currentTicks);
 40.1577 +-  if (tpm_marshal_TPM_CURRENT_TICKS(&p, &length, currentTicks)
 40.1578 +-      || rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, info, info_length, *sig)) {   
 40.1579 +-    tpm_free(*sig);
 40.1580 +-    tpm_free(info);
 40.1581 +-    return TPM_FAIL;
 40.1582 +-  } 
 40.1583 +-  return TPM_SUCCESS;
 40.1584 ++  return TPM_DISABLED_CMD;
 40.1585 + }
 40.1586 + 
 40.1587 + void tpm_update_ticks(void)
 40.1588 + {
 40.1589 +-  if (tpmData.stany.data.currentTicks.tag == 0) {
 40.1590 +-    tpmData.stany.data.currentTicks.tag = TPM_TAG_CURRENT_TICKS;
 40.1591 +-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();
 40.1592 +-    tpmData.stany.data.currentTicks.tickType = tpmData.permanent.data.tickType;
 40.1593 +-    tpm_get_random_bytes(tpmData.stany.data.currentTicks.tickNonce.nonce, 
 40.1594 +-      sizeof(TPM_NONCE));
 40.1595 +-    tpmData.stany.data.currentTicks.tickRate = 1;
 40.1596 +-    tpmData.stany.data.currentTicks.tickSecurity = TICK_SEC_NO_CHECK;
 40.1597 +-  } else {
 40.1598 +-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();   
 40.1599 +-  }
 40.1600 + }
 40.1601 +   
 40.1602 + 
 40.1603 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_transport.c tpm_emulator/tpm/tpm_transport.c
 40.1604 +--- tpm_emulator-0.3-x86_64/tpm/tpm_transport.c	2006-08-29 15:07:21.647294656 -0700
 40.1605 ++++ tpm_emulator/tpm/tpm_transport.c	2006-08-29 15:26:17.129675096 -0700
 40.1606 +@@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE
 40.1607 + static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20],
 40.1608 +                              BYTE pubKeyHash[20], TPM_DIGEST *transDigest)
 40.1609 + {
 40.1610 +-  UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_IN);
 40.1611 ++  UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_IN);
 40.1612 +   BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_IN(x)];
 40.1613 +   UINT32 len = sizeof(buf);
 40.1614 +   sha1_ctx_t sha1;
 40.1615 +@@ -76,7 +76,7 @@ static void transport_log_in(TPM_COMMAND
 40.1616 + static void transport_log_out(TPM_CURRENT_TICKS *currentTicks, BYTE parameters[20],
 40.1617 +                               TPM_MODIFIER_INDICATOR locality, TPM_DIGEST *transDigest)
 40.1618 + {
 40.1619 +-  UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_OUT);
 40.1620 ++  UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_OUT);
 40.1621 +   BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_OUT(x)];
 40.1622 +   UINT32 len = sizeof(buf);
 40.1623 +   sha1_ctx_t sha1;
 40.1624 +@@ -191,7 +191,7 @@ static void decrypt_wrapped_command(BYTE
 40.1625 +     sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
 40.1626 +     sha1_update(&sha1, "in", 2);
 40.1627 +     sha1_update(&sha1, secret, sizeof(TPM_SECRET));
 40.1628 +-    j = cpu_to_be32(i);
 40.1629 ++    j = CPU_TO_BE32(i);
 40.1630 +     sha1_update(&sha1, (BYTE*)&j, 4);
 40.1631 +     sha1_final(&sha1, mask);
 40.1632 +     for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 
 40.1633 +@@ -213,7 +213,7 @@ static void encrypt_wrapped_command(BYTE
 40.1634 +     sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
 40.1635 +     sha1_update(&sha1, "out", 3);
 40.1636 +     sha1_update(&sha1, secret, sizeof(TPM_SECRET));
 40.1637 +-    j = cpu_to_be32(i);
 40.1638 ++    j = CPU_TO_BE32(i);
 40.1639 +     sha1_update(&sha1, (BYTE*)&j, 4);
 40.1640 +     sha1_final(&sha1, mask);
 40.1641 +     for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 
 40.1642 +@@ -253,9 +253,9 @@ TPM_RESULT TPM_ExecuteTransport(UINT32 i
 40.1643 +   /* verify authorization */
 40.1644 +   tpm_compute_in_param_digest(&req);
 40.1645 +   sha1_init(&sha1);
 40.1646 +-  res = cpu_to_be32(TPM_ORD_ExecuteTransport);
 40.1647 ++  res = CPU_TO_BE32(TPM_ORD_ExecuteTransport);
 40.1648 +   sha1_update(&sha1, (BYTE*)&res, 4);
 40.1649 +-  res = cpu_to_be32(inWrappedCmdSize);
 40.1650 ++  res = CPU_TO_BE32(inWrappedCmdSize);
 40.1651 +   sha1_update(&sha1, (BYTE*)&res, 4);
 40.1652 +   sha1_update(&sha1, req.auth1.digest, sizeof(req.auth1.digest));
 40.1653 +   sha1_final(&sha1, auth1->digest);
 40.1654 +@@ -357,7 +357,7 @@ TPM_RESULT TPM_ReleaseTransportSigned(TP
 40.1655 +   /* setup a TPM_SIGN_INFO structure */
 40.1656 +   memcpy(&buf[0], "\x05\x00TRAN", 6);
 40.1657 +   memcpy(&buf[6], antiReplay->nonce, 20);
 40.1658 +-  *(UINT32*)&buf[26] = cpu_to_be32(20);
 40.1659 ++  *(UINT32*)&buf[26] = CPU_TO_BE32(20);
 40.1660 +   memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
 40.1661 +   /* sign info structure */ 
 40.1662 +   res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize);
 40.1663 +diff -uprN tpm_emulator-0.3-x86_64/tpm_version.h tpm_emulator/tpm_version.h
 40.1664 +--- tpm_emulator-0.3-x86_64/tpm_version.h	2006-08-29 15:07:21.649294352 -0700
 40.1665 ++++ tpm_emulator/tpm_version.h	1969-12-31 16:00:00.000000000 -0800
 40.1666 +@@ -1,6 +0,0 @@
 40.1667 +-#ifndef _TPM_VERSION_H_
 40.1668 +-#define _TPM_VERSION_H_
 40.1669 +-#define VERSION_MAJOR 0
 40.1670 +-#define VERSION_MINOR 3
 40.1671 +-#define VERSION_BUILD 1136893683
 40.1672 +-#endif /* _TPM_VERSION_H_ */
 40.1673 +diff -uprN tpm_emulator-0.3-x86_64/tpmd.c tpm_emulator/tpmd.c
 40.1674 +--- tpm_emulator-0.3-x86_64/tpmd.c	1969-12-31 16:00:00.000000000 -0800
 40.1675 ++++ tpm_emulator/tpmd.c	2006-08-29 15:26:17.130674944 -0700
 40.1676 +@@ -0,0 +1,141 @@
 40.1677 ++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 40.1678 ++ * Copyright (C) 2005 INTEL Corp
 40.1679 ++ *
 40.1680 ++ * This module is free software; you can redistribute it and/or modify
 40.1681 ++ * it under the terms of the GNU General Public License as published
 40.1682 ++ * by the Free Software Foundation; either version 2 of the License,
 40.1683 ++ * or (at your option) any later version.
 40.1684 ++ *
 40.1685 ++ * This module is distributed in the hope that it will be useful,
 40.1686 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 40.1687 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 40.1688 ++ * GNU General Public License for more details.
 40.1689 ++ *
 40.1690 ++ */
 40.1691 ++
 40.1692 ++#include <stdio.h>
 40.1693 ++#include <stdlib.h>
 40.1694 ++#include <unistd.h>
 40.1695 ++#include <string.h>
 40.1696 ++#include <sys/types.h>
 40.1697 ++#include <sys/stat.h>
 40.1698 ++#include <fcntl.h>
 40.1699 ++#include <sys/time.h>
 40.1700 ++
 40.1701 ++#include "tpm_emulator.h"
 40.1702 ++
 40.1703 ++#define TPM_RX_FNAME "/tmp/tpm_in.fifo"
 40.1704 ++#define TPM_TX_FNAME "/tmp/tpm_out.fifo"
 40.1705 ++
 40.1706 ++#define BUFFER_SIZE 2048
 40.1707 ++
 40.1708 ++static int devurandom=0;
 40.1709 ++	  
 40.1710 ++void get_random_bytes(void *buf, int nbytes) {
 40.1711 ++  
 40.1712 ++  if (devurandom == 0) {
 40.1713 ++    devurandom = open("/dev/urandom", O_RDONLY);
 40.1714 ++  }
 40.1715 ++
 40.1716 ++  if (read(devurandom, buf, nbytes) != nbytes) {
 40.1717 ++      printf("Can't get random number.\n");
 40.1718 ++      exit(-1);
 40.1719 ++  }
 40.1720 ++}
 40.1721 ++
 40.1722 ++uint64_t tpm_get_ticks(void)
 40.1723 ++{
 40.1724 ++  //struct timeval tv;
 40.1725 ++  //int gettimeofday(&tv, struct timezone *tz);
 40.1726 ++  return 0;
 40.1727 ++}
 40.1728 ++
 40.1729 ++int main(int argc, char **argv)
 40.1730 ++{
 40.1731 ++  uint8_t in[BUFFER_SIZE], *out;
 40.1732 ++  uint32_t out_size;
 40.1733 ++  int in_size, written;
 40.1734 ++  int i;
 40.1735 ++ 
 40.1736 ++  int tpm_tx_fh=-1, tpm_rx_fh=-1;
 40.1737 ++  if (argc < 2) {
 40.1738 ++    printf("Usage: tpmd clear|save|deactivated\n" );
 40.1739 ++	  return -1;
 40.1740 ++  }
 40.1741 ++
 40.1742 ++  /* initialize TPM emulator */
 40.1743 ++  if (!strcmp(argv[1], "clear")) {
 40.1744 ++    printf("Initializing tpm: %s\n", argv[1]);
 40.1745 ++    tpm_emulator_init(1);
 40.1746 ++  } else if (!strcmp(argv[1], "save")) { 
 40.1747 ++    printf("Initializing tpm: %s\n", argv[1]);
 40.1748 ++    tpm_emulator_init(2);
 40.1749 ++  } else if (!strcmp(argv[1], "deactivated")) {
 40.1750 ++    printf("Initializing tpm: %s\n", argv[1]);
 40.1751 ++    tpm_emulator_init(3);
 40.1752 ++  } else {
 40.1753 ++    printf("invalid startup mode '%s'; must be 'clear', "
 40.1754 ++      "'save' (default) or 'deactivated", argv[1]);
 40.1755 ++    return -1;
 40.1756 ++  }
 40.1757 ++
 40.1758 ++  while (1) {
 40.1759 ++abort_command:
 40.1760 ++    if (tpm_rx_fh < 0) {
 40.1761 ++      tpm_rx_fh = open(TPM_RX_FNAME, O_RDONLY);
 40.1762 ++    }
 40.1763 ++    
 40.1764 ++    if (tpm_rx_fh < 0) {
 40.1765 ++      printf("ERROR: failed to open devices to listen to guest.\n");
 40.1766 ++      return -1;
 40.1767 ++    }
 40.1768 ++    
 40.1769 ++    if (tpm_tx_fh < 0) {
 40.1770 ++      tpm_tx_fh = open(TPM_TX_FNAME, O_WRONLY);
 40.1771  +    }
 40.1772  +
 40.1773 -     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
 40.1774 -   }
 40.1775 -   /* set tick type */
 40.1776 ++    if (tpm_tx_fh < 0) {
 40.1777 ++      printf("ERROR: failed to open devices to respond to guest.\n");
 40.1778 ++      return -1;
 40.1779 ++    }
 40.1780 ++
 40.1781 ++    in_size = read(tpm_rx_fh, in, BUFFER_SIZE);
 40.1782 ++    if (in_size < 6) { // Magic size of minium TPM command
 40.1783 ++      printf("Recv[%d] to small: 0x", in_size);
 40.1784 ++      if (in_size <= 0) {
 40.1785 ++          close(tpm_rx_fh);
 40.1786 ++          tpm_rx_fh = -1;
 40.1787 ++          goto abort_command;
 40.1788 ++      }
 40.1789 ++    } else { 
 40.1790 ++      printf("Recv[%d]: 0x", in_size);
 40.1791 ++      for (i=0; i< in_size; i++) 
 40.1792 ++        printf("%x ", in[i]);
 40.1793 ++      printf("\n");
 40.1794 ++    }
 40.1795 ++
 40.1796 ++    
 40.1797 ++    if (tpm_handle_command(in, in_size, &out, &out_size) != 0) { 
 40.1798 ++        printf("ERROR: Handler Failed.\n");
 40.1799 ++    }
 40.1800 ++
 40.1801 ++    written = write(tpm_tx_fh, out, out_size);
 40.1802 ++
 40.1803 ++    if (written != out_size ) {
 40.1804 ++      printf("ERROR: Part of response not written %d/%d.\nAttempt: ", written, out_size);
 40.1805 ++    } else {
 40.1806 ++      printf("Sent[%Zu]: ", out_size);
 40.1807 ++    }
 40.1808 ++    for (i=0; i< out_size; i++)
 40.1809 ++      printf("%x ", out[i]);
 40.1810 ++    printf("\n");
 40.1811 ++    tpm_free(out);
 40.1812 ++
 40.1813 ++  } // loop
 40.1814 ++
 40.1815 ++  tpm_emulator_shutdown();
 40.1816 ++
 40.1817 ++  close(tpm_tx_fh);
 40.1818 ++  close(tpm_rx_fh);
 40.1819 ++
 40.1820 ++}
    41.1 --- a/tools/vtpm/vtpm.patch	Wed Jun 28 07:51:52 2006 -0600
    41.2 +++ b/tools/vtpm/vtpm.patch	Wed Jun 28 07:52:21 2006 -0600
    41.3 @@ -1,13 +1,13 @@
    41.4 -diff -uprN orig/tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS
    41.5 ---- orig/tpm_emulator-0.3-x86_64/AUTHORS	2006-01-10 04:21:45.000000000 -0800
    41.6 -+++ vtpm/AUTHORS	2006-05-30 12:23:26.000000000 -0700
    41.7 +diff -uprN tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS
    41.8 +--- tpm_emulator-0.3-x86_64/AUTHORS	2006-08-29 15:07:21.618299064 -0700
    41.9 ++++ vtpm/AUTHORS	2006-08-29 15:12:07.184886344 -0700
   41.10  @@ -1,2 +1,3 @@
   41.11   Mario Strasser <mast@gmx.net>
   41.12   Heiko Stamer <stamer@gaos.org> [DAA]
   41.13  +INTEL Corp <> [VTPM Extensions]
   41.14 -diff -uprN orig/tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog
   41.15 ---- orig/tpm_emulator-0.3-x86_64/ChangeLog	2006-01-10 04:21:45.000000000 -0800
   41.16 -+++ vtpm/ChangeLog	2006-05-30 12:23:26.000000000 -0700
   41.17 +diff -uprN tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog
   41.18 +--- tpm_emulator-0.3-x86_64/ChangeLog	2006-08-29 15:07:21.618299064 -0700
   41.19 ++++ vtpm/ChangeLog	2006-08-29 15:12:07.185886192 -0700
   41.20  @@ -1,3 +1,7 @@
   41.21  +2005-08-16 Intel Corp
   41.22  +	* Moved module out of kernel to run as a ring 3 app
   41.23 @@ -16,9 +16,117 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
   41.24   2005-12-24  Mario Strasser <mast@gmx.net>
   41.25   	* tpm_transport.c, tpm_marshalling.c, tpm_structures.h:
   41.26   		Transport session functionality added
   41.27 -diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
   41.28 ---- orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c	2006-05-30 12:28:02.000000000 -0700
   41.29 -+++ vtpm/crypto/gmp_kernel_wrapper.c	2006-05-30 12:23:26.000000000 -0700
   41.30 +diff -uprN tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile
   41.31 +--- tpm_emulator-0.3-x86_64/Makefile	2006-08-29 15:08:20.532342768 -0700
   41.32 ++++ vtpm/Makefile	2006-08-29 15:13:53.023796384 -0700
   41.33 +@@ -1,22 +1,31 @@
   41.34 + # Software-Based Trusted Platform Module (TPM) Emulator for Linux
   41.35 + # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
   41.36 ++# Copyright (C) 2006 INTEL Corp.
   41.37 + #
   41.38 + # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
   41.39 + 
   41.40 +-# kernel settings
   41.41 +-KERNEL_RELEASE := $(shell uname -r)
   41.42 +-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
   41.43 +-MOD_SUBDIR     := misc
   41.44 + COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
   41.45 + 
   41.46 + # module settings
   41.47 +-MODULE_NAME    := tpm_emulator
   41.48 ++BIN            := vtpmd
   41.49 + VERSION_MAJOR  := 0
   41.50 + VERSION_MINOR  := 3
   41.51 + VERSION_BUILD  := $(shell date +"%s")
   41.52 + 
   41.53 +-# enable/disable DEBUG messages
   41.54 +-EXTRA_CFLAGS   += -Wall -DDEBUG -g  
   41.55 ++# Installation program and options
   41.56 ++INSTALL         = install
   41.57 ++INSTALL_PROG    = $(INSTALL) -m0755
   41.58 ++INSTALL_DIR     = $(INSTALL) -d -m0755
   41.59 ++
   41.60 ++# Xen tools installation directory
   41.61 ++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
   41.62 ++
   41.63 ++CC      := gcc
   41.64 ++CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
   41.65 ++CFLAGS  += -I. -Itpm -I../../vtpm_manager/manager
   41.66 ++
   41.67 ++# Is the simulator running in it's own vm?
   41.68 ++#CFLAGS += -DVTPM_MULTI_VM
   41.69 + 
   41.70 + ifeq ($(COMPILE_ARCH),x86_64)
   41.71 + LIBDIR = lib64
   41.72 +@@ -34,38 +43,31 @@ DIRS           := . crypto tpm 
   41.73 + SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
   41.74 + OBJS           := $(patsubst %.c, %.o, $(SRCS))
   41.75 + SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
   41.76 +-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
   41.77 +-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
   41.78 + 
   41.79 +-obj-m               := $(MODULE_NAME).o
   41.80 +-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
   41.81 ++obj-m               := $(BIN)
   41.82 ++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
   41.83 + 
   41.84 + EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
   41.85 + 
   41.86 + # do not print "Entering directory ..."
   41.87 + MAKEFLAGS      += --no-print-directory
   41.88 + 
   41.89 +-all:	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
   41.90 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
   41.91 ++all: $(BIN)
   41.92 ++
   41.93 ++$(BIN):	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS)
   41.94 ++	$(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
   41.95 ++
   41.96 ++%.o: %.c
   41.97 ++	$(CC) $(CFLAGS) -c $< -o $@
   41.98 + 
   41.99 +-install:
  41.100 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
  41.101 +-	test -d /var/tpm || mkdir /var/tpm
  41.102 +-	test -c /dev/tpm || mknod /dev/tpm c 10 224
  41.103 +-	chmod 666 /dev/tpm
  41.104 +-	depmod -a
  41.105 ++install: $(BIN)
  41.106 ++	$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
  41.107 + 
  41.108 + clean:
  41.109 +-	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
  41.110 +-	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
  41.111 ++	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
  41.112 + 
  41.113 +-dist:	$(DISTSRC)
  41.114 +-	rm -rf $(DISTDIR)
  41.115 +-	mkdir $(DISTDIR)
  41.116 +-	cp --parents $(DISTSRC) $(DISTDIR)/
  41.117 +-	rm -f $(DISTDIR)/crypto/gmp.h 
  41.118 +-	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
  41.119 +-	rm -rf $(DISTDIR)
  41.120 ++mrproper: clean
  41.121 ++	rm -f $(BIN) tpm_version.h
  41.122 + 
  41.123 + $(src)/crypto/libgmp.a:
  41.124 + 	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
  41.125 +diff -uprN tpm_emulator-0.3-x86_64/README vtpm/README
  41.126 +--- tpm_emulator-0.3-x86_64/README	2006-08-29 15:07:43.530967832 -0700
  41.127 ++++ vtpm/README	2006-08-29 15:12:07.190885432 -0700
  41.128 +@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
  41.129 + Copyright
  41.130 + --------------------------------------------------------------------------
  41.131 + Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
  41.132 +-Institute of Technology (ETH) Zurich.
  41.133 ++                   Institute of Technology (ETH) Zurich.
  41.134 ++Copyright (C) 2005 INTEL Corp 
  41.135 +               
  41.136 + This program is free software; you can redistribute it and/or modify
  41.137 + it under the terms of the GNU General Public License as published by
  41.138 +diff -uprN tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c vtpm/crypto/gmp_kernel_wrapper.c
  41.139 +--- tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c	2006-08-29 15:07:43.525968592 -0700
  41.140 ++++ vtpm/crypto/gmp_kernel_wrapper.c	2006-08-29 15:12:07.186886040 -0700
  41.141  @@ -1,5 +1,6 @@
  41.142   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.143    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.144 @@ -78,9 +186,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.145     }
  41.146   }
  41.147   
  41.148 -diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
  41.149 ---- orig/tpm_emulator-0.3-x86_64/crypto/rsa.c	2006-01-10 04:21:45.000000000 -0800
  41.150 -+++ vtpm/crypto/rsa.c	2006-05-30 12:23:26.000000000 -0700
  41.151 +diff -uprN tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
  41.152 +--- tpm_emulator-0.3-x86_64/crypto/rsa.c	2006-08-29 15:07:21.618299064 -0700
  41.153 ++++ vtpm/crypto/rsa.c	2006-08-29 15:12:07.187885888 -0700
  41.154  @@ -1,5 +1,6 @@
  41.155   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.156    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.157 @@ -106,8 +214,8 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.158         sha1_final(&ctx, &msg[1]);
  41.159         if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
  41.160             SHA1_DIGEST_LENGTH) != 0) return -1;
  41.161 -diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c
  41.162 ---- orig/tpm_emulator-0.3-x86_64/linux_module.c	2006-05-30 12:28:02.000000000 -0700
  41.163 +diff -uprN tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c
  41.164 +--- tpm_emulator-0.3-x86_64/linux_module.c	2006-08-29 15:07:43.526968440 -0700
  41.165  +++ vtpm/linux_module.c	1969-12-31 16:00:00.000000000 -0800
  41.166  @@ -1,194 +0,0 @@
  41.167  -/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
  41.168 @@ -304,9 +412,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.169  -  return (ticks > 0) ? ticks : 1;
  41.170  -}
  41.171  -
  41.172 -diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h
  41.173 ---- orig/tpm_emulator-0.3-x86_64/linux_module.h	2006-05-30 12:28:02.000000000 -0700
  41.174 -+++ vtpm/linux_module.h	2006-05-30 12:23:26.000000000 -0700
  41.175 +diff -uprN tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h
  41.176 +--- tpm_emulator-0.3-x86_64/linux_module.h	2006-08-29 15:07:43.527968288 -0700
  41.177 ++++ vtpm/linux_module.h	2006-08-29 15:12:07.189885584 -0700
  41.178  @@ -1,5 +1,6 @@
  41.179   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.180    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.181 @@ -406,116 +514,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.182   #define BE16_TO_CPU(x) __be16_to_cpu(x)
  41.183   #define LE16_TO_CPU(x) __le16_to_cpu(x)
  41.184   
  41.185 -diff -uprN orig/tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile
  41.186 ---- orig/tpm_emulator-0.3-x86_64/Makefile	2006-05-30 12:28:02.000000000 -0700
  41.187 -+++ vtpm/Makefile	2006-05-30 12:23:26.000000000 -0700
  41.188 -@@ -1,22 +1,31 @@
  41.189 - # Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.190 - # Copyright (C) 2004 Mario Strasser <mast@gmx.net>
  41.191 -+# Copyright (C) 2006 INTEL Corp.
  41.192 - #
  41.193 - # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
  41.194 - 
  41.195 --# kernel settings
  41.196 --KERNEL_RELEASE := $(shell uname -r)
  41.197 --KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
  41.198 --MOD_SUBDIR     := misc
  41.199 - COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
  41.200 - 
  41.201 - # module settings
  41.202 --MODULE_NAME    := tpm_emulator
  41.203 -+BIN            := vtpmd
  41.204 - VERSION_MAJOR  := 0
  41.205 - VERSION_MINOR  := 3
  41.206 - VERSION_BUILD  := $(shell date +"%s")
  41.207 - 
  41.208 --# enable/disable DEBUG messages
  41.209 --EXTRA_CFLAGS   += -Wall -DDEBUG -g  
  41.210 -+# Installation program and options
  41.211 -+INSTALL         = install
  41.212 -+INSTALL_PROG    = $(INSTALL) -m0755
  41.213 -+INSTALL_DIR     = $(INSTALL) -d -m0755
  41.214 -+
  41.215 -+# Xen tools installation directory
  41.216 -+TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
  41.217 -+
  41.218 -+CC      := gcc
  41.219 -+CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
  41.220 -+CFLAGS  += -I. -Itpm -I../../vtpm_manager/manager
  41.221 -+
  41.222 -+# Is the simulator running in it's own vm?
  41.223 -+#CFLAGS += -DVTPM_MULTI_VM
  41.224 - 
  41.225 - ifeq ($(COMPILE_ARCH),x86_64)
  41.226 - LIBDIR = lib64
  41.227 -@@ -34,38 +43,31 @@ DIRS           := . crypto tpm 
  41.228 - SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
  41.229 - OBJS           := $(patsubst %.c, %.o, $(SRCS))
  41.230 - SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
  41.231 --DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
  41.232 --DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
  41.233 - 
  41.234 --obj-m               := $(MODULE_NAME).o
  41.235 --$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  41.236 -+obj-m               := $(BIN)
  41.237 -+$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  41.238 - 
  41.239 - EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
  41.240 - 
  41.241 - # do not print "Entering directory ..."
  41.242 - MAKEFLAGS      += --no-print-directory
  41.243 - 
  41.244 --all:	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
  41.245 --	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
  41.246 -+all: $(BIN)
  41.247 -+
  41.248 -+$(BIN):	$(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) $(OBJS)
  41.249 -+	$(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
  41.250 -+
  41.251 -+%.o: %.c
  41.252 -+	$(CC) $(CFLAGS) -c $< -o $@
  41.253 - 
  41.254 - install:
  41.255 --	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
  41.256 --	test -d /var/tpm || mkdir /var/tpm
  41.257 --	test -c /dev/tpm || mknod /dev/tpm c 10 224
  41.258 --	chmod 666 /dev/tpm
  41.259 --	depmod -a
  41.260 -+	$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
  41.261 - 
  41.262 - clean:
  41.263 --	@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
  41.264 --	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
  41.265 -+	rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
  41.266 - 
  41.267 --dist:	$(DISTSRC)
  41.268 --	rm -rf $(DISTDIR)
  41.269 --	mkdir $(DISTDIR)
  41.270 --	cp --parents $(DISTSRC) $(DISTDIR)/
  41.271 --	rm -f $(DISTDIR)/crypto/gmp.h 
  41.272 --	tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
  41.273 --	rm -rf $(DISTDIR)
  41.274 -+mrproper: clean
  41.275 -+	rm -f $(BIN) tpm_version.h
  41.276 - 
  41.277 - $(src)/crypto/libgmp.a:
  41.278 - 	test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) $(src)/crypto/libgmp.a
  41.279 -diff -uprN orig/tpm_emulator-0.3-x86_64/README vtpm/README
  41.280 ---- orig/tpm_emulator-0.3-x86_64/README	2006-05-30 12:28:02.000000000 -0700
  41.281 -+++ vtpm/README	2006-05-30 12:23:26.000000000 -0700
  41.282 -@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
  41.283 - Copyright
  41.284 - --------------------------------------------------------------------------
  41.285 - Copyright (C) 2004 Mario Strasser <mast@gmx.net> and Swiss Federal 
  41.286 --Institute of Technology (ETH) Zurich.
  41.287 -+                   Institute of Technology (ETH) Zurich.
  41.288 -+Copyright (C) 2005 INTEL Corp 
  41.289 -               
  41.290 - This program is free software; you can redistribute it and/or modify
  41.291 - it under the terms of the GNU General Public License as published by
  41.292 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
  41.293 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c	2006-01-10 04:21:45.000000000 -0800
  41.294 -+++ vtpm/tpm/tpm_audit.c	2006-05-30 12:23:26.000000000 -0700
  41.295 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
  41.296 +--- tpm_emulator-0.3-x86_64/tpm/tpm_audit.c	2006-08-29 15:07:21.620298760 -0700
  41.297 ++++ vtpm/tpm/tpm_audit.c	2006-08-29 15:12:07.191885280 -0700
  41.298  @@ -1,6 +1,7 @@
  41.299   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.300    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.301 @@ -578,9 +579,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.302     return TPM_SUCCESS;
  41.303   }
  41.304  -
  41.305 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
  41.306 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c	2006-01-10 04:21:45.000000000 -0800
  41.307 -+++ vtpm/tpm/tpm_authorization.c	2006-05-30 12:23:26.000000000 -0700
  41.308 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c vtpm/tpm/tpm_authorization.c
  41.309 +--- tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c	2006-08-29 15:07:21.620298760 -0700
  41.310 ++++ vtpm/tpm/tpm_authorization.c	2006-08-29 15:12:07.192885128 -0700
  41.311  @@ -1,6 +1,7 @@
  41.312   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.313    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.314 @@ -598,9 +599,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.315     
  41.316     info("tpm_verify_auth(%08x)", auth->authHandle);
  41.317     /* get dedicated authorization or transport session */
  41.318 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
  41.319 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c	2006-01-10 04:21:45.000000000 -0800
  41.320 -+++ vtpm/tpm/tpm_capability.c	2006-05-30 12:23:26.000000000 -0700
  41.321 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
  41.322 +--- tpm_emulator-0.3-x86_64/tpm/tpm_capability.c	2006-08-29 15:07:21.620298760 -0700
  41.323 ++++ vtpm/tpm/tpm_capability.c	2006-08-29 15:12:07.193884976 -0700
  41.324  @@ -1,6 +1,7 @@
  41.325   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.326    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.327 @@ -623,9 +624,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.328     }
  41.329   }
  41.330  -
  41.331 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
  41.332 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c	2006-01-10 04:21:45.000000000 -0800
  41.333 -+++ vtpm/tpm/tpm_cmd_handler.c	2006-05-30 12:23:26.000000000 -0700
  41.334 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
  41.335 +--- tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c	2006-08-29 15:07:21.621298608 -0700
  41.336 ++++ vtpm/tpm/tpm_cmd_handler.c	2006-08-29 15:12:07.197884368 -0700
  41.337  @@ -1,6 +1,7 @@
  41.338   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.339    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.340 @@ -683,9 +684,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.341     /* setup authorisation as well as response tag and size */
  41.342     memset(rsp, 0, sizeof(*rsp));
  41.343     switch (req->tag) {
  41.344 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
  41.345 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c	2006-05-30 12:28:02.000000000 -0700
  41.346 -+++ vtpm/tpm/tpm_crypto.c	2006-05-30 12:23:26.000000000 -0700
  41.347 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
  41.348 +--- tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c	2006-08-29 15:07:43.531967680 -0700
  41.349 ++++ vtpm/tpm/tpm_crypto.c	2006-08-29 15:12:07.198884216 -0700
  41.350  @@ -1,6 +1,7 @@
  41.351   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.352    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.353 @@ -708,9 +709,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.354     return TPM_SUCCESS;
  41.355   }
  41.356  -
  41.357 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c
  41.358 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c	2006-01-10 04:21:45.000000000 -0800
  41.359 -+++ vtpm/tpm/tpm_daa.c	2006-05-30 12:23:26.000000000 -0700
  41.360 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c
  41.361 +--- tpm_emulator-0.3-x86_64/tpm/tpm_daa.c	2006-08-29 15:07:21.622298456 -0700
  41.362 ++++ vtpm/tpm/tpm_daa.c	2006-08-29 15:12:07.203883456 -0700
  41.363  @@ -700,14 +700,14 @@ info("tested until here");
  41.364             sizeof(session->DAA_tpmSpecific.DAA_rekey));
  41.365         sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
  41.366 @@ -865,9 +866,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.367         sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
  41.368         mpz_init(f), mpz_init(q);
  41.369         mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
  41.370 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
  41.371 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c	2006-05-30 12:28:02.000000000 -0700
  41.372 -+++ vtpm/tpm/tpm_data.c	2006-05-30 12:23:26.000000000 -0700
  41.373 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
  41.374 +--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c	2006-08-29 15:08:20.535342312 -0700
  41.375 ++++ vtpm/tpm/tpm_data.c	2006-08-29 15:12:07.206883000 -0700
  41.376  @@ -1,6 +1,7 @@
  41.377   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.378    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.379 @@ -1177,7 +1178,7 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.380   }
  41.381   
  41.382   #else
  41.383 -@@ -267,7 +462,6 @@ int tpm_restore_permanent_data(void)
  41.384 +@@ -278,7 +473,6 @@ int tpm_restore_permanent_data(void)
  41.385   
  41.386   int tpm_erase_permanent_data(void)
  41.387   {
  41.388 @@ -1186,9 +1187,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.389     return res;
  41.390   }
  41.391  -
  41.392 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
  41.393 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c	2006-01-10 04:21:45.000000000 -0800
  41.394 -+++ vtpm/tpm/tpm_deprecated.c	2006-05-30 12:23:26.000000000 -0700
  41.395 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c vtpm/tpm/tpm_deprecated.c
  41.396 +--- tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c	2006-08-29 15:07:21.622298456 -0700
  41.397 ++++ vtpm/tpm/tpm_deprecated.c	2006-08-29 15:12:07.207882848 -0700
  41.398  @@ -1,6 +1,7 @@
  41.399   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.400    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.401 @@ -1215,9 +1216,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.402                           authContextSize, &contextBlob);
  41.403     if (res != TPM_SUCCESS) return res;
  41.404     len = *authContextSize;
  41.405 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
  41.406 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h	2006-01-10 04:21:45.000000000 -0800
  41.407 -+++ vtpm/tpm/tpm_emulator.h	2006-05-30 12:23:26.000000000 -0700
  41.408 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
  41.409 +--- tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h	2006-08-29 15:07:21.648294504 -0700
  41.410 ++++ vtpm/tpm/tpm_emulator.h	2006-08-29 15:12:07.208882696 -0700
  41.411  @@ -1,5 +1,6 @@
  41.412   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.413    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.414 @@ -1235,9 +1236,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.415   #undef  TPM_GENERATE_SEED_DAA
  41.416   
  41.417   #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */        
  41.418 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
  41.419 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c	2006-01-10 04:21:45.000000000 -0800
  41.420 -+++ vtpm/tpm/tpm_integrity.c	2006-05-30 12:23:26.000000000 -0700
  41.421 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
  41.422 +--- tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c	2006-08-29 15:07:21.645294960 -0700
  41.423 ++++ vtpm/tpm/tpm_integrity.c	2006-08-29 15:12:07.208882696 -0700
  41.424  @@ -1,6 +1,7 @@
  41.425   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.426    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.427 @@ -1251,9 +1252,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.428     return TPM_SUCCESS;
  41.429   }
  41.430  -
  41.431 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
  41.432 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h	2006-01-10 04:21:45.000000000 -0800
  41.433 -+++ vtpm/tpm/tpm_structures.h	2006-05-30 12:23:26.000000000 -0700
  41.434 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_structures.h vtpm/tpm/tpm_structures.h
  41.435 +--- tpm_emulator-0.3-x86_64/tpm/tpm_structures.h	2006-08-29 15:08:20.545340792 -0700
  41.436 ++++ vtpm/tpm/tpm_structures.h	2006-08-29 15:12:07.211882240 -0700
  41.437  @@ -1,6 +1,7 @@
  41.438   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.439    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.440 @@ -1271,9 +1272,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.441   #include "crypto/rsa.h"
  41.442   
  41.443   /*
  41.444 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
  41.445 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c	2006-01-10 04:21:45.000000000 -0800
  41.446 -+++ vtpm/tpm/tpm_testing.c	2006-05-30 12:23:26.000000000 -0700
  41.447 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
  41.448 +--- tpm_emulator-0.3-x86_64/tpm/tpm_testing.c	2006-08-29 15:07:21.646294808 -0700
  41.449 ++++ vtpm/tpm/tpm_testing.c	2006-08-29 15:12:07.213881936 -0700
  41.450  @@ -1,6 +1,7 @@
  41.451   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.452    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.453 @@ -1389,9 +1390,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.454     rsa_private_key_t priv_key;
  41.455     rsa_public_key_t pub_key;
  41.456   
  41.457 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
  41.458 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c	2006-01-10 04:21:45.000000000 -0800
  41.459 -+++ vtpm/tpm/tpm_ticks.c	2006-05-30 12:23:26.000000000 -0700
  41.460 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
  41.461 +--- tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c	2006-08-29 15:07:21.646294808 -0700
  41.462 ++++ vtpm/tpm/tpm_ticks.c	2006-08-29 15:12:07.235878592 -0700
  41.463  @@ -1,6 +1,7 @@
  41.464   /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.465    * Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
  41.466 @@ -1474,9 +1475,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.467   }
  41.468     
  41.469   
  41.470 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c vtpm/tpm/tpm_transport.c
  41.471 ---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c	2006-01-10 04:21:45.000000000 -0800
  41.472 -+++ vtpm/tpm/tpm_transport.c	2006-05-30 12:23:26.000000000 -0700
  41.473 +diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_transport.c vtpm/tpm/tpm_transport.c
  41.474 +--- tpm_emulator-0.3-x86_64/tpm/tpm_transport.c	2006-08-29 15:07:21.647294656 -0700
  41.475 ++++ vtpm/tpm/tpm_transport.c	2006-08-29 15:12:07.239877984 -0700
  41.476  @@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE
  41.477   static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20],
  41.478                                BYTE pubKeyHash[20], TPM_DIGEST *transDigest)
  41.479 @@ -1534,9 +1535,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  41.480     memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
  41.481     /* sign info structure */ 
  41.482     res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize);
  41.483 -diff -uprN orig/tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c
  41.484 ---- orig/tpm_emulator-0.3-x86_64/tpmd.c	1969-12-31 16:00:00.000000000 -0800
  41.485 -+++ vtpm/tpmd.c	2006-05-30 12:23:26.000000000 -0700
  41.486 +diff -uprN tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c
  41.487 +--- tpm_emulator-0.3-x86_64/tpmd.c	1969-12-31 16:00:00.000000000 -0800
  41.488 ++++ vtpm/tpmd.c	2006-08-29 15:12:07.240877832 -0700
  41.489  @@ -0,0 +1,207 @@
  41.490  +/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
  41.491  + * Copyright (C) 2005 INTEL Corp
    42.1 --- a/tools/vtpm_manager/Rules.mk	Wed Jun 28 07:51:52 2006 -0600
    42.2 +++ b/tools/vtpm_manager/Rules.mk	Wed Jun 28 07:52:21 2006 -0600
    42.3 @@ -56,6 +56,9 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT
    42.4  # vtpm_manager listens on fifo's rather than backend
    42.5  #CFLAGS += -DDUMMY_BACKEND
    42.6  
    42.7 +# TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos
    42.8 +#CFLAGS += -DDUMMY_TPM
    42.9 +
   42.10  # Do not have manager launch DMs.
   42.11  #CFLAGS += -DMANUAL_DM_LAUNCH
   42.12  
    43.1 --- a/tools/vtpm_manager/manager/dmictl.c	Wed Jun 28 07:51:52 2006 -0600
    43.2 +++ b/tools/vtpm_manager/manager/dmictl.c	Wed Jun 28 07:52:21 2006 -0600
    43.3 @@ -76,14 +76,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
    43.4    
    43.5    VTPM_DMI_RESOURCE *new_dmi=NULL;
    43.6    TPM_RESULT status=TPM_FAIL;
    43.7 -  BYTE type;
    43.8 -  UINT32 dmi_id, domain_id, *dmi_id_key; 
    43.9 +  BYTE type, startup_mode;
   43.10 +  UINT32 dmi_id, *dmi_id_key=NULL; 
   43.11  
   43.12    if (param_buf == NULL) { // Assume creation of Dom 0 control
   43.13 -    type = 0;
   43.14 -    domain_id = VTPM_CTL_DM;
   43.15 +    type = VTPM_TYPE_NON_MIGRATABLE;
   43.16      dmi_id = VTPM_CTL_DM;
   43.17 -  } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) {
   43.18 +  } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(BYTE) + sizeof(UINT32)) {
   43.19      vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n", buffer_len(param_buf));
   43.20      status = TPM_BAD_PARAMETER;
   43.21      goto abort_egress;
   43.22 @@ -91,13 +90,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
   43.23      vtpm_globals->connected_dmis++; // Put this here so we don't count Dom0
   43.24      BSG_UnpackList( param_buf->bytes, 3,
   43.25  		    BSG_TYPE_BYTE, &type,
   43.26 -		    BSG_TYPE_UINT32, &domain_id,
   43.27 +		    BSG_TYPE_BYTE, &startup_mode,
   43.28  		    BSG_TYPE_UINT32,  &dmi_id);
   43.29    }
   43.30 -  
   43.31 +
   43.32    new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
   43.33    if (new_dmi == NULL) { 
   43.34 -    vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on domain %d.\n", dmi_id, domain_id);
   43.35 +    vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached.\n", dmi_id );
   43.36      // Brand New DMI. Initialize the persistent pieces
   43.37      if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) == NULL) {
   43.38        status = TPM_RESOURCES;
   43.39 @@ -106,32 +105,44 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
   43.40      memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
   43.41      new_dmi->dmi_id = dmi_id;
   43.42      new_dmi->connected = FALSE;
   43.43 +
   43.44 +    if (type != VTPM_TYPE_MIGRATED) {
   43.45 +      new_dmi->dmi_type = type;
   43.46 +    } else {
   43.47 +      vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n");
   43.48 +      status = TPM_BAD_PARAMETER;
   43.49 +      goto free_egress;
   43.50 +    }
   43.51      
   43.52      if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
   43.53        status = TPM_RESOURCES;
   43.54 -      goto abort_egress;
   43.55 +      goto free_egress;
   43.56      }      
   43.57      *dmi_id_key = new_dmi->dmi_id;
   43.58      
   43.59      // install into map
   43.60      if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
   43.61 -      free(new_dmi);
   43.62 -      free(dmi_id_key);
   43.63 +      vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance into table. Aborting.\n", dmi_id);
   43.64        status = TPM_FAIL;
   43.65 -      goto egress;
   43.66 +      goto free_egress;
   43.67      }
   43.68     
   43.69    } else 
   43.70 -    vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d .\n", dmi_id, domain_id);
   43.71 +    vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d.\n", dmi_id);
   43.72    
   43.73    if (new_dmi->connected) {
   43.74      vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached instance %d. Ignoring\n", dmi_id);
   43.75      status = TPM_BAD_PARAMETER;
   43.76 -    goto egress;
   43.77 +    goto abort_egress;
   43.78    }
   43.79    
   43.80 +  if (type == VTPM_TYPE_MIGRATED) {
   43.81 +    vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach previously migrated instance %d without recovering first. Ignoring\n", dmi_id);
   43.82 +    status = TPM_BAD_PARAMETER;
   43.83 +    goto abort_egress;
   43.84 +  }
   43.85 +
   43.86    // Initialize the Non-persistent pieces
   43.87 -  new_dmi->dmi_domain_id = domain_id;
   43.88    new_dmi->NVMLocation = NULL;
   43.89    
   43.90    new_dmi->TCSContext = 0;
   43.91 @@ -144,9 +155,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
   43.92  
   43.93    // Design specific new DMI code. 
   43.94    // Includes: create IPCs, Measuring DMI, and maybe launching DMI
   43.95 -  status = VTPM_New_DMI_Extra(new_dmi);
   43.96 +  status = VTPM_New_DMI_Extra(new_dmi, startup_mode);
   43.97    goto egress;
   43.98    
   43.99 + free_egress:   // Error that requires freeing of newly allocated dmi 
  43.100 +  free(new_dmi);
  43.101 +  free(dmi_id_key);
  43.102 +
  43.103   abort_egress:
  43.104    vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s. Cleaning.\n", dmi_id, tpm_get_error_name(status));
  43.105    close_dmi(new_dmi );
  43.106 @@ -221,7 +236,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI( const
  43.107      goto abort_egress;
  43.108    }
  43.109    
  43.110 -	//TODO: Automatically delete file dmi_res->NVMLocation
  43.111 +  //vtpm scripts delete file dmi_res->NVMLocation for us
  43.112    
  43.113    // Close DMI first
  43.114    TPMTRYRETURN(close_dmi( dmi_res ));
    44.1 --- a/tools/vtpm_manager/manager/securestorage.c	Wed Jun 28 07:51:52 2006 -0600
    44.2 +++ b/tools/vtpm_manager/manager/securestorage.c	Wed Jun 28 07:52:21 2006 -0600
    44.3 @@ -190,8 +190,7 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
    44.4    long bytes_written;
    44.5    buffer_t sealed_NVM;
    44.6    
    44.7 -  
    44.8 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x\n", buffer_len(inbuf));
    44.9 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(inbuf));
   44.10  
   44.11    TPMTRYRETURN( envelope_encrypt(inbuf,
   44.12                                   &vtpm_globals->storageKey,
   44.13 @@ -310,6 +309,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
   44.14    UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
   44.15    struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
   44.16    struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes};
   44.17 +  BYTE vtpm_manager_gen = VTPM_MANAGER_GEN;
   44.18  
   44.19    struct hashtable_itr *dmi_itr;
   44.20    VTPM_DMI_RESOURCE *dmi_res;
   44.21 @@ -321,7 +321,8 @@ TPM_RESULT VTPM_SaveManagerData(void) {
   44.22    boot_key_size =  sizeof(UINT32) +       // bootkeysize
   44.23                     bootKeySize;           // boot key
   44.24  
   44.25 -  TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths
   44.26 +  TPMTRYRETURN(buffer_init(&clear_flat_global,sizeof(BYTE) + // manager version
   44.27 +                                              3*sizeof(TPM_DIGEST) + // Auths
   44.28                                                sizeof(UINT32) +// storagekeysize
   44.29                                                storageKeySize, NULL) ); // storage key
   44.30  
   44.31 @@ -332,7 +333,8 @@ TPM_RESULT VTPM_SaveManagerData(void) {
   44.32    boot_key_size = BSG_PackList(flat_boot_key, 1,
   44.33                                 BSG_TPM_SIZE32_DATA, &boot_key_pack);
   44.34  
   44.35 -  BSG_PackList(clear_flat_global.bytes, 3,
   44.36 +  BSG_PackList(clear_flat_global.bytes, 4,
   44.37 +                BSG_TYPE_BYTE,    &vtpm_manager_gen,
   44.38                  BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
   44.39                  BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
   44.40                  BSG_TPM_SIZE32_DATA, &storage_key_pack);
   44.41 @@ -348,7 +350,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
   44.42  
   44.43      flat_dmis = (BYTE *) malloc( 
   44.44                       (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
   44.45 -                     (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info
   44.46 +                     (sizeof(UINT32) +sizeof(BYTE) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info
   44.47  
   44.48      dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
   44.49      do {
   44.50 @@ -360,8 +362,9 @@ TPM_RESULT VTPM_SaveManagerData(void) {
   44.51          continue;
   44.52  
   44.53  
   44.54 -      flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3,
   44.55 +      flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 4,
   44.56                                          BSG_TYPE_UINT32, &dmi_res->dmi_id,
   44.57 +                                        BSG_TYPE_BYTE, &dmi_res->dmi_type,
   44.58                                          BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
   44.59                                          BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
   44.60  
   44.61 @@ -408,6 +411,7 @@ TPM_RESULT VTPM_LoadManagerData(void) {
   44.62    buffer_t  unsealed_data;
   44.63    struct pack_buf_t storage_key_pack, boot_key_pack;
   44.64    UINT32 *dmi_id_key, enc_size;
   44.65 +  BYTE vtpm_manager_gen;
   44.66  
   44.67    VTPM_DMI_RESOURCE *dmi_res;
   44.68    struct stat file_stat;
   44.69 @@ -458,8 +462,14 @@ TPM_RESULT VTPM_LoadManagerData(void) {
   44.70                                   &unsealed_data) );
   44.71    step_size += enc_size;
   44.72  
   44.73 +  if (*unsealed_data.bytes != VTPM_MANAGER_GEN) {
   44.74 +      // Once there is more than one gen, this will include some compatability stuff
   44.75 +      vtpmlogerror(VTPM_LOG_VTPM, "Warning: Manager Data file is gen %d, which this manager is gen %d.\n", vtpm_manager_gen, VTPM_MANAGER_GEN);
   44.76 +  }
   44.77 +
   44.78    // Global Values needing to be saved
   44.79 -  BSG_UnpackList( unsealed_data.bytes, 3,
   44.80 +  BSG_UnpackList( unsealed_data.bytes, 4,
   44.81 +                  BSG_TYPE_BYTE,    &vtpm_manager_gen, 
   44.82                    BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
   44.83                    BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
   44.84                    BSG_TPM_SIZE32_DATA, &storage_key_pack);
   44.85 @@ -469,7 +479,7 @@ TPM_RESULT VTPM_LoadManagerData(void) {
   44.86  
   44.87    // Per DMI values to be saved
   44.88    while ( step_size < fh_size ){
   44.89 -    if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
   44.90 +    if (fh_size - step_size < (long) (sizeof(UINT32) + sizeof(BYTE) + 2*sizeof(TPM_DIGEST))) {
   44.91        vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of manager state.\n", fh_size-step_size);
   44.92        step_size = fh_size;
   44.93      } else {
   44.94 @@ -478,8 +488,9 @@ TPM_RESULT VTPM_LoadManagerData(void) {
   44.95  
   44.96        dmi_res->connected = FALSE;
   44.97  
   44.98 -      step_size += BSG_UnpackList(flat_table + step_size, 3,
   44.99 +      step_size += BSG_UnpackList(flat_table + step_size, 4,
  44.100                                   BSG_TYPE_UINT32, &dmi_res->dmi_id,
  44.101 +                                 BSG_TYPE_BYTE, &dmi_res->dmi_type,
  44.102                                   BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
  44.103                                   BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
  44.104  
    45.1 --- a/tools/vtpm_manager/manager/vtpm_manager.c	Wed Jun 28 07:51:52 2006 -0600
    45.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.c	Wed Jun 28 07:52:21 2006 -0600
    45.3 @@ -92,8 +92,9 @@ TPM_RESULT VTPM_Create_Manager(){
    45.4    status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
    45.5    
    45.6    // If we can read PubEK then there is no owner and we should take it.
    45.7 +  // We use the abilty to read the pubEK to flag that the TPM is owned.
    45.8 +  // FIXME: Change to just trying to take ownership and react to the status
    45.9    if (status == TPM_SUCCESS) { 
   45.10 -    vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
   45.11      TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
   45.12  				    (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
   45.13  				    &SRK_AUTH,
   45.14 @@ -103,6 +104,8 @@ TPM_RESULT VTPM_Create_Manager(){
   45.15      TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
   45.16                                         (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,  
   45.17                                         &vtpm_globals->keyAuth));     
   45.18 +  } else {
   45.19 +    vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
   45.20    }
   45.21    
   45.22    // Generate storage key's auth
   45.23 @@ -165,7 +168,7 @@ TPM_RESULT VTPM_Create_Manager(){
   45.24                                &vtpm_globals->bootKey,
   45.25                                TRUE ) );
   45.26  
   45.27 -  printf("***************************** FIXME: SAVE NEW STATE *******\n");
   45.28 +  TPMTRYRETURN( VTSP_SaveState(vtpm_globals->manager_tcs_handle) );
   45.29    goto egress;
   45.30    
   45.31   abort_egress:
   45.32 @@ -181,7 +184,7 @@ TPM_RESULT VTPM_Create_Manager(){
   45.33  TPM_RESULT VTPM_Init_Manager() {
   45.34    TPM_RESULT status = TPM_FAIL, serviceStatus;   
   45.35    BYTE *randomsead;
   45.36 -  UINT32 randomsize;
   45.37 +  UINT32 randomsize=256;
   45.38  
   45.39    if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
   45.40      status = TPM_FAIL;
   45.41 @@ -216,7 +219,7 @@ TPM_RESULT VTPM_Init_Manager() {
   45.42  			   &vtpm_globals->keyAuth) );
   45.43    vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
   45.44  
   45.45 -	// If failed, create new Manager.
   45.46 +  // If failed, create new Manager.
   45.47    serviceStatus = VTPM_LoadManagerData();
   45.48    if (serviceStatus == TPM_IOERROR) {
   45.49      vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first time initialization.\n");
    46.1 --- a/tools/vtpm_manager/manager/vtpm_manager.h	Wed Jun 28 07:51:52 2006 -0600
    46.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.h	Wed Jun 28 07:52:21 2006 -0600
    46.3 @@ -73,6 +73,12 @@
    46.4  #define VTPM_RESTORE_CONTEXT_FAILED    4
    46.5  #define VTPM_INVALID_REQUEST       5
    46.6  
    46.7 +//*********************** Parameter Values *************************
    46.8 +#define VTPM_TYPE_NON_MIGRATABLE  0x00
    46.9 +#define VTPM_TYPE_MIGRATABLE      0x01
   46.10 +#define VTPM_TYPE_MIGRATED        0xFF // VTPM has been migrated.
   46.11 +                                       // VTPM can be recovered or deleted only
   46.12 +
   46.13  /******************* Command Parameter API *************************
   46.14  
   46.15  VTPM Command Format
   46.16 @@ -94,8 +100,8 @@ VTPM Response Format
   46.17  
   46.18  VTPM_Open:
   46.19    Input Parameters:
   46.20 -    Domain_type: 1 byte
   46.21 -    domain_id: 4 bytes
   46.22 +    Domain_type: 1 byte 
   46.23 +    startup_mode: 1 byte // Cold Boot = 1, resume = 2, deactive = 3
   46.24      instance_id: 4 bytes
   46.25    Output Parameters:
   46.26      None
    47.1 --- a/tools/vtpm_manager/manager/vtpm_manager_handler.c	Wed Jun 28 07:51:52 2006 -0600
    47.2 +++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c	Wed Jun 28 07:52:21 2006 -0600
    47.3 @@ -78,13 +78,14 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
    47.4                                   BOOL is_priv,
    47.5                                   char *thread_name) {
    47.6    TPM_RESULT      status =  TPM_FAIL; // Should never return
    47.7 -  UINT32          dmi, in_param_size, cmd_size, out_param_size, out_message_size, out_message_size_full;
    47.8 -  BYTE            *cmd_header, *in_param, *out_message;
    47.9 +  UINT32          dmi, in_param_size, cmd_size, out_param_size, out_message_size, reply_size;
   47.10 +  BYTE            *cmd_header=NULL, *in_param=NULL, *out_message=NULL, *reply;
   47.11    buffer_t        *command_buf=NULL, *result_buf=NULL;
   47.12    TPM_TAG         tag;
   47.13    TPM_COMMAND_CODE ord;
   47.14    VTPM_DMI_RESOURCE *dmi_res;
   47.15    int  size_read, size_write, i;
   47.16 +  BOOL add_header=TRUE; // This indicates to prepend a header on result_buf before sending
   47.17    
   47.18    cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
   47.19    command_buf = (buffer_t *) malloc(sizeof(buffer_t));
   47.20 @@ -100,7 +101,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
   47.21      // Read command header 
   47.22      size_read = vtpm_ipc_read(rx_ipc_h, NULL, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
   47.23      if (size_read > 0) {
   47.24 -      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read);
   47.25 +      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d]: 0x", size_read);
   47.26        for (i=0; i<size_read; i++) 
   47.27  	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
   47.28      } else {
   47.29 @@ -165,6 +166,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
   47.30           (!dmi_res->connected) ) {
   47.31        vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent or disconnected DMI %d. Aborting...\n", dmi);
   47.32        status = TPM_BAD_PARAMETER;
   47.33 +      goto abort_with_error;
   47.34      }
   47.35  
   47.36      if (tag == VTPM_TAG_REQ) { 
   47.37 @@ -176,9 +178,14 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
   47.38          status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, dmi_res, cmd_header, command_buf, result_buf, thread_name);
   47.39  
   47.40          // This means calling the DMI failed, not that the cmd failed in the DMI
   47.41 +        // Since the return will be interpretted by a TPM app, all errors are IO_ERRORs to the app
   47.42          if (status != TPM_SUCCESS) { 
   47.43 +          status = TPM_IOERROR;
   47.44  	  goto abort_with_error;
   47.45          }
   47.46 +        // Unlike all other commands, forwarded commands yield a result_buf that includes the DMI's status. This
   47.47 +        // should be forwarded to the caller VM
   47.48 +        add_header = FALSE;
   47.49        } else {
   47.50          // We are not supposed to forward TPM commands at all.
   47.51          int i;
   47.52 @@ -205,38 +212,43 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
   47.53  #ifndef VTPM_MULTI_VM
   47.54   abort_with_error:
   47.55  #endif
   47.56 -    
   47.57 -    // Prepend VTPM header with destination DM stamped
   47.58 -    out_param_size = buffer_len(result_buf);
   47.59 -    out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
   47.60 -    out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
   47.61 -    out_message = (BYTE *) malloc (out_message_size_full);
   47.62 +   
   47.63 +    if (add_header) { 
   47.64 +      // Prepend VTPM header with destination DM stamped
   47.65 +      out_param_size = buffer_len(result_buf);
   47.66 +      out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
   47.67 +      reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
   47.68 +      out_message = (BYTE *) malloc (reply_size);
   47.69 +      reply = out_message;
   47.70      
   47.71 -    BSG_PackList(out_message, 4,
   47.72 -		 BSG_TYPE_UINT32, (BYTE *) &dmi,
   47.73 -		 BSG_TPM_TAG, (BYTE *) &tag,
   47.74 -		 BSG_TYPE_UINT32, (BYTE *) &out_message_size,
   47.75 -		 BSG_TPM_RESULT, (BYTE *) &status);
   47.76 +      BSG_PackList(out_message, 4,
   47.77 +		   BSG_TYPE_UINT32, (BYTE *) &dmi,
   47.78 +		   BSG_TPM_TAG, (BYTE *) &tag,
   47.79 +		   BSG_TYPE_UINT32, (BYTE *) &out_message_size,
   47.80 +		   BSG_TPM_RESULT, (BYTE *) &status);
   47.81      
   47.82 -    if (buffer_len(result_buf) > 0) 
   47.83 -      memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size);
   47.84 -
   47.85 -    //Note: Send message + dmi_id
   47.86 -    size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_vtpm_ipc_h, out_message, out_message_size_full );
   47.87 +      if (buffer_len(result_buf) > 0) 
   47.88 +        memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size);
   47.89 +      //Note: Send message + dmi_id
   47.90 +    } else {
   47.91 +      reply = result_buf->bytes;
   47.92 +      reply_size = buffer_len(result_buf);
   47.93 +    }  
   47.94 +    size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size );
   47.95      if (size_write > 0) {
   47.96        vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
   47.97 -      for (i=0; i < out_message_size_full; i++) 
   47.98 -	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]);
   47.99 +      for (i=0; i < reply_size; i++) 
  47.100 +	vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", reply[i]);
  47.101        
  47.102        vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");            
  47.103      } else {
  47.104        vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. Aborting... \n", thread_name);
  47.105        goto abort_command;
  47.106      }
  47.107 -    free(out_message);
  47.108 +    free(out_message); out_message=NULL;
  47.109      
  47.110 -    if (size_write < (int)out_message_size_full) {
  47.111 -      vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, out_message_size_full);
  47.112 +    if (size_write < (int)reply_size) {
  47.113 +      vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, reply_size);
  47.114        goto abort_command;
  47.115      }
  47.116      
  47.117 @@ -246,9 +258,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
  47.118      //free buffers
  47.119      bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
  47.120      //free(in_param); // This was converted to command_buf. No need to free 
  47.121 -    if (command_buf != result_buf) 
  47.122 -      buffer_free(result_buf);
  47.123 -    
  47.124 +    buffer_free(result_buf);
  47.125      buffer_free(command_buf);
  47.126  
  47.127      // If we have a write lock, save the manager table
  47.128 @@ -258,6 +268,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
  47.129      }
  47.130  
  47.131      vtpm_lock_unlock();
  47.132 +    add_header = TRUE; // Reset to the default
  47.133    } // End while(1)
  47.134    
  47.135  }
  47.136 @@ -369,6 +380,7 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(v
  47.137      dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
  47.138      size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV );
  47.139      if (size_write > 0) {
  47.140 +      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
  47.141        for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++) 
  47.142          vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
  47.143  
  47.144 @@ -438,7 +450,8 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(v
  47.145      vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
  47.146    }
  47.147     
  47.148 -  if (buffer_init_convert(result_buf, adj_param_size, in_param) != TPM_SUCCESS) {
  47.149 +  if ( (buffer_init(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV, cmd_header) != TPM_SUCCESS) || 
  47.150 +       (buffer_append_raw(result_buf, adj_param_size, in_param) != TPM_SUCCESS) ) {
  47.151      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
  47.152      status = TPM_FAIL;
  47.153      goto abort_with_error;
    48.1 --- a/tools/vtpm_manager/manager/vtpmd.c	Wed Jun 28 07:51:52 2006 -0600
    48.2 +++ b/tools/vtpm_manager/manager/vtpmd.c	Wed Jun 28 07:52:21 2006 -0600
    48.3 @@ -64,14 +64,6 @@
    48.4  #define VTPM_TX_HP_FNAME       "/var/vtpm/fifos/to_console.fifo"
    48.5  #define VTPM_RX_HP_FNAME       "/var/vtpm/fifos/from_console.fifo"
    48.6  
    48.7 -
    48.8 -#define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo"
    48.9 -#define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
   48.10 -
   48.11 -#define VTPM_TX_FIFO  "/var/vtpm/fifos/vtpm-to-%d.fifo"
   48.12 -#define VTPM_RX_FIFO  "/var/vtpm/fifos/vtpm-from-all.fifo"
   48.13 -
   48.14 -
   48.15  struct vtpm_thread_params_s {
   48.16    vtpm_ipc_handle_t *tx_ipc_h;
   48.17    vtpm_ipc_handle_t *rx_ipc_h;
   48.18 @@ -113,7 +105,7 @@ void signal_handler(int reason) {
   48.19  
   48.20  struct sigaction ctl_c_handler;
   48.21  
   48.22 -TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
   48.23 +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode) {
   48.24  
   48.25    TPM_RESULT status = TPM_SUCCESS;
   48.26    int fh;
   48.27 @@ -150,14 +142,14 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
   48.28  
   48.29      // Measure DMI
   48.30      // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value
   48.31 -    // Also, this mechanism is specific to 1 VM.
   48.32 +    // Also, this mechanism is specific to 1 VM architecture.
   48.33      /*
   48.34      fh = open(TPM_EMULATOR_PATH, O_RDONLY);
   48.35      stat_ret = fstat(fh, &file_stat);
   48.36      if (stat_ret == 0)
   48.37        dmi_size = file_stat.st_size;
   48.38      else {
   48.39 -      vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n");
   48.40 +      vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n");
   48.41        status = TPM_IOERROR;
   48.42        goto abort_egress;
   48.43      }
   48.44 @@ -179,10 +171,20 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
   48.45        status = TPM_RESOURCES;
   48.46        goto abort_egress;
   48.47      } else if (pid == 0) {
   48.48 -      if ( stat(dmi_res->NVMLocation, &file_info) == -1)
   48.49 +      switch (startup_mode) {
   48.50 +      case TPM_ST_CLEAR:
   48.51          execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL);
   48.52 -      else
   48.53 +        break;
   48.54 +      case TPM_ST_STATE:
   48.55          execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL);
   48.56 +        break;
   48.57 +      case TPM_ST_DEACTIVATED:
   48.58 +        execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", dmi_id_str, NULL);
   48.59 +        break;
   48.60 +      default:
   48.61 +        status = TPM_BAD_PARAMETER;
   48.62 +        goto abort_egress;
   48.63 +      }
   48.64  
   48.65        // Returning from these at all is an error.
   48.66        vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
   48.67 @@ -309,7 +311,7 @@ int main(int argc, char **argv) {
   48.68    be_thread_params.fw_tpm = TRUE;
   48.69    be_thread_params.fw_tx_ipc_h = NULL;
   48.70    be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h;
   48.71 -  be_thread_params.is_priv = TRUE;                   //FIXME: Change when HP is up
   48.72 +  be_thread_params.is_priv = FALSE;
   48.73    be_thread_params.thread_name = "Backend Listener";
   48.74  
   48.75    dmi_thread_params.tx_ipc_h = NULL;
   48.76 @@ -318,7 +320,7 @@ int main(int argc, char **argv) {
   48.77    dmi_thread_params.fw_tx_ipc_h = NULL;
   48.78    dmi_thread_params.fw_rx_ipc_h = NULL;
   48.79    dmi_thread_params.is_priv = FALSE; 
   48.80 -  dmi_thread_params.thread_name = "VTPM Listeners";
   48.81 +  dmi_thread_params.thread_name = "VTPM Listener";
   48.82  
   48.83    hp_thread_params.tx_ipc_h = &tx_hp_ipc_h;
   48.84    hp_thread_params.rx_ipc_h = &rx_hp_ipc_h;
   48.85 @@ -345,10 +347,10 @@ int main(int argc, char **argv) {
   48.86    }
   48.87  
   48.88   
   48.89 -//  if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) {
   48.90 -//    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
   48.91 -//    exit(-1);
   48.92 -//  }
   48.93 +  if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) {
   48.94 +    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
   48.95 +    exit(-1);
   48.96 +  }
   48.97   
   48.98    //Join the other threads until exit time.
   48.99    pthread_join(be_thread, NULL);
    49.1 --- a/tools/vtpm_manager/manager/vtpmpriv.h	Wed Jun 28 07:51:52 2006 -0600
    49.2 +++ b/tools/vtpm_manager/manager/vtpmpriv.h	Wed Jun 28 07:52:21 2006 -0600
    49.3 @@ -40,15 +40,19 @@
    49.4  #ifndef __VTPMPRIV_H__
    49.5  #define __VTPMPRIV_H__
    49.6  
    49.7 +#include "vtpm_manager.h"
    49.8  #include "tcg.h"
    49.9  #include "tcs.h"
   49.10  #include "buffer.h"
   49.11  #include "crypto.h"
   49.12  #include "vtpm_ipc.h"
   49.13  
   49.14 -#define STATE_FILE    "/var/vtpm/VTPM"
   49.15 -#define DMI_NVM_FILE  "/var/vtpm/vtpm_dm_%d.data"
   49.16 -#define VTPM_CTL_DM   0
   49.17 +#define VTPM_MANAGER_GEN   2     // This is incremented when the manager's table
   49.18 +                                 // is changed. It's used for backwards compatability
   49.19 +
   49.20 +#define STATE_FILE         "/var/vtpm/VTPM"
   49.21 +#define DMI_NVM_FILE       "/var/vtpm/vtpm_dm_%d.data"
   49.22 +#define VTPM_CTL_DM        0
   49.23  
   49.24  // ------------------------ Private Structures -----------------------
   49.25  typedef struct VTPM_DMI_RESOURCE_T {
   49.26 @@ -70,6 +74,7 @@ typedef struct VTPM_DMI_RESOURCE_T {
   49.27                                          // of NVM.
   49.28    // Persistent Information about DMI
   49.29    UINT32                dmi_id;
   49.30 +  BYTE                  dmi_type;
   49.31    TPM_DIGEST            NVM_measurement;  // Equal to the SHA1 of the blob
   49.32    TPM_DIGEST            DMI_measurement;  // Correct measurement of the owning DMI
   49.33  } VTPM_DMI_RESOURCE;
   49.34 @@ -138,7 +143,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI(const 
   49.35  TPM_RESULT VTPM_SaveManagerData(void);
   49.36  TPM_RESULT VTPM_LoadManagerData(void);
   49.37  
   49.38 -TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
   49.39 +TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode);
   49.40  
   49.41  TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
   49.42  
    50.1 --- a/tools/vtpm_manager/manager/vtsp.c	Wed Jun 28 07:51:52 2006 -0600
    50.2 +++ b/tools/vtpm_manager/manager/vtsp.c	Wed Jun 28 07:52:21 2006 -0600
    50.3 @@ -971,6 +971,17 @@ TPM_RESULT VTSP_Unseal(const TCS_CONTEXT
    50.4    return status;
    50.5  }
    50.6  
    50.7 +TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE    hContext) {
    50.8 +
    50.9 +  vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n");
   50.10 +
   50.11 +  TPM_RESULT status = TPM_SUCCESS;
   50.12 +
   50.13 +  // Call TCS
   50.14 +  return ( TCSP_SaveState ( hContext ) );
   50.15 +
   50.16 +}
   50.17 +
   50.18  
   50.19  // Function Reaches into unsupported TCS command, beware.
   50.20  TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE    hContext,
    51.1 --- a/tools/vtpm_manager/manager/vtsp.h	Wed Jun 28 07:51:52 2006 -0600
    51.2 +++ b/tools/vtpm_manager/manager/vtsp.h	Wed Jun 28 07:52:21 2006 -0600
    51.3 @@ -118,4 +118,6 @@ TPM_RESULT VTSP_Unseal(const TCS_CONTEXT
    51.4                         TCS_AUTH                    *auth,
    51.5                         TCS_AUTH                    *dataAuth);
    51.6  
    51.7 +TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE    hContext);
    51.8 +
    51.9  #endif //_VTSP_H_
    52.1 --- a/tools/vtpm_manager/tcs/tcs.c	Wed Jun 28 07:51:52 2006 -0600
    52.2 +++ b/tools/vtpm_manager/tcs/tcs.c	Wed Jun 28 07:52:21 2006 -0600
    52.3 @@ -1126,6 +1126,49 @@ TPM_RESULT TCSP_ReadPubek(TCS_CONTEXT_HA
    52.4    return(returnCode);
    52.5  }
    52.6  
    52.7 +
    52.8 +TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE   hContext)  // in
    52.9 +{
   52.10 +  // setup input/output parameters block
   52.11 +  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
   52.12 +  UINT32 paramSize = 0;
   52.13 +  TPM_COMMAND_CODE ordinal = TPM_ORD_SaveState;
   52.14 +  TPM_RESULT returnCode = TPM_SUCCESS;
   52.15 +
   52.16 +  // setup the TPM driver input and output buffers
   52.17 +  TDDL_RESULT hRes = TDDL_E_FAIL;
   52.18 +  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
   52.19 +  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
   52.20 +
   52.21 +  // Convert Byte Input parameter in the input byte stream InBuf
   52.22 +  InLength = BSG_PackList(InBuf, 3,
   52.23 +                          BSG_TPM_TAG, &tag,
   52.24 +                          BSG_TYPE_UINT32, &paramSize,
   52.25 +                          BSG_TPM_COMMAND_CODE, &ordinal);
   52.26 +  // fill paramSize again as we now have the correct size
   52.27 +  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
   52.28 +
   52.29 +  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
   52.30 +
   52.31 +  // call the TPM driver
   52.32 +  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == TDDL_SUCCESS) {
   52.33 +    // unpack OutBuf to get the tag, paramSize, & returnCode
   52.34 +    BSG_UnpackList(OutBuf, 3,
   52.35 +                           BSG_TPM_TAG, &tag,
   52.36 +                           BSG_TYPE_UINT32, &paramSize,
   52.37 +                           BSG_TPM_COMMAND_CODE, &returnCode);
   52.38 +
   52.39 +    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
   52.40 +      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
   52.41 +    } else {
   52.42 +      vtpmlogerror(VTPM_LOG_TCS, "TCSP_SaveState Failed with return code %s\n", tpm_get_error_name(returnCode));
   52.43 +    }
   52.44 +  }
   52.45 +
   52.46 +  return(returnCode);
   52.47 +}
   52.48 +
   52.49 +
   52.50  TPM_RESULT TCSP_RawTransmitData(   UINT32 inDataSize,  // in
   52.51  				   BYTE *inData,       // in
   52.52  				   UINT32 *outDataSize,// in/out
    53.1 --- a/tools/vtpm_manager/tcs/tcs.h	Wed Jun 28 07:51:52 2006 -0600
    53.2 +++ b/tools/vtpm_manager/tcs/tcs.h	Wed Jun 28 07:52:21 2006 -0600
    53.3 @@ -229,7 +229,10 @@ TPM_RESULT TCSP_ReadPubek (  TCS_CONTEXT
    53.4  			     );
    53.5  
    53.6  
    53.7 -// Non-Standard TCSP call to give direct access to TransmitData.
    53.8 +// Non-Standard TCSP calls
    53.9 +TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE   hContext);  // in
   53.10 +
   53.11 +//Give direct access to TransmitData.
   53.12  // Key and Auth Management is done before transfering command to TDDL.
   53.13  TPM_RESULT TCSP_RawTransmitData(UINT32 inDataSize,  // in
   53.14  				BYTE *inData,       // in
    54.1 --- a/tools/vtpm_manager/tcs/transmit.c	Wed Jun 28 07:51:52 2006 -0600
    54.2 +++ b/tools/vtpm_manager/tcs/transmit.c	Wed Jun 28 07:52:21 2006 -0600
    54.3 @@ -43,7 +43,17 @@
    54.4  
    54.5  // flag to track whether TDDL has been opened
    54.6  static int g_TDDL_open = 0;
    54.7 -static int g_fd = -1;              // the fd to the TPM
    54.8 +static int g_tx_fd = -1;              // the fd to the TPM
    54.9 +
   54.10 +#ifndef DUMMY_TPM
   54.11 + #define TPM_TX_FNAME "/dev/tpm0"
   54.12 + static int *g_rx_fdp = &g_tx_fd;
   54.13 +#else
   54.14 + #define TPM_TX_FNAME "/tmp/tpm_in.fifo"
   54.15 + #define TPM_RX_FNAME "/tmp/tpm_out.fifo"
   54.16 + static int g_rx_fd = -1;
   54.17 + static int *g_rx_fdp = &g_rx_fd;              // the fd to the TPM
   54.18 +#endif
   54.19  
   54.20  TPM_RESULT
   54.21  TDDL_TransmitData( TDDL_BYTE* in,
   54.22 @@ -60,10 +70,9 @@ TDDL_TransmitData( TDDL_BYTE* in,
   54.23    vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
   54.24    
   54.25    ssize_t size = 0;
   54.26 -  int fd = g_fd;
   54.27    
   54.28    // send the request
   54.29 -  size = write (fd, in, insize);
   54.30 +  size = write (g_tx_fd, in, insize);
   54.31    if (size < 0) {
   54.32      vtpmlogerror(VTPM_LOG_TXDATA, "write() failed");
   54.33      ERRORDIE (TPM_IOERROR);
   54.34 @@ -74,7 +83,7 @@ TDDL_TransmitData( TDDL_BYTE* in,
   54.35    }
   54.36  
   54.37    // read the response
   54.38 -  size = read (fd, out, TCPA_MAX_BUFFER_LENGTH);
   54.39 +  size = read (*g_rx_fdp, out, TCPA_MAX_BUFFER_LENGTH);
   54.40    if (size < 0) {
   54.41      vtpmlogerror(VTPM_LOG_TXDATA, "read() failed");
   54.42      ERRORDIE (TPM_IOERROR);
   54.43 @@ -98,18 +107,20 @@ TDDL_TransmitData( TDDL_BYTE* in,
   54.44  TPM_RESULT TDDL_Open() {
   54.45    
   54.46    TDDL_RESULT status = TDDL_SUCCESS;
   54.47 -  int fd = -1;
   54.48    
   54.49    if (g_TDDL_open)
   54.50      return TPM_FAIL;
   54.51 -  
   54.52 -  fd = open ("/dev/tpm0", O_RDWR);
   54.53 -  if (fd < 0) {
   54.54 +
   54.55 +#ifdef DUMMY_TPM  
   54.56 +  *g_rx_fdp = open (TPM_RX_FNAME, O_RDWR);
   54.57 +#endif
   54.58 +
   54.59 +  g_tx_fd = open (TPM_TX_FNAME, O_RDWR);
   54.60 +  if (g_tx_fd < 0) {
   54.61      vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed");
   54.62      return TPM_IOERROR;
   54.63    }
   54.64    
   54.65 -  g_fd = fd;
   54.66    g_TDDL_open = 1;
   54.67    
   54.68    return status;
   54.69 @@ -119,13 +130,18 @@ void TDDL_Close() {
   54.70    if (! g_TDDL_open)
   54.71          return;
   54.72  
   54.73 -  if (g_fd>= 0) {
   54.74 -    if (close(g_fd) < 0) 
   54.75 +  if (g_tx_fd>= 0) {
   54.76 +    if (close(g_tx_fd) < 0) 
   54.77        vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
   54.78 -    
   54.79 -    g_fd = -1;
   54.80 +    g_tx_fd = -1;
   54.81    }
   54.82      
   54.83 +  if (*g_rx_fdp>= 0) {
   54.84 +    if (close(*g_rx_fdp) < 0) 
   54.85 +      vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
   54.86 +    *g_rx_fdp = -1;
   54.87 +  }
   54.88 +
   54.89    g_TDDL_open = 0;
   54.90    
   54.91  }
    55.1 --- a/tools/vtpm_manager/util/tcg.h	Wed Jun 28 07:51:52 2006 -0600
    55.2 +++ b/tools/vtpm_manager/util/tcg.h	Wed Jun 28 07:52:21 2006 -0600
    55.3 @@ -389,6 +389,11 @@ typedef struct pack_constbuf_t {
    55.4  #define TPM_DELEGATE_ADMIN      TPM_BASE + 77 // Delegation table management not enabled
    55.5  #define TPM_TRANSPORT_EXCLUSIVE    TPM_BASE + 78 // There was a command executed outside of an exclusive transport session
    55.6  
    55.7 +// TPM_STARTUP_TYPE values
    55.8 +#define TPM_ST_CLEAR 0x0001
    55.9 +#define TPM_ST_STATE 0x0002
   55.10 +#define TPM_ST_DEACTIVATED 0x003
   55.11 +
   55.12  // TPM_TAG values
   55.13  #define TPM_TAG_RQU_COMMAND 0x00c1
   55.14  #define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
    56.1 --- a/tools/xenstat/xentop/xentop.1	Wed Jun 28 07:51:52 2006 -0600
    56.2 +++ b/tools/xenstat/xentop/xentop.1	Wed Jun 28 07:52:21 2006 -0600
    56.3 @@ -25,6 +25,8 @@
    56.4  [\fB\-n\fR]
    56.5  [\fB\-r\fR]
    56.6  [\fB\-v\fR]
    56.7 +[\fB\-b\fR]
    56.8 +[\fB\-i\fRITERATIONS]
    56.9  
   56.10  .SH DESCRIPTION
   56.11  \fBxentop\fR displays information about the Xen system and domains, in a
   56.12 @@ -50,6 +52,13 @@ repeat table header before each domain
   56.13  .TP
   56.14  \fB\-v\fR, \fB\-\-vcpus\fR
   56.15  output VCPU data
   56.16 +.TP
   56.17 +\fB\-b\fR, \fB\-\-batch\fR
   56.18 +output data in batch mode (to stdout)
   56.19 +.TP
   56.20 +\fB\-i\fR, \fB\-\-iterations\fR=\fIITERATIONS\fR
   56.21 +maximum number of iterations xentop should produce before ending
   56.22 +
   56.23  
   56.24  .SH "INTERACTIVE COMMANDS"
   56.25  All interactive commands are case-insensitive.
    57.1 --- a/tools/xenstat/xentop/xentop.c	Wed Jun 28 07:51:52 2006 -0600
    57.2 +++ b/tools/xenstat/xentop/xentop.c	Wed Jun 28 07:52:21 2006 -0600
    57.3 @@ -153,6 +153,9 @@ xenstat_node *cur_node = NULL;
    57.4  field_id sort_field = FIELD_DOMID;
    57.5  unsigned int first_domain_index = 0;
    57.6  unsigned int delay = 3;
    57.7 +unsigned int batch = 0;
    57.8 +unsigned int loop = 1;
    57.9 +unsigned int iterations = 0;
   57.10  int show_vcpus = 0;
   57.11  int show_networks = 0;
   57.12  int repeat_header = 0;
   57.13 @@ -179,6 +182,8 @@ static void usage(const char *program)
   57.14  	       "-n, --networks       output vif network data\n"
   57.15  	       "-r, --repeat-header  repeat table header before each domain\n"
   57.16  	       "-v, --vcpus          output vcpu data\n"
   57.17 +	       "-b, --batch	     output in batch mode, no user input accepted\n"
   57.18 +	       "-i, --iterations     number of iterations before exiting\n"
   57.19  	       "\n" XENTOP_BUGSTO,
   57.20  	       program);
   57.21  	return;
   57.22 @@ -236,9 +241,15 @@ static void print(const char *fmt, ...)
   57.23  {
   57.24  	va_list args;
   57.25  
   57.26 -	if(current_row() < lines()-1) {
   57.27 +	if (!batch) {
   57.28 +		if((current_row() < lines()-1)) {
   57.29 +			va_start(args, fmt);
   57.30 +			vw_printw(stdscr, fmt, args);
   57.31 +			va_end(args);
   57.32 +		}
   57.33 +	} else {
   57.34  		va_start(args, fmt);
   57.35 -		vw_printw(stdscr, fmt, args);
   57.36 +		vprintf(fmt, args);
   57.37  		va_end(args);
   57.38  	}
   57.39  }
   57.40 @@ -803,6 +814,7 @@ static void top(void)
   57.41  			do_network(domains[i]);
   57.42  	}
   57.43  
   57.44 +	if(!batch)
   57.45  	do_bottom_line();
   57.46  }
   57.47  
   57.48 @@ -818,9 +830,11 @@ int main(int argc, char **argv)
   57.49  		{ "repeat-header", no_argument,       NULL, 'r' },
   57.50  		{ "vcpus",         no_argument,       NULL, 'v' },
   57.51  		{ "delay",         required_argument, NULL, 'd' },
   57.52 +		{ "batch",	   no_argument,	      NULL, 'b' },
   57.53 +		{ "iterations",	   required_argument, NULL, 'i' },
   57.54  		{ 0, 0, 0, 0 },
   57.55  	};
   57.56 -	const char *sopts = "hVbnvd:";
   57.57 +	const char *sopts = "hVbnvd:bi:";
   57.58  
   57.59  	if (atexit(cleanup) != 0)
   57.60  		fail("Failed to install cleanup handler.\n");
   57.61 @@ -847,6 +861,13 @@ int main(int argc, char **argv)
   57.62  		case 'd':
   57.63  			delay = atoi(optarg);
   57.64  			break;
   57.65 +		case 'b':
   57.66 +			batch = 1;
   57.67 +			break;
   57.68 +		case 'i':
   57.69 +			iterations = atoi(optarg);
   57.70 +			loop = 0;
   57.71 +			break;
   57.72  		}
   57.73  	}
   57.74  
   57.75 @@ -855,28 +876,41 @@ int main(int argc, char **argv)
   57.76  	if (xhandle == NULL)
   57.77  		fail("Failed to initialize xenstat library\n");
   57.78  
   57.79 -	/* Begin curses stuff */
   57.80 -	initscr();
   57.81 -	start_color();
   57.82 -	cbreak();
   57.83 -	noecho();
   57.84 -	nonl();
   57.85 -	keypad(stdscr, TRUE);
   57.86 -	halfdelay(5);
   57.87 -	use_default_colors();
   57.88 -	init_pair(1, -1, COLOR_YELLOW);
   57.89 +	if (!batch) {
   57.90 +		/* Begin curses stuff */
   57.91 +		initscr();
   57.92 +		start_color();
   57.93 +		cbreak();
   57.94 +		noecho();
   57.95 +		nonl();
   57.96 +		keypad(stdscr, TRUE);
   57.97 +		halfdelay(5);
   57.98 +		use_default_colors();
   57.99 +		init_pair(1, -1, COLOR_YELLOW);
  57.100  
  57.101 -	do {
  57.102 -		gettimeofday(&curtime, NULL);
  57.103 -		if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) {
  57.104 -			clear();
  57.105 -			top();
  57.106 -			oldtime = curtime;
  57.107 -			refresh();
  57.108 -		}
  57.109 -		ch = getch();
  57.110 -	} while (handle_key(ch));
  57.111 -
  57.112 +		do {
  57.113 +			gettimeofday(&curtime, NULL);
  57.114 +			if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) {
  57.115 +				clear();
  57.116 +				top();
  57.117 +				oldtime = curtime;
  57.118 +				refresh();
  57.119 +				if ((!loop) && !(--iterations))
  57.120 +					break;
  57.121 +			}
  57.122 +			ch = getch();
  57.123 +		} while (handle_key(ch));
  57.124 +	} else {
  57.125 +			do {
  57.126 +				gettimeofday(&curtime, NULL);
  57.127 +				top();
  57.128 +				oldtime = curtime;
  57.129 +				sleep(delay);
  57.130 +				if ((!loop) && !(--iterations))
  57.131 +					break;
  57.132 +			} while (1);
  57.133 +	}
  57.134 +	
  57.135  	/* Cleanup occurs in cleanup(), so no work to do here. */
  57.136  
  57.137  	return 0;
    58.1 --- a/tools/xm-test/tests/info/02_info_compiledata_pos.py	Wed Jun 28 07:51:52 2006 -0600
    58.2 +++ b/tools/xm-test/tests/info/02_info_compiledata_pos.py	Wed Jun 28 07:52:21 2006 -0600
    58.3 @@ -24,7 +24,8 @@ for line in lines:
    58.4          map[pieces[0]] = pieces[1]
    58.5  
    58.6  for field in ["cores_per_socket", "threads_per_core", "cpu_mhz",
    58.7 -              "total_memory", "free_memory", "xen_major", "xen_minor"]:
    58.8 +              "total_memory", "free_memory", "xen_major", "xen_minor",
    58.9 +              "xen_pagesize"]:
   58.10      val = map[field]
   58.11      if not val.isdigit():
   58.12          FAIL("Numeric field %s not all-numbers: %s" % (field, val))
    59.1 --- a/xen/Makefile	Wed Jun 28 07:51:52 2006 -0600
    59.2 +++ b/xen/Makefile	Wed Jun 28 07:52:21 2006 -0600
    59.3 @@ -14,8 +14,8 @@ default: build
    59.4  .PHONY: dist
    59.5  dist: install
    59.6  
    59.7 -.PHONY: build install clean cscope TAGS tags
    59.8 -build install debug clean cscope TAGS tags::
    59.9 +.PHONY: build install clean distclean cscope TAGS tags
   59.10 +build install debug clean distclean cscope TAGS tags::
   59.11  	make -f Rules.mk _$@
   59.12  
   59.13  .PHONY: _build
   59.14 @@ -50,6 +50,10 @@ build install debug clean cscope TAGS ta
   59.15  	rm -f include/asm-*/asm-offsets.h
   59.16  	rm -f include/xen/acm_policy.h
   59.17  
   59.18 +.PHONY: _distclean
   59.19 +_distclean: clean
   59.20 +	rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out
   59.21 +
   59.22  $(TARGET).gz: $(TARGET)
   59.23  	gzip -f -9 < $< > $@.new
   59.24  	mv $@.new $@
   59.25 @@ -132,11 +136,11 @@ endef
   59.26  
   59.27  .PHONY: _TAGS
   59.28  _TAGS: 
   59.29 -	$(all_sources) | etags -
   59.30 +	rm -f TAGS && $(all_sources) | xargs etags -a
   59.31  
   59.32  .PHONY: _tags
   59.33  _tags: 
   59.34 -	$(all_sources) | xargs ctags
   59.35 +	rm -f TAGS && $(all_sources) | xargs ctags -a
   59.36  
   59.37  .PHONY: _cscope
   59.38  _cscope:
    60.1 --- a/xen/arch/x86/dom0_ops.c	Wed Jun 28 07:51:52 2006 -0600
    60.2 +++ b/xen/arch/x86/dom0_ops.c	Wed Jun 28 07:52:21 2006 -0600
    60.3 @@ -194,6 +194,7 @@ long arch_do_dom0_op(struct dom0_op *op,
    60.4          pi->nr_nodes         = 1;
    60.5          pi->total_pages      = total_pages;
    60.6          pi->free_pages       = avail_domheap_pages();
    60.7 +        pi->scrub_pages      = avail_scrub_pages();
    60.8          pi->cpu_khz          = cpu_khz;
    60.9          memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
   60.10          memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
    61.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Jun 28 07:51:52 2006 -0600
    61.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed Jun 28 07:52:21 2006 -0600
    61.3 @@ -47,7 +47,6 @@
    61.4  #include <asm/shadow_64.h>
    61.5  #endif
    61.6  #include <public/sched.h>
    61.7 -#include <public/hvm/ioreq.h>
    61.8  
    61.9  #define SVM_EXTRA_DEBUG
   61.10  
   61.11 @@ -66,8 +65,6 @@ extern void send_pio_req(struct cpu_user
   61.12  extern int svm_instrlen(struct cpu_user_regs *regs, int mode);
   61.13  extern void svm_dump_inst(unsigned long eip);
   61.14  extern int svm_dbg_on;
   61.15 -void svm_manual_event_injection32(struct vcpu *v, struct cpu_user_regs *regs,