[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 4b51d081378d6783cce48255ffb7655931f26d63
# Parent  c4b68afe97d36b87c460d1bef3eac135f66d9fc9
# Parent  2245974798126074c31521b0903cc7e67e8aec23
merge with xen-unstable.hg
---
 tools/libxc/xc_aout9.h                               |   30 
 tools/libxc/xc_load_aout9.c                          |  178 -
 Makefile                                             |    5 
 docs/Makefile                                        |    3 
 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c       |    2 
 linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c   |  134 +
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c   |   43 
 linux-2.6-xen-sparse/drivers/xen/blkback/common.h    |    1 
 linux-2.6-xen-sparse/drivers/xen/blkback/interface.c |   22 
 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c    |   73 
 linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c    |  100 
 linux-2.6-xen-sparse/drivers/xen/netback/interface.c |    8 
 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c  |    5 
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c   |   65 
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c    |    6 
 linux-2.6-xen-sparse/drivers/xen/tpmback/common.h    |   11 
 linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c |   10 
 linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c   |   91 
 linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c    |   37 
 linux-2.6-xen-sparse/include/linux/skbuff.h          |   42 
 linux-2.6-xen-sparse/net/core/dev.c                  |  238 +-
 linux-2.6-xen-sparse/net/core/skbuff.c               |  144 +
 patches/linux-2.6.16.13/net-gso.patch                | 1974 +++++++++++++++++++
 patches/linux-2.6.16.13/xenoprof-generic.patch       |   81 
 tools/Makefile                                       |    3 
 tools/examples/Makefile                              |    2 
 tools/examples/vtpm                                  |    6 
 tools/examples/vtpm-common.sh                        |   36 
 tools/examples/vtpm-impl                             |  136 +
 tools/libxc/Makefile                                 |    1 
 tools/libxc/xc_ia64_stubs.c                          |   11 
 tools/libxc/xc_linux_build.c                         |    8 
 tools/libxc/xg_private.h                             |    7 
 tools/python/xen/lowlevel/xc/xc.c                    |   29 
 tools/python/xen/xend/XendNode.py                    |    4 
 tools/python/xen/xend/balloon.py                     |   71 
 tools/python/xen/xm/main.py                          |   37 
 tools/vtpm/Rules.mk                                  |    3 
 tools/vtpm/tpm_emulator-0.3-x86_64.patch             |  238 +-
 tools/vtpm/tpm_emulator.patch                        | 1120 ++++++++++
 tools/vtpm/vtpm.patch                                |  236 +-
 tools/vtpm_manager/Rules.mk                          |    3 
 tools/vtpm_manager/manager/dmictl.c                  |   57 
 tools/vtpm_manager/manager/securestorage.c           |   29 
 tools/vtpm_manager/manager/vtpm_manager.c            |   11 
 tools/vtpm_manager/manager/vtpm_manager.h            |   10 
 tools/vtpm_manager/manager/vtpm_manager_handler.c    |   75 
 tools/vtpm_manager/manager/vtpmd.c                   |   40 
 tools/vtpm_manager/manager/vtpmpriv.h                |   13 
 tools/vtpm_manager/manager/vtsp.c                    |   11 
 tools/vtpm_manager/manager/vtsp.h                    |    2 
 tools/vtpm_manager/tcs/tcs.c                         |   43 
 tools/vtpm_manager/tcs/tcs.h                         |    5 
 tools/vtpm_manager/tcs/transmit.c                    |   42 
 tools/vtpm_manager/util/tcg.h                        |    5 
 tools/xenstat/xentop/xentop.1                        |    9 
 tools/xenstat/xentop/xentop.c                        |   84 
 tools/xm-test/tests/info/02_info_compiledata_pos.py  |    3 
 xen/Makefile                                         |   12 
 xen/arch/x86/dom0_ops.c                              |    1 
 xen/arch/x86/hvm/svm/svm.c                           |   40 
 xen/arch/x86/hvm/vioapic.c                           |   41 
 xen/arch/x86/hvm/vlapic.c                            |   38 
 xen/arch/x86/hvm/vmx/vmx.c                           |  150 -
 xen/arch/x86/microcode.c                             |  138 -
 xen/arch/x86/oprofile/nmi_int.c                      |    2 
 xen/arch/x86/oprofile/xenoprof.c                     |  358 ++-
 xen/arch/x86/smp.c                                   |    5 
 xen/arch/x86/x86_emulate.c                           |    9 
 xen/common/kernel.c                                  |    5 
 xen/common/page_alloc.c                              |   12 
 xen/include/asm-x86/bitops.h                         |   30 
 xen/include/asm-x86/hvm/vcpu.h                       |    3 
 xen/include/asm-x86/hvm/vlapic.h                     |   62 
 xen/include/public/dom0_ops.h                        |    1 
 xen/include/public/hvm/ioreq.h                       |    5 
 xen/include/public/io/netif.h                        |   33 
 xen/include/public/version.h                         |    5 
 xen/include/public/xenoprof.h                        |    9 
 xen/include/xen/mm.h                                 |    1 
 xen/include/xen/xenoprof.h                           |    1 
 81 files changed, 5191 insertions(+), 1463 deletions(-)

diff -r c4b68afe97d3 -r 4b51d081378d Makefile
--- a/Makefile  Wed Jun 28 07:51:52 2006 -0600
+++ b/Makefile  Wed Jun 28 07:52:21 2006 -0600
@@ -123,7 +123,10 @@ clean::
 
 # clean, but blow away kernel build tree plus tarballs
 .PHONY: distclean
-distclean: clean
+distclean:
+       $(MAKE) -C xen distclean
+       $(MAKE) -C tools distclean
+       $(MAKE) -C docs distclean
        rm -rf dist patches/tmp
        for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done
        for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done
diff -r c4b68afe97d3 -r 4b51d081378d docs/Makefile
--- a/docs/Makefile     Wed Jun 28 07:51:52 2006 -0600
+++ b/docs/Makefile     Wed Jun 28 07:52:21 2006 -0600
@@ -80,6 +80,9 @@ clean:
        rm -rf man5
        rm -rf man1
 
+.PHONY: distclean
+distclean: clean
+
 .PHONY: install
 install: all
        rm -rf $(DESTDIR)$(pkgdocdir)
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Wed Jun 28 07:51:52 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Wed Jun 28 07:52:21 
2006 -0600
@@ -264,7 +264,7 @@ static void contiguous_bitmap_clear(
 }
 
 /* Protected by balloon_lock. */
-#define MAX_CONTIG_ORDER 7
+#define MAX_CONTIG_ORDER 9 /* 2MB */
 static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
 
 /* Ensure multi-page extents are contiguous in machine memory. */
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Wed Jun 28 
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Wed Jun 28 
07:52:21 2006 -0600
@@ -28,6 +28,7 @@
 
 #include <xen/interface/xen.h>
 #include <xen/interface/xenoprof.h>
+#include <../../../drivers/oprofile/cpu_buffer.h>
 
 static int xenoprof_start(void);
 static void xenoprof_stop(void);
@@ -50,6 +51,11 @@ int ovf_irq[NR_CPUS];
 /* cpu model type string - copied from Xen memory space on XENOPROF_init 
command */
 char cpu_type[XENOPROF_CPU_TYPE_SIZE];
 
+/* Passive sample buffers shared with Xen */
+xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS];
+/* Passive shared buffer area */
+char *p_shared_buffer[MAX_OPROF_DOMAINS];
+
 #ifdef CONFIG_PM
 
 static int xenoprof_suspend(struct sys_device * dev, pm_message_t state)
@@ -102,16 +108,14 @@ static void __exit exit_driverfs(void)
 #endif /* CONFIG_PM */
 
 unsigned long long oprofile_samples = 0;
-
-static irqreturn_t 
-xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+unsigned long long p_oprofile_samples = 0;
+
+unsigned int pdomains;
+struct xenoprof_passive passive_domains[MAX_OPROF_DOMAINS];
+
+static void xenoprof_add_pc(xenoprof_buf_t *buf, int is_passive)
 {
        int head, tail, size;
-       struct xenoprof_buf * buf;
-       int cpu;
-
-       cpu = smp_processor_id();
-       buf = xenoprof_buf[cpu];
 
        head = buf->event_head;
        tail = buf->event_tail;
@@ -122,7 +126,10 @@ xenoprof_ovf_interrupt(int irq, void * d
                        oprofile_add_pc(buf->event_log[tail].eip,
                                        buf->event_log[tail].mode,
                                        buf->event_log[tail].event);
-                       oprofile_samples++;
+                       if (!is_passive)
+                               oprofile_samples++;
+                       else
+                               p_oprofile_samples++;
                        tail++;
                }
                tail = 0;
@@ -131,11 +138,47 @@ xenoprof_ovf_interrupt(int irq, void * d
                oprofile_add_pc(buf->event_log[tail].eip,
                                buf->event_log[tail].mode,
                                buf->event_log[tail].event);
-               oprofile_samples++;
+               if (!is_passive)
+                       oprofile_samples++;
+               else
+                       p_oprofile_samples++;
                tail++;
        }
 
        buf->event_tail = tail;
+}
+
+static void xenoprof_handle_passive(void)
+{
+       int i, j;
+
+       for (i = 0; i < pdomains; i++)
+               for (j = 0; j < passive_domains[i].nbuf; j++) {
+                       xenoprof_buf_t *buf = p_xenoprof_buf[i][j];
+                       if (buf->event_head == buf->event_tail)
+                               continue;
+                        oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_START, 
passive_domains[i].domain_id);
+                       xenoprof_add_pc(buf, 1);
+                        oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_STOP, 
passive_domains[i].domain_id);
+               }                       
+}
+
+static irqreturn_t 
+xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+       struct xenoprof_buf * buf;
+       int cpu;
+       static unsigned long flag;
+
+       cpu = smp_processor_id();
+       buf = xenoprof_buf[cpu];
+
+       xenoprof_add_pc(buf, 0);
+
+       if (is_primary && !test_and_set_bit(0, &flag)) {
+               xenoprof_handle_passive();
+               clear_bit(0, &flag);
+       }
 
        return IRQ_HANDLED;
 }
@@ -312,6 +355,63 @@ out:
        return ret;
 }
 
+static int xenoprof_set_passive(int * p_domains,
+                                unsigned int pdoms)
+{
+       int ret;
+       int i, j;
+       int vm_size;
+       int npages;
+       struct xenoprof_buf *buf;
+       pgprot_t prot = __pgprot(_KERNPG_TABLE);
+
+       if (!is_primary)
+               return 0;
+
+       if (pdoms > MAX_OPROF_DOMAINS)
+               return -E2BIG;
+
+       ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_passive_list, NULL);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < pdoms; i++) {
+               passive_domains[i].domain_id = p_domains[i];
+               passive_domains[i].max_samples = 2048;
+               ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, 
&passive_domains[i]);
+               if (ret)
+                       return ret;
+
+               npages = (passive_domains[i].bufsize * passive_domains[i].nbuf 
- 1) / PAGE_SIZE + 1;
+               vm_size = npages * PAGE_SIZE;
+
+               p_shared_buffer[i] = (char 
*)vm_map_xen_pages(passive_domains[i].buf_maddr,
+                                                             vm_size, prot);
+               if (!p_shared_buffer[i]) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               for (j = 0; j < passive_domains[i].nbuf; j++) {
+                       buf = (struct xenoprof_buf *)
+                               &p_shared_buffer[i][j * 
passive_domains[i].bufsize];
+                       BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
+                       p_xenoprof_buf[i][buf->vcpu_id] = buf;
+               }
+
+       }
+
+       pdomains = pdoms;
+       return 0;
+
+out:
+       for (j = 0; j < i; j++) {
+               vunmap(p_shared_buffer[j]);
+               p_shared_buffer[j] = NULL;
+       }
+
+       return ret;
+}
 
 struct op_counter_config counter_config[OP_MAX_COUNTER];
 
@@ -346,6 +446,7 @@ struct oprofile_operations xenoprof_ops 
 struct oprofile_operations xenoprof_ops = {
        .create_files   = xenoprof_create_files,
        .set_active     = xenoprof_set_active,
+       .set_passive    = xenoprof_set_passive,
        .setup          = xenoprof_setup,
        .shutdown       = xenoprof_shutdown,
        .start          = xenoprof_start,
@@ -420,6 +521,8 @@ int __init oprofile_arch_init(struct opr
 
 void __exit oprofile_arch_exit(void)
 {
+       int i;
+
        if (using_xenoprof)
                exit_driverfs();
 
@@ -427,6 +530,13 @@ void __exit oprofile_arch_exit(void)
                vunmap(shared_buffer);
                shared_buffer = NULL;
        }
-       if (is_primary)
+       if (is_primary) {
+               for (i = 0; i < pdomains; i++)
+                       if (p_shared_buffer[i]) {
+                               vunmap(p_shared_buffer[i]);
+                               p_shared_buffer[i] = NULL;
+                       }
                HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL);
-}
+        }
+
+}
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Wed Jun 28 
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Wed Jun 28 
07:52:21 2006 -0600
@@ -172,7 +172,7 @@ static unsigned long current_target(void
 
 static int increase_reservation(unsigned long nr_pages)
 {
-       unsigned long *frame_list, pfn, i, flags;
+       unsigned long *frame_list, frame, pfn, i, flags;
        struct page   *page;
        long           rc;
        struct xen_memory_reservation reservation = {
@@ -185,8 +185,11 @@ static int increase_reservation(unsigned
                nr_pages = PAGE_SIZE / sizeof(unsigned long);
 
        frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
-       if (frame_list == NULL)
-               return -ENOMEM;
+       if (frame_list == NULL) {
+               frame_list = &frame;
+               if (nr_pages > 1)
+                       nr_pages = 1;
+       }
 
        balloon_lock(flags);
 
@@ -202,14 +205,17 @@ static int increase_reservation(unsigned
        rc = HYPERVISOR_memory_op(
                XENMEM_populate_physmap, &reservation);
        if (rc < nr_pages) {
-               int ret;
-               /* We hit the Xen hard limit: reprobe. */
-               set_xen_guest_handle(reservation.extent_start, frame_list);
-               reservation.nr_extents   = rc;
-               ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
-                               &reservation);
-               BUG_ON(ret != rc);
-               hard_limit = current_pages + rc - driver_pages;
+               if (rc > 0) {
+                       int ret;
+
+                       /* We hit the Xen hard limit: reprobe. */
+                       reservation.nr_extents = rc;
+                       ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+                                       &reservation);
+                       BUG_ON(ret != rc);
+               }
+               if (rc >= 0)
+                       hard_limit = current_pages + rc - driver_pages;
                goto out;
        }
 
@@ -247,14 +253,15 @@ static int increase_reservation(unsigned
  out:
        balloon_unlock(flags);
 
-       free_page((unsigned long)frame_list);
+       if (frame_list != &frame)
+               free_page((unsigned long)frame_list);
 
        return 0;
 }
 
 static int decrease_reservation(unsigned long nr_pages)
 {
-       unsigned long *frame_list, pfn, i, flags;
+       unsigned long *frame_list, frame, pfn, i, flags;
        struct page   *page;
        void          *v;
        int            need_sleep = 0;
@@ -269,8 +276,11 @@ static int decrease_reservation(unsigned
                nr_pages = PAGE_SIZE / sizeof(unsigned long);
 
        frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
-       if (frame_list == NULL)
-               return -ENOMEM;
+       if (frame_list == NULL) {
+               frame_list = &frame;
+               if (nr_pages > 1)
+                       nr_pages = 1;
+       }
 
        for (i = 0; i < nr_pages; i++) {
                if ((page = alloc_page(GFP_HIGHUSER)) == NULL) {
@@ -321,7 +331,8 @@ static int decrease_reservation(unsigned
 
        balloon_unlock(flags);
 
-       free_page((unsigned long)frame_list);
+       if (frame_list != &frame)
+               free_page((unsigned long)frame_list);
 
        return need_sleep;
 }
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Wed Jun 28 07:51:52 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Wed Jun 28 07:52:21 
2006 -0600
@@ -95,6 +95,7 @@ typedef struct blkif_st {
 } blkif_t;
 
 blkif_t *blkif_alloc(domid_t domid);
+void blkif_disconnect(blkif_t *blkif);
 void blkif_free(blkif_t *blkif);
 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
 
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Wed Jun 28 
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Wed Jun 28 
07:52:21 2006 -0600
@@ -32,6 +32,7 @@
 
 #include "common.h"
 #include <xen/evtchn.h>
+#include <linux/kthread.h>
 
 static kmem_cache_t *blkif_cachep;
 
@@ -139,22 +140,33 @@ int blkif_map(blkif_t *blkif, unsigned l
        return 0;
 }
 
-void blkif_free(blkif_t *blkif)
+void blkif_disconnect(blkif_t *blkif)
 {
+       if (blkif->xenblkd) {
+               kthread_stop(blkif->xenblkd);
+               blkif->xenblkd = NULL;
+       }
+
        atomic_dec(&blkif->refcnt);
        wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
+       atomic_inc(&blkif->refcnt);
 
-       /* Already disconnected? */
-       if (blkif->irq)
+       if (blkif->irq) {
                unbind_from_irqhandler(blkif->irq, blkif);
-
-       vbd_free(&blkif->vbd);
+               blkif->irq = 0;
+       }
 
        if (blkif->blk_ring.sring) {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
+               blkif->blk_ring.sring = NULL;
        }
+}
 
+void blkif_free(blkif_t *blkif)
+{
+       if (!atomic_dec_and_test(&blkif->refcnt))
+               BUG();
        kmem_cache_free(blkif_cachep, blkif);
 }
 
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Jun 28 07:51:52 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Jun 28 07:52:21 
2006 -0600
@@ -42,7 +42,6 @@ static int connect_ring(struct backend_i
 static int connect_ring(struct backend_info *);
 static void backend_changed(struct xenbus_watch *, const char **,
                            unsigned int);
-
 
 static void update_blkif_status(blkif_t *blkif)
 { 
@@ -73,6 +72,70 @@ static void update_blkif_status(blkif_t 
 }
 
 
+/****************************************************************
+ *  sysfs interface for VBD I/O requests
+ */
+
+#ifdef CONFIG_SYSFS
+
+#define VBD_SHOW(name, format, args...)                                        
\
+       static ssize_t show_##name(struct device *_dev,                 \
+                                  struct device_attribute *attr,       \
+                                  char *buf)                           \
+       {                                                               \
+               struct xenbus_device *dev = to_xenbus_device(_dev);     \
+               struct backend_info *be = dev->dev.driver_data;         \
+                                                                       \
+               return sprintf(buf, format, ##args);                    \
+       }                                                               \
+       DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
+VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
+VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
+
+static struct attribute *vbdstat_attrs[] = {
+       &dev_attr_oo_req.attr,
+       &dev_attr_rd_req.attr,
+       &dev_attr_wr_req.attr,
+       NULL
+};
+
+static struct attribute_group vbdstat_group = {
+       .name = "statistics",
+       .attrs = vbdstat_attrs,
+};
+
+int xenvbd_sysfs_addif(struct xenbus_device *dev)
+{
+       int error = 0;
+       
+       error = sysfs_create_group(&dev->dev.kobj,
+                                  &vbdstat_group);
+       if (error)
+               goto fail;
+       
+       return 0;
+       
+fail:
+       sysfs_remove_group(&dev->dev.kobj,
+                          &vbdstat_group);
+       return error;
+}
+
+void xenvbd_sysfs_delif(struct xenbus_device *dev)
+{
+       sysfs_remove_group(&dev->dev.kobj,
+                          &vbdstat_group);
+}
+
+#else
+
+#define xenvbd_sysfs_addif(dev) (0)
+#define xenvbd_sysfs_delif(dev) ((void)0)
+
+#endif /* CONFIG_SYSFS */
+
 static ssize_t show_physical_device(struct device *_dev,
                                    struct device_attribute *attr, char *buf)
 {
@@ -105,15 +168,17 @@ static int blkback_remove(struct xenbus_
                kfree(be->backend_watch.node);
                be->backend_watch.node = NULL;
        }
+
        if (be->blkif) {
-               if (be->blkif->xenblkd)
-                       kthread_stop(be->blkif->xenblkd);
+               blkif_disconnect(be->blkif);
+               vbd_free(&be->blkif->vbd);
                blkif_free(be->blkif);
                be->blkif = NULL;
        }
 
        device_remove_file(&dev->dev, &dev_attr_physical_device);
        device_remove_file(&dev->dev, &dev_attr_mode);
+       xenvbd_sysfs_delif(dev);
 
        kfree(be);
        dev->dev.driver_data = NULL;
@@ -236,6 +301,7 @@ static void backend_changed(struct xenbu
 
                device_create_file(&dev->dev, &dev_attr_physical_device);
                device_create_file(&dev->dev, &dev_attr_mode);
+               xenvbd_sysfs_addif(dev);
 
                /* We're potentially connected now */
                update_blkif_status(be->blkif); 
@@ -273,6 +339,7 @@ static void frontend_changed(struct xenb
                break;
 
        case XenbusStateClosing:
+               blkif_disconnect(be->blkif);
                xenbus_switch_state(dev, XenbusStateClosing);
                break;
 
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Jun 28 07:51:52 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Jun 28 07:52:21 
2006 -0600
@@ -58,15 +58,17 @@ HYPERVISOR_ATTR_RO(minor);
 
 static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer)
 {
-       int ret;
-       char *extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
+       int ret = -ENOMEM;
+       char *extra;
+
+       extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL);
        if (extra) {
                ret = HYPERVISOR_xen_version(XENVER_extraversion, extra);
                if (!ret)
-                       return sprintf(buffer, "%s\n", extra);
+                       ret = sprintf(buffer, "%s\n", extra);
                kfree(extra);
-       } else
-               ret = -ENOMEM;
+       }
+
        return ret;
 }
 
@@ -86,7 +88,8 @@ static struct attribute_group version_gr
 
 static int __init xen_sysfs_version_init(void)
 {
-       return sysfs_create_group(&hypervisor_subsys.kset.kobj, &version_group);
+       return sysfs_create_group(&hypervisor_subsys.kset.kobj,
+                                 &version_group);
 }
 
 static void xen_sysfs_version_destroy(void)
@@ -98,16 +101,16 @@ static void xen_sysfs_version_destroy(vo
 
 static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer)
 {
-       int ret;
-       struct xen_compile_info *info =
-           kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
+       int ret = -ENOMEM;
+       struct xen_compile_info *info;
+
+       info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
        if (info) {
                ret = HYPERVISOR_xen_version(XENVER_compile_info, info);
                if (!ret)
                        ret = sprintf(buffer, "%s\n", info->compiler);
                kfree(info);
-       } else
-               ret = -ENOMEM;
+       }
 
        return ret;
 }
@@ -116,7 +119,7 @@ HYPERVISOR_ATTR_RO(compiler);
 
 static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer)
 {
-       int ret;
+       int ret = -ENOMEM;
        struct xen_compile_info *info;
 
        info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
@@ -125,8 +128,8 @@ static ssize_t compiled_by_show(struct h
                if (!ret)
                        ret = sprintf(buffer, "%s\n", info->compile_by);
                kfree(info);
-       } else
-               ret = -ENOMEM;
+       }
+
        return ret;
 }
 
@@ -134,7 +137,7 @@ HYPERVISOR_ATTR_RO(compiled_by);
 
 static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer)
 {
-       int ret;
+       int ret = -ENOMEM;
        struct xen_compile_info *info;
 
        info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL);
@@ -143,8 +146,8 @@ static ssize_t compile_date_show(struct 
                if (!ret)
                        ret = sprintf(buffer, "%s\n", info->compile_date);
                kfree(info);
-       } else
-               ret = -ENOMEM;
+       }
+
        return ret;
 }
 
@@ -178,15 +181,17 @@ static void xen_compilation_destroy(void
 
 static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer)
 {
-       int ret;
-       char *caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
+       int ret = -ENOMEM;
+       char *caps;
+
+       caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL);
        if (caps) {
                ret = HYPERVISOR_xen_version(XENVER_capabilities, caps);
                if (!ret)
                        ret = sprintf(buffer, "%s\n", caps);
                kfree(caps);
-       } else
-               ret = -ENOMEM;
+       }
+
        return ret;
 }
 
@@ -194,15 +199,17 @@ HYPERVISOR_ATTR_RO(capabilities);
 
 static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer)
 {
-       int ret;
-       char *cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
+       int ret = -ENOMEM;
+       char *cset;
+
+       cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL);
        if (cset) {
                ret = HYPERVISOR_xen_version(XENVER_changeset, cset);
                if (!ret)
                        ret = sprintf(buffer, "%s\n", cset);
                kfree(cset);
-       } else
-               ret = -ENOMEM;
+       }
+
        return ret;
 }
 
@@ -210,36 +217,51 @@ HYPERVISOR_ATTR_RO(changeset);
 
 static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer)
 {
-       int ret;
-       struct xen_platform_parameters *parms =
-           kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
+       int ret = -ENOMEM;
+       struct xen_platform_parameters *parms;
+
+       parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL);
        if (parms) {
-               ret = HYPERVISOR_xen_version(XENVER_platform_parameters, parms);
+               ret = HYPERVISOR_xen_version(XENVER_platform_parameters,
+                                            parms);
                if (!ret)
                        ret = sprintf(buffer, "%lx\n", parms->virt_start);
                kfree(parms);
-       } else
-               ret = -ENOMEM;
+       }
+
        return ret;
 }
 
 HYPERVISOR_ATTR_RO(virtual_start);
+
+static ssize_t pagesize_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+       int ret;
+
+       ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL);
+       if (ret > 0)
+               ret = sprintf(buffer, "%x\n", ret);
+
+       return ret;
+}
+
+HYPERVISOR_ATTR_RO(pagesize);
 
 /* eventually there will be several more features to export */
 static ssize_t xen_feature_show(int index, char *buffer)
 {
-       int ret;
-
-       struct xen_feature_info *info =
-           kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
+       int ret = -ENOMEM;
+       struct xen_feature_info *info;
+
+       info = kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL);
        if (info) {
                info->submap_idx = index;
                ret = HYPERVISOR_xen_version(XENVER_get_features, info);
                if (!ret)
                        ret = sprintf(buffer, "%d\n", info->submap);
                kfree(info);
-       } else
-               ret = -ENOMEM;
+       }
+
        return ret;
 }
 
@@ -254,6 +276,7 @@ static struct attribute *xen_properties_
        &capabilities_attr.attr,
        &changeset_attr.attr,
        &virtual_start_attr.attr,
+       &pagesize_attr.attr,
        &writable_pt_attr.attr,
        NULL
 };
@@ -271,7 +294,8 @@ static int __init xen_properties_init(vo
 
 static void xen_properties_destroy(void)
 {
-       sysfs_remove_group(&hypervisor_subsys.kset.kobj, &xen_properties_group);
+       sysfs_remove_group(&hypervisor_subsys.kset.kobj,
+                          &xen_properties_group);
 }
 
 static int __init hyper_sysfs_init(void)
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Wed Jun 28 
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Wed Jun 28 
07:52:21 2006 -0600
@@ -37,9 +37,9 @@ static void __netif_up(netif_t *netif)
 static void __netif_up(netif_t *netif)
 {
        struct net_device *dev = netif->dev;
-       spin_lock_bh(&dev->xmit_lock);
+       netif_tx_lock_bh(dev);
        netif->active = 1;
-       spin_unlock_bh(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
        enable_irq(netif->irq);
        netif_schedule_work(netif);
 }
@@ -48,9 +48,9 @@ static void __netif_down(netif_t *netif)
 {
        struct net_device *dev = netif->dev;
        disable_irq(netif->irq);
-       spin_lock_bh(&dev->xmit_lock);
+       netif_tx_lock_bh(dev);
        netif->active = 0;
-       spin_unlock_bh(&dev->xmit_lock);
+       netif_tx_unlock_bh(dev);
        netif_deschedule_work(netif);
 }
 
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Wed Jun 28 
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Wed Jun 28 
07:52:21 2006 -0600
@@ -125,6 +125,10 @@ static struct ethtool_ops network_ethtoo
 {
        .get_tx_csum = ethtool_op_get_tx_csum,
        .set_tx_csum = ethtool_op_set_tx_csum,
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = ethtool_op_set_sg,
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = ethtool_op_set_tso,
 };
 
 /*
@@ -152,6 +156,7 @@ static void loopback_construct(struct ne
 
        dev->features        = (NETIF_F_HIGHDMA |
                                NETIF_F_LLTX |
+                               NETIF_F_TSO |
                                NETIF_F_SG |
                                NETIF_F_IP_CSUM);
 
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Jun 28 
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Jun 28 
07:52:21 2006 -0600
@@ -43,7 +43,7 @@ static void netif_idx_release(u16 pendin
 static void netif_idx_release(u16 pending_idx);
 static void netif_page_release(struct page *page);
 static void make_tx_response(netif_t *netif, 
-                            u16      id,
+                            netif_tx_request_t *txp,
                             s8       st);
 static int  make_rx_response(netif_t *netif, 
                             u16      id, 
@@ -481,7 +481,7 @@ inline static void net_tx_action_dealloc
 
                netif = pending_tx_info[pending_idx].netif;
 
-               make_tx_response(netif, pending_tx_info[pending_idx].req.id, 
+               make_tx_response(netif, &pending_tx_info[pending_idx].req, 
                                 NETIF_RSP_OKAY);
 
                pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
@@ -490,14 +490,16 @@ inline static void net_tx_action_dealloc
        }
 }
 
-static void netbk_tx_err(netif_t *netif, RING_IDX end)
+static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end)
 {
        RING_IDX cons = netif->tx.req_cons;
 
        do {
-               netif_tx_request_t *txp = RING_GET_REQUEST(&netif->tx, cons);
-               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
-       } while (++cons < end);
+               make_tx_response(netif, txp, NETIF_RSP_ERROR);
+               if (++cons >= end)
+                       break;
+               txp = RING_GET_REQUEST(&netif->tx, cons);
+       } while (1);
        netif->tx.req_cons = cons;
        netif_schedule_work(netif);
        netif_put(netif);
@@ -508,7 +510,7 @@ static int netbk_count_requests(netif_t 
 {
        netif_tx_request_t *first = txp;
        RING_IDX cons = netif->tx.req_cons;
-       int frags = 1;
+       int frags = 0;
 
        while (txp->flags & NETTXF_more_data) {
                if (frags >= work_to_do) {
@@ -543,7 +545,7 @@ static gnttab_map_grant_ref_t *netbk_get
        skb_frag_t *frags = shinfo->frags;
        netif_tx_request_t *txp;
        unsigned long pending_idx = *((u16 *)skb->data);
-       RING_IDX cons = netif->tx.req_cons + 1;
+       RING_IDX cons = netif->tx.req_cons;
        int i, start;
 
        /* Skip first skb fragment if it is on same page as header fragment. */
@@ -581,7 +583,7 @@ static int netbk_tx_check_mop(struct sk_
        err = mop->status;
        if (unlikely(err)) {
                txp = &pending_tx_info[pending_idx].req;
-               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+               make_tx_response(netif, txp, NETIF_RSP_ERROR);
                pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
                netif_put(netif);
        } else {
@@ -614,7 +616,7 @@ static int netbk_tx_check_mop(struct sk_
 
                /* Error on this fragment: respond to client with an error. */
                txp = &pending_tx_info[pending_idx].req;
-               make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
+               make_tx_response(netif, txp, NETIF_RSP_ERROR);
                pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
                netif_put(netif);
 
@@ -668,6 +670,7 @@ static void net_tx_action(unsigned long 
        struct sk_buff *skb;
        netif_t *netif;
        netif_tx_request_t txreq;
+       struct netif_tx_extra txtra;
        u16 pending_idx;
        RING_IDX i;
        gnttab_map_grant_ref_t *mop;
@@ -726,22 +729,37 @@ static void net_tx_action(unsigned long 
                }
                netif->remaining_credit -= txreq.size;
 
+               work_to_do--;
+               netif->tx.req_cons = ++i;
+
+               if (txreq.flags & NETTXF_extra_info) {
+                       if (work_to_do-- <= 0) {
+                               DPRINTK("Missing extra info\n");
+                               netbk_tx_err(netif, &txreq, i);
+                               continue;
+                       }
+
+                       memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i),
+                              sizeof(txtra));
+                       netif->tx.req_cons = ++i;
+               }
+
                ret = netbk_count_requests(netif, &txreq, work_to_do);
                if (unlikely(ret < 0)) {
-                       netbk_tx_err(netif, i - ret);
+                       netbk_tx_err(netif, &txreq, i - ret);
                        continue;
                }
                i += ret;
 
                if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
                        DPRINTK("Too many frags\n");
-                       netbk_tx_err(netif, i);
+                       netbk_tx_err(netif, &txreq, i);
                        continue;
                }
 
                if (unlikely(txreq.size < ETH_HLEN)) {
                        DPRINTK("Bad packet size: %d\n", txreq.size);
-                       netbk_tx_err(netif, i);
+                       netbk_tx_err(netif, &txreq, i);
                        continue; 
                }
 
@@ -750,25 +768,31 @@ static void net_tx_action(unsigned long 
                        DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", 
                                txreq.offset, txreq.size, 
                                (txreq.offset &~PAGE_MASK) + txreq.size);
-                       netbk_tx_err(netif, i);
+                       netbk_tx_err(netif, &txreq, i);
                        continue;
                }
 
                pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
 
                data_len = (txreq.size > PKT_PROT_LEN &&
-                           ret < MAX_SKB_FRAGS + 1) ?
+                           ret < MAX_SKB_FRAGS) ?
                        PKT_PROT_LEN : txreq.size;
 
                skb = alloc_skb(data_len+16, GFP_ATOMIC);
                if (unlikely(skb == NULL)) {
                        DPRINTK("Can't allocate a skb in start_xmit.\n");
-                       netbk_tx_err(netif, i);
+                       netbk_tx_err(netif, &txreq, i);
                        break;
                }
 
                /* Packets passed to netif_rx() must have some headroom. */
                skb_reserve(skb, 16);
+
+               if (txreq.flags & NETTXF_gso) {
+                       skb_shinfo(skb)->gso_size = txtra.u.gso.size;
+                       skb_shinfo(skb)->gso_segs = txtra.u.gso.segs;
+                       skb_shinfo(skb)->gso_type = txtra.u.gso.type;
+               }
 
                gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
                                  GNTMAP_host_map | GNTMAP_readonly,
@@ -782,7 +806,7 @@ static void net_tx_action(unsigned long 
 
                __skb_put(skb, data_len);
 
-               skb_shinfo(skb)->nr_frags = ret - 1;
+               skb_shinfo(skb)->nr_frags = ret;
                if (data_len < txreq.size) {
                        skb_shinfo(skb)->nr_frags++;
                        skb_shinfo(skb)->frags[0].page =
@@ -898,7 +922,7 @@ irqreturn_t netif_be_int(int irq, void *
 }
 
 static void make_tx_response(netif_t *netif, 
-                            u16      id,
+                            netif_tx_request_t *txp,
                             s8       st)
 {
        RING_IDX i = netif->tx.rsp_prod_pvt;
@@ -906,8 +930,11 @@ static void make_tx_response(netif_t *ne
        int notify;
 
        resp = RING_GET_RESPONSE(&netif->tx, i);
-       resp->id     = id;
+       resp->id     = txp->id;
        resp->status = st;
+
+       if (txp->flags & NETTXF_extra_info)
+               RING_GET_RESPONSE(&netif->tx, ++i)->status = NETIF_RSP_NULL;
 
        netif->tx.rsp_prod_pvt = ++i;
        RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->tx, notify);
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Jun 28 07:51:52 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Jun 28 07:52:21 
2006 -0600
@@ -101,6 +101,12 @@ static int netback_probe(struct xenbus_d
                        goto abort_transaction;
                }
 
+               err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
+               if (err) {
+                       message = "writing feature-tso";
+                       goto abort_transaction;
+               }
+
                err = xenbus_transaction_end(xbt, 0);
        } while (err == -EAGAIN);
 
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Jun 28 07:51:52 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Wed Jun 28 07:52:21 
2006 -0600
@@ -21,6 +21,8 @@
        pr_debug("(file=%s, line=%d) " _f,      \
                 __FILE__ , __LINE__ , ## _a )
 
+struct backend_info;
+
 typedef struct tpmif_st {
        struct list_head tpmif_list;
        /* Unique identifier for this interface. */
@@ -43,7 +45,7 @@ typedef struct tpmif_st {
        struct list_head list;  /* scheduling list */
        atomic_t refcnt;
 
-       long int tpm_instance;
+       struct backend_info *bi;
        unsigned long mmap_vstart;
 
        grant_handle_t shmem_handle;
@@ -54,7 +56,7 @@ typedef struct tpmif_st {
 } tpmif_t;
 
 void tpmif_disconnect_complete(tpmif_t * tpmif);
-tpmif_t *tpmif_find(domid_t domid, long int instance);
+tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi);
 void tpmif_interface_init(void);
 void tpmif_interface_exit(void);
 void tpmif_schedule_work(tpmif_t * tpmif);
@@ -63,10 +65,11 @@ void tpmif_xenbus_exit(void);
 void tpmif_xenbus_exit(void);
 int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn);
 irqreturn_t tpmif_be_int(int irq, void *dev_id, struct pt_regs *regs);
-int tpmif_vtpm_open(tpmif_t *tpmif, domid_t domain, u32 instance);
-int tpmif_vtpm_close(u32 instance);
+
+long int tpmback_get_instance(struct backend_info *bi);
 
 int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
+
 
 #define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
 #define tpmif_put(_b)                                  \
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Wed Jun 28 
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Wed Jun 28 
07:52:21 2006 -0600
@@ -20,7 +20,7 @@ int num_frontends = 0;
 
 LIST_HEAD(tpmif_list);
 
-static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
+static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi)
 {
        tpmif_t *tpmif;
 
@@ -31,7 +31,7 @@ static tpmif_t *alloc_tpmif(domid_t domi
        memset(tpmif, 0, sizeof (*tpmif));
        tpmif->domid = domid;
        tpmif->status = DISCONNECTED;
-       tpmif->tpm_instance = instance;
+       tpmif->bi = bi;
        snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
        atomic_set(&tpmif->refcnt, 1);
 
@@ -54,12 +54,12 @@ static void free_tpmif(tpmif_t * tpmif)
        kmem_cache_free(tpmif_cachep, tpmif);
 }
 
-tpmif_t *tpmif_find(domid_t domid, long int instance)
+tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi)
 {
        tpmif_t *tpmif;
 
        list_for_each_entry(tpmif, &tpmif_list, tpmif_list) {
-               if (tpmif->tpm_instance == instance) {
+               if (tpmif->bi == bi) {
                        if (tpmif->domid == domid) {
                                tpmif_get(tpmif);
                                return tpmif;
@@ -69,7 +69,7 @@ tpmif_t *tpmif_find(domid_t domid, long 
                }
        }
 
-       return alloc_tpmif(domid, instance);
+       return alloc_tpmif(domid, bi);
 }
 
 static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Wed Jun 28 
07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Wed Jun 28 
07:52:21 2006 -0600
@@ -161,7 +161,7 @@ static struct packet *packet_alloc(tpmif
        if (NULL != pak) {
                if (tpmif) {
                        pak->tpmif = tpmif;
-                       pak->tpm_instance = tpmif->tpm_instance;
+                       pak->tpm_instance = tpmback_get_instance(tpmif->bi);
                        tpmif_get(tpmif);
                }
                pak->data_len = size;
@@ -685,95 +685,6 @@ static struct miscdevice vtpms_miscdevic
 };
 
 /***************************************************************
- Virtual TPM functions and data stuctures
-***************************************************************/
-
-static u8 create_cmd[] = {
-       1, 193,                 /* 0: TPM_TAG_RQU_COMMAMD */
-       0, 0, 0, 19,            /* 2: length */
-       0, 0, 0, 0x1,           /* 6: VTPM_ORD_OPEN */
-       0,                      /* 10: VTPM type */
-       0, 0, 0, 0,             /* 11: domain id */
-       0, 0, 0, 0              /* 15: instance id */
-};
-
-int tpmif_vtpm_open(tpmif_t * tpmif, domid_t domid, u32 instance)
-{
-       int rc = 0;
-       struct packet *pak;
-
-       pak = packet_alloc(tpmif,
-                          sizeof (create_cmd),
-                          create_cmd[1],
-                          PACKET_FLAG_DISCARD_RESPONSE |
-                          PACKET_FLAG_CHECK_RESPONSESTATUS);
-       if (pak) {
-               u8 buf[sizeof (create_cmd)];
-               u32 domid_no = htonl((u32) domid);
-               u32 instance_no = htonl(instance);
-
-               memcpy(buf, create_cmd, sizeof (create_cmd));
-
-               memcpy(&buf[11], &domid_no, sizeof (u32));
-               memcpy(&buf[15], &instance_no, sizeof (u32));
-
-               /* copy the buffer into the packet */
-               rc = packet_set(pak, buf, sizeof (buf));
-
-               if (rc == 0) {
-                       pak->tpm_instance = 0;
-                       rc = vtpm_queue_packet(pak);
-               }
-               if (rc < 0) {
-                       /* could not be queued or built */
-                       packet_free(pak);
-               }
-       } else {
-               rc = -ENOMEM;
-       }
-       return rc;
-}
-
-static u8 destroy_cmd[] = {
-       1, 193,                 /* 0: TPM_TAG_RQU_COMMAMD */
-       0, 0, 0, 14,            /* 2: length */
-       0, 0, 0, 0x2,           /* 6: VTPM_ORD_CLOSE */
-       0, 0, 0, 0              /* 10: instance id */
-};
-
-int tpmif_vtpm_close(u32 instid)
-{
-       int rc = 0;
-       struct packet *pak;
-
-       pak = packet_alloc(NULL,
-                          sizeof (destroy_cmd),
-                          destroy_cmd[1], PACKET_FLAG_DISCARD_RESPONSE);
-       if (pak) {
-               u8 buf[sizeof (destroy_cmd)];
-               u32 instid_no = htonl(instid);
-
-               memcpy(buf, destroy_cmd, sizeof (destroy_cmd));
-               memcpy(&buf[10], &instid_no, sizeof (u32));
-
-               /* copy the buffer into the packet */
-               rc = packet_set(pak, buf, sizeof (buf));
-
-               if (rc == 0) {
-                       pak->tpm_instance = 0;
-                       rc = vtpm_queue_packet(pak);
-               }
-               if (rc < 0) {
-                       /* could not be queued or built */
-                       packet_free(pak);
-               }
-       } else {
-               rc = -ENOMEM;
-       }
-       return rc;
-}
-
-/***************************************************************
  Utility functions
 ***************************************************************/
 
diff -r c4b68afe97d3 -r 4b51d081378d 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Wed Jun 28 07:51:52 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Wed Jun 28 07:52:21 
2006 -0600
@@ -45,6 +45,14 @@ static void frontend_changed(struct xenb
 static void frontend_changed(struct xenbus_device *dev,
                             enum xenbus_state frontend_state);
 
+long int tpmback_get_instance(struct backend_info *bi)
+{
+       long int res = -1;
+       if (bi && bi->is_instance_set)
+               res = bi->instance;
+       return res;
+}
+
 static int tpmback_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev->dev.driver_data;
@@ -57,6 +65,7 @@ static int tpmback_remove(struct xenbus_
                be->backend_watch.node = NULL;
        }
        if (be->tpmif) {
+               be->tpmif->bi = NULL;
                vtpm_release_packets(be->tpmif, 0);
                tpmif_put(be->tpmif);
                be->tpmif = NULL;
@@ -150,15 +159,10 @@ static void frontend_changed(struct xenb
                break;
 
        case XenbusStateClosing:
-               be->tpmif->tpm_instance = -1;
+               be->instance = -1;
                break;
 
        case XenbusStateClosed:
-               /*
-                * Notify the vTPM manager about the front-end
-                * having left.
-                */
-               tpmif_vtpm_close(be->instance);
                device_unregister(&be->dev->dev);
                tpmback_remove(dev);
                break;
@@ -177,28 +181,10 @@ static void frontend_changed(struct xenb
 
 static void maybe_connect(struct backend_info *be)
 {
-       int err;
-
        if (be->tpmif == NULL || be->tpmif->status == CONNECTED)
                return;
 
        connect(be);
-
-       /*
-        * Notify the vTPM manager about a new front-end.
-        */
-       err = tpmif_vtpm_open(be->tpmif,
-                             be->frontend_id,
-                             be->instance);
-       if (err) {
-               xenbus_dev_error(be->dev, err,
-                                "queueing vtpm open packet");
-               /*
-                * Should close down this device and notify FE
-                * about closure.
-                */
-               return;
-       }
 }
 
 
@@ -256,8 +242,7 @@ static int connect_ring(struct backend_i
        }
 
        if (!be->tpmif) {
-               be->tpmif = tpmif_find(dev->otherend_id,
-                                      be->instance);
+               be->tpmif = tpmif_find(dev->otherend_id, be);
                if (IS_ERR(be->tpmif)) {
                        err = PTR_ERR(be->tpmif);
                        be->tpmif = NULL;
diff -r c4b68afe97d3 -r 4b51d081378d linux-2.6-xen-sparse/include/linux/skbuff.h
--- a/linux-2.6-xen-sparse/include/linux/skbuff.h       Wed Jun 28 07:51:52 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/linux/skbuff.h       Wed Jun 28 07:52:21 
2006 -0600
@@ -134,9 +134,10 @@ struct skb_shared_info {
 struct skb_shared_info {
        atomic_t        dataref;
        unsigned short  nr_frags;
-       unsigned short  tso_size;
-       unsigned short  tso_segs;
-       unsigned short  ufo_size;
+       unsigned short  gso_size;
+       /* Warning: this field is not always filled in (UFO)! */
+       unsigned short  gso_segs;
+       unsigned short  gso_type;
        unsigned int    ip6_frag_id;
        struct sk_buff  *frag_list;
        skb_frag_t      frags[MAX_SKB_FRAGS];
@@ -166,6 +167,14 @@ enum {
        SKB_FCLONE_UNAVAILABLE,
        SKB_FCLONE_ORIG,
        SKB_FCLONE_CLONE,
+};
+
+enum {
+       SKB_GSO_TCPV4 = 1 << 0,
+       SKB_GSO_UDPV4 = 1 << 1,
+
+       /* This indicates the skb is from an untrusted source. */
+       SKB_GSO_DODGY = 1 << 2,
 };
 
 /** 
@@ -1157,18 +1166,34 @@ static inline int skb_can_coalesce(struc
        return 0;
 }
 
+static inline int __skb_linearize(struct sk_buff *skb)
+{
+       return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
+}
+
 /**
  *     skb_linearize - convert paged skb to linear one
  *     @skb: buffer to linarize
- *     @gfp: allocation mode
  *
  *     If there is no free memory -ENOMEM is returned, otherwise zero
  *     is returned and the old skb data released.
  */
-extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
-{
-       return __skb_linearize(skb, gfp);
+static inline int skb_linearize(struct sk_buff *skb)
+{
+       return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
+}
+
+/**
+ *     skb_linearize_cow - make sure skb is linear and writable
+ *     @skb: buffer to process
+ *
+ *     If there is no free memory -ENOMEM is returned, otherwise zero
+ *     is returned and the old skb data released.
+ */
+static inline int skb_linearize_cow(struct sk_buff *skb)
+{
+       return skb_is_nonlinear(skb) || skb_cloned(skb) ?
+              __skb_linearize(skb) : 0;
 }
 
 /**
@@ -1263,6 +1288,7 @@ extern void              skb_split(struct sk_b
                                 struct sk_buff *skb1, const u32 len);
 
 extern void           skb_release_data(struct sk_buff *skb);
+extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
 
 static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
                                       int len, void *buffer)
diff -r c4b68afe97d3 -r 4b51d081378d linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c       Wed Jun 28 07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/net/core/dev.c       Wed Jun 28 07:52:21 2006 -0600
@@ -115,6 +115,7 @@
 #include <net/iw_handler.h>
 #endif /* CONFIG_NET_RADIO */
 #include <asm/current.h>
+#include <linux/err.h>
 
 #ifdef CONFIG_XEN
 #include <net/ip.h>
@@ -1038,7 +1039,7 @@ static inline void net_timestamp(struct 
  *     taps currently in use.
  */
 
-void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
+static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 {
        struct packet_type *ptype;
 
@@ -1112,6 +1113,45 @@ out:
        return ret;
 }
 
+/**
+ *     skb_gso_segment - Perform segmentation on skb.
+ *     @skb: buffer to segment
+ *     @features: features for the output path (see dev->features)
+ *
+ *     This function segments the given skb and returns a list of segments.
+ *
+ *     It may return NULL if the skb requires no segmentation.  This is
+ *     only possible when GSO is used for verifying header integrity.
+ */
+struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
+{
+       struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
+       struct packet_type *ptype;
+       int type = skb->protocol;
+
+       BUG_ON(skb_shinfo(skb)->frag_list);
+       BUG_ON(skb->ip_summed != CHECKSUM_HW);
+
+       skb->mac.raw = skb->data;
+       skb->mac_len = skb->nh.raw - skb->data;
+       __skb_pull(skb, skb->mac_len);
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
+               if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
+                       segs = ptype->gso_segment(skb, features);
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
+       __skb_push(skb, skb->data - skb->mac.raw);
+
+       return segs;
+}
+
+EXPORT_SYMBOL(skb_gso_segment);
+
 /* Take action when hardware reception checksum errors are detected. */
 #ifdef CONFIG_BUG
 void netdev_rx_csum_fault(struct net_device *dev)
@@ -1148,75 +1188,108 @@ static inline int illegal_highdma(struct
 #define illegal_highdma(dev, skb)      (0)
 #endif
 
-/* Keep head the same: replace data */
-int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
-{
-       unsigned int size;
-       u8 *data;
-       long offset;
-       struct skb_shared_info *ninfo;
-       int headerlen = skb->data - skb->head;
-       int expand = (skb->tail + skb->data_len) - skb->end;
-
-       if (skb_shared(skb))
-               BUG();
-
-       if (expand <= 0)
-               expand = 0;
-
-       size = skb->end - skb->head + expand;
-       size = SKB_DATA_ALIGN(size);
-       data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
-       if (!data)
-               return -ENOMEM;
-
-       /* Copy entire thing */
-       if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
-               BUG();
-
-       /* Set up shinfo */
-       ninfo = (struct skb_shared_info*)(data + size);
-       atomic_set(&ninfo->dataref, 1);
-       ninfo->tso_size = skb_shinfo(skb)->tso_size;
-       ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
-       ninfo->nr_frags = 0;
-       ninfo->frag_list = NULL;
-
-       /* Offset between the two in bytes */
-       offset = data - skb->head;
-
-       /* Free old data. */
-       skb_release_data(skb);
-
-       skb->head = data;
-       skb->end  = data + size;
-
-       /* Set up new pointers */
-       skb->h.raw   += offset;
-       skb->nh.raw  += offset;
-       skb->mac.raw += offset;
-       skb->tail    += offset;
-       skb->data    += offset;
-
-       /* We are no longer a clone, even if we were. */
-       skb->cloned    = 0;
-
-       skb->tail     += skb->data_len;
-       skb->data_len  = 0;
+struct dev_gso_cb {
+       void (*destructor)(struct sk_buff *skb);
+};
+
+#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
+
+static void dev_gso_skb_destructor(struct sk_buff *skb)
+{
+       struct dev_gso_cb *cb;
+
+       do {
+               struct sk_buff *nskb = skb->next;
+
+               skb->next = nskb->next;
+               nskb->next = NULL;
+               kfree_skb(nskb);
+       } while (skb->next);
+
+       cb = DEV_GSO_CB(skb);
+       if (cb->destructor)
+               cb->destructor(skb);
+}
+
+/**
+ *     dev_gso_segment - Perform emulated hardware segmentation on skb.
+ *     @skb: buffer to segment
+ *
+ *     This function segments the given skb and stores the list of segments
+ *     in skb->next.
+ */
+static int dev_gso_segment(struct sk_buff *skb)
+{
+       struct net_device *dev = skb->dev;
+       struct sk_buff *segs;
+       int features = dev->features & ~(illegal_highdma(dev, skb) ?
+                                        NETIF_F_SG : 0);
+
+       segs = skb_gso_segment(skb, features);
+
+       /* Verifying header integrity only. */
+       if (!segs)
+               return 0;
+
+       if (unlikely(IS_ERR(segs)))
+               return PTR_ERR(segs);
+
+       skb->next = segs;
+       DEV_GSO_CB(skb)->destructor = skb->destructor;
+       skb->destructor = dev_gso_skb_destructor;
+
+       return 0;
+}
+
+int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       if (likely(!skb->next)) {
+               if (netdev_nit)
+                       dev_queue_xmit_nit(skb, dev);
+
+               if (netif_needs_gso(dev, skb)) {
+                       if (unlikely(dev_gso_segment(skb)))
+                               goto out_kfree_skb;
+                       if (skb->next)
+                               goto gso;
+               }
+
+               return dev->hard_start_xmit(skb, dev);
+       }
+
+gso:
+       do {
+               struct sk_buff *nskb = skb->next;
+               int rc;
+
+               skb->next = nskb->next;
+               nskb->next = NULL;
+               rc = dev->hard_start_xmit(nskb, dev);
+               if (unlikely(rc)) {
+                       nskb->next = skb->next;
+                       skb->next = nskb;
+                       return rc;
+               }
+               if (unlikely(netif_queue_stopped(dev) && skb->next))
+                       return NETDEV_TX_BUSY;
+       } while (skb->next);
+       
+       skb->destructor = DEV_GSO_CB(skb)->destructor;
+
+out_kfree_skb:
+       kfree_skb(skb);
        return 0;
 }
 
 #define HARD_TX_LOCK(dev, cpu) {                       \
        if ((dev->features & NETIF_F_LLTX) == 0) {      \
-               spin_lock(&dev->xmit_lock);             \
-               dev->xmit_lock_owner = cpu;             \
+               netif_tx_lock(dev);                     \
        }                                               \
 }
 
 #define HARD_TX_UNLOCK(dev) {                          \
        if ((dev->features & NETIF_F_LLTX) == 0) {      \
-               dev->xmit_lock_owner = -1;              \
-               spin_unlock(&dev->xmit_lock);           \
+               netif_tx_unlock(dev);                   \
        }                                               \
 }
 
@@ -1289,9 +1362,19 @@ int dev_queue_xmit(struct sk_buff *skb)
        struct Qdisc *q;
        int rc = -ENOMEM;
 
+       /* If a checksum-deferred packet is forwarded to a device that needs a
+        * checksum, correct the pointers and force checksumming.
+        */
+       if (skb_checksum_setup(skb))
+               goto out_kfree_skb;
+
+       /* GSO will handle the following emulations directly. */
+       if (netif_needs_gso(dev, skb))
+               goto gso;
+
        if (skb_shinfo(skb)->frag_list &&
            !(dev->features & NETIF_F_FRAGLIST) &&
-           __skb_linearize(skb, GFP_ATOMIC))
+           __skb_linearize(skb))
                goto out_kfree_skb;
 
        /* Fragmented skb is linearized if device does not support SG,
@@ -1300,31 +1383,26 @@ int dev_queue_xmit(struct sk_buff *skb)
         */
        if (skb_shinfo(skb)->nr_frags &&
            (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-           __skb_linearize(skb, GFP_ATOMIC))
+           __skb_linearize(skb))
                goto out_kfree_skb;
 
-       /* If a checksum-deferred packet is forwarded to a device that needs a
-        * checksum, correct the pointers and force checksumming.
-        */
-       if(skb_checksum_setup(skb))
-               goto out_kfree_skb;
-  
        /* If packet is not checksummed and device does not support
         * checksumming for this protocol, complete checksumming here.
         */
        if (skb->ip_summed == CHECKSUM_HW &&
-           (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
+           (!(dev->features & NETIF_F_GEN_CSUM) &&
             (!(dev->features & NETIF_F_IP_CSUM) ||
              skb->protocol != htons(ETH_P_IP))))
                if (skb_checksum_help(skb, 0))
                        goto out_kfree_skb;
 
+gso:
        spin_lock_prefetch(&dev->queue_lock);
 
        /* Disable soft irqs for various locks below. Also 
         * stops preemption for RCU. 
         */
-       local_bh_disable(); 
+       rcu_read_lock_bh(); 
 
        /* Updates of qdisc are serialized by queue_lock. 
         * The struct Qdisc which is pointed to by qdisc is now a 
@@ -1358,8 +1436,8 @@ int dev_queue_xmit(struct sk_buff *skb)
        /* The device has no queue. Common case for software devices:
           loopback, all the sorts of tunnels...
 
-          Really, it is unlikely that xmit_lock protection is necessary here.
-          (f.e. loopback and IP tunnels are clean ignoring statistics
+          Really, it is unlikely that netif_tx_lock protection is necessary
+          here.  (f.e. loopback and IP tunnels are clean ignoring statistics
           counters.)
           However, it is possible, that they rely on protection
           made by us here.
@@ -1375,11 +1453,8 @@ int dev_queue_xmit(struct sk_buff *skb)
                        HARD_TX_LOCK(dev, cpu);
 
                        if (!netif_queue_stopped(dev)) {
-                               if (netdev_nit)
-                                       dev_queue_xmit_nit(skb, dev);
-
                                rc = 0;
-                               if (!dev->hard_start_xmit(skb, dev)) {
+                               if (!dev_hard_start_xmit(skb, dev)) {
                                        HARD_TX_UNLOCK(dev);
                                        goto out;
                                }
@@ -1398,13 +1473,13 @@ int dev_queue_xmit(struct sk_buff *skb)
        }
 
        rc = -ENETDOWN;
-       local_bh_enable();
+       rcu_read_unlock_bh();
 
 out_kfree_skb:
        kfree_skb(skb);
        return rc;
 out:
-       local_bh_enable();
+       rcu_read_unlock_bh();
        return rc;
 }
 
@@ -2732,7 +2807,7 @@ int register_netdevice(struct net_device
        BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
 
        spin_lock_init(&dev->queue_lock);
-       spin_lock_init(&dev->xmit_lock);
+       spin_lock_init(&dev->_xmit_lock);
        dev->xmit_lock_owner = -1;
 #ifdef CONFIG_NET_CLS_ACT
        spin_lock_init(&dev->ingress_lock);
@@ -2776,9 +2851,7 @@ int register_netdevice(struct net_device
 
        /* Fix illegal SG+CSUM combinations. */
        if ((dev->features & NETIF_F_SG) &&
-           !(dev->features & (NETIF_F_IP_CSUM |
-                              NETIF_F_NO_CSUM |
-                              NETIF_F_HW_CSUM))) {
+           !(dev->features & NETIF_F_ALL_CSUM)) {
                printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
                       dev->name);
                dev->features &= ~NETIF_F_SG;
@@ -3330,7 +3403,6 @@ EXPORT_SYMBOL(__dev_get_by_index);
 EXPORT_SYMBOL(__dev_get_by_index);
 EXPORT_SYMBOL(__dev_get_by_name);
 EXPORT_SYMBOL(__dev_remove_pack);
-EXPORT_SYMBOL(__skb_linearize);
 EXPORT_SYMBOL(dev_valid_name);
 EXPORT_SYMBOL(dev_add_pack);
 EXPORT_SYMBOL(dev_alloc_name);
diff -r c4b68afe97d3 -r 4b51d081378d linux-2.6-xen-sparse/net/core/skbuff.c
--- a/linux-2.6-xen-sparse/net/core/skbuff.c    Wed Jun 28 07:51:52 2006 -0600
+++ b/linux-2.6-xen-sparse/net/core/skbuff.c    Wed Jun 28 07:52:21 2006 -0600
@@ -165,9 +165,9 @@ struct sk_buff *__alloc_skb(unsigned int
        shinfo = skb_shinfo(skb);
        atomic_set(&shinfo->dataref, 1);
        shinfo->nr_frags  = 0;
-       shinfo->tso_size = 0;
-       shinfo->tso_segs = 0;
-       shinfo->ufo_size = 0;
+       shinfo->gso_size = 0;
+       shinfo->gso_segs = 0;
+       shinfo->gso_type = 0;
        shinfo->ip6_frag_id = 0;
        shinfo->frag_list = NULL;
 
@@ -237,9 +237,9 @@ struct sk_buff *alloc_skb_from_cache(kme
        shinfo = skb_shinfo(skb);
        atomic_set(&shinfo->dataref, 1);
        shinfo->nr_frags  = 0;
-       shinfo->tso_size = 0;
-       shinfo->tso_segs = 0;
-       shinfo->ufo_size = 0;
+       shinfo->gso_size = 0;
+       shinfo->gso_segs = 0;
+       shinfo->gso_type = 0;
        shinfo->ip6_frag_id = 0;
        shinfo->frag_list = NULL;
 
@@ -524,8 +524,9 @@ static void copy_skb_header(struct sk_bu
        new->tc_index   = old->tc_index;
 #endif
        atomic_set(&new->users, 1);
-       skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
-       skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
+       skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
+       skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
+       skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
 }
 
 /**
@@ -1799,6 +1800,133 @@ int skb_append_datato_frags(struct sock 
 
        return 0;
 }
+
+/**
+ *     skb_segment - Perform protocol segmentation on skb.
+ *     @skb: buffer to segment
+ *     @features: features for the output path (see dev->features)
+ *
+ *     This function performs segmentation on the given skb.  It returns
+ *     the segment at the given position.  It returns NULL if there are
+ *     no more segments to generate, or when an error is encountered.
+ */
+struct sk_buff *skb_segment(struct sk_buff *skb, int features)
+{
+       struct sk_buff *segs = NULL;
+       struct sk_buff *tail = NULL;
+       unsigned int mss = skb_shinfo(skb)->gso_size;
+       unsigned int doffset = skb->data - skb->mac.raw;
+       unsigned int offset = doffset;
+       unsigned int headroom;
+       unsigned int len;
+       int sg = features & NETIF_F_SG;
+       int nfrags = skb_shinfo(skb)->nr_frags;
+       int err = -ENOMEM;
+       int i = 0;
+       int pos;
+
+       __skb_push(skb, doffset);
+       headroom = skb_headroom(skb);
+       pos = skb_headlen(skb);
+
+       do {
+               struct sk_buff *nskb;
+               skb_frag_t *frag;
+               int hsize, nsize;
+               int k;
+               int size;
+
+               len = skb->len - offset;
+               if (len > mss)
+                       len = mss;
+
+               hsize = skb_headlen(skb) - offset;
+               if (hsize < 0)
+                       hsize = 0;
+               nsize = hsize + doffset;
+               if (nsize > len + doffset || !sg)
+                       nsize = len + doffset;
+
+               nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
+               if (unlikely(!nskb))
+                       goto err;
+
+               if (segs)
+                       tail->next = nskb;
+               else
+                       segs = nskb;
+               tail = nskb;
+
+               nskb->dev = skb->dev;
+               nskb->priority = skb->priority;
+               nskb->protocol = skb->protocol;
+               nskb->dst = dst_clone(skb->dst);
+               memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
+               nskb->pkt_type = skb->pkt_type;
+               nskb->mac_len = skb->mac_len;
+
+               skb_reserve(nskb, headroom);
+               nskb->mac.raw = nskb->data;
+               nskb->nh.raw = nskb->data + skb->mac_len;
+               nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
+               memcpy(skb_put(nskb, doffset), skb->data, doffset);
+
+               if (!sg) {
+                       nskb->csum = skb_copy_and_csum_bits(skb, offset,
+                                                           skb_put(nskb, len),
+                                                           len, 0);
+                       continue;
+               }
+
+               frag = skb_shinfo(nskb)->frags;
+               k = 0;
+
+               nskb->ip_summed = CHECKSUM_HW;
+               nskb->csum = skb->csum;
+               memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
+
+               while (pos < offset + len) {
+                       BUG_ON(i >= nfrags);
+
+                       *frag = skb_shinfo(skb)->frags[i];
+                       get_page(frag->page);
+                       size = frag->size;
+
+                       if (pos < offset) {
+                               frag->page_offset += offset - pos;
+                               frag->size -= offset - pos;
+                       }
+
+                       k++;
+
+                       if (pos + size <= offset + len) {
+                               i++;
+                               pos += size;
+                       } else {
+                               frag->size -= pos + size - (offset + len);
+                               break;
+                       }
+
+                       frag++;
+               }
+
+               skb_shinfo(nskb)->nr_frags = k;
+               nskb->data_len = len - hsize;
+               nskb->len += nskb->data_len;
+               nskb->truesize += nskb->data_len;
+       } while ((offset += len) < skb->len);
+
+       return segs;
+
+err:
+       while ((skb = segs)) {
+               segs = skb->next;
+               kfree(skb);
+       }
+       return ERR_PTR(err);
+}
+
+EXPORT_SYMBOL_GPL(skb_segment);
 
 void __init skb_init(void)
 {
diff -r c4b68afe97d3 -r 4b51d081378d 
patches/linux-2.6.16.13/xenoprof-generic.patch
--- a/patches/linux-2.6.16.13/xenoprof-generic.patch    Wed Jun 28 07:51:52 
2006 -0600
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch    Wed Jun 28 07:52:21 
2006 -0600
@@ -1,6 +1,6 @@ diff -pruN ../pristine-linux-2.6.16.13/d
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 
./drivers/oprofile/buffer_sync.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/buffer_sync.c   2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 
./drivers/oprofile/buffer_sync.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/buffer_sync.c   2006-06-27 12:14:53.000000000 +0800
 @@ -6,6 +6,10 @@
   *
   * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -12,7 +12,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
   * This is the core of the buffer management. Each
   * CPU buffer is processed and entered into the
   * global event buffer. Such processing is necessary
-@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
+@@ -275,15 +279,30 @@ static void add_cpu_switch(int i)
        last_cookie = INVALID_COOKIE;
  }
  
@@ -33,7 +33,13 @@ diff -pruN ../pristine-linux-2.6.16.13/d
 +              break;
 +      case CPU_MODE_XEN:
 +              add_event_entry(XEN_ENTER_SWITCH_CODE);
-+              break;
++              break;
++        case CPU_MODE_PASSIVE_START:
++                add_event_entry(PASSIVE_START_CODE);
++                break;
++        case CPU_MODE_PASSIVE_STOP:
++                add_event_entry(PASSIVE_STOP_CODE);
++                break;
 +      default:
 +              break;
 +      }
@@ -43,7 +49,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  static void
  add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
  {
-@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
+@@ -348,9 +367,9 @@ static int add_us_sample(struct mm_struc
   * for later lookup from userspace.
   */
  static int
@@ -55,7 +61,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
                add_sample_entry(s->eip, s->event);
                return 1;
        } else if (mm) {
-@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
+@@ -496,10 +515,11 @@ void sync_buffer(int cpu)
        struct mm_struct *mm = NULL;
        struct task_struct * new;
        unsigned long cookie = 0;
@@ -64,34 +70,62 @@ diff -pruN ../pristine-linux-2.6.16.13/d
        unsigned int i;
        sync_buffer_state state = sb_buffer_start;
        unsigned long available;
-@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
++      int domain_switch = NO_DOMAIN_SWITCH;
+ 
+       down(&buffer_sem);
+  
+@@ -513,12 +533,19 @@ void sync_buffer(int cpu)
                struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
   
                if (is_code(s->eip)) {
 -                      if (s->event <= CPU_IS_KERNEL) {
-+                      if (s->event <= CPU_MODE_XEN) {
++                      if (s->event < CPU_TRACE_BEGIN) {
                                /* kernel/userspace switch */
 -                              in_kernel = s->event;
 +                              cpu_mode = s->event;
                                if (state == sb_buffer_start)
                                        state = sb_sample_start;
 -                              add_kernel_ctx_switch(s->event);
-+                              add_cpu_mode_switch(s->event);
++
++                              if (s->event == CPU_MODE_PASSIVE_START)
++                                      domain_switch = 
DOMAIN_SWITCH_START_EVENT1;
++                              else if (s->event == CPU_MODE_PASSIVE_STOP)
++                                      domain_switch = 
DOMAIN_SWITCH_STOP_EVENT1;
++
++                              if (domain_switch != DOMAIN_SWITCH_START_EVENT2)
++                                      add_cpu_mode_switch(s->event);
                        } else if (s->event == CPU_TRACE_BEGIN) {
                                state = sb_bt_start;
                                add_trace_begin();
-@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
+@@ -535,11 +562,20 @@ void sync_buffer(int cpu)
+                               add_user_ctx_switch(new, cookie);
                        }
                } else {
-                       if (state >= sb_bt_start &&
+-                      if (state >= sb_bt_start &&
 -                          !add_sample(mm, s, in_kernel)) {
-+                          !add_sample(mm, s, cpu_mode)) {
-                               if (state == sb_bt_start) {
-                                       state = sb_bt_ignore;
-                                       
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 
./drivers/oprofile/cpu_buffer.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c  2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.c    2006-05-04 17:41:51.000000000 +0100
+-                              if (state == sb_bt_start) {
+-                                      state = sb_bt_ignore;
+-                                      
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
++                      if (domain_switch == DOMAIN_SWITCH_START_EVENT1) {
++                              add_event_entry(s->event);
++                              domain_switch = DOMAIN_SWITCH_START_EVENT2;
++                      } else if (domain_switch == DOMAIN_SWITCH_START_EVENT1) 
{
++                              add_sample_entry(s->eip, s->event);
++                      } else if (domain_switch == DOMAIN_SWITCH_STOP_EVENT1) {
++                              domain_switch = NO_DOMAIN_SWITCH;
++                      } else {
++                              if (state >= sb_bt_start &&
++                                  !add_sample(mm, s, cpu_mode)) {
++                                      if (state == sb_bt_start) {
++                                              state = sb_bt_ignore;
++                                              
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
++                                      }
+                               }
+                       }
+               }
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 
./drivers/oprofile/cpu_buffer.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c  2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/cpu_buffer.c    2006-06-19 22:43:53.000000000 +0800
 @@ -6,6 +6,10 @@
   *
   * @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -139,13 +173,12 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  {
        struct task_struct * task;
  
-@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
+@@ -181,16 +185,14 @@ static int log_sample(struct oprofile_cp
                return 0;
        }
  
 -      is_kernel = !!is_kernel;
-+      WARN_ON(cpu_mode > CPU_MODE_XEN);
- 
+-
        task = current;
  
        /* notice a switch from user->kernel or vice versa */
@@ -161,9 +194,9 @@ diff -pruN ../pristine-linux-2.6.16.13/d
        /* notice a task switch */
        if (cpu_buf->last_task != task) {
                cpu_buf->last_task = task;
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 
./drivers/oprofile/cpu_buffer.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h  2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/cpu_buffer.h    2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 
./drivers/oprofile/cpu_buffer.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h  2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/cpu_buffer.h    2006-06-27 10:38:08.000000000 +0800
 @@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
        volatile unsigned long tail_pos;
        unsigned long buffer_size;
@@ -173,22 +206,26 @@ diff -pruN ../pristine-linux-2.6.16.13/d
        int tracing;
        struct op_sample * buffer;
        unsigned long sample_received;
-@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
+@@ -51,7 +51,13 @@ extern struct oprofile_cpu_buffer cpu_bu
  void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
  
  /* transient events for the CPU buffer -> event buffer */
 -#define CPU_IS_KERNEL 1
 -#define CPU_TRACE_BEGIN 2
-+#define CPU_MODE_USER    0
-+#define CPU_MODE_KERNEL  1
-+#define CPU_MODE_XEN     2
-+#define CPU_TRACE_BEGIN  3
++#define CPU_MODE_USER           0
++#define CPU_MODE_KERNEL         1
++#define CPU_MODE_XEN            2
++#define CPU_MODE_PASSIVE_START  3
++#define CPU_MODE_PASSIVE_STOP   4
++#define CPU_TRACE_BEGIN         5
++
++#define IGNORED_PC              0
  
  #endif /* OPROFILE_CPU_BUFFER_H */
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 
./drivers/oprofile/event_buffer.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h        
2006-05-02 22:38:44.000000000 +0100
-+++ ./drivers/oprofile/event_buffer.h  2006-05-04 17:41:51.000000000 +0100
-@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h 
./drivers/oprofile/event_buffer.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h        
2006-05-03 05:38:44.000000000 +0800
++++ ./drivers/oprofile/event_buffer.h  2006-06-19 22:43:53.000000000 +0800
+@@ -29,11 +29,14 @@ void wake_up_buffer_waiter(void);
  #define CPU_SWITCH_CODE               2
  #define COOKIE_SWITCH_CODE            3
  #define KERNEL_ENTER_SWITCH_CODE      4
@@ -199,12 +236,14 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  #define TRACE_BEGIN_CODE              8
  #define TRACE_END_CODE                        9
 +#define XEN_ENTER_SWITCH_CODE         10
++#define PASSIVE_START_CODE            11
++#define PASSIVE_STOP_CODE             12
   
  #define INVALID_COOKIE ~0UL
  #define NO_COOKIE 0UL
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 
./drivers/oprofile/oprof.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c       2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprof.c 2006-05-04 17:41:51.000000000 +0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 
./drivers/oprofile/oprof.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c       2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprof.c 2006-06-19 23:45:17.000000000 +0800
 @@ -5,6 +5,10 @@
   * @remark Read the file COPYING
   *
@@ -225,7 +264,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  struct oprofile_operations oprofile_ops;
  
  unsigned long oprofile_started;
-@@ -33,6 +37,19 @@ static DECLARE_MUTEX(start_sem);
+@@ -33,6 +37,32 @@ static DECLARE_MUTEX(start_sem);
   */
  static int timer = 0;
  
@@ -242,23 +281,37 @@ diff -pruN ../pristine-linux-2.6.16.13/d
 +      return err;
 +}
 +
++int oprofile_set_passive(int passive_domains[], unsigned int pdomains)
++{
++      int err;
++
++      if (!oprofile_ops.set_passive)
++              return -EINVAL;
++
++      down(&start_sem);
++      err = oprofile_ops.set_passive(passive_domains, pdomains);
++      up(&start_sem);
++      return err;
++}
++
  int oprofile_setup(void)
  {
        int err;
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 
./drivers/oprofile/oprof.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h       2006-05-02 
22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprof.h 2006-05-04 17:41:51.000000000 +0100
-@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 
./drivers/oprofile/oprof.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h       2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprof.h 2006-06-19 23:42:36.000000000 +0800
+@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
  void oprofile_timer_init(struct oprofile_operations * ops);
  
  int oprofile_set_backtrace(unsigned long depth);
 +
 +int oprofile_set_active(int active_domains[], unsigned int adomains);
++int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
   
  #endif /* OPROF_H */
-diff -pruN ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 
./drivers/oprofile/oprofile_files.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c      
2006-05-02 22:38:44.000000000 +0100
-+++ ./drivers/oprofile/oprofile_files.c        2006-05-04 17:41:51.000000000 
+0100
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c 
./drivers/oprofile/oprofile_files.c
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c      
2006-05-03 05:38:44.000000000 +0800
++++ ./drivers/oprofile/oprofile_files.c        2006-06-19 23:29:07.000000000 
+0800
 @@ -5,15 +5,21 @@
   * @remark Read the file COPYING
   *
@@ -282,7 +335,7 @@ diff -pruN ../pristine-linux-2.6.16.13/d
  unsigned long fs_buffer_size = 131072;
  unsigned long fs_cpu_buffer_size = 8192;
  unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-@@ -117,11 +123,108 @@ static ssize_t dump_write(struct file * 
+@@ -117,11 +123,202 @@ static ssize_t dump_write(struct file * 
  static struct file_operations dump_fops = {
        .write          = dump_write,
  };
@@ -384,17 +437,110 @@ diff -pruN ../pristine-linux-2.6.16.13/d
 +      .write          = adomain_write,
 +};
 +
++static unsigned int pdomains = 0;
++static int passive_domains[MAX_OPROF_DOMAINS];
++static DEFINE_MUTEX(pdom_mutex);
++
++static ssize_t pdomain_write(struct file * file, char const __user * buf, 
++                           size_t count, loff_t * offset)
++{
++      char *tmpbuf;
++      char *startp, *endp;
++      int i;
++      unsigned long val;
++      ssize_t retval = count;
++      
++      if (*offset)
++              return -EINVAL; 
++      if (count > TMPBUFSIZE - 1)
++              return -EINVAL;
++
++      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
++              return -ENOMEM;
++
++      if (copy_from_user(tmpbuf, buf, count)) {
++              kfree(tmpbuf);
++              return -EFAULT;
++      }
++      tmpbuf[count] = 0;
++
++      mutex_lock(&pdom_mutex);
++
++      startp = tmpbuf;
++      /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
++      for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
++              val = simple_strtoul(startp, &endp, 0);
++              if (endp == startp)
++                      break;
++              while (ispunct(*endp) || isspace(*endp))
++                      endp++;
++              passive_domains[i] = val;
++              if (passive_domains[i] != val)
++                      /* Overflow, force error below */
++                      i = MAX_OPROF_DOMAINS + 1;
++              startp = endp;
++      }
++      /* Force error on trailing junk */
++      pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
++
++      kfree(tmpbuf);
++
++      if (pdomains > MAX_OPROF_DOMAINS
++          || oprofile_set_passive(passive_domains, pdomains)) {
++              pdomains = 0;
++              retval = -EINVAL;
++      }
++
++      mutex_unlock(&pdom_mutex);
++      return retval;
++}
++
++static ssize_t pdomain_read(struct file * file, char __user * buf, 
++                          size_t count, loff_t * offset)
++{
++      char * tmpbuf;
++      size_t len;
++      int i;
++      ssize_t retval;
++
++      if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
++              return -ENOMEM;
++
++      mutex_lock(&pdom_mutex);
++
++      len = 0;
++      for (i = 0; i < pdomains; i++)
++              len += snprintf(tmpbuf + len,
++                              len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
++                              "%u ", passive_domains[i]);
++      WARN_ON(len > TMPBUFSIZE);
++      if (len != 0 && len <= TMPBUFSIZE)
++              tmpbuf[len-1] = '\n';
++
++      mutex_unlock(&pdom_mutex);
++
++      retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
++
++      kfree(tmpbuf);
++      return retval;
++}
++
++static struct file_operations passive_domain_ops = {
++      .read           = pdomain_read,
++      .write          = pdomain_write,
++};
++
  void oprofile_create_files(struct super_block * sb, struct dentry * root)
  {
        oprofilefs_create_file(sb, root, "enable", &enable_fops);
        oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
 +      oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
++      oprofilefs_create_file(sb, root, "passive_domains", 
&passive_domain_ops);
        oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
        oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
        oprofilefs_create_ulong(sb, root, "buffer_watershed", 
&fs_buffer_watershed);
-diff -pruN ../pristine-linux-2.6.16.13/include/linux/oprofile.h 
./include/linux/oprofile.h
---- ../pristine-linux-2.6.16.13/include/linux/oprofile.h       2006-05-02 
22:38:44.000000000 +0100
-+++ ./include/linux/oprofile.h 2006-05-04 17:41:51.000000000 +0100
+--- ../pristine-linux-2.6.16.13/include/linux/oprofile.h       2006-05-03 
05:38:44.000000000 +0800
++++ ./include/linux/oprofile.h 2006-06-19 23:52:00.000000000 +0800
 @@ -16,6 +16,8 @@
  #include <linux/types.h>
  #include <linux/spinlock.h>
@@ -404,12 +550,15 @@ diff -pruN ../pristine-linux-2.6.16.13/i
   
  struct super_block;
  struct dentry;
-@@ -27,6 +29,8 @@ struct oprofile_operations {
+@@ -27,6 +29,11 @@ struct oprofile_operations {
        /* create any necessary configuration files in the oprofile fs.
         * Optional. */
        int (*create_files)(struct super_block * sb, struct dentry * root);
 +      /* setup active domains with Xen */
 +      int (*set_active)(int *active_domains, unsigned int adomains);
++        /* setup passive domains with Xen */
++        int (*set_passive)(int *passive_domains, unsigned int pdomains);
++      
        /* Do any necessary interrupt setup. Optional. */
        int (*setup)(void);
        /* Do any necessary interrupt shutdown. Optional. */
diff -r c4b68afe97d3 -r 4b51d081378d tools/Makefile
--- a/tools/Makefile    Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/Makefile    Wed Jun 28 07:52:21 2006 -0600
@@ -45,6 +45,9 @@ clean: check_clean
        done
        $(MAKE) ioemuclean
 
+.PHONY: distclean
+distclean: clean
+
 .PHONY: check
 check:
        $(MAKE) -C check
diff -r c4b68afe97d3 -r 4b51d081378d tools/examples/Makefile
--- a/tools/examples/Makefile   Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/examples/Makefile   Wed Jun 28 07:52:21 2006 -0600
@@ -32,7 +32,7 @@ XEN_SCRIPT_DATA = xen-script-common.sh l
 XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
 XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
 XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
-XEN_SCRIPT_DATA += vtpm-migration.sh
+XEN_SCRIPT_DATA += vtpm-migration.sh vtpm-impl
 
 XEN_HOTPLUG_DIR = /etc/hotplug
 XEN_HOTPLUG_SCRIPTS = xen-backend.agent
diff -r c4b68afe97d3 -r 4b51d081378d tools/examples/vtpm
--- a/tools/examples/vtpm       Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/examples/vtpm       Wed Jun 28 07:52:21 2006 -0600
@@ -9,13 +9,7 @@ case "$command" in
   add)
     vtpm_create_instance
   ;;
-  online)
-    vtpm_create_instance
-  ;;
   remove)
-    vtpm_remove_instance
-  ;;
-  offline)
     vtpm_remove_instance
   ;;
 esac
diff -r c4b68afe97d3 -r 4b51d081378d tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh     Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/examples/vtpm-common.sh     Wed Jun 28 07:52:21 2006 -0600
@@ -23,7 +23,7 @@ VTPMDB="/etc/xen/vtpm.db"
 VTPMDB="/etc/xen/vtpm.db"
 
 #In the vtpm-impl file some commands should be defined:
-#      vtpm_create, vtpm_setup, vtpm_reset, etc. (see below)
+#      vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
 #This should be indicated by setting VTPM_IMPL_DEFINED.
 if [ -r "$dir/vtpm-impl" ]; then
        . "$dir/vtpm-impl"
@@ -36,7 +36,7 @@ if [ -z "$VTPM_IMPL_DEFINED" ]; then
        function vtpm_setup() {
                true
        }
-       function vtpm_reset() {
+       function vtpm_start() {
                true
        }
        function vtpm_suspend() {
@@ -256,22 +256,22 @@ function vtpm_create_instance () {
                else
                        instance=$(vtpmdb_get_free_instancenum)
                fi
-               if [ "$reason" == "create" ]; then
-                       vtpm_create $instance
-               else
-                       vtpm_resume $instance $domname
-               fi
+
+               vtpm_create $instance
+
                if [ $vtpm_fatal_error -eq 0 ]; then
                        vtpmdb_add_instance $domname $instance
                fi
+       else
+               if [ "$reason" == "resume" ]; then
+                       vtpm_resume $instance
+               else
+                       vtpm_start $instance
+               fi
        fi
 
        release_lock vtpmdb
 
-       if [ $vtpm_fatal_error -eq 0 -a \
-            "$reason" == "create" ]; then
-               vtpm_reset $instance
-       fi
        xenstore_write $XENBUS_PATH/instance $instance
 }
 
@@ -283,19 +283,17 @@ function vtpm_remove_instance () {
        local instance reason domname
        domname=$(xenstore_read "$XENBUS_PATH"/domain)
 
-       if [ "$doname" != "" ]; then
+       if [ "$domname" != "" ]; then
                claim_lock vtpmdb
 
                instance=$(vtpmdb_find_instance $domname)
 
                if [ "$instance" != "0" ]; then
-                       if [ "$reason" == "suspend" ]; then
-                               vtpm_suspend $instance
-                       fi
-               fi
-       fi
-
-       release_lock vtpmdb
+                       vtpm_suspend $instance
+               fi
+
+               release_lock vtpmdb
+       fi
 }
 
 
diff -r c4b68afe97d3 -r 4b51d081378d tools/libxc/Makefile
--- a/tools/libxc/Makefile      Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/libxc/Makefile      Wed Jun 28 07:52:21 2006 -0600
@@ -31,7 +31,6 @@ GUEST_SRCS-y += xc_load_elf.c
 GUEST_SRCS-y += xc_load_elf.c
 GUEST_SRCS-y += xg_private.c
 GUEST_SRCS-$(CONFIG_IA64) += xc_ia64_stubs.c
-GUEST_SRCS-$(CONFIG_PLAN9) += xc_load_aout9.c
 GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
 GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
 
diff -r c4b68afe97d3 -r 4b51d081378d tools/libxc/xc_ia64_stubs.c
--- a/tools/libxc/xc_ia64_stubs.c       Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/libxc/xc_ia64_stubs.c       Wed Jun 28 07:52:21 2006 -0600
@@ -38,23 +38,12 @@ int xc_linux_restore(int xc_handle, int 
     return -1;
 }
 
-int
-xc_plan9_build(int xc_handle,
-               uint32_t domid,
-               const char *image_name,
-               const char *cmdline,
-               unsigned int control_evtchn, unsigned long flags)
-{
-    PERROR("xc_plan9_build not implemented\n");
-    return -1;
-}
 /*  
     VMM uses put_user to copy pfn_list to guest buffer, this maybe fail,
     VMM doesn't handle this now.
     This method will touch guest buffer to make sure the buffer's mapping
     is tracked by VMM,
  */
-
 int xc_ia64_get_pfn_list(int xc_handle,
                          uint32_t domid,
                          xen_pfn_t *pfn_buf,
diff -r c4b68afe97d3 -r 4b51d081378d tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/libxc/xc_linux_build.c      Wed Jun 28 07:52:21 2006 -0600
@@ -7,7 +7,6 @@
 #include <xenctrl.h>
 
 #include "xc_elf.h"
-#include "xc_aout9.h"
 #include <stdlib.h>
 #include <unistd.h>
 #include <inttypes.h>
@@ -34,10 +33,6 @@
 
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
-
-#ifdef __ia64__
-#define probe_aout9(image,image_size,load_funcs) 1
-#endif
 
 struct initrd_info {
     enum { INITRD_none, INITRD_file, INITRD_mem } type;
@@ -124,8 +119,7 @@ static int probeimageformat(const char *
                             struct load_funcs *load_funcs)
 {
     if ( probe_elf(image, image_size, load_funcs) &&
-         probe_bin(image, image_size, load_funcs) &&
-         probe_aout9(image, image_size, load_funcs) )
+         probe_bin(image, image_size, load_funcs) )
     {
         ERROR( "Unrecognized image format" );
         return -EINVAL;
diff -r c4b68afe97d3 -r 4b51d081378d tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/libxc/xg_private.h  Wed Jun 28 07:52:21 2006 -0600
@@ -196,8 +196,5 @@ int probe_elf(const char *image, unsigne
               struct load_funcs *funcs);
 int probe_bin(const char *image, unsigned long image_size,
               struct load_funcs *funcs);
-int probe_aout9(const char *image, unsigned long image_size,
-                struct load_funcs *funcs);
-
-#endif
-
+
+#endif /* XG_PRIVATE_H */
diff -r c4b68afe97d3 -r 4b51d081378d tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Jun 28 07:52:21 2006 -0600
@@ -582,6 +582,12 @@ static PyObject *pyxc_readconsolering(Xc
 }
 
 
+static unsigned long pages_to_kib(unsigned long pages)
+{
+    return pages * (XC_PAGE_SIZE / 1024);
+}
+
+
 static PyObject *pyxc_pages_to_kib(XcObject *self, PyObject *args)
 {
     unsigned long pages;
@@ -589,13 +595,7 @@ static PyObject *pyxc_pages_to_kib(XcObj
     if (!PyArg_ParseTuple(args, "l", &pages))
         return NULL;
 
-    return PyLong_FromUnsignedLong(pages * (XC_PAGE_SIZE / 1024));
-}
-
-
-static unsigned long pages_to_mb(unsigned long pages)
-{
-    return (pages * (XC_PAGE_SIZE / 1024) + 1023) / 1024;
+    return PyLong_FromUnsignedLong(pages_to_kib(pages));
 }
 
 
@@ -618,13 +618,14 @@ static PyObject *pyxc_physinfo(XcObject 
     if(q>cpu_cap)
         *(q-1)=0;
 
-    return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:i,s:s}",
+    return Py_BuildValue("{s:i,s:i,s:i,s:i,s:l,s:l,s:l,s:i,s:s}",
                          "threads_per_core", info.threads_per_core,
                          "cores_per_socket", info.cores_per_socket,
                          "sockets_per_node", info.sockets_per_node,
                          "nr_nodes",         info.nr_nodes,
-                         "total_memory",     pages_to_mb(info.total_pages),
-                         "free_memory",      pages_to_mb(info.free_pages),
+                         "total_memory",     pages_to_kib(info.total_pages),
+                         "free_memory",      pages_to_kib(info.free_pages),
+                         "scrub_memory",     pages_to_kib(info.scrub_pages),
                          "cpu_khz",          info.cpu_khz,
                          "hw_caps",          cpu_cap);
 }
@@ -637,6 +638,7 @@ static PyObject *pyxc_xeninfo(XcObject *
     xen_capabilities_info_t xen_caps;
     xen_platform_parameters_t p_parms;
     long xen_version;
+    long xen_pagesize;
     char str[128];
 
     xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
@@ -658,11 +660,16 @@ static PyObject *pyxc_xeninfo(XcObject *
 
     sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
 
-    return Py_BuildValue("{s:i,s:i,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}",
+    xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
+    if (xen_pagesize < 0 )
+        return PyErr_SetFromErrno(xc_error);
+
+    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}",
                          "xen_major", xen_version >> 16,
                          "xen_minor", (xen_version & 0xffff),
                          "xen_extra", xen_extra,
                          "xen_caps",  xen_caps,
+                         "xen_pagesize", xen_pagesize,
                          "platform_params", str,
                          "xen_changeset", xen_chgset,
                          "cc_compiler", xen_cc.compiler,
diff -r c4b68afe97d3 -r 4b51d081378d tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/python/xen/xend/XendNode.py Wed Jun 28 07:52:21 2006 -0600
@@ -64,6 +64,9 @@ class XendNode:
                            info['cores_per_socket'] *
                            info['threads_per_core'])
         info['cpu_mhz'] = info['cpu_khz'] / 1000
+        # physinfo is in KiB
+        info['total_memory'] = info['total_memory'] / 1024
+        info['free_memory']  = info['free_memory'] / 1024
 
         ITEM_ORDER = ['nr_cpus',
                       'nr_nodes',
@@ -86,6 +89,7 @@ class XendNode:
                       'xen_minor',
                       'xen_extra',
                       'xen_caps',
+                      'xen_pagesize',
                       'platform_params',
                       'xen_changeset',
                       'cc_compiler',
diff -r c4b68afe97d3 -r 4b51d081378d tools/python/xen/xend/balloon.py
--- a/tools/python/xen/xend/balloon.py  Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/python/xen/xend/balloon.py  Wed Jun 28 07:52:21 2006 -0600
@@ -29,9 +29,7 @@ from XendError import VmError
 
 PROC_XEN_BALLOON = '/proc/xen/balloon'
 
-BALLOON_OUT_SLACK = 1 # MiB.  We need this because the physinfo details are
-                      # rounded.
-RETRY_LIMIT = 10
+RETRY_LIMIT = 20
 RETRY_LIMIT_INCR = 5
 ##
 # The time to sleep between retries grows linearly, using this value (in
@@ -68,22 +66,22 @@ def _get_proc_balloon(label):
         f.close()
 
 def get_dom0_current_alloc():
-    """Returns the current memory allocation (in MiB) of dom0."""
+    """Returns the current memory allocation (in KiB) of dom0."""
 
     kb = _get_proc_balloon(labels['current'])
     if kb == None:
         raise VmError('Failed to query current memory allocation of dom0.')
-    return kb / 1024
+    return kb
 
 def get_dom0_target_alloc():
-    """Returns the target memory allocation (in MiB) of dom0."""
+    """Returns the target memory allocation (in KiB) of dom0."""
 
     kb = _get_proc_balloon(labels['target'])
     if kb == None:
         raise VmError('Failed to query target memory allocation of dom0.')
-    return kb / 1024
+    return kb
 
-def free(required):
+def free(need_mem):
     """Balloon out memory from the privileged domain so that there is the
     specified required amount (in KiB) free.
     """
@@ -92,9 +90,10 @@ def free(required):
     # to balloon out to free some up.  Memory freed by a destroyed domain may
     # not appear in the free_memory field immediately, because it needs to be
     # scrubbed before it can be released to the free list, which is done
-    # asynchronously by Xen; ballooning is asynchronous also.  No matter where
-    # we expect the free memory to come from, therefore, we need to wait for
-    # it to become available.
+    # asynchronously by Xen; ballooning is asynchronous also.  Such memory
+    # does, however, need to be accounted for when calculating how much dom0
+    # needs to balloon.  No matter where we expect the free memory to come
+    # from, we need to wait for it to become available.
     #
     # We are not allowed to balloon below dom0_min_mem, or if dom0_min_mem
     # is 0, we cannot balloon at all.  Memory can still become available
@@ -108,43 +107,49 @@ def free(required):
     # usage, so we recheck the required alloc each time around the loop, but
     # track the last used value so that we don't trigger too many watches.
 
-    need_mem = (required + 1023) / 1024 + BALLOON_OUT_SLACK
-
     xroot = XendRoot.instance()
     xc = xen.lowlevel.xc.xc()
 
     try:
-        dom0_min_mem = xroot.get_dom0_min_mem()
+        dom0_min_mem = xroot.get_dom0_min_mem() * 1024
 
         retries = 0
         sleep_time = SLEEP_TIME_GROWTH
         last_new_alloc = None
         rlimit = RETRY_LIMIT
         while retries < rlimit:
-            free_mem = xc.physinfo()['free_memory']
+            physinfo = xc.physinfo()
+            free_mem = physinfo['free_memory']
+            scrub_mem = physinfo['scrub_memory']
 
             if free_mem >= need_mem:
-                log.debug("Balloon: free %d; need %d; done.", free_mem,
-                          need_mem)
+                log.debug("Balloon: %d KiB free; need %d; done.",
+                          free_mem, need_mem)
                 return
 
             if retries == 0:
-                rlimit += ((need_mem - free_mem)/1024) * RETRY_LIMIT_INCR
-                log.debug("Balloon: free %d; need %d; retries: %d.", 
-                          free_mem, need_mem, rlimit)
+                rlimit += ((need_mem - free_mem)/1024/1024) * RETRY_LIMIT_INCR
+                log.debug("Balloon: %d KiB free; %d to scrub; need %d; 
retries: %d.",
+                          free_mem, scrub_mem, need_mem, rlimit)
 
             if dom0_min_mem > 0:
                 dom0_alloc = get_dom0_current_alloc()
-                new_alloc = dom0_alloc - (need_mem - free_mem)
+                new_alloc = dom0_alloc - (need_mem - free_mem - scrub_mem)
 
-                if (new_alloc >= dom0_min_mem and
-                    new_alloc != last_new_alloc):
-                    log.debug("Balloon: setting dom0 target to %d.",
-                              new_alloc)
-                    dom0 = XendDomain.instance().privilegedDomain()
-                    dom0.setMemoryTarget(new_alloc)
-                    last_new_alloc = new_alloc
-                    # Continue to retry, waiting for ballooning.
+                if free_mem + scrub_mem >= need_mem:
+                    if last_new_alloc == None:
+                        log.debug("Balloon: waiting on scrubbing")
+                        last_new_alloc = dom0_alloc
+                else:
+                    if (new_alloc >= dom0_min_mem and
+                        new_alloc != last_new_alloc):
+                        new_alloc_mb = new_alloc / 1024  # Round down
+                        log.debug("Balloon: setting dom0 target to %d MiB.",
+                                  new_alloc_mb)
+                        dom0 = XendDomain.instance().privilegedDomain()
+                        dom0.setMemoryTarget(new_alloc_mb)
+                        last_new_alloc = new_alloc
+                # Continue to retry, waiting for ballooning or scrubbing.
 
             time.sleep(sleep_time)
             if retries < 2 * RETRY_LIMIT:
@@ -154,15 +159,15 @@ def free(required):
         # Not enough memory; diagnose the problem.
         if dom0_min_mem == 0:
             raise VmError(('Not enough free memory and dom0_min_mem is 0, so '
-                           'I cannot release any more.  I need %d MiB but '
+                           'I cannot release any more.  I need %d KiB but '
                            'only have %d.') %
                           (need_mem, free_mem))
         elif new_alloc < dom0_min_mem:
             raise VmError(
-                ('I need %d MiB, but dom0_min_mem is %d and shrinking to '
-                 '%d MiB would leave only %d MiB free.') %
+                ('I need %d KiB, but dom0_min_mem is %d and shrinking to '
+                 '%d KiB would leave only %d KiB free.') %
                 (need_mem, dom0_min_mem, dom0_min_mem,
-                 free_mem + dom0_alloc - dom0_min_mem))
+                 free_mem + scrub_mem + dom0_alloc - dom0_min_mem))
         else:
             raise VmError('The privileged domain did not balloon!')
 
diff -r c4b68afe97d3 -r 4b51d081378d tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/python/xen/xm/main.py       Wed Jun 28 07:52:21 2006 -0600
@@ -887,7 +887,7 @@ def parse_dev_info(info):
         'ring-ref'   : get_info('ring-ref',     int,   -1),
         }
 
-def has_long_option(args):
+def arg_check_for_resource_list(args, name):
     use_long = 0
     try:
         (options, params) = getopt.gnu_getopt(args, 'l', ['long'])
@@ -898,16 +898,19 @@ def has_long_option(args):
     for (k, v) in options:
         if k in ['-l', '--long']:
             use_long = 1
-    return (use_long, params)
-
-def xm_network_list(args):
-    arg_check(args, "network-list", 1, 2)
-
-    (use_long, params) = has_long_option(args)
 
     if len(params) == 0:
         print 'No domain parameter given'
-        sys.exit(1)
+        usage(name)
+    if len(params) > 1:
+        print 'No multiple domain parameters allowed'
+        usage(name)
+    
+    return (use_long, params)
+
+def xm_network_list(args):
+    (use_long, params) = arg_check_for_resource_list(args, "network-list")
+
     dom = params[0]
     if use_long:
         devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
@@ -931,13 +934,8 @@ def xm_network_list(args):
                    % ni)
 
 def xm_block_list(args):
-    arg_check(args, "block-list", 1, 2)
-
-    (use_long, params) = has_long_option(args)
-
-    if len(params) == 0:
-        print 'No domain parameter given'
-        sys.exit(1)
+    (use_long, params) = arg_check_for_resource_list(args, "block-list")
+
     dom = params[0]
     if use_long:
         devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
@@ -960,13 +958,8 @@ def xm_block_list(args):
                    % ni)
 
 def xm_vtpm_list(args):
-    arg_check(args, "vtpm-list", 1, 2)
-
-    (use_long, params) = has_long_option(args)
-
-    if len(params) == 0:
-        print 'No domain parameter given'
-        sys.exit(1)
+    (use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
+
     dom = params[0]
     if use_long:
         devs = server.xend.domain.getDeviceSxprs(dom, 'vtpm')
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm/Rules.mk
--- a/tools/vtpm/Rules.mk       Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm/Rules.mk       Wed Jun 28 07:52:21 2006 -0600
@@ -33,8 +33,7 @@ OBJS  = $(patsubst %.c,%.o,$(SRCS))
 
 -include $(DEP_FILES)
 
-# Emulator does not work on 64-bit systems, and may be broken on 32 right now
-BUILD_EMULATOR = n
+BUILD_EMULATOR = y
 
 # Make sure these are just rules
 .PHONY : all build install clean
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm/tpm_emulator-0.3-x86_64.patch
--- a/tools/vtpm/tpm_emulator-0.3-x86_64.patch  Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm/tpm_emulator-0.3-x86_64.patch  Wed Jun 28 07:52:21 2006 -0600
@@ -1,6 +1,49 @@ diff -uprN tpm_emulator-0.3/crypto/gmp_k
-diff -uprN tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c 
tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
---- tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c       2006-01-10 
04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c        2006-05-26 
11:26:02.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile
+--- orig/tpm_emulator-0.3/Makefile     2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/Makefile   2006-08-29 15:08:20.532342768 -0700
+@@ -7,6 +7,7 @@
+ KERNEL_RELEASE := $(shell uname -r)
+ KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
+ MOD_SUBDIR     := misc
++COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
+ 
+ # module settings
+ MODULE_NAME    := tpm_emulator
+@@ -17,8 +18,14 @@ VERSION_BUILD  := $(shell date +"%s")
+ # enable/disable DEBUG messages
+ EXTRA_CFLAGS   += -Wall -DDEBUG -g  
+ 
++ifeq ($(COMPILE_ARCH),x86_64)
++LIBDIR = lib64
++else
++LIBDIR = lib
++endif
++
+ # GNU MP configuration
+-GMP_LIB        := /usr/lib/libgmp.a
++GMP_LIB        := /usr/$(LIBDIR)/libgmp.a
+ GMP_HEADER     := /usr/include/gmp.h
+ 
+ # sources and objects
+diff -uprN orig/tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README
+--- orig/tpm_emulator-0.3/README       2006-01-10 04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/README     2006-08-29 15:07:43.530967832 -0700
+@@ -43,6 +43,12 @@ Example:
+ GMP_LIB        := /usr/lib/libgmp.a
+ GMP_HEADER     := /usr/include/gmp.h
+ 
++GNU MP Library on 64 bit Systems
++--------------------------------------------------------------------------
++Some 64-bit kernels have problems with importing the user-space gmp 
++library (/usr/lib*/libgmp.a) into kernel space.  These kernels will require
++that the gmp library be recompiled for kernel space with -mcmodel=kernel.
++
+ Installation
+ --------------------------------------------------------------------------
+ The compilation and installation process uses the build environment for 
+diff -uprN orig/tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c 
tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c
+--- orig/tpm_emulator-0.3/crypto/gmp_kernel_wrapper.c  2006-01-10 
04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c        2006-08-29 
15:07:43.525968592 -0700
 @@ -79,7 +79,7 @@ void __attribute__ ((regparm(0))) *kerne
  {
    void *ret  = (void*)kmalloc(size, GFP_KERNEL);
@@ -19,9 +62,9 @@ diff -uprN tpm_emulator-0.3/crypto/gmp_k
    memcpy(ret, oldptr, old_size);
    kfree(oldptr);
    return ret;
-diff -uprN tpm_emulator-0.3/linux_module.c 
tpm_emulator-0.3-x86_64/linux_module.c
---- tpm_emulator-0.3/linux_module.c    2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/linux_module.c     2006-05-26 11:26:02.000000000 
-0700
+diff -uprN orig/tpm_emulator-0.3/linux_module.c 
tpm_emulator-0.3-x86_64/linux_module.c
+--- orig/tpm_emulator-0.3/linux_module.c       2006-01-10 04:21:45.000000000 
-0800
++++ tpm_emulator-0.3-x86_64/linux_module.c     2006-08-29 15:07:43.526968440 
-0700
 @@ -72,7 +72,7 @@ static int tpm_release(struct inode *ino
  
  static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t 
*ppos)
@@ -40,9 +83,9 @@ diff -uprN tpm_emulator-0.3/linux_module
    down(&tpm_mutex);
    *ppos = 0;
    if (tpm_response.data != NULL) kfree(tpm_response.data);
-diff -uprN tpm_emulator-0.3/linux_module.h 
tpm_emulator-0.3-x86_64/linux_module.h
---- tpm_emulator-0.3/linux_module.h    2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/linux_module.h     2006-05-26 11:26:02.000000000 
-0700
+diff -uprN orig/tpm_emulator-0.3/linux_module.h 
tpm_emulator-0.3-x86_64/linux_module.h
+--- orig/tpm_emulator-0.3/linux_module.h       2006-01-10 04:21:45.000000000 
-0800
++++ tpm_emulator-0.3-x86_64/linux_module.h     2006-08-29 15:07:43.527968288 
-0700
 @@ -28,8 +28,10 @@
  
  /* module settings */
@@ -54,52 +97,9 @@ diff -uprN tpm_emulator-0.3/linux_module
  #include "tpm_version.h"
  
  #define TPM_DEVICE_MINOR      224
-diff -uprN tpm_emulator-0.3/Makefile tpm_emulator-0.3-x86_64/Makefile
---- tpm_emulator-0.3/Makefile  2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/Makefile   2006-05-26 11:26:02.000000000 -0700
-@@ -7,6 +7,7 @@
- KERNEL_RELEASE := $(shell uname -r)
- KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
- MOD_SUBDIR     := misc
-+COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
- 
- # module settings
- MODULE_NAME    := tpm_emulator
-@@ -17,8 +18,14 @@ VERSION_BUILD  := $(shell date +"%s")
- # enable/disable DEBUG messages
- EXTRA_CFLAGS   += -Wall -DDEBUG -g  
- 
-+ifeq ($(COMPILE_ARCH),x86_64)
-+LIBDIR = lib64
-+else
-+LIBDIR = lib
-+endif
-+
- # GNU MP configuration
--GMP_LIB        := /usr/lib/libgmp.a
-+GMP_LIB        := /usr/$(LIBDIR)/libgmp.a
- GMP_HEADER     := /usr/include/gmp.h
- 
- # sources and objects
-diff -uprN tpm_emulator-0.3/README tpm_emulator-0.3-x86_64/README
---- tpm_emulator-0.3/README    2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/README     2006-05-26 11:26:02.000000000 -0700
-@@ -43,6 +43,12 @@ Example:
- GMP_LIB        := /usr/lib/libgmp.a
- GMP_HEADER     := /usr/include/gmp.h
- 
-+GNU MP Library on 64 bit Systems
-+--------------------------------------------------------------------------
-+Some 64-bit kernels have problems with importing the user-space gmp 
-+library (/usr/lib*/libgmp.a) into kernel space.  These kernels will require
-+that the gmp library be recompiled for kernel space with -mcmodel=kernel.
-+
- Installation
- --------------------------------------------------------------------------
- The compilation and installation process uses the build environment for 
-diff -uprN tpm_emulator-0.3/tpm/tpm_credentials.c 
tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c
---- tpm_emulator-0.3/tpm/tpm_credentials.c     2006-01-10 04:21:45.000000000 
-0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c      2006-05-26 
11:26:02.000000000 -0700
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_credentials.c 
tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c
+--- orig/tpm_emulator-0.3/tpm/tpm_credentials.c        2006-01-10 
04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_credentials.c      2006-08-29 
15:07:43.530967832 -0700
 @@ -47,16 +47,16 @@ int tpm_compute_pubkey_checksum(TPM_NONC
  
  TPM_RESULT tpm_get_pubek(TPM_PUBKEY *pubEndorsementKey)
@@ -140,9 +140,9 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_cred
      publicPortion->algorithmParms.algorithmID = TPM_ALG_RSA;
      publicPortion->algorithmParms.encScheme = srk->encScheme;
      publicPortion->algorithmParms.sigScheme = srk->sigScheme;
-diff -uprN tpm_emulator-0.3/tpm/tpm_crypto.c 
tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c
---- tpm_emulator-0.3/tpm/tpm_crypto.c  2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c   2006-05-26 11:26:02.000000000 
-0700
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_crypto.c 
tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c
+--- orig/tpm_emulator-0.3/tpm/tpm_crypto.c     2006-01-10 04:21:45.000000000 
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c   2006-08-29 15:07:43.531967680 
-0700
 @@ -182,7 +182,8 @@ TPM_RESULT TPM_CertifyKey(TPM_KEY_HANDLE
    TPM_KEY_DATA *cert, *key;
    sha1_ctx_t sha1_ctx;
@@ -192,10 +192,10 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_cryp
      free_TPM_KEY_PARMS(certifyInfo->algorithmParms);
      return TPM_FAIL;
    }
-diff -uprN tpm_emulator-0.3/tpm/tpm_data.c 
tpm_emulator-0.3-x86_64/tpm/tpm_data.c
---- tpm_emulator-0.3/tpm/tpm_data.c    2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c     2006-05-26 11:26:02.000000000 
-0700
-@@ -214,7 +214,7 @@ static int read_from_file(uint8_t **data
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_data.c 
tpm_emulator-0.3-x86_64/tpm/tpm_data.c
+--- orig/tpm_emulator-0.3/tpm/tpm_data.c       2006-01-10 04:21:45.000000000 
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_data.c     2006-08-29 15:08:20.535342312 
-0700
+@@ -214,23 +214,30 @@ static int read_from_file(uint8_t **data
  int tpm_store_permanent_data(void)
  {
    uint8_t *buf, *ptr;
@@ -203,8 +203,35 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_data
 +  UINT32 buf_length, len;
  
    /* marshal data */
-   buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
-@@ -242,13 +242,14 @@ int tpm_store_permanent_data(void)
+-  buf_length = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
+-    + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) + 2
+-    + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data);
++  buf_length = len = 4 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
++    + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) 
++    + sizeof_TPM_STANY_FLAGS(tpmData.stany.flags) + 2
++    + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data) 
++    + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data)
++    + sizeof_TPM_STANY_DATA(tpmData.stany.data);
+   buf = ptr = tpm_malloc(buf_length);
+   if (buf == NULL
+       || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version)
+       || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
+       || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)
++      || tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
+       || tpm_marshal_BOOL(&ptr, &len, 
tpmData.permanent.flags.selfTestSucceeded)
+       || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned)
+-      || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)) 
{
++      || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
++      || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
++      || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
+     tpm_free(buf);
+     return -1;
+   }
++
+   if (write_to_file(buf, buf_length - len)) {
+     tpm_free(buf);
+     return -1; 
+@@ -242,24 +249,29 @@ int tpm_store_permanent_data(void)
  int tpm_restore_permanent_data(void)
  {
    uint8_t *buf, *ptr;
@@ -221,9 +248,25 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_data
    /* unmarshal data */
    if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
        || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION))
-diff -uprN tpm_emulator-0.3/tpm/tpm_marshalling.c 
tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c
---- tpm_emulator-0.3/tpm/tpm_marshalling.c     2006-01-10 04:21:45.000000000 
-0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c      2006-05-26 
11:26:02.000000000 -0700
+       || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
+       || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len, 
&tpmData.permanent.flags)
++      || tpm_unmarshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
+       || tpm_unmarshal_BOOL(&ptr, &len, 
&tpmData.permanent.flags.selfTestSucceeded)
+       || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned)
+-      || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, 
&tpmData.permanent.data)) {
++      || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
++      || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
++      || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
+     tpm_free(buf);
+     return -1;
+   }
++
+   tpm_free(buf);
+   return 0;
+ }
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_marshalling.c 
tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c
+--- orig/tpm_emulator-0.3/tpm/tpm_marshalling.c        2006-01-10 
04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.c      2006-08-29 
15:08:20.537342008 -0700
 @@ -1212,7 +1212,7 @@ int tpm_unmarshal_TPM_STANY_FLAGS(BYTE *
  
  int tpm_marshal_RSA(BYTE **ptr, UINT32 *length, rsa_private_key_t *v)
@@ -233,9 +276,92 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_mars
    if (*length < sizeof_RSA((*v))) return -1;
    if (v->size > 0) {
      rsa_export_modulus(v, &(*ptr)[6], &m_len);
-diff -uprN tpm_emulator-0.3/tpm/tpm_owner.c 
tpm_emulator-0.3-x86_64/tpm/tpm_owner.c
---- tpm_emulator-0.3/tpm/tpm_owner.c   2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c    2006-05-26 11:26:02.000000000 
-0700
+@@ -1356,6 +1356,66 @@ int tpm_unmarshal_TPM_PERMANENT_DATA(BYT
+   return 0;
+ }
+ 
++int tpm_marshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA 
*v)
++{
++  if (tpm_marshal_TPM_STRUCTURE_TAG(ptr, length, v->tag)
++    || tpm_marshal_TPM_NONCE(ptr, length, &v->contextNonceKey)
++    || tpm_marshal_TPM_COUNT_ID(ptr, length, v->countID) ) return -1;
++
++  return 0;
++}
++
++int tpm_unmarshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, 
TPM_STCLEAR_DATA *v)
++{
++  if (tpm_unmarshal_TPM_STRUCTURE_TAG(ptr, length, &v->tag)
++    || tpm_unmarshal_TPM_NONCE(ptr, length, &v->contextNonceKey)
++    || tpm_unmarshal_TPM_COUNT_ID(ptr, length, &v->countID) ) return -1;
++
++  return 0;
++}
++
++int tpm_marshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v)
++{
++  UINT32 i;
++  if (tpm_marshal_TPM_STRUCTURE_TAG(ptr, length, v->tag)
++    || tpm_marshal_TPM_NONCE(ptr, length, &v->contextNonceSession)
++    || tpm_marshal_TPM_DIGEST(ptr, length, &v->auditDigest)
++    || tpm_marshal_BOOL(ptr, length, v->auditSession)
++    || tpm_marshal_TPM_CURRENT_TICKS(ptr, length, &v->currentTicks)
++    || tpm_marshal_UINT32(ptr, length, v->contextCount)
++    || tpm_marshal_UINT32_ARRAY(ptr, length, v->contextList, 
TPM_MAX_SESSION_LIST)) return -1;
++  for (i = 0; i < TPM_MAX_SESSIONS; i++) {
++    if (tpm_marshal_TPM_SESSION_DATA(ptr, length, &v->sessions[i])) return -1;
++  }
++  for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) {
++    if (tpm_marshal_TPM_DAA_SESSION_DATA(ptr, length, &v->sessionsDAA[i])) 
return -1;
++  }
++  if (tpm_marshal_TPM_TRANSHANDLE(ptr, length, v->transExclusive)) return -1;
++
++  return 0;
++}
++
++int tpm_unmarshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA 
*v)
++{
++  UINT32 i;
++  if (tpm_unmarshal_TPM_STRUCTURE_TAG(ptr, length, &v->tag)
++    || tpm_unmarshal_TPM_NONCE(ptr, length, &v->contextNonceSession)
++    || tpm_unmarshal_TPM_DIGEST(ptr, length, &v->auditDigest)
++    || tpm_unmarshal_BOOL(ptr, length, &v->auditSession)
++    || tpm_unmarshal_TPM_CURRENT_TICKS(ptr, length, &v->currentTicks)
++    || tpm_unmarshal_UINT32(ptr, length, &v->contextCount)
++    || tpm_unmarshal_UINT32_ARRAY(ptr, length, v->contextList, 
TPM_MAX_SESSION_LIST)) return -1;
++  for (i = 0; i < TPM_MAX_SESSIONS; i++) {
++    if (tpm_unmarshal_TPM_SESSION_DATA(ptr, length, &v->sessions[i])) return 
-1;
++  }
++  for (i = 0; i < TPM_MAX_SESSIONS_DAA; i++) {
++    if (tpm_unmarshal_TPM_DAA_SESSION_DATA(ptr, length, &v->sessionsDAA[i])) 
return -1;
++  }
++  if (tpm_unmarshal_TPM_TRANSHANDLE(ptr, length, &v->transExclusive)) return 
-1;
++
++  return 0;
++}
++
+ int tpm_marshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA 
*v)
+ {
+   if (tpm_marshal_BYTE(ptr, length, v->type)
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_marshalling.h 
tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.h
+--- orig/tpm_emulator-0.3/tpm/tpm_marshalling.h        2006-01-10 
04:21:45.000000000 -0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_marshalling.h      2006-08-29 
15:08:20.538341856 -0700
+@@ -420,6 +420,12 @@ int tpm_unmarshal_TPM_KEY_DATA(BYTE **pt
+ int tpm_marshal_TPM_PERMANENT_DATA(BYTE **ptr, UINT32 *length, 
TPM_PERMANENT_DATA *);
+ int tpm_unmarshal_TPM_PERMANENT_DATA(BYTE **ptr, UINT32 *length, 
TPM_PERMANENT_DATA *);
+ 
++int tpm_marshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, TPM_STCLEAR_DATA 
*v);
++int tpm_unmarshal_TPM_STCLEAR_DATA(BYTE **ptr, UINT32 *length, 
TPM_STCLEAR_DATA *v);
++
++int tpm_marshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA *v);
++int tpm_unmarshal_TPM_STANY_DATA(BYTE **ptr, UINT32 *length, TPM_STANY_DATA 
*v);
++
+ int tpm_marshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, TPM_SESSION_DATA 
*v);
+ int tpm_unmarshal_TPM_SESSION_DATA(BYTE **ptr, UINT32 *length, 
TPM_SESSION_DATA *v);
+ 
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_owner.c 
tpm_emulator-0.3-x86_64/tpm/tpm_owner.c
+--- orig/tpm_emulator-0.3/tpm/tpm_owner.c      2006-01-10 04:21:45.000000000 
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_owner.c    2006-08-29 15:07:43.535967072 
-0700
 @@ -108,7 +108,7 @@ TPM_RESULT TPM_TakeOwnership(TPM_PROTOCO
    TPM_RESULT res;
    rsa_private_key_t *ek = &tpmData.permanent.data.endorsementKey;
@@ -255,9 +381,63 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_owne
    /* setup tpmProof and set state to owned */
    tpm_get_random_bytes(tpmData.permanent.data.tpmProof.nonce, 
      sizeof(tpmData.permanent.data.tpmProof.nonce));
-diff -uprN tpm_emulator-0.3/tpm/tpm_storage.c 
tpm_emulator-0.3-x86_64/tpm/tpm_storage.c
---- tpm_emulator-0.3/tpm/tpm_storage.c 2006-01-10 04:21:45.000000000 -0800
-+++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c  2006-05-26 14:33:18.000000000 
-0700
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_startup.c 
tpm_emulator-0.3-x86_64/tpm/tpm_startup.c
+--- orig/tpm_emulator-0.3/tpm/tpm_startup.c    2006-01-10 04:21:45.000000000 
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_startup.c  2006-08-29 15:08:20.538341856 
-0700
+@@ -41,24 +41,29 @@ void TPM_Init(TPM_STARTUP_TYPE startupTy
+ TPM_RESULT TPM_Startup(TPM_STARTUP_TYPE startupType)
+ {
+   int i;
++  int restore_fail;
+   info("TPM_Startup(%d)", startupType);
+   if (tpmData.stany.flags.postInitialise == FALSE) return 
TPM_INVALID_POSTINIT;
+-  /* reset STANY_FLAGS */
+-  SET_TO_ZERO(&tpmData.stany.flags);
+-  tpmData.stany.flags.tag = TPM_TAG_STANY_FLAGS;
+-  /* reset STANY_DATA (invalidates ALL sessions) */
+-  SET_TO_ZERO(&tpmData.stany.data);
+-  tpmData.stany.data.tag = TPM_TAG_STANY_DATA;
+-  /* init session-context nonce */
+-  SET_TO_RAND(&tpmData.stany.data.contextNonceSession);
++
++  /* try and restore state to get EK, SRK, etc */
++  restore_fail = tpm_restore_permanent_data();
++
+   /* set data and flags according to the given startup type */
+   if (startupType == TPM_ST_CLEAR) {
++    /* reset STANY_FLAGS */
++    SET_TO_ZERO(&tpmData.stany.flags);
++    tpmData.stany.flags.tag = TPM_TAG_STANY_FLAGS;
++    /* reset STANY_DATA (invalidates ALL sessions) */
++    SET_TO_ZERO(&tpmData.stany.data);
++    tpmData.stany.data.tag = TPM_TAG_STANY_DATA;
++    /* init session-context nonce */
++    SET_TO_RAND(&tpmData.stany.data.contextNonceSession);
+     /* reset PCR values */
+     for (i = 0; i < TPM_NUM_PCR; i++) {
+-      if (tpmData.permanent.data.pcrAttrib[i].pcrReset)
+-        SET_TO_ZERO(tpmData.permanent.data.pcrValue[i].digest);
++      if (!tpmData.permanent.data.pcrAttrib[i].pcrReset)
++        SET_TO_ZERO(&tpmData.permanent.data.pcrValue[i].digest);
+       else
+-        SET_TO_0xFF(tpmData.permanent.data.pcrValue[i].digest);
++        SET_TO_0xFF(&tpmData.permanent.data.pcrValue[i].digest);
+     }
+     /* reset STCLEAR_FLAGS */
+     SET_TO_ZERO(&tpmData.stclear.flags);
+@@ -77,7 +82,8 @@ TPM_RESULT TPM_Startup(TPM_STARTUP_TYPE 
+     /* init key-context nonce */
+     SET_TO_RAND(&tpmData.stclear.data.contextNonceKey);
+   } else if (startupType == TPM_ST_STATE) {
+-    if (tpm_restore_permanent_data()) {
++    /* restore must have been successful for TPM_ST_STATE */
++    if (restore_fail) {
+       error("restoring permanent data failed");
+       tpmData.permanent.data.testResult = "tpm_restore_permanent_data() 
failed";
+       tpmData.permanent.flags.selfTestSucceeded = FALSE;
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_storage.c 
tpm_emulator-0.3-x86_64/tpm/tpm_storage.c
+--- orig/tpm_emulator-0.3/tpm/tpm_storage.c    2006-01-10 04:21:45.000000000 
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_storage.c  2006-08-29 15:07:43.537966768 
-0700
 @@ -58,6 +58,7 @@ int encrypt_sealed_data(TPM_KEY_DATA *ke
                          BYTE *enc, UINT32 *enc_size)
  {
@@ -482,3 +662,76 @@ diff -uprN tpm_emulator-0.3/tpm/tpm_stor
    if (tpm_setup_key_parms(key, &pubKey->algorithmParms) != 0) {
      tpm_free(pubKey->pubKey.key);
      return TPM_FAIL;
+diff -uprN orig/tpm_emulator-0.3/tpm/tpm_structures.h 
tpm_emulator-0.3-x86_64/tpm/tpm_structures.h
+--- orig/tpm_emulator-0.3/tpm/tpm_structures.h 2006-01-10 04:21:45.000000000 
-0800
++++ tpm_emulator-0.3-x86_64/tpm/tpm_structures.h       2006-08-29 
15:08:20.545340792 -0700
+@@ -1723,6 +1723,7 @@ typedef struct tdTPM_DAA_ISSUER {
+   TPM_DIGEST DAA_digest_gamma;
+   BYTE DAA_generic_q[26];
+ } TPM_DAA_ISSUER;
++#define sizeof_TPM_DAA_ISSUER(s) (2 + (20 * 6) + 26 )
+ 
+ /*
+  * TPM_DAA_TPM ([TPM_Part2], Section 22.8)
+@@ -1738,6 +1739,7 @@ typedef struct tdTPM_DAA_TPM {
+   TPM_DIGEST DAA_rekey;
+   UINT32 DAA_count;
+ } TPM_DAA_TPM;
++#define sizeof_TPM_DAA_TPM(s) (2 + (4 * 20) + 4)
+ 
+ /*
+  * TPM_DAA_CONTEXT ([TPM_Part2], Section 22.9)
+@@ -1752,6 +1754,7 @@ typedef struct tdTPM_DAA_CONTEXT {
+   BYTE DAA_scratch[256];
+   BYTE DAA_stage;
+ } TPM_DAA_CONTEXT;
++#define sizeof_TPM_DAA_CONTEXT(s) (2 + (3 * 20) + 256 + 1)
+ 
+ /*
+  * TPM_DAA_JOINDATA ([TPM_Part2], Section 22.10)
+@@ -1763,6 +1766,7 @@ typedef struct tdTPM_DAA_JOINDATA {
+   BYTE DAA_join_u1[138]; /* WATCH: 138 (v1.2 rev 85) */
+   TPM_DIGEST DAA_digest_n0;
+ } TPM_DAA_JOINDATA;
++#define sizeof_TPM_DAA_JOINDATA(s) (1 + 1 + 20)
+ 
+ /*
+  * TPM_DAA_BLOB ([TPM_Part2], Section 22.12)
+@@ -2033,6 +2037,7 @@ typedef struct tdTPM_STCLEAR_DATA {
+   TPM_COUNT_ID countID;
+   //UINT32 ownerReference;
+ } TPM_STCLEAR_DATA;
++#define sizeof_TPM_STCLEAR_DATA(s) (2 + 20 + 4)
+ 
+ /*
+  * TPM_SESSION_DATA
+@@ -2069,6 +2074,11 @@ typedef struct tdTPM_DAA_SESSION_DATA {
+   TPM_DAA_JOINDATA DAA_joinSession;
+   TPM_HANDLE handle;
+ } TPM_DAA_SESSION_DATA;
++#define sizeof_TPM_DAA_SESSION_DATA(s) ( 1 \
++  + sizeof_TPM_DAA_ISSUER(s.DAA_issuerSettings) \
++  + sizeof_TPM_DAA_TPM(s.DAA_tpmSpecific) \
++  + sizeof_TPM_DAA_CONTEXT(s.DAA_session) \
++  + sizeof_TPM_DAA_JOINDATA(s.DAA_joinSession) + 4)
+ 
+ /*
+  * TPM_STANY_DATA ([TPM_Part2], Section 7.6)
+@@ -2095,6 +2105,17 @@ typedef struct tdTPM_STANY_DATA {
+   TPM_DAA_SESSION_DATA sessionsDAA[TPM_MAX_SESSIONS_DAA];
+   TPM_TRANSHANDLE transExclusive;
+ } TPM_STANY_DATA;
++#define sizeof_TPM_STANY_DATA(s) (2 + 20 + 20 + 1 \
++  + sizeof_TPM_CURRENT_TICKS(s.currentTicks) \
++  + 4 + (4 * TPM_MAX_SESSION_LIST) \
++  + (sizeof_TPM_SESSION_DATA(s.sessions[0]) * TPM_MAX_SESSION_LIST) \
++  + (sizeof_TPM_DAA_SESSION_DATA(s.sessionsDAA[0]) * TPM_MAX_SESSIONS_DAA) + 
4)
++
++#define sizeof_TPM_PERMANENT_DATA(s) (2 + 4 + 4*20 \
++  + sizeof_RSA(s.endorsementKey) + TPM_ORD_MAX/8 \
++  + (1+TPM_MAX_KEYS)*sizeof_TPM_KEY_DATA(s.srk) \
++  + TPM_NUM_PCR*(sizeof_TPM_PCR_ATTRIBUTES(x)+20) \
++  + TPM_MAX_COUNTERS*sizeof_TPM_COUNTER_VALUE2(x) + 1 + 4 + 20)
+ 
+ /*
+  * TPM_DATA
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm/tpm_emulator.patch
--- a/tools/vtpm/tpm_emulator.patch     Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm/tpm_emulator.patch     Wed Jun 28 07:52:21 2006 -0600
@@ -1,68 +1,63 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
-diff -uprN orig/tpm_emulator-0.2-x86_64/AUTHORS tpm_emulator/AUTHORS
---- orig/tpm_emulator-0.2-x86_64/AUTHORS       2005-08-15 00:58:57.000000000 
-0700
-+++ tpm_emulator/AUTHORS       2005-09-14 20:27:22.000000000 -0700
-@@ -1 +1,2 @@
+diff -uprN tpm_emulator-0.3-x86_64/AUTHORS tpm_emulator/AUTHORS
+--- tpm_emulator-0.3-x86_64/AUTHORS    2006-08-29 15:07:21.618299064 -0700
++++ tpm_emulator/AUTHORS       2006-08-29 15:26:17.099679656 -0700
+@@ -1,2 +1,3 @@
  Mario Strasser <mast@xxxxxxx>
-+INTEL Corp <>
-diff -uprN orig/tpm_emulator-0.2-x86_64/ChangeLog tpm_emulator/ChangeLog
---- orig/tpm_emulator-0.2-x86_64/ChangeLog     2005-08-15 00:58:57.000000000 
-0700
-+++ tpm_emulator/ChangeLog     2005-09-14 20:27:22.000000000 -0700
-@@ -1,3 +1,7 @@
-+2005-08-16: INTEL Corp
-+      * Set default permissions to PCRs
-+      * Changed device to /dev/tpm0
-+
- 2005-08-15  Mario Strasser <mast@xxxxxxx>
-       * all: some typos corrected
-       * tpm_integrity.c: bug in TPM_Extend fixed
-diff -uprN orig/tpm_emulator-0.2-x86_64/linux_module.h 
tpm_emulator/linux_module.h
---- orig/tpm_emulator-0.2-x86_64/linux_module.h        2005-09-15 
19:21:14.844078720 -0700
-+++ tpm_emulator/linux_module.h        2005-09-14 20:27:22.000000000 -0700
-@@ -1,5 +1,6 @@
- /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
-  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
-+ * Copyright (C) 2005 INTEL Corp.
-  *
-  * This module is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published
-@@ -35,7 +36,7 @@
- #include "tpm_version.h"
- 
- #define TPM_DEVICE_MINOR      224
--#define TPM_DEVICE_NAME         "tpm"
-+#define TPM_DEVICE_NAME         "tpm0"
- #define TPM_MODULE_NAME       "tpm_emulator"
- 
- /* debug and log output functions */
-diff -uprN orig/tpm_emulator-0.2-x86_64/Makefile tpm_emulator/Makefile
---- orig/tpm_emulator-0.2-x86_64/Makefile      2005-09-15 19:21:14.845078568 
-0700
-+++ tpm_emulator/Makefile      2005-09-14 20:27:22.000000000 -0700
-@@ -1,16 +1,22 @@
+ Heiko Stamer <stamer@xxxxxxxx> [DAA]
++INTEL Corp <> [Dropped to Ring3]
+diff -uprN tpm_emulator-0.3-x86_64/ChangeLog tpm_emulator/ChangeLog
+--- tpm_emulator-0.3-x86_64/ChangeLog  2006-08-29 15:07:21.618299064 -0700
++++ tpm_emulator/ChangeLog     2006-08-29 15:26:17.100679504 -0700
+@@ -1,3 +1,6 @@
++2005-08-16 Intel Corp
++      * Moved module out of kernel to run as a ring 3 app
++
+ 2005-12-24  Mario Strasser <mast@xxxxxxx>
+       * tpm_transport.c, tpm_marshalling.c, tpm_structures.h:
+               Transport session functionality added
+diff -uprN tpm_emulator-0.3-x86_64/Makefile tpm_emulator/Makefile
+--- tpm_emulator-0.3-x86_64/Makefile   2006-08-29 15:08:20.532342768 -0700
++++ tpm_emulator/Makefile      2006-08-29 15:27:39.559143912 -0700
+@@ -1,22 +1,31 @@
  # Software-Based Trusted Platform Module (TPM) Emulator for Linux
  # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
-+# Copyright (C) 2005 INTEL Corp.
++# Copyright (C) 2006 INTEL Corp.
  #
- # $Id: Makefile 10 2005-04-26 20:59:50Z mast $
- 
-+XEN_ROOT       := ../../..
-+EUID           := $(shell id -u)
-+
- # kernel settings
- KERNEL_RELEASE := $(shell uname -r)
+ # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
+ 
+-# kernel settings
+-KERNEL_RELEASE := $(shell uname -r)
 -KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
-+CUR_DIR        := $(shell pwd)
-+LINUX_VERSION  := $(shell cat 
$(CUR_DIR)/$(XEN_ROOT)/buildconfigs/mk.linux-2.6-xen | grep "LINUX_VER" | grep 
"2.6" | gawk '{ print $$3 }' )
-+KERNEL_BUILD   := $(XEN_ROOT)/linux-$(LINUX_VERSION)-xen
- MOD_SUBDIR     := misc
+-MOD_SUBDIR     := misc
  COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
  
  # module settings
 -MODULE_NAME    := tpm_emulator
 +BIN            := tpm_emulator
  VERSION_MAJOR  := 0
- VERSION_MINOR  := 2
+ VERSION_MINOR  := 3
  VERSION_BUILD  := $(shell date +"%s")
-@@ -34,11 +38,9 @@ DIRS           := . crypto tpm 
+ 
+-# enable/disable DEBUG messages
+-EXTRA_CFLAGS   += -Wall -DDEBUG -g  
++# Installation program and options
++INSTALL         = install
++INSTALL_PROG    = $(INSTALL) -m0755
++INSTALL_DIR     = $(INSTALL) -d -m0755
++
++# Xen tools installation directory
++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
++
++CC      := gcc
++CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
++CFLAGS  += -I. -Itpm
++
++# Is the simulator running in it's own vm?
++#CFLAGS += -DVTPM_MULTI_VM
+ 
+ ifeq ($(COMPILE_ARCH),x86_64)
+ LIBDIR = lib64
+@@ -34,38 +43,31 @@ DIRS           := . crypto tpm 
  SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
  OBJS           := $(patsubst %.c, %.o, $(SRCS))
  SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
@@ -71,29 +66,37 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
  
 -obj-m               := $(MODULE_NAME).o
 -$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
-+obj-m               := $(BIN).o
++obj-m               := $(BIN)
 +$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
  
  EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
  
-@@ -49,23 +51,17 @@ all:       $(src)/crypto/gmp.h $(src)/crypto/l
-       @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
- 
- install:
+ # do not print "Entering directory ..."
+ MAKEFLAGS      += --no-print-directory
+ 
+-all:  $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
++all: $(BIN)
++
++$(BIN):       $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) 
$(OBJS)
++      $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
++
++%.o: %.c
++      $(CC) $(CFLAGS) -c $< -o $@
+ 
+-install:
 -      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
 -      test -d /var/tpm || mkdir /var/tpm
 -      test -c /dev/tpm || mknod /dev/tpm c 10 224
 -      chmod 666 /dev/tpm
 -      depmod -a
-+      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) INSTALL_MOD_PATH=$(DESTDIR) 
modules_install
-+      test -d $(DESTDIR)/var/tpm || mkdir $(DESTDIR)/var/tpm
-+      test -d $(DESTDIR)/dev || mkdir $(DESTDIR)/dev
-+      test -c $(DESTDIR)/dev/tpm0 || [ $(EUID) -ne 0 ] || mknod 
$(DESTDIR)/dev/tpm0 c 10 224
-+      [ $(EUID) -ne 0 ] || chmod 666 $(DESTDIR)/dev/tpm0
++install: $(BIN)
++      $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
  
  clean:
-       @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
-       rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
+-      rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
++      rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
  
 -dist: $(DISTSRC)
 -      rm -rf $(DISTDIR)
@@ -103,25 +106,421 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
 -      tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
 -      rm -rf $(DISTDIR)
 +mrproper: clean
++      rm -f $(BIN) tpm_version.h
  
  $(src)/crypto/libgmp.a:
        test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) 
$(src)/crypto/libgmp.a
-diff -uprN orig/tpm_emulator-0.2-x86_64/README tpm_emulator/README
---- orig/tpm_emulator-0.2-x86_64/README        2005-08-15 00:58:57.000000000 
-0700
-+++ tpm_emulator/README        2005-09-14 20:27:22.000000000 -0700
-@@ -13,7 +13,8 @@ $Id: README 8 2005-01-25 21:11:45Z jmoli
+diff -uprN tpm_emulator-0.3-x86_64/README tpm_emulator/README
+--- tpm_emulator-0.3-x86_64/README     2006-08-29 15:07:43.530967832 -0700
++++ tpm_emulator/README        2006-08-29 15:26:17.105678744 -0700
+@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
  Copyright
  --------------------------------------------------------------------------
  Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal 
 -Institute of Technology (ETH) Zurich.
 +                   Institute of Technology (ETH) Zurich.
-+Copyright (C) 2005 
++Copyright (C) 2005 INTEL Corp 
                
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
-diff -uprN orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c 
tpm_emulator/tpm/tpm_data.c
---- orig/tpm_emulator-0.2-x86_64/tpm/tpm_data.c        2005-09-15 
19:21:14.847078264 -0700
-+++ tpm_emulator/tpm/tpm_data.c        2005-09-14 20:27:22.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/README.1st tpm_emulator/README.1st
+--- tpm_emulator-0.3-x86_64/README.1st 1969-12-31 16:00:00.000000000 -0800
++++ tpm_emulator/README.1st    2006-08-29 15:26:17.105678744 -0700
+@@ -0,0 +1 @@
++Note that you must manually create /tmp/tpm_in.fifo and /tmp/tpm_out.fifo for 
this emulator to work.
+diff -uprN tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 
tpm_emulator/crypto/gmp_kernel_wrapper.c
+--- tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c        2006-08-29 
15:07:43.525968592 -0700
++++ tpm_emulator/crypto/gmp_kernel_wrapper.c   2006-08-29 15:26:17.101679352 
-0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -24,15 +25,10 @@ int __gmp_junk;
+ void __attribute__ ((regparm(0))) __gmp_assert_fail(const char *filename, 
+   int linenum, const char *expr) 
+ {
+-  panic(KERN_CRIT TPM_MODULE_NAME "%s:%d: GNU MP assertion failed: %s\n", 
++  error("%s:%d: GNU MP assertion failed: %s\n", 
+     filename, linenum, expr);
+ }
+ 
+-void __attribute__ ((regparm(0))) abort(void)
+-{
+-  panic(KERN_CRIT TPM_MODULE_NAME "GNU MP abort() was called\n");
+-}
+-
+ /* overwrite GNU MP random functions (used by mpz/millerrabin.c) */ 
+ 
+ void __attribute__ ((regparm(0))) gmp_randinit(gmp_randstate_t rstate, 
+@@ -77,20 +73,19 @@ void __attribute__ ((regparm(0))) mpz_ur
+ 
+ void __attribute__ ((regparm(0))) *kernel_allocate(size_t size)
+ {
+-  void *ret  = (void*)kmalloc(size, GFP_KERNEL);
+-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME 
+-    "GMP: cannot allocate memory (size=%Zu)\n", size);
++  void *ret  = (void*)malloc(size);
++  if (!ret) error("GMP: cannot allocate memory (size=%Zu)\n", size);
+   return ret;
+ }
+ 
+ void __attribute__ ((regparm(0))) *kernel_reallocate(void *oldptr, 
+   size_t old_size, size_t new_size)
+ {
+-  void *ret = (void*)kmalloc(new_size, GFP_KERNEL);
+-  if (!ret) panic(KERN_CRIT TPM_MODULE_NAME "GMP: Cannot reallocate memory "
++  void *ret = (void*)malloc(new_size);
++  if (!ret) error("GMP: Cannot reallocate memory "
+     "(old_size=%Zu new_size=%Zu)\n", old_size, new_size);
+   memcpy(ret, oldptr, old_size);
+-  kfree(oldptr);
++  free(oldptr);
+   return ret;
+ }
+ 
+@@ -99,7 +94,7 @@ void __attribute__ ((regparm(0))) kernel
+   /* overwrite used memory */
+   if (blk_ptr != NULL) { 
+     memset(blk_ptr, 0, blk_size);
+-    kfree(blk_ptr);
++    free(blk_ptr);
+   }
+ }
+ 
+diff -uprN tpm_emulator-0.3-x86_64/crypto/rsa.c tpm_emulator/crypto/rsa.c
+--- tpm_emulator-0.3-x86_64/crypto/rsa.c       2006-08-29 15:07:21.618299064 
-0700
++++ tpm_emulator/crypto/rsa.c  2006-08-29 15:26:17.102679200 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -381,7 +382,7 @@ static int encode_message(int type, uint
+       msg[0] = 0x00;
+       get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
+       sha1_init(&ctx);
+-      sha1_update(&ctx, "TCPA", 4);
++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
+       sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
+       memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00, 
+         msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
+@@ -429,7 +430,7 @@ static int decode_message(int type, uint
+       mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
+         &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
+       sha1_init(&ctx);
+-      sha1_update(&ctx, "TCPA", 4);
++      sha1_update(&ctx, (uint8_t *) "TCPA", 4);
+       sha1_final(&ctx, &msg[1]);
+       if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
+           SHA1_DIGEST_LENGTH) != 0) return -1;
+diff -uprN tpm_emulator-0.3-x86_64/linux_module.c tpm_emulator/linux_module.c
+--- tpm_emulator-0.3-x86_64/linux_module.c     2006-08-29 15:07:43.526968440 
-0700
++++ tpm_emulator/linux_module.c        1969-12-31 16:00:00.000000000 -0800
+@@ -1,194 +0,0 @@
+-/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
+- * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+- *
+- * This module is free software; you can redistribute it and/or modify 
+- * it under the terms of the GNU General Public License as published 
+- * by the Free Software Foundation; either version 2 of the License, 
+- * or (at your option) any later version.  
+- *
+- * This module is distributed in the hope that it will be useful, 
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+- * GNU General Public License for more details.
+- *
+- * $Id: linux_module.c 76 2006-01-02 22:17:58Z hstamer $
+- */
+-
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/miscdevice.h>
+-#include <linux/poll.h>
+-#include "linux_module.h"
+-#include "tpm/tpm_emulator.h"
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Mario Strasser <mast@xxxxxxx>");
+-MODULE_DESCRIPTION("Trusted Platform Module (TPM) Emulator");
+-MODULE_SUPPORTED_DEVICE(TPM_DEVICE_NAME);
+-
+-/* module startup parameters */
+-char *startup = "save";
+-module_param(startup, charp, 0444);
+-MODULE_PARM_DESC(startup, " Sets the startup mode of the TPM. "
+-  "Possible values are 'clear', 'save' (default) and 'deactivated.");
+-char *storage_file = "/var/tpm/tpm_emulator-1.2.0.2";
+-module_param(storage_file, charp, 0644);
+-MODULE_PARM_DESC(storage_file, " Sets the persistent-data storage " 
+-  "file of the TPM.");
+-
+-/* TPM lock */
+-static struct semaphore tpm_mutex;
+-
+-/* TPM command response */
+-static struct {
+-  uint8_t *data;
+-  uint32_t size;
+-} tpm_response;
+-
+-/* module state */
+-#define STATE_IS_OPEN 0
+-static uint32_t module_state;
+-
+-static int tpm_open(struct inode *inode, struct file *file)
+-{
+-  debug("%s()", __FUNCTION__);
+-  if (test_and_set_bit(STATE_IS_OPEN, (void*)&module_state)) return -EBUSY;
+-  return 0;
+-}
+-
+-static int tpm_release(struct inode *inode, struct file *file)
+-{
+-  debug("%s()", __FUNCTION__);
+-  clear_bit(STATE_IS_OPEN, (void*)&module_state);
+-  down(&tpm_mutex);
+-  if (tpm_response.data != NULL) {
+-    kfree(tpm_response.data);
+-    tpm_response.data = NULL;
+-  }
+-  up(&tpm_mutex);
+-  return 0;
+-}
+-
+-static ssize_t tpm_read(struct file *file, char *buf, size_t count, loff_t 
*ppos)
+-{
+-  debug("%s(%Zu)", __FUNCTION__, count);
+-  down(&tpm_mutex);
+-  if (tpm_response.data != NULL) {
+-    count = min(count, (size_t)tpm_response.size - (size_t)*ppos);
+-    count -= copy_to_user(buf, &tpm_response.data[*ppos], count);
+-    *ppos += count;
+-    if ((size_t)tpm_response.size == (size_t)*ppos) {
+-      kfree(tpm_response.data);
+-      tpm_response.data = NULL;
+-    }
+-  } else {
+-    count = 0;
+-  }
+-  up(&tpm_mutex);
+-  return count;
+-}
+-
+-static ssize_t tpm_write(struct file *file, const char *buf, size_t count, 
loff_t *ppos)
+-{
+-  debug("%s(%Zu)", __FUNCTION__, count);
+-  down(&tpm_mutex);
+-  *ppos = 0;
+-  if (tpm_response.data != NULL) kfree(tpm_response.data);
+-  if (tpm_handle_command(buf, count, &tpm_response.data, 
+-                         &tpm_response.size) != 0) { 
+-    count = -EILSEQ;
+-    tpm_response.data = NULL;
+-  }
+-  up(&tpm_mutex);
+-  return count;
+-}
+-
+-#define TPMIOC_CANCEL   _IO('T', 0x00)
+-#define TPMIOC_TRANSMIT _IO('T', 0x01)
+-
+-static int tpm_ioctl(struct inode *inode, struct file *file, unsigned int 
cmd, unsigned long arg)
+-{
+-  debug("%s(%d, %p)", __FUNCTION__, cmd, (char*)arg);
+-  if (cmd == TPMIOC_TRANSMIT) {
+-    uint32_t count = ntohl(*(uint32_t*)(arg + 2));
+-    down(&tpm_mutex);
+-    if (tpm_response.data != NULL) kfree(tpm_response.data);
+-    if (tpm_handle_command((char*)arg, count, &tpm_response.data,
+-                           &tpm_response.size) == 0) {
+-      tpm_response.size -= copy_to_user((char*)arg, tpm_response.data,
+-                            tpm_response.size);
+-      kfree(tpm_response.data);
+-      tpm_response.data = NULL;
+-    } else {
+-      tpm_response.size = 0;
+-      tpm_response.data = NULL;
+-    }
+-    up(&tpm_mutex);
+-    return tpm_response.size;
+-  }
+-  return -1;
+-}
+-
+-struct file_operations fops = {
+-  .owner   = THIS_MODULE,
+-  .open    = tpm_open,
+-  .release = tpm_release,
+-  .read    = tpm_read,
+-  .write   = tpm_write,
+-  .ioctl   = tpm_ioctl,
+-};
+-
+-static struct miscdevice tpm_dev = {
+-  .minor      = TPM_DEVICE_MINOR, 
+-  .name       = TPM_DEVICE_NAME, 
+-  .fops       = &fops,
+-};
+-
+-int __init init_tpm_module(void)
+-{
+-  int res = misc_register(&tpm_dev);
+-  if (res != 0) {
+-    error("misc_register() failed for minor %d\n", TPM_DEVICE_MINOR);
+-    return res;
+-  }
+-  /* initialize variables */
+-  sema_init(&tpm_mutex, 1);
+-  module_state = 0;
+-  tpm_response.data = NULL;    
+-  /* initialize TPM emulator */
+-  if (!strcmp(startup, "clear")) {
+-    tpm_emulator_init(1);
+-  } else if (!strcmp(startup, "save")) {
+-    tpm_emulator_init(2);
+-  } else if (!strcmp(startup, "deactivated")) {
+-    tpm_emulator_init(3);
+-  } else {
+-    error("invalid startup mode '%s'; must be 'clear', "
+-      "'save' (default) or 'deactivated", startup);
+-    misc_deregister(&tpm_dev);
+-    return -EINVAL;
+-  }
+-  return 0;
+-}
+-
+-void __exit cleanup_tpm_module(void)
+-{
+-  tpm_emulator_shutdown();
+-  misc_deregister(&tpm_dev);
+-  if (tpm_response.data != NULL) kfree(tpm_response.data);
+-}
+-
+-module_init(init_tpm_module);
+-module_exit(cleanup_tpm_module);
+-
+-uint64_t tpm_get_ticks(void)
+-{
+-  static struct timespec old_time = {0, 0};
+-  struct timespec new_time = current_kernel_time();
+-  uint64_t ticks = (uint64_t)(old_time.tv_sec - new_time.tv_sec) * 1000000
+-                   + (old_time.tv_nsec - new_time.tv_nsec) / 1000;
+-  old_time = new_time;
+-  return (ticks > 0) ? ticks : 1;
+-}
+-
+diff -uprN tpm_emulator-0.3-x86_64/linux_module.h tpm_emulator/linux_module.h
+--- tpm_emulator-0.3-x86_64/linux_module.h     2006-08-29 15:07:43.527968288 
-0700
++++ tpm_emulator/linux_module.h        2006-08-29 15:26:17.103679048 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -17,17 +18,22 @@
+ #ifndef _LINUX_MODULE_H_
+ #define _LINUX_MODULE_H_
+ 
+-#include <linux/version.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
++#include <malloc.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <string.h>
+ #include <linux/types.h>
+-#include <linux/string.h>
+-#include <linux/random.h>
+-#include <linux/time.h>
+-#include <asm/byteorder.h>
+ 
+-/* module settings */
++#include <endian.h>
++#define __BYTEORDER_HAS_U64__
++#ifdef LITTLE_ENDIAN
++ #include <linux/byteorder/little_endian.h>
++#else
++ #include <linux/byteorder/big_endian.h>
++#endif
+ 
++/* module settings */
++#define min(A,B) ((A)<(B)?(A):(B))
+ #ifndef STR
+ #define STR(s) __STR__(s)
+ #define __STR__(s) #s
+@@ -38,35 +44,36 @@
+ #define TPM_DEVICE_NAME         "tpm"
+ #define TPM_MODULE_NAME       "tpm_emulator"
+ 
+-/* debug and log output functions */
+-
+ #ifdef DEBUG
+-#define debug(fmt, ...) printk(KERN_DEBUG "%s %s:%d: Debug: " fmt "\n", \
+-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
++#define debug(fmt, ...) printf("TPMD: %s:%d: Debug: " fmt "\n", \
++                        __FILE__, __LINE__, ## __VA_ARGS__)
+ #else
+ #define debug(fmt, ...) 
+ #endif
+-#define info(fmt, ...)  printk(KERN_INFO "%s %s:%d: Info: " fmt "\n", \
+-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
+-#define error(fmt, ...) printk(KERN_ERR "%s %s:%d: Error: " fmt "\n", \
+-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
+-#define alert(fmt, ...) printk(KERN_ALERT "%s %s:%d: Alert: " fmt "\n", \
+-                        TPM_MODULE_NAME, __FILE__, __LINE__, ## __VA_ARGS__)
++#define info(fmt, ...)  printf("TPMD: %s:%d: Info: " fmt "\n", \
++                        __FILE__, __LINE__, ## __VA_ARGS__)
++#define error(fmt, ...) printf("TPMD: %s:%d: Error: " fmt "\n", \
++                        __FILE__, __LINE__, ## __VA_ARGS__)
++#define alert(fmt, ...) printf("TPMD: %s:%d: Alert: " fmt "\n", \
++                        __FILE__, __LINE__, ## __VA_ARGS__)
+ 
+ /* memory allocation */
+ 
+ static inline void *tpm_malloc(size_t size) 
+ {
+-  return kmalloc(size, GFP_KERNEL);  
++  return malloc(size);  
+ }
+ 
+ static inline void tpm_free(const void *ptr)
+ {
+-  if (ptr != NULL) kfree(ptr);
++  if (ptr != NULL) free( (void *) ptr);
+ }
+ 
+ /* random numbers */
+ 
++//FIXME;
++void get_random_bytes(void *buf, int nbytes);
++
+ static inline void tpm_get_random_bytes(void *buf, int nbytes)
+ {
+   get_random_bytes(buf, nbytes);
+@@ -86,9 +93,9 @@ uint64_t tpm_get_ticks(void);
+ #define CPU_TO_LE16(x) __cpu_to_le16(x)
+ 
+ #define BE64_TO_CPU(x) __be64_to_cpu(x)
+-#define LE64_TO_CPU(x) __be64_to_cpu(x)
++#define LE64_TO_CPU(x) __le64_to_cpu(x)
+ #define BE32_TO_CPU(x) __be32_to_cpu(x)
+-#define LE32_TO_CPU(x) __be32_to_cpu(x)
++#define LE32_TO_CPU(x) __le32_to_cpu(x)
+ #define BE16_TO_CPU(x) __be16_to_cpu(x)
+ #define LE16_TO_CPU(x) __le16_to_cpu(x)
+ 
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_audit.c tpm_emulator/tpm/tpm_audit.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_audit.c    2006-08-29 15:07:21.620298760 
-0700
++++ tpm_emulator/tpm/tpm_audit.c       2006-08-29 15:26:17.107678440 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -130,15 +529,1213 @@ diff -uprN orig/tpm_emulator-0.2-x86_64/
   *
   * This module is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published
-@@ -85,6 +86,11 @@ void tpm_init_data(void)
-   tpmData.permanent.data.version.revMinor = VERSION_MINOR;
-   /* setup PCR attributes */
-   for (i = 0; i < TPM_NUM_PCR; i++) {
-+    int j;
-+    for (j=0; j < TPM_NUM_LOCALITY; j++) {
-+      tpmData.permanent.data.pcrAttrib[i].pcrExtendLocal[j] = TRUE;
+@@ -45,14 +46,14 @@ void tpm_audit_request(TPM_COMMAND_CODE 
+       tpmData.permanent.data.auditMonotonicCounter++;
+     }
+     /* update audit digest */
+-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_IN);
+-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_IN);
++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
+     sha1_init(&sha1_ctx);
+     sha1_update(&sha1_ctx, req->param, req->paramSize);
+     sha1_final(&sha1_ctx, &buf[6]);
+-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
+     memset(&buf[30], 0, 4);
+-    *((UINT32*)&buf[34]) = 
cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
++    *((UINT32*)&buf[34]) = 
CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
+     sha1_init(&sha1_ctx);
+     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
+       sizeof(TPM_DIGEST));
+@@ -70,15 +71,15 @@ void tpm_audit_response(TPM_COMMAND_CODE
+       && (AUDIT_STATUS[ord / 8] & (1 << (ord & 0x07)))) {
+     info("tpm_audit_response()");
+     /* update audit digest */
+-    *((UINT16*)&buf[0])  = cpu_to_be16(TPM_TAG_AUDIT_EVENT_OUT);
+-    *((UINT32*)&buf[2]) = cpu_to_be32(ordinal);
++    *((UINT16*)&buf[0])  = CPU_TO_BE16(TPM_TAG_AUDIT_EVENT_OUT);
++    *((UINT32*)&buf[2]) = CPU_TO_BE32(ordinal);
+     sha1_init(&sha1_ctx);
+     sha1_update(&sha1_ctx, rsp->param, rsp->paramSize);
+     sha1_final(&sha1_ctx, &buf[6]);
+-    *((UINT16*)&buf[26])  = cpu_to_be16(TPM_TAG_COUNTER_VALUE);
++    *((UINT16*)&buf[26])  = CPU_TO_BE16(TPM_TAG_COUNTER_VALUE);
+     memset(&buf[30], 0, 4);
+-    *((UINT32*)&buf[34]) = 
cpu_to_be32(tpmData.permanent.data.auditMonotonicCounter);
+-    *((UINT32*)&buf[34]) = cpu_to_be32(rsp->result);
++    *((UINT32*)&buf[34]) = 
CPU_TO_BE32(tpmData.permanent.data.auditMonotonicCounter);
++    *((UINT32*)&buf[34]) = CPU_TO_BE32(rsp->result);
+     sha1_init(&sha1_ctx);
+     sha1_update(&sha1_ctx, tpmData.stany.data.auditDigest.digest, 
+       sizeof(TPM_DIGEST));
+@@ -158,7 +159,7 @@ TPM_RESULT TPM_GetAuditDigestSigned(TPM_
+   }
+   memcpy(&buf[0], "\x05\x00ADIG", 6);
+   memcpy(&buf[6], antiReplay->nonce, 20);
+-  *(UINT32*)&buf[26] = cpu_to_be32(buf_size - 30);
++  *(UINT32*)&buf[26] = CPU_TO_BE32(buf_size - 30);
+   memcpy(&buf[30], auditDigest->digest, 20);
+   ptr = &buf[50];
+   len = buf_size - 50;
+@@ -198,4 +199,3 @@ TPM_RESULT TPM_SetOrdinalAuditStatus(TPM
+   }
+   return TPM_SUCCESS;
+ }
+-
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 
tpm_emulator/tpm/tpm_authorization.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c    2006-08-29 
15:07:21.620298760 -0700
++++ tpm_emulator/tpm/tpm_authorization.c       2006-08-29 15:26:17.108678288 
-0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -279,7 +280,7 @@ TPM_RESULT tpm_verify_auth(TPM_AUTH *aut
+ {
+   hmac_ctx_t ctx;
+   TPM_SESSION_DATA *session;
+-  UINT32 auth_handle = cpu_to_be32(auth->authHandle);
++  UINT32 auth_handle = CPU_TO_BE32(auth->authHandle);
+   
+   info("tpm_verify_auth(%08x)", auth->authHandle);
+   /* get dedicated authorization or transport session */
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 
tpm_emulator/tpm/tpm_capability.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_capability.c       2006-08-29 
15:07:21.620298760 -0700
++++ tpm_emulator/tpm/tpm_capability.c  2006-08-29 15:26:17.109678136 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -406,7 +407,7 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+ 
+     case TPM_CAP_KEY_HANDLE:
+       debug("[TPM_CAP_KEY_HANDLE]");
+-      subCapSize = cpu_to_be32(TPM_RT_KEY);
++      subCapSize = CPU_TO_BE32(TPM_RT_KEY);
+       return cap_handle(4, (BYTE*)&subCapSize, respSize, resp);
+ 
+     case TPM_CAP_CHECK_LOADED:
+@@ -480,4 +481,3 @@ TPM_RESULT TPM_GetCapability(TPM_CAPABIL
+       return TPM_BAD_MODE;
+   }
+ }
+-
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 
tpm_emulator/tpm/tpm_cmd_handler.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c      2006-08-29 
15:07:21.621298608 -0700
++++ tpm_emulator/tpm/tpm_cmd_handler.c 2006-08-29 15:26:17.113677528 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -73,7 +74,7 @@ void tpm_compute_in_param_digest(TPM_REQ
+ {
+   sha1_ctx_t sha1;
+   UINT32 offset = tpm_get_param_offset(req->ordinal);
+-  UINT32 ord = cpu_to_be32(req->ordinal);
++  UINT32 ord = CPU_TO_BE32(req->ordinal);
+ 
+   /* compute SHA1 hash */
+   if (offset <= req->paramSize) {
+@@ -89,8 +90,8 @@ void tpm_compute_in_param_digest(TPM_REQ
+ void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
+ {
+   sha1_ctx_t sha1;
+-  UINT32 res = cpu_to_be32(rsp->result);
+-  UINT32 ord = cpu_to_be32(ordinal);
++  UINT32 res = CPU_TO_BE32(rsp->result);
++  UINT32 ord = CPU_TO_BE32(ordinal);
+ 
+   /* compute SHA1 hash */
+   sha1_init(&sha1);
+@@ -3123,7 +3124,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+       hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
+ #if 0
+       if (tpm_get_auth(rsp->auth2->authHandle)->type == TPM_ST_OIAP) {
+-        UINT32 handle = cpu_to_be32(rsp->auth2->authHandle);
++        UINT32 handle = CPU_TO_BE32(rsp->auth2->authHandle);
+         hmac_update(&hmac, (BYTE*)&handle, 4);
+       }
+ #endif
+@@ -3138,7 +3139,7 @@ static void tpm_setup_rsp_auth(TPM_COMMA
+       hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
+ #if 0
+       if (tpm_get_auth(rsp->auth1->authHandle)->type == TPM_ST_OIAP) {
+-        UINT32 handle = cpu_to_be32(rsp->auth1->authHandle);
++        UINT32 handle = CPU_TO_BE32(rsp->auth1->authHandle);
+         hmac_update(&hmac, (BYTE*)&handle, 4);
+       }
+ #endif
+@@ -3221,7 +3222,9 @@ extern const char *tpm_error_to_string(T
+ void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
+ {
+   TPM_RESULT res;
+-  
++
++  req->tag = (BYTE) req->tag;  // FIXME: Why is this here
++
+   /* setup authorisation as well as response tag and size */
+   memset(rsp, 0, sizeof(*rsp));
+   switch (req->tag) {
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c 
tpm_emulator/tpm/tpm_crypto.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c   2006-08-29 15:07:43.531967680 
-0700
++++ tpm_emulator/tpm/tpm_crypto.c      2006-08-29 15:26:17.114677376 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -106,7 +107,7 @@ TPM_RESULT tpm_sign(TPM_KEY_DATA *key, T
+     /* setup TPM_SIGN_INFO structure */
+     memcpy(&buf[0], "\x05\x00SIGN", 6);
+     memcpy(&buf[6], auth->nonceOdd.nonce, 20);
+-    *(UINT32*)&buf[26] = cpu_to_be32(areaToSignSize);
++    *(UINT32*)&buf[26] = CPU_TO_BE32(areaToSignSize);
+     memcpy(&buf[30], areaToSign, areaToSignSize);
+     if (rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, 
+         buf, areaToSignSize + 30, *sig)) {
+@@ -383,4 +384,3 @@ TPM_RESULT TPM_CertifyKey2(TPM_KEY_HANDL
+   }
+   return TPM_SUCCESS;
+ }
+-
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_daa.c tpm_emulator/tpm/tpm_daa.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_daa.c      2006-08-29 15:07:21.622298456 
-0700
++++ tpm_emulator/tpm/tpm_daa.c 2006-08-29 15:26:17.119676616 -0700
+@@ -700,14 +700,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -787,14 +787,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1440,14 +1440,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1660,14 +1660,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -1740,14 +1740,14 @@ info("tested until here");
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -2828,14 +2828,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -3050,7 +3050,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+         sha1_init(&sha1);
+         sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest, 
+           sizeof(session->DAA_session.DAA_digest));
+-        sha1_update(&sha1, "\x01", 1);
++        sha1_update(&sha1, (BYTE *) "\x01", 1);
+         sha1_update(&sha1, inputData1, inputSize1);
+         sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
+       }
+@@ -3078,7 +3078,7 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+         sha1_init(&sha1);
+         sha1_update(&sha1, (BYTE*) &session->DAA_session.DAA_digest, 
+           sizeof(session->DAA_session.DAA_digest));
+-        sha1_update(&sha1, "\x01", 1);
++        sha1_update(&sha1, (BYTE *) "\x01", 1);
+         rsa_export_modulus(&aikData->key, scratch, &size);
+         sha1_update(&sha1, scratch, size);
+         sha1_final(&sha1, (BYTE*) &session->DAA_session.DAA_digest);
+@@ -3134,14 +3134,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+@@ -3213,14 +3213,14 @@ TPM_RESULT TPM_DAA_Sign(TPM_HANDLE handl
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x00", 1);
++      sha1_update(&sha1, (BYTE *) "\x00", 1);
+       sha1_final(&sha1, scratch);
+       sha1_init(&sha1);
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_rekey, 
+           sizeof(session->DAA_tpmSpecific.DAA_rekey));
+       sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
+           sizeof(session->DAA_tpmSpecific.DAA_count));
+-      sha1_update(&sha1, "\x01", 1);
++      sha1_update(&sha1, (BYTE *) "\x01", 1);
+       sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
+       mpz_init(f), mpz_init(q);
+       mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c tpm_emulator/tpm/tpm_data.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c     2006-08-29 15:08:20.535342312 
-0700
++++ tpm_emulator/tpm/tpm_data.c        2006-08-29 15:26:17.121676312 -0700
+@@ -150,44 +150,43 @@ void tpm_release_data(void)
+ 
+ #ifdef TPM_STORE_TO_FILE
+ 
+-#include <linux/fs.h>
+-#include <linux/unistd.h>
+-#include <asm/uaccess.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <unistd.h>
+ 
+ #define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." 
STR(VERSION_MINOR) 
+ 
+ static int write_to_file(uint8_t *data, size_t data_length)
+ {
+   int res;
+-  struct file *fp;
+-  mm_segment_t old_fs = get_fs();
+-  fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | 
S_IWUSR);
+-  if (IS_ERR(fp)) return -1;
+-  set_fs(get_ds());
+-  res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
+-  set_fs(old_fs);
+-  filp_close(fp, NULL);
++  int fp;
++  fp = open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | 
S_IWUSR);
++  res = write(fp, data, data_length);
++  close(fp);
+   return (res == data_length) ? 0 : -1;
+ }
+ 
+ static int read_from_file(uint8_t **data, size_t *data_length)
+ {
+   int res;
+-  struct file *fp;
+-  mm_segment_t old_fs = get_fs();
+-  fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
+-  if (IS_ERR(fp)) return -1;
+-  *data_length = (size_t)fp->f_dentry->d_inode->i_size;
+-  /* *data_length = i_size_read(fp->f_dentry->d_inode); */
++  int fp, file_status;
++  struct stat file_info;
++  fp = open(TPM_STORAGE_FILE, O_RDONLY, 0);
++  file_status = fstat(fp, &file_info);
++  if (file_status < 0) {
++    close(fp);
++    return -1;
++  } 
++
++  *data_length = file_info.st_size; 
+   *data = tpm_malloc(*data_length);
+   if (*data == NULL) {
+-    filp_close(fp, NULL);
++    close(fp);
+     return -1;
+   }
+-  set_fs(get_ds());
+-  res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
+-  set_fs(old_fs);
+-  filp_close(fp, NULL);
++  res = read(fp, *data, *data_length);
++  close(fp);
+   if (res != *data_length) {
+     tpm_free(*data);
+     return -1;
+@@ -278,7 +277,7 @@ int tpm_restore_permanent_data(void)
+ 
+ int tpm_erase_permanent_data(void)
+ {
+-  int res = write_to_file("", 0);
++  int res = write_to_file((uint8_t *) "", 0);
+   return res;
+ }
+ 
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c.orig 
tpm_emulator/tpm/tpm_data.c.orig
+--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c.orig        1969-12-31 
16:00:00.000000000 -0800
++++ tpm_emulator/tpm/tpm_data.c.orig   2006-08-29 15:26:08.469991568 -0700
+@@ -0,0 +1,284 @@
++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
++ * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ *                    Swiss Federal Institute of Technology (ETH) Zurich
++ *
++ * This module is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published
++ * by the Free Software Foundation; either version 2 of the License,
++ * or (at your option) any later version.
++ *
++ * This module is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * $Id: tpm_data.c 36 2005-10-26 20:31:19Z hstamer $
++ */
++
++#include "tpm_emulator.h"
++#include "tpm_structures.h"
++#include "tpm_marshalling.h"
++#include "linux_module.h"
++
++TPM_DATA tpmData;
++
++BOOL tpm_get_physical_presence(void)
++{
++  return (tpmData.stclear.flags.physicalPresence || TRUE);
++}
++
++static inline void init_pcr_attr(int pcr, BOOL reset, BYTE rl, BYTE el)
++{
++  int i;
++  tpmData.permanent.data.pcrAttrib[pcr].pcrReset = reset;
++  for (i = 0; i < TPM_NUM_LOCALITY; i++) {
++    tpmData.permanent.data.pcrAttrib[pcr].pcrResetLocal[i] = (rl & (1 << i));
++    tpmData.permanent.data.pcrAttrib[pcr].pcrExtendLocal[i] = (el & (1 << i));
++  }
++}
++
++void tpm_init_data(void)
++{
++  /* endorsement key */
++  uint8_t ek_n[] =  "\xa8\xdb\xa9\x42\xa8\xf3\xb8\x06\x85\x90\x76\x93\xad\xf7"
++    "\x74\xec\x3f\xd3\x3d\x9d\xe8\x2e\xff\x15\xed\x0e\xce\x5f\x93"
++    "\x92\xeb\xd1\x96\x2b\x72\x18\x81\x79\x12\x9d\x9c\x40\xd7\x1a"
++    "\x21\xda\x5f\x56\xe0\xc9\x48\x31\xdd\x96\xdc\xbb\x45\xc6\x8e"
++    "\xad\x58\x23\xcb\xbe\xbb\x13\x2d\x6b\x86\xc5\x57\xf5\xdd\x48"
++    "\xc1\x3d\xcd\x4d\xda\x81\xc4\x43\x17\xaa\x05\x40\x33\x62\x0a"
++    "\x59\xdb\x28\xcd\xb5\x08\x31\xbb\x06\xf5\xf7\x71\xae\x21\xa8"
++    "\xf2\x2f\x0e\x17\x80\x5d\x9c\xdf\xaa\xe9\x89\x09\x54\x65\x2b"
++    "\x46\xfb\x9d\xb2\x00\x70\x63\x0d\x9a\x6d\x3d\x5e\x11\x78\x65"
++    "\x90\xe6\x26\xee\x77\xbe\x08\xff\x07\x60\x5a\xcc\xf1\x0a\xbd"
++    "\x44\x92\x6b\xca\xb6\xce\x66\xf9\x93\x40\xae\xf3\x3e\x53\x02"
++    "\x3c\xa6\x81\xb3\xbe\xad\x6e\x6c\xa6\xf0\xeb\xdf\xe9\xa2\x83"
++    "\x36\x0e\x52\x0d\x64\x17\xd9\xff\xa1\x74\x7c\x2b\xbc\x6a\xcc"
++    "\xe5\x4e\xb4\x52\xd9\xec\x43\xbd\x26\x6a\x2b\x19\x19\x6e\x97"
++    "\xb8\x1d\x9f\x7b\xe7\x32\x2d\xdd\x7c\x51\xc8\xe4\xf3\x02\xd4"
++    "\x7c\x90\x44\xa0\x33\x72\x81\x75\xa9\x16\x27\x5c\x00\x1d\x07"
++    "\x81\xd4\xf7\xac\xcb\xfe\xd6\x60\x03\x6f\x7a\xcc\x00\xd1\xc4"
++    "\x85\x37";
++  uint8_t ek_e[] = "\x01\x00\x01";
++  uint8_t ek_p[] = "\xd7\xea\x61\x15\x8b\xa3\x71\xdf\xa8\x74\x77\xca\x88\x95"
++    "\xd0\x76\x17\x43\x2c\xf6\x23\x27\x44\xb9\x0e\x18\x35\x7e\xe4"
++    "\xc3\xcb\x13\x6e\xfc\x38\x02\x1e\x77\x26\x40\x9d\x17\xb2\x39"
++    "\x9c\x7f\x5f\x98\xe6\xf2\x55\x0c\x12\x05\x4c\xb3\x51\xae\x29"
++    "\xe7\xcd\xce\x41\x0b\x28\x4d\x97\x13\x4b\x60\xc8\xd8\x70\x81"
++    "\xf9\x1c\x12\x44\xdf\x53\x0a\x87\x9d\x33\x92\x4a\x34\x69\xf0"
++    "\x70\x5e\x1b\x5d\x65\xc7\x84\x90\xa2\x62\xdf\x83\x14\x10\x69"
++    "\xe2\xa7\x18\x43\xd7\x1f\x60\xc9\x03\x8f\xd6\xa4\xce\xb2\x9d"
++    "\x40\x37\x70\x17\x4c\xe3\x69\xd4\x59";
++  uint8_t ek_q[] = "\xc8\x34\xd2\xd0\x7c\xfa\xdc\x68\xe2\x72\xd7\x92\xe2\x50"
++    "\x93\xfc\xbb\x72\x55\x4d\x6b\x7a\x0c\x0b\xcf\x87\x66\x1f\x81"
++    "\x71\xf3\x50\xcb\xaa\xe6\x43\x7e\xbe\x11\xc4\xec\x00\x53\xf4"
++    "\x78\x13\x2b\x59\x26\x4a\x9f\x91\x61\x8f\xa7\x07\x64\x11\x5a"
++    "\xf4\xaf\x9c\x9b\x5a\x5d\x69\x20\x17\x55\x74\xba\xd8\xe4\x59"
++    "\x39\x1a\x0a\x7b\x4a\x30\xf0\xc8\x7f\xd9\xaf\x72\xc5\xb6\x71"
++    "\xd1\xc0\x8b\x5b\xa2\x2e\xa7\x15\xca\x50\x75\x10\x48\x9c\x2b"
++    "\x18\xb9\x67\x8f\x5d\x64\xc3\x28\x9f\x2f\x16\x2f\x08\xda\x47"
++    "\xec\x86\x43\x0c\x80\x99\x07\x34\x0f";
++  int i;
++  /* reset all data to NULL, FALSE or 0 */
++  memset(&tpmData, 0, sizeof(tpmData));
++  tpmData.permanent.data.tag = TPM_TAG_PERMANENT_DATA;
++  /* set permanent flags */
++  tpmData.permanent.flags.tag = TPM_TAG_PERMANENT_FLAGS;
++  tpmData.permanent.flags.disable = FALSE;
++  tpmData.permanent.flags.deactivated = FALSE;
++  tpmData.permanent.flags.ownership = TRUE;
++  tpmData.permanent.flags.readPubek = TRUE;
++  tpmData.permanent.flags.allowMaintenance = TRUE;
++  tpmData.permanent.flags.enableRevokeEK = TRUE;
++  /* set TPM vision */
++  tpmData.permanent.data.version.major = 1;
++  tpmData.permanent.data.version.minor = 2;
++  tpmData.permanent.data.version.revMajor = VERSION_MAJOR;
++  tpmData.permanent.data.version.revMinor = VERSION_MINOR;
++  /* setup PCR attributes */
++  for (i = 0; i < min(16, TPM_NUM_PCR); i++) {
++    init_pcr_attr(i, FALSE, 0x00, 0x1f);
++  }
++  if (TPM_NUM_PCR >= 24) {
++    init_pcr_attr(16, TRUE, 0x1f, 0x1f);
++    init_pcr_attr(17, TRUE, 0x10, 0x1c);
++    init_pcr_attr(18, TRUE, 0x10, 0x1c);
++    init_pcr_attr(19, TRUE, 0x10, 0x0c);
++    init_pcr_attr(20, TRUE, 0x14, 0x0e);
++    init_pcr_attr(21, TRUE, 0x04, 0x04);
++    init_pcr_attr(22, TRUE, 0x04, 0x04);
++    init_pcr_attr(23, TRUE, 0x1f, 0x1f);
++  }
++  for (i = 24; i < TPM_NUM_PCR; i++) {
++    init_pcr_attr(i, TRUE, 0x00, 0x00);
++  }
++  /* set tick type */
++  tpmData.permanent.data.tickType = TICK_INC;
++#ifdef TPM_GENERATE_EK
++  /* generate a new endorsement key */
++  rsa_generate_key(&tpmData.permanent.data.endorsementKey, 2048);
++#else
++  /* setup endorsement key */
++  rsa_import_key(&tpmData.permanent.data.endorsementKey, 
++    RSA_MSB_FIRST, ek_n, 256, ek_e, 3, ek_p, ek_q);
++#endif
++#ifdef TPM_GENERATE_SEED_DAA
++  /* generate the DAA seed (cf. [TPM_Part2], v1.2 rev 85, Section 7.4) */
++  tpm_get_random_bytes(tpmData.permanent.data.tpmDAASeed.digest, 
++    sizeof(tpmData.permanent.data.tpmDAASeed.digest));
++#else
++  /* FIXME: setup DAA seed */
++  memcpy(tpmData.permanent.data.tpmDAASeed.digest, 
++    "\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
++    "\x00\x00\x00\x77", 20);
++#endif
++
++  memcpy(tpmData.permanent.data.ekReset.nonce, "\xde\xad\xbe\xef", 4);
++}
++
++void tpm_release_data(void)
++{
++  int i;
++  /* release the EK, SRK as well as all other rsa keys */
++  if (tpmData.permanent.data.endorsementKey.size > 0)
++    rsa_release_private_key(&tpmData.permanent.data.endorsementKey);
++  if (tpmData.permanent.data.srk.valid)
++    rsa_release_private_key(&tpmData.permanent.data.srk.key);
++  for (i = 0; i < TPM_MAX_KEYS; i++)
++    if (tpmData.permanent.data.keys[i].valid)
++      rsa_release_private_key(&tpmData.permanent.data.keys[i].key);
++}
++
++#ifdef TPM_STORE_TO_FILE
++
++#include <linux/fs.h>
++#include <linux/unistd.h>
++#include <asm/uaccess.h>
++
++#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." 
STR(VERSION_MINOR) 
++
++static int write_to_file(uint8_t *data, size_t data_length)
++{
++  int res;
++  struct file *fp;
++  mm_segment_t old_fs = get_fs();
++  fp = filp_open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | 
S_IWUSR);
++  if (IS_ERR(fp)) return -1;
++  set_fs(get_ds());
++  res = fp->f_op->write(fp, data, data_length, &fp->f_pos);
++  set_fs(old_fs);
++  filp_close(fp, NULL);
++  return (res == data_length) ? 0 : -1;
++}
++
++static int read_from_file(uint8_t **data, size_t *data_length)
++{
++  int res;
++  struct file *fp;
++  mm_segment_t old_fs = get_fs();
++  fp = filp_open(TPM_STORAGE_FILE, O_RDONLY, 0);
++  if (IS_ERR(fp)) return -1;
++  *data_length = (size_t)fp->f_dentry->d_inode->i_size;
++  /* *data_length = i_size_read(fp->f_dentry->d_inode); */
++  *data = tpm_malloc(*data_length);
++  if (*data == NULL) {
++    filp_close(fp, NULL);
++    return -1;
++  }
++  set_fs(get_ds());
++  res = fp->f_op->read(fp, *data, *data_length, &fp->f_pos);
++  set_fs(old_fs);
++  filp_close(fp, NULL);
++  if (res != *data_length) {
++    tpm_free(*data);
++    return -1;
++  }
++  return 0;
++}
++
++#else
++
++static int write_to_file(uint8_t *data, size_t data_length)
++{
++  info("TPM_STORE_TO_FILE disabled, no data written");
++  return 0;
++}
++
++static int read_from_file(uint8_t **data, size_t *data_length)
++{
++  info("TPM_STORE_TO_FILE disabled, no data read");
++  return 0;
++}
++
++#endif /* TPM_STORE_TO_FILE */
++
++int tpm_store_permanent_data(void)
++{
++  uint8_t *buf, *ptr;
++  UINT32 buf_length, len;
++
++  /* marshal data */
++  buf_length = len = 4 + sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags)
++    + sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags) 
++    + sizeof_TPM_STANY_FLAGS(tpmData.stany.flags) + 2
++    + sizeof_TPM_STCLEAR_DATA(tpmData.stclear.data) 
++    + sizeof_TPM_PERMANENT_DATA(tpmData.permanent.data)
++    + sizeof_TPM_STANY_DATA(tpmData.stany.data);
++  buf = ptr = tpm_malloc(buf_length);
++  if (buf == NULL
++      || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version)
++      || tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
++      || tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)
++      || tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
++      || tpm_marshal_BOOL(&ptr, &len, 
tpmData.permanent.flags.selfTestSucceeded)
++      || tpm_marshal_BOOL(&ptr, &len, tpmData.permanent.flags.owned)
++      || tpm_marshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
++      || tpm_marshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
++      || tpm_marshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
++    tpm_free(buf);
++    return -1;
++  }
++
++  if (write_to_file(buf, buf_length - len)) {
++    tpm_free(buf);
++    return -1; 
++  }
++  tpm_free(buf);
++  return 0;
++}
++
++int tpm_restore_permanent_data(void)
++{
++  uint8_t *buf, *ptr;
++  size_t buf_length;
++  UINT32 len;
++  TPM_VERSION ver;
++
++  /* read data */
++  if (read_from_file(&buf, &buf_length)) return -1;
++  ptr = buf;
++  len = (uint32_t) buf_length;
++  /* unmarshal data */
++  if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
++      || memcmp(&ver, &tpmData.permanent.data.version, sizeof(TPM_VERSION))
++      || tpm_unmarshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)
++      || tpm_unmarshal_TPM_PERMANENT_FLAGS(&ptr, &len, 
&tpmData.permanent.flags)
++      || tpm_unmarshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)
++      || tpm_unmarshal_BOOL(&ptr, &len, 
&tpmData.permanent.flags.selfTestSucceeded)
++      || tpm_unmarshal_BOOL(&ptr, &len, &tpmData.permanent.flags.owned)
++      || tpm_unmarshal_TPM_STCLEAR_DATA(&ptr, &len, &tpmData.stclear.data)
++      || tpm_unmarshal_TPM_PERMANENT_DATA(&ptr, &len, &tpmData.permanent.data)
++      || tpm_unmarshal_TPM_STANY_DATA(&ptr, &len, &tpmData.stany.data)) {
++    tpm_free(buf);
++    return -1;
++  }
++
++  tpm_free(buf);
++  return 0;
++}
++
++int tpm_erase_permanent_data(void)
++{
++  int res = write_to_file("", 0);
++  return res;
++}
++
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 
tpm_emulator/tpm/tpm_deprecated.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c       2006-08-29 
15:07:21.622298456 -0700
++++ tpm_emulator/tpm/tpm_deprecated.c  2006-08-29 15:26:17.122676160 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -50,7 +51,7 @@ TPM_RESULT TPM_SaveKeyContext(TPM_KEY_HA
+   BYTE *ptr;
+   UINT32 len;
+   info("TPM_SaveKeyContext()");
+-  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, "SaveKeyContext..", 
++  res = TPM_SaveContext(keyHandle, TPM_RT_KEY, (BYTE*)"SaveKeyContext..", 
+                         keyContextSize, &contextBlob);
+   if (res != TPM_SUCCESS) return res;
+   len = *keyContextSize;
+@@ -82,7 +83,7 @@ TPM_RESULT TPM_SaveAuthContext(TPM_AUTHH
+   BYTE *ptr;
+   UINT32 len;
+   info("TPM_SaveAuthContext()");
+-  res = TPM_SaveContext(authHandle, TPM_RT_KEY, "SaveAuthContext.", 
++  res = TPM_SaveContext(authHandle, TPM_RT_KEY, (BYTE*)"SaveAuthContext.", 
+                         authContextSize, &contextBlob);
+   if (res != TPM_SUCCESS) return res;
+   len = *authContextSize;
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 
tpm_emulator/tpm/tpm_emulator.h
+--- tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-08-29 15:07:21.648294504 
-0700
++++ tpm_emulator/tpm/tpm_emulator.h    2006-08-29 15:26:17.122676160 -0700
+@@ -1,5 +1,6 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -22,7 +23,8 @@
+ /* TPM configuration */
+ #define TPM_STORE_TO_FILE       1
+ #undef  TPM_STRONG_PERSISTENCE
+-#undef  TPM_GENERATE_EK
++//#undef  TPM_GENERATE_EK
++#define  TPM_GENERATE_EK
+ #undef  TPM_GENERATE_SEED_DAA
+ 
+ #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */        
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 
tpm_emulator/tpm/tpm_integrity.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c        2006-08-29 
15:07:21.645294960 -0700
++++ tpm_emulator/tpm/tpm_integrity.c   2006-08-29 15:26:17.123676008 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -194,4 +195,3 @@ TPM_RESULT tpm_verify_pcr(TPM_KEY_DATA *
+   }
+   return TPM_SUCCESS;
+ }
+-
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 
tpm_emulator/tpm/tpm_structures.h
+--- tpm_emulator-0.3-x86_64/tpm/tpm_structures.h       2006-08-29 
15:08:20.545340792 -0700
++++ tpm_emulator/tpm/tpm_structures.h  2006-08-29 15:26:17.125675704 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -18,7 +19,7 @@
+ #ifndef _TPM_STRUCTURES_H_
+ #define _TPM_STRUCTURES_H_
+ 
+-#include <linux/types.h>
++//#include <linux/types.h>
+ #include "crypto/rsa.h"
+ 
+ /*
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 
tpm_emulator/tpm/tpm_testing.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_testing.c  2006-08-29 15:07:21.646294808 
-0700
++++ tpm_emulator/tpm/tpm_testing.c     2006-08-29 15:26:17.127675400 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -95,24 +96,24 @@ static int tpm_test_sha1(void)
+   struct {
+     uint8_t *data; uint32_t repetitions; uint8_t *digest;
+   } test_cases[] =  {{
+-    "abc", 1,
+-    
"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
++      (uint8_t*)"abc", 1,
++    
(uint8_t*)"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D"
+   }, {
+-    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
+-    
"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
++    (uint8_t*)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
++    
(uint8_t*)"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1"
+   }, {
+-    "a", 1000000,
+-    
"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
++    (uint8_t*)"a", 1000000,
++    
(uint8_t*)"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F"
+   }, {
+-    "0123456701234567012345670123456701234567012345670123456701234567", 10,
+-    
"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
++    
(uint8_t*)"0123456701234567012345670123456701234567012345670123456701234567", 
10,
++    
(uint8_t*)"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
+   }};
+ 
+   debug("tpm_test_sha1()");
+   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
+     sha1_init(&ctx);
+     for (j = 0; j < test_cases[i].repetitions; j++)
+-      sha1_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
++      sha1_update(&ctx, test_cases[i].data, 
strlen((char*)test_cases[i].data));
+     sha1_final(&ctx, digest);
+     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return 
-1;
+   }
+@@ -128,41 +129,41 @@ static int tpm_test_hmac(void)
+   struct {
+     uint8_t *key, key_len, *data, data_len, *digest;
+   } test_cases[] = {{
+-    "\x0b", 20, "Hi There", 8,
+-    
"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
++    (uint8_t*)"\x0b", 20, (uint8_t*)"Hi There", 8,
++    
(uint8_t*)"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00"
+   }, {
+-    "Jefe", 4, "what do ya want for nothing?", 28,
+-    
"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
++    (uint8_t*)"Jefe", 4, (uint8_t*)"what do ya want for nothing?", 28,
++    
(uint8_t*)"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79"
+   }, {
+-    "\xaa", 20, "\xdd", 50,
+-    
"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
++    (uint8_t*)"\xaa", 20, (uint8_t*)"\xdd", 50,
++    
(uint8_t*)"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3"
+   }, {
+-    
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
+-    "\x15\x16\x17\x18\x19", 25, "\xcd", 50,
+-    
"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
++    
(uint8_t*)"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
++    "\x15\x16\x17\x18\x19", 25, (uint8_t*)"\xcd", 50,
++    
(uint8_t*)"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda"
+   }, {
+-    "\x0c", 20, "Test With Truncation", 20,
+-    
"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
++    (uint8_t*)"\x0c", 20, (uint8_t*)"Test With Truncation", 20,
++    
(uint8_t*)"\x4c\x1a\x03\x42\x4b\x55\xe0\x7f\xe7\xf2\x7b\xe1\xd5\x8b\xb9\x32\x4a\x9a\x5a\x04"
+   }, {
+-    "\xaa", 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54,
+-    
"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
++    (uint8_t*)"\xaa", 80, (uint8_t*)"Test Using Larger Than Block-Size Key - 
Hash Key First", 54,
++    
(uint8_t*)"\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55\xed\x40\x21\x12"
+   }, {
+-    "\xaa", 80,
+-    "Test Using Larger Than Block-Size Key and Larger Than One Block-Size 
Data", 73,
+-    
"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
++    (uint8_t*)"\xaa", 80,
++    (uint8_t*)"Test Using Larger Than Block-Size Key and Larger Than One 
Block-Size Data", 73,
++    
(uint8_t*)"\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08\xbb\xff\x1a\x91"
+   }};
+ 
+   debug("tpm_test_hmac()");
+   for (i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
+-    if (strlen(test_cases[i].key) < test_cases[i].key_len) {
++    if (strlen((char*)test_cases[i].key) < test_cases[i].key_len) {
+       uint8_t key[test_cases[i].key_len];
+       memset(key, test_cases[i].key[0], test_cases[i].key_len);
+       hmac_init(&ctx, key, test_cases[i].key_len);
+     } else {
+       hmac_init(&ctx, test_cases[i].key, test_cases[i].key_len);
+     }
+-    for (j = 0; j < test_cases[i].data_len; j += strlen(test_cases[i].data)) {
+-      hmac_update(&ctx, test_cases[i].data, strlen(test_cases[i].data));
++    for (j = 0; j < test_cases[i].data_len; j += 
strlen((char*)test_cases[i].data)) {
++      hmac_update(&ctx, test_cases[i].data, 
strlen((char*)test_cases[i].data));
+     }
+     hmac_final(&ctx, digest);
+     if (memcmp(digest, test_cases[i].digest, SHA1_DIGEST_LENGTH) != 0) return 
-1;
+@@ -173,9 +174,9 @@ static int tpm_test_hmac(void)
+ static int tpm_test_rsa_EK(void)
+ {
+   int res = 0;
+-  char *data = "RSA PKCS #1 v1.5 Test-String";
++  uint8_t *data = (uint8_t*)"RSA PKCS #1 v1.5 Test-String";
+   uint8_t buf[256];
+-  size_t buf_len, data_len = strlen(data);
++  size_t buf_len, data_len = strlen((char*)data);
+   rsa_private_key_t priv_key;
+   rsa_public_key_t pub_key;
+ 
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c tpm_emulator/tpm/tpm_ticks.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c    2006-08-29 15:07:21.646294808 
-0700
++++ tpm_emulator/tpm/tpm_ticks.c       2006-08-29 15:26:17.128675248 -0700
+@@ -1,6 +1,7 @@
+ /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
+  * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
+  *                    Swiss Federal Institute of Technology (ETH) Zurich
++ * Copyright (C) 2005 INTEL Corp
+  *
+  * This module is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published
+@@ -37,9 +38,7 @@ TPM_RESULT TPM_SetTickType(TPM_TICKTYPE 
+ TPM_RESULT TPM_GetTicks(TPM_CURRENT_TICKS *currentTime)
+ {
+   info("TPM_GetTicks()");
+-  memcpy(currentTime, &tpmData.stany.data.currentTicks, 
+-    sizeof(TPM_CURRENT_TICKS));
+-  return TPM_SUCCESS;
++  return TPM_DISABLED_CMD;
+ }
+ 
+ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HANDLE keyHandle, TPM_NONCE *antiReplay,
+@@ -47,61 +46,12 @@ TPM_RESULT TPM_TickStampBlob(TPM_KEY_HAN
+                              TPM_CURRENT_TICKS *currentTicks, 
+                              UINT32 *sigSize, BYTE **sig)
+ {
+-  TPM_RESULT res;
+-  TPM_KEY_DATA *key;
+-  BYTE *info, *p;
+-  UINT32 info_length, length;
+   info("TPM_TickStampBlob()");
+-  /* get key */
+-  key = tpm_get_key(keyHandle);
+-  if (key == NULL) return TPM_INVALID_KEYHANDLE;
+-  /* verify authorization */ 
+-  res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
+-  if (res != TPM_SUCCESS) return res;
+-  if (key->keyUsage != TPM_KEY_SIGNING && key->keyUsage != TPM_KEY_LEGACY
+-      && key->keyUsage != TPM_KEY_IDENTITY) return TPM_INVALID_KEYUSAGE;
+-  /* get current ticks */
+-  TPM_GetTicks(currentTicks);
+-  /* sign data using signature scheme PKCS1_SHA1 and TPM_SIGN_INFO container 
*/
+-  *sigSize = key->key.size >> 3;
+-  *sig = tpm_malloc(*sigSize);
+-  if (*sig == NULL) return TPM_FAIL; 
+-  /* setup TPM_SIGN_INFO structure */
+-  info_length = 30 + sizeof(TPM_DIGEST) + 
sizeof_TPM_CURRENT_TICKS(currentTicks);
+-  info = tpm_malloc(info_length);
+-  if (info == NULL) {
+-    tpm_free(*sig);
+-    return TPM_FAIL;
+-  }
+-  memcpy(&info[0], "\x05\x00TSTP", 6);
+-  memcpy(&info[6], antiReplay->nonce, 20);
+-  *(UINT32*)&info[26] = cpu_to_be32(20
+-                        + sizeof_TPM_CURRENT_TICKS(currentTicks));
+-  memcpy(&info[30], digestToStamp->digest, sizeof(TPM_DIGEST));
+-  p = &info[30 + sizeof(TPM_DIGEST)]; 
+-  length = sizeof_TPM_CURRENT_TICKS(currentTicks);
+-  if (tpm_marshal_TPM_CURRENT_TICKS(&p, &length, currentTicks)
+-      || rsa_sign(&key->key, RSA_SSA_PKCS1_SHA1, info, info_length, *sig)) {  
 
+-    tpm_free(*sig);
+-    tpm_free(info);
+-    return TPM_FAIL;
+-  } 
+-  return TPM_SUCCESS;
++  return TPM_DISABLED_CMD;
+ }
+ 
+ void tpm_update_ticks(void)
+ {
+-  if (tpmData.stany.data.currentTicks.tag == 0) {
+-    tpmData.stany.data.currentTicks.tag = TPM_TAG_CURRENT_TICKS;
+-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();
+-    tpmData.stany.data.currentTicks.tickType = 
tpmData.permanent.data.tickType;
+-    tpm_get_random_bytes(tpmData.stany.data.currentTicks.tickNonce.nonce, 
+-      sizeof(TPM_NONCE));
+-    tpmData.stany.data.currentTicks.tickRate = 1;
+-    tpmData.stany.data.currentTicks.tickSecurity = TICK_SEC_NO_CHECK;
+-  } else {
+-    tpmData.stany.data.currentTicks.currentTicks += tpm_get_ticks();   
+-  }
+ }
+   
+ 
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 
tpm_emulator/tpm/tpm_transport.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_transport.c        2006-08-29 
15:07:21.647294656 -0700
++++ tpm_emulator/tpm/tpm_transport.c   2006-08-29 15:26:17.129675096 -0700
+@@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE
+ static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20],
+                              BYTE pubKeyHash[20], TPM_DIGEST *transDigest)
+ {
+-  UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_IN);
++  UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_IN);
+   BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_IN(x)];
+   UINT32 len = sizeof(buf);
+   sha1_ctx_t sha1;
+@@ -76,7 +76,7 @@ static void transport_log_in(TPM_COMMAND
+ static void transport_log_out(TPM_CURRENT_TICKS *currentTicks, BYTE 
parameters[20],
+                               TPM_MODIFIER_INDICATOR locality, TPM_DIGEST 
*transDigest)
+ {
+-  UINT32 tag = cpu_to_be32(TPM_TAG_TRANSPORT_LOG_OUT);
++  UINT32 tag = CPU_TO_BE32(TPM_TAG_TRANSPORT_LOG_OUT);
+   BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_OUT(x)];
+   UINT32 len = sizeof(buf);
+   sha1_ctx_t sha1;
+@@ -191,7 +191,7 @@ static void decrypt_wrapped_command(BYTE
+     sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
+     sha1_update(&sha1, "in", 2);
+     sha1_update(&sha1, secret, sizeof(TPM_SECRET));
+-    j = cpu_to_be32(i);
++    j = CPU_TO_BE32(i);
+     sha1_update(&sha1, (BYTE*)&j, 4);
+     sha1_final(&sha1, mask);
+     for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 
+@@ -213,7 +213,7 @@ static void encrypt_wrapped_command(BYTE
+     sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
+     sha1_update(&sha1, "out", 3);
+     sha1_update(&sha1, secret, sizeof(TPM_SECRET));
+-    j = cpu_to_be32(i);
++    j = CPU_TO_BE32(i);
+     sha1_update(&sha1, (BYTE*)&j, 4);
+     sha1_final(&sha1, mask);
+     for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 
+@@ -253,9 +253,9 @@ TPM_RESULT TPM_ExecuteTransport(UINT32 i
+   /* verify authorization */
+   tpm_compute_in_param_digest(&req);
+   sha1_init(&sha1);
+-  res = cpu_to_be32(TPM_ORD_ExecuteTransport);
++  res = CPU_TO_BE32(TPM_ORD_ExecuteTransport);
+   sha1_update(&sha1, (BYTE*)&res, 4);
+-  res = cpu_to_be32(inWrappedCmdSize);
++  res = CPU_TO_BE32(inWrappedCmdSize);
+   sha1_update(&sha1, (BYTE*)&res, 4);
+   sha1_update(&sha1, req.auth1.digest, sizeof(req.auth1.digest));
+   sha1_final(&sha1, auth1->digest);
+@@ -357,7 +357,7 @@ TPM_RESULT TPM_ReleaseTransportSigned(TP
+   /* setup a TPM_SIGN_INFO structure */
+   memcpy(&buf[0], "\x05\x00TRAN", 6);
+   memcpy(&buf[6], antiReplay->nonce, 20);
+-  *(UINT32*)&buf[26] = cpu_to_be32(20);
++  *(UINT32*)&buf[26] = CPU_TO_BE32(20);
+   memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
+   /* sign info structure */ 
+   res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize);
+diff -uprN tpm_emulator-0.3-x86_64/tpm_version.h tpm_emulator/tpm_version.h
+--- tpm_emulator-0.3-x86_64/tpm_version.h      2006-08-29 15:07:21.649294352 
-0700
++++ tpm_emulator/tpm_version.h 1969-12-31 16:00:00.000000000 -0800
+@@ -1,6 +0,0 @@
+-#ifndef _TPM_VERSION_H_
+-#define _TPM_VERSION_H_
+-#define VERSION_MAJOR 0
+-#define VERSION_MINOR 3
+-#define VERSION_BUILD 1136893683
+-#endif /* _TPM_VERSION_H_ */
+diff -uprN tpm_emulator-0.3-x86_64/tpmd.c tpm_emulator/tpmd.c
+--- tpm_emulator-0.3-x86_64/tpmd.c     1969-12-31 16:00:00.000000000 -0800
++++ tpm_emulator/tpmd.c        2006-08-29 15:26:17.130674944 -0700
+@@ -0,0 +1,141 @@
++/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
++ * Copyright (C) 2005 INTEL Corp
++ *
++ * This module is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published
++ * by the Free Software Foundation; either version 2 of the License,
++ * or (at your option) any later version.
++ *
++ * This module is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <sys/time.h>
++
++#include "tpm_emulator.h"
++
++#define TPM_RX_FNAME "/tmp/tpm_in.fifo"
++#define TPM_TX_FNAME "/tmp/tpm_out.fifo"
++
++#define BUFFER_SIZE 2048
++
++static int devurandom=0;
++        
++void get_random_bytes(void *buf, int nbytes) {
++  
++  if (devurandom == 0) {
++    devurandom = open("/dev/urandom", O_RDONLY);
++  }
++
++  if (read(devurandom, buf, nbytes) != nbytes) {
++      printf("Can't get random number.\n");
++      exit(-1);
++  }
++}
++
++uint64_t tpm_get_ticks(void)
++{
++  //struct timeval tv;
++  //int gettimeofday(&tv, struct timezone *tz);
++  return 0;
++}
++
++int main(int argc, char **argv)
++{
++  uint8_t in[BUFFER_SIZE], *out;
++  uint32_t out_size;
++  int in_size, written;
++  int i;
++ 
++  int tpm_tx_fh=-1, tpm_rx_fh=-1;
++  if (argc < 2) {
++    printf("Usage: tpmd clear|save|deactivated\n" );
++        return -1;
++  }
++
++  /* initialize TPM emulator */
++  if (!strcmp(argv[1], "clear")) {
++    printf("Initializing tpm: %s\n", argv[1]);
++    tpm_emulator_init(1);
++  } else if (!strcmp(argv[1], "save")) { 
++    printf("Initializing tpm: %s\n", argv[1]);
++    tpm_emulator_init(2);
++  } else if (!strcmp(argv[1], "deactivated")) {
++    printf("Initializing tpm: %s\n", argv[1]);
++    tpm_emulator_init(3);
++  } else {
++    printf("invalid startup mode '%s'; must be 'clear', "
++      "'save' (default) or 'deactivated", argv[1]);
++    return -1;
++  }
++
++  while (1) {
++abort_command:
++    if (tpm_rx_fh < 0) {
++      tpm_rx_fh = open(TPM_RX_FNAME, O_RDONLY);
 +    }
-+
-     tpmData.permanent.data.pcrAttrib[i].pcrReset = TRUE;
-   }
-   /* set tick type */
++    
++    if (tpm_rx_fh < 0) {
++      printf("ERROR: failed to open devices to listen to guest.\n");
++      return -1;
++    }
++    
++    if (tpm_tx_fh < 0) {
++      tpm_tx_fh = open(TPM_TX_FNAME, O_WRONLY);
++    }
++
++    if (tpm_tx_fh < 0) {
++      printf("ERROR: failed to open devices to respond to guest.\n");
++      return -1;
++    }
++
++    in_size = read(tpm_rx_fh, in, BUFFER_SIZE);
++    if (in_size < 6) { // Magic size of minium TPM command
++      printf("Recv[%d] to small: 0x", in_size);
++      if (in_size <= 0) {
++          close(tpm_rx_fh);
++          tpm_rx_fh = -1;
++          goto abort_command;
++      }
++    } else { 
++      printf("Recv[%d]: 0x", in_size);
++      for (i=0; i< in_size; i++) 
++        printf("%x ", in[i]);
++      printf("\n");
++    }
++
++    
++    if (tpm_handle_command(in, in_size, &out, &out_size) != 0) { 
++        printf("ERROR: Handler Failed.\n");
++    }
++
++    written = write(tpm_tx_fh, out, out_size);
++
++    if (written != out_size ) {
++      printf("ERROR: Part of response not written %d/%d.\nAttempt: ", 
written, out_size);
++    } else {
++      printf("Sent[%Zu]: ", out_size);
++    }
++    for (i=0; i< out_size; i++)
++      printf("%x ", out[i]);
++    printf("\n");
++    tpm_free(out);
++
++  } // loop
++
++  tpm_emulator_shutdown();
++
++  close(tpm_tx_fh);
++  close(tpm_rx_fh);
++
++}
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm/vtpm.patch
--- a/tools/vtpm/vtpm.patch     Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm/vtpm.patch     Wed Jun 28 07:52:21 2006 -0600
@@ -1,13 +1,13 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
-diff -uprN orig/tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS
---- orig/tpm_emulator-0.3-x86_64/AUTHORS       2006-01-10 04:21:45.000000000 
-0800
-+++ vtpm/AUTHORS       2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/AUTHORS vtpm/AUTHORS
+--- tpm_emulator-0.3-x86_64/AUTHORS    2006-08-29 15:07:21.618299064 -0700
++++ vtpm/AUTHORS       2006-08-29 15:12:07.184886344 -0700
 @@ -1,2 +1,3 @@
  Mario Strasser <mast@xxxxxxx>
  Heiko Stamer <stamer@xxxxxxxx> [DAA]
 +INTEL Corp <> [VTPM Extensions]
-diff -uprN orig/tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog
---- orig/tpm_emulator-0.3-x86_64/ChangeLog     2006-01-10 04:21:45.000000000 
-0800
-+++ vtpm/ChangeLog     2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/ChangeLog vtpm/ChangeLog
+--- tpm_emulator-0.3-x86_64/ChangeLog  2006-08-29 15:07:21.618299064 -0700
++++ vtpm/ChangeLog     2006-08-29 15:12:07.185886192 -0700
 @@ -1,3 +1,7 @@
 +2005-08-16 Intel Corp
 +      * Moved module out of kernel to run as a ring 3 app
@@ -16,9 +16,117 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  2005-12-24  Mario Strasser <mast@xxxxxxx>
        * tpm_transport.c, tpm_marshalling.c, tpm_structures.h:
                Transport session functionality added
-diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 
vtpm/crypto/gmp_kernel_wrapper.c
---- orig/tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c   2006-05-30 
12:28:02.000000000 -0700
-+++ vtpm/crypto/gmp_kernel_wrapper.c   2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile
+--- tpm_emulator-0.3-x86_64/Makefile   2006-08-29 15:08:20.532342768 -0700
++++ vtpm/Makefile      2006-08-29 15:13:53.023796384 -0700
+@@ -1,22 +1,31 @@
+ # Software-Based Trusted Platform Module (TPM) Emulator for Linux
+ # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
++# Copyright (C) 2006 INTEL Corp.
+ #
+ # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
+ 
+-# kernel settings
+-KERNEL_RELEASE := $(shell uname -r)
+-KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
+-MOD_SUBDIR     := misc
+ COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
+ 
+ # module settings
+-MODULE_NAME    := tpm_emulator
++BIN            := vtpmd
+ VERSION_MAJOR  := 0
+ VERSION_MINOR  := 3
+ VERSION_BUILD  := $(shell date +"%s")
+ 
+-# enable/disable DEBUG messages
+-EXTRA_CFLAGS   += -Wall -DDEBUG -g  
++# Installation program and options
++INSTALL         = install
++INSTALL_PROG    = $(INSTALL) -m0755
++INSTALL_DIR     = $(INSTALL) -d -m0755
++
++# Xen tools installation directory
++TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
++
++CC      := gcc
++CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
++CFLAGS  += -I. -Itpm -I../../vtpm_manager/manager
++
++# Is the simulator running in it's own vm?
++#CFLAGS += -DVTPM_MULTI_VM
+ 
+ ifeq ($(COMPILE_ARCH),x86_64)
+ LIBDIR = lib64
+@@ -34,38 +43,31 @@ DIRS           := . crypto tpm 
+ SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
+ OBJS           := $(patsubst %.c, %.o, $(SRCS))
+ SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
+-DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
+-DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
+ 
+-obj-m               := $(MODULE_NAME).o
+-$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
++obj-m               := $(BIN)
++$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
+ 
+ EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
+ 
+ # do not print "Entering directory ..."
+ MAKEFLAGS      += --no-print-directory
+ 
+-all:  $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
++all: $(BIN)
++
++$(BIN):       $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) 
$(OBJS)
++      $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
++
++%.o: %.c
++      $(CC) $(CFLAGS) -c $< -o $@
+ 
+-install:
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
+-      test -d /var/tpm || mkdir /var/tpm
+-      test -c /dev/tpm || mknod /dev/tpm c 10 224
+-      chmod 666 /dev/tpm
+-      depmod -a
++install: $(BIN)
++      $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
+ 
+ clean:
+-      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
+-      rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
++      rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
+ 
+-dist: $(DISTSRC)
+-      rm -rf $(DISTDIR)
+-      mkdir $(DISTDIR)
+-      cp --parents $(DISTSRC) $(DISTDIR)/
+-      rm -f $(DISTDIR)/crypto/gmp.h 
+-      tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
+-      rm -rf $(DISTDIR)
++mrproper: clean
++      rm -f $(BIN) tpm_version.h
+ 
+ $(src)/crypto/libgmp.a:
+       test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) 
$(src)/crypto/libgmp.a
+diff -uprN tpm_emulator-0.3-x86_64/README vtpm/README
+--- tpm_emulator-0.3-x86_64/README     2006-08-29 15:07:43.530967832 -0700
++++ vtpm/README        2006-08-29 15:12:07.190885432 -0700
+@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
+ Copyright
+ --------------------------------------------------------------------------
+ Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal 
+-Institute of Technology (ETH) Zurich.
++                   Institute of Technology (ETH) Zurich.
++Copyright (C) 2005 INTEL Corp 
+               
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+diff -uprN tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c 
vtpm/crypto/gmp_kernel_wrapper.c
+--- tpm_emulator-0.3-x86_64/crypto/gmp_kernel_wrapper.c        2006-08-29 
15:07:43.525968592 -0700
++++ vtpm/crypto/gmp_kernel_wrapper.c   2006-08-29 15:12:07.186886040 -0700
 @@ -1,5 +1,6 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -78,9 +186,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    }
  }
  
-diff -uprN orig/tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
---- orig/tpm_emulator-0.3-x86_64/crypto/rsa.c  2006-01-10 04:21:45.000000000 
-0800
-+++ vtpm/crypto/rsa.c  2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/crypto/rsa.c vtpm/crypto/rsa.c
+--- tpm_emulator-0.3-x86_64/crypto/rsa.c       2006-08-29 15:07:21.618299064 
-0700
++++ vtpm/crypto/rsa.c  2006-08-29 15:12:07.187885888 -0700
 @@ -1,5 +1,6 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -106,8 +214,8 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
        sha1_final(&ctx, &msg[1]);
        if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH], 
            SHA1_DIGEST_LENGTH) != 0) return -1;
-diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c
---- orig/tpm_emulator-0.3-x86_64/linux_module.c        2006-05-30 
12:28:02.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/linux_module.c vtpm/linux_module.c
+--- tpm_emulator-0.3-x86_64/linux_module.c     2006-08-29 15:07:43.526968440 
-0700
 +++ vtpm/linux_module.c        1969-12-31 16:00:00.000000000 -0800
 @@ -1,194 +0,0 @@
 -/* Software-Based Trusted Platform Module (TPM) Emulator for Linux 
@@ -304,9 +412,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
 -  return (ticks > 0) ? ticks : 1;
 -}
 -
-diff -uprN orig/tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h
---- orig/tpm_emulator-0.3-x86_64/linux_module.h        2006-05-30 
12:28:02.000000000 -0700
-+++ vtpm/linux_module.h        2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/linux_module.h vtpm/linux_module.h
+--- tpm_emulator-0.3-x86_64/linux_module.h     2006-08-29 15:07:43.527968288 
-0700
++++ vtpm/linux_module.h        2006-08-29 15:12:07.189885584 -0700
 @@ -1,5 +1,6 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -406,116 +514,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  #define BE16_TO_CPU(x) __be16_to_cpu(x)
  #define LE16_TO_CPU(x) __le16_to_cpu(x)
  
-diff -uprN orig/tpm_emulator-0.3-x86_64/Makefile vtpm/Makefile
---- orig/tpm_emulator-0.3-x86_64/Makefile      2006-05-30 12:28:02.000000000 
-0700
-+++ vtpm/Makefile      2006-05-30 12:23:26.000000000 -0700
-@@ -1,22 +1,31 @@
- # Software-Based Trusted Platform Module (TPM) Emulator for Linux
- # Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>
-+# Copyright (C) 2006 INTEL Corp.
- #
- # $Id: Makefile 69 2005-12-13 12:55:52Z mast $
- 
--# kernel settings
--KERNEL_RELEASE := $(shell uname -r)
--KERNEL_BUILD   := /lib/modules/$(KERNEL_RELEASE)/build
--MOD_SUBDIR     := misc
- COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
- 
- # module settings
--MODULE_NAME    := tpm_emulator
-+BIN            := vtpmd
- VERSION_MAJOR  := 0
- VERSION_MINOR  := 3
- VERSION_BUILD  := $(shell date +"%s")
- 
--# enable/disable DEBUG messages
--EXTRA_CFLAGS   += -Wall -DDEBUG -g  
-+# Installation program and options
-+INSTALL         = install
-+INSTALL_PROG    = $(INSTALL) -m0755
-+INSTALL_DIR     = $(INSTALL) -d -m0755
-+
-+# Xen tools installation directory
-+TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
-+
-+CC      := gcc
-+CFLAGS  += -g -Wall $(INCLUDE) -DDEBUG
-+CFLAGS  += -I. -Itpm -I../../vtpm_manager/manager
-+
-+# Is the simulator running in it's own vm?
-+#CFLAGS += -DVTPM_MULTI_VM
- 
- ifeq ($(COMPILE_ARCH),x86_64)
- LIBDIR = lib64
-@@ -34,38 +43,31 @@ DIRS           := . crypto tpm 
- SRCS           := $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.c))
- OBJS           := $(patsubst %.c, %.o, $(SRCS))
- SRCS           += $(foreach dir, $(DIRS), $(wildcard $(src)/$(dir)/*.h))
--DISTSRC        := ./README ./AUTHORS ./ChangeLog ./Makefile $(SRCS)
--DISTDIR        := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)
- 
--obj-m               := $(MODULE_NAME).o
--$(MODULE_NAME)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
-+obj-m               := $(BIN)
-+$(BIN)-objs := $(patsubst $(src)/%.o, %.o, $(OBJS)) crypto/libgmp.a
- 
- EXTRA_CFLAGS   += -I$(src) -I$(src)/crypto -I$(src)/tpm 
- 
- # do not print "Entering directory ..."
- MAKEFLAGS      += --no-print-directory
- 
--all:  $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version
--      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules
-+all: $(BIN)
-+
-+$(BIN):       $(src)/crypto/gmp.h $(src)/crypto/libgmp.a version $(SRCS) 
$(OBJS)
-+      $(CC) $(CFLAGS) $(OBJS) $(src)/crypto/libgmp.a -o $(BIN)
-+
-+%.o: %.c
-+      $(CC) $(CFLAGS) -c $< -o $@
- 
- install:
--      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) modules_install
--      test -d /var/tpm || mkdir /var/tpm
--      test -c /dev/tpm || mknod /dev/tpm c 10 224
--      chmod 666 /dev/tpm
--      depmod -a
-+      $(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
- 
- clean:
--      @$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
--      rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a
-+      rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
- 
--dist: $(DISTSRC)
--      rm -rf $(DISTDIR)
--      mkdir $(DISTDIR)
--      cp --parents $(DISTSRC) $(DISTDIR)/
--      rm -f $(DISTDIR)/crypto/gmp.h 
--      tar -chzf $(DISTDIR).tar.gz $(DISTDIR)
--      rm -rf $(DISTDIR)
-+mrproper: clean
-+      rm -f $(BIN) tpm_version.h
- 
- $(src)/crypto/libgmp.a:
-       test -f $(src)/crypto/libgmp.a || ln -s $(GMP_LIB) 
$(src)/crypto/libgmp.a
-diff -uprN orig/tpm_emulator-0.3-x86_64/README vtpm/README
---- orig/tpm_emulator-0.3-x86_64/README        2006-05-30 12:28:02.000000000 
-0700
-+++ vtpm/README        2006-05-30 12:23:26.000000000 -0700
-@@ -13,7 +13,8 @@ $Id: README 78 2006-01-07 10:45:39Z mast
- Copyright
- --------------------------------------------------------------------------
- Copyright (C) 2004 Mario Strasser <mast@xxxxxxx> and Swiss Federal 
--Institute of Technology (ETH) Zurich.
-+                   Institute of Technology (ETH) Zurich.
-+Copyright (C) 2005 INTEL Corp 
-               
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_audit.c       2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_audit.c       2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_audit.c vtpm/tpm/tpm_audit.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_audit.c    2006-08-29 15:07:21.620298760 
-0700
++++ vtpm/tpm/tpm_audit.c       2006-08-29 15:12:07.191885280 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -578,9 +579,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    return TPM_SUCCESS;
  }
 -
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 
vtpm/tpm/tpm_authorization.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c       2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_authorization.c       2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c 
vtpm/tpm/tpm_authorization.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_authorization.c    2006-08-29 
15:07:21.620298760 -0700
++++ vtpm/tpm/tpm_authorization.c       2006-08-29 15:12:07.192885128 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -598,9 +599,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    
    info("tpm_verify_auth(%08x)", auth->authHandle);
    /* get dedicated authorization or transport session */
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 
vtpm/tpm/tpm_capability.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_capability.c  2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_capability.c  2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_capability.c 
vtpm/tpm/tpm_capability.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_capability.c       2006-08-29 
15:07:21.620298760 -0700
++++ vtpm/tpm/tpm_capability.c  2006-08-29 15:12:07.193884976 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -623,9 +624,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    }
  }
 -
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 
vtpm/tpm/tpm_cmd_handler.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_cmd_handler.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c 
vtpm/tpm/tpm_cmd_handler.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_cmd_handler.c      2006-08-29 
15:07:21.621298608 -0700
++++ vtpm/tpm/tpm_cmd_handler.c 2006-08-29 15:12:07.197884368 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -683,9 +684,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    /* setup authorisation as well as response tag and size */
    memset(rsp, 0, sizeof(*rsp));
    switch (req->tag) {
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c      2006-05-30 
12:28:02.000000000 -0700
-+++ vtpm/tpm/tpm_crypto.c      2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c vtpm/tpm/tpm_crypto.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_crypto.c   2006-08-29 15:07:43.531967680 
-0700
++++ vtpm/tpm/tpm_crypto.c      2006-08-29 15:12:07.198884216 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -708,9 +709,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    return TPM_SUCCESS;
  }
 -
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_daa.c 2006-01-10 04:21:45.000000000 
-0800
-+++ vtpm/tpm/tpm_daa.c 2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_daa.c vtpm/tpm/tpm_daa.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_daa.c      2006-08-29 15:07:21.622298456 
-0700
++++ vtpm/tpm/tpm_daa.c 2006-08-29 15:12:07.203883456 -0700
 @@ -700,14 +700,14 @@ info("tested until here");
            sizeof(session->DAA_tpmSpecific.DAA_rekey));
        sha1_update(&sha1, (BYTE*) &session->DAA_tpmSpecific.DAA_count, 
@@ -865,9 +866,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
        sha1_final(&sha1, scratch + SHA1_DIGEST_LENGTH);
        mpz_init(f), mpz_init(q);
        mpz_import(f, 2 * SHA1_DIGEST_LENGTH, 1, 1, 0, 0, scratch);
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_data.c        2006-05-30 
12:28:02.000000000 -0700
-+++ vtpm/tpm/tpm_data.c        2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_data.c vtpm/tpm/tpm_data.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_data.c     2006-08-29 15:08:20.535342312 
-0700
++++ vtpm/tpm/tpm_data.c        2006-08-29 15:12:07.206883000 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1177,7 +1178,7 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  }
  
  #else
-@@ -267,7 +462,6 @@ int tpm_restore_permanent_data(void)
+@@ -278,7 +473,6 @@ int tpm_restore_permanent_data(void)
  
  int tpm_erase_permanent_data(void)
  {
@@ -1186,9 +1187,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    return res;
  }
 -
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 
vtpm/tpm/tpm_deprecated.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c  2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_deprecated.c  2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c 
vtpm/tpm/tpm_deprecated.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_deprecated.c       2006-08-29 
15:07:21.622298456 -0700
++++ vtpm/tpm/tpm_deprecated.c  2006-08-29 15:12:07.207882848 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1215,9 +1216,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
                          authContextSize, &contextBlob);
    if (res != TPM_SUCCESS) return res;
    len = *authContextSize;
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 
vtpm/tpm/tpm_emulator.h
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h    2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_emulator.h    2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h vtpm/tpm/tpm_emulator.h
+--- tpm_emulator-0.3-x86_64/tpm/tpm_emulator.h 2006-08-29 15:07:21.648294504 
-0700
++++ vtpm/tpm/tpm_emulator.h    2006-08-29 15:12:07.208882696 -0700
 @@ -1,5 +1,6 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1235,9 +1236,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  #undef  TPM_GENERATE_SEED_DAA
  
  #define TPM_MANUFACTURER 0x4554485A /* 'ETHZ' */        
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c 
vtpm/tpm/tpm_integrity.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c   2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_integrity.c   2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c vtpm/tpm/tpm_integrity.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_integrity.c        2006-08-29 
15:07:21.645294960 -0700
++++ vtpm/tpm/tpm_integrity.c   2006-08-29 15:12:07.208882696 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1251,9 +1252,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    return TPM_SUCCESS;
  }
 -
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 
vtpm/tpm/tpm_structures.h
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_structures.h  2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_structures.h  2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_structures.h 
vtpm/tpm/tpm_structures.h
+--- tpm_emulator-0.3-x86_64/tpm/tpm_structures.h       2006-08-29 
15:08:20.545340792 -0700
++++ vtpm/tpm/tpm_structures.h  2006-08-29 15:12:07.211882240 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1271,9 +1272,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  #include "crypto/rsa.h"
  
  /*
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c 
vtpm/tpm/tpm_testing.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_testing.c     2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_testing.c     2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_testing.c vtpm/tpm/tpm_testing.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_testing.c  2006-08-29 15:07:21.646294808 
-0700
++++ vtpm/tpm/tpm_testing.c     2006-08-29 15:12:07.213881936 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1389,9 +1390,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    rsa_private_key_t priv_key;
    rsa_public_key_t pub_key;
  
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c       2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_ticks.c       2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c vtpm/tpm/tpm_ticks.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_ticks.c    2006-08-29 15:07:21.646294808 
-0700
++++ vtpm/tpm/tpm_ticks.c       2006-08-29 15:12:07.235878592 -0700
 @@ -1,6 +1,7 @@
  /* Software-Based Trusted Platform Module (TPM) Emulator for Linux
   * Copyright (C) 2004 Mario Strasser <mast@xxxxxxx>,
@@ -1474,9 +1475,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
  }
    
  
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c 
vtpm/tpm/tpm_transport.c
---- orig/tpm_emulator-0.3-x86_64/tpm/tpm_transport.c   2006-01-10 
04:21:45.000000000 -0800
-+++ vtpm/tpm/tpm_transport.c   2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpm/tpm_transport.c vtpm/tpm/tpm_transport.c
+--- tpm_emulator-0.3-x86_64/tpm/tpm_transport.c        2006-08-29 
15:07:21.647294656 -0700
++++ vtpm/tpm/tpm_transport.c   2006-08-29 15:12:07.239877984 -0700
 @@ -59,7 +59,7 @@ static int decrypt_transport_auth(TPM_KE
  static void transport_log_in(TPM_COMMAND_CODE ordinal, BYTE parameters[20],
                               BYTE pubKeyHash[20], TPM_DIGEST *transDigest)
@@ -1534,9 +1535,9 @@ diff -uprN orig/tpm_emulator-0.3-x86_64/
    memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
    /* sign info structure */ 
    res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), signature, signSize);
-diff -uprN orig/tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c
---- orig/tpm_emulator-0.3-x86_64/tpmd.c        1969-12-31 16:00:00.000000000 
-0800
-+++ vtpm/tpmd.c        2006-05-30 12:23:26.000000000 -0700
+diff -uprN tpm_emulator-0.3-x86_64/tpmd.c vtpm/tpmd.c
+--- tpm_emulator-0.3-x86_64/tpmd.c     1969-12-31 16:00:00.000000000 -0800
++++ vtpm/tpmd.c        2006-08-29 15:12:07.240877832 -0700
 @@ -0,0 +1,207 @@
 +/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
 + * Copyright (C) 2005 INTEL Corp
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk       Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/Rules.mk       Wed Jun 28 07:52:21 2006 -0600
@@ -56,6 +56,9 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT
 # vtpm_manager listens on fifo's rather than backend
 #CFLAGS += -DDUMMY_BACKEND
 
+# TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos
+#CFLAGS += -DDUMMY_TPM
+
 # Do not have manager launch DMs.
 #CFLAGS += -DMANUAL_DM_LAUNCH
 
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c       Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/dmictl.c       Wed Jun 28 07:52:21 2006 -0600
@@ -76,14 +76,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
   
   VTPM_DMI_RESOURCE *new_dmi=NULL;
   TPM_RESULT status=TPM_FAIL;
-  BYTE type;
-  UINT32 dmi_id, domain_id, *dmi_id_key; 
+  BYTE type, startup_mode;
+  UINT32 dmi_id, *dmi_id_key=NULL; 
 
   if (param_buf == NULL) { // Assume creation of Dom 0 control
-    type = 0;
-    domain_id = VTPM_CTL_DM;
+    type = VTPM_TYPE_NON_MIGRATABLE;
     dmi_id = VTPM_CTL_DM;
-  } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(UINT32) *2) {
+  } else if (buffer_len(param_buf) != sizeof(BYTE) + sizeof(BYTE) + 
sizeof(UINT32)) {
     vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n", 
buffer_len(param_buf));
     status = TPM_BAD_PARAMETER;
     goto abort_egress;
@@ -91,13 +90,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
     vtpm_globals->connected_dmis++; // Put this here so we don't count Dom0
     BSG_UnpackList( param_buf->bytes, 3,
                    BSG_TYPE_BYTE, &type,
-                   BSG_TYPE_UINT32, &domain_id,
+                   BSG_TYPE_BYTE, &startup_mode,
                    BSG_TYPE_UINT32,  &dmi_id);
   }
-  
+
   new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, 
&dmi_id);
   if (new_dmi == NULL) { 
-    vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached on 
domain %d.\n", dmi_id, domain_id);
+    vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached.\n", 
dmi_id );
     // Brand New DMI. Initialize the persistent pieces
     if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) 
== NULL) {
       status = TPM_RESOURCES;
@@ -106,32 +105,44 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
     memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
     new_dmi->dmi_id = dmi_id;
     new_dmi->connected = FALSE;
+
+    if (type != VTPM_TYPE_MIGRATED) {
+      new_dmi->dmi_type = type;
+    } else {
+      vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n");
+      status = TPM_BAD_PARAMETER;
+      goto free_egress;
+    }
     
     if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
       status = TPM_RESOURCES;
-      goto abort_egress;
+      goto free_egress;
     }      
     *dmi_id_key = new_dmi->dmi_id;
     
     // install into map
     if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
-      free(new_dmi);
-      free(dmi_id_key);
+      vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance into table. 
Aborting.\n", dmi_id);
       status = TPM_FAIL;
-      goto egress;
+      goto free_egress;
     }
    
   } else 
-    vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d on domain %d 
.\n", dmi_id, domain_id);
+    vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d.\n", dmi_id);
   
   if (new_dmi->connected) {
     vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached 
instance %d. Ignoring\n", dmi_id);
     status = TPM_BAD_PARAMETER;
-    goto egress;
-  }
-  
+    goto abort_egress;
+  }
+  
+  if (type == VTPM_TYPE_MIGRATED) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach previously migrated 
instance %d without recovering first. Ignoring\n", dmi_id);
+    status = TPM_BAD_PARAMETER;
+    goto abort_egress;
+  }
+
   // Initialize the Non-persistent pieces
-  new_dmi->dmi_domain_id = domain_id;
   new_dmi->NVMLocation = NULL;
   
   new_dmi->TCSContext = 0;
@@ -144,9 +155,13 @@ TPM_RESULT VTPM_Handle_New_DMI(const buf
 
   // Design specific new DMI code. 
   // Includes: create IPCs, Measuring DMI, and maybe launching DMI
-  status = VTPM_New_DMI_Extra(new_dmi);
-  goto egress;
-  
+  status = VTPM_New_DMI_Extra(new_dmi, startup_mode);
+  goto egress;
+  
+ free_egress:   // Error that requires freeing of newly allocated dmi 
+  free(new_dmi);
+  free(dmi_id_key);
+
  abort_egress:
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s. 
Cleaning.\n", dmi_id, tpm_get_error_name(status));
   close_dmi(new_dmi );
@@ -221,7 +236,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI( const
     goto abort_egress;
   }
   
-       //TODO: Automatically delete file dmi_res->NVMLocation
+  //vtpm scripts delete file dmi_res->NVMLocation for us
   
   // Close DMI first
   TPMTRYRETURN(close_dmi( dmi_res ));
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c        Wed Jun 28 07:51:52 
2006 -0600
+++ b/tools/vtpm_manager/manager/securestorage.c        Wed Jun 28 07:52:21 
2006 -0600
@@ -190,8 +190,7 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
   long bytes_written;
   buffer_t sealed_NVM;
   
-  
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x\n", buffer_len(inbuf));
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", 
buffer_len(inbuf));
 
   TPMTRYRETURN( envelope_encrypt(inbuf,
                                  &vtpm_globals->storageKey,
@@ -310,6 +309,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
   UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
   struct pack_buf_t storage_key_pack = {storageKeySize, 
vtpm_globals->storageKeyWrap.bytes};
   struct pack_buf_t boot_key_pack = {bootKeySize, 
vtpm_globals->bootKeyWrap.bytes};
+  BYTE vtpm_manager_gen = VTPM_MANAGER_GEN;
 
   struct hashtable_itr *dmi_itr;
   VTPM_DMI_RESOURCE *dmi_res;
@@ -321,7 +321,8 @@ TPM_RESULT VTPM_SaveManagerData(void) {
   boot_key_size =  sizeof(UINT32) +       // bootkeysize
                    bootKeySize;           // boot key
 
-  TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths
+  TPMTRYRETURN(buffer_init(&clear_flat_global,sizeof(BYTE) + // manager version
+                                              3*sizeof(TPM_DIGEST) + // Auths
                                               sizeof(UINT32) +// storagekeysize
                                               storageKeySize, NULL) ); // 
storage key
 
@@ -332,7 +333,8 @@ TPM_RESULT VTPM_SaveManagerData(void) {
   boot_key_size = BSG_PackList(flat_boot_key, 1,
                                BSG_TPM_SIZE32_DATA, &boot_key_pack);
 
-  BSG_PackList(clear_flat_global.bytes, 3,
+  BSG_PackList(clear_flat_global.bytes, 4,
+                BSG_TYPE_BYTE,    &vtpm_manager_gen,
                 BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
                 BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
                 BSG_TPM_SIZE32_DATA, &storage_key_pack);
@@ -348,7 +350,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
 
     flat_dmis = (BYTE *) malloc( 
                      (hashtable_count(vtpm_globals->dmi_map) - 1) * // num 
DMIS (-1 for Dom0)
-                     (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info
+                     (sizeof(UINT32) +sizeof(BYTE) + 2*sizeof(TPM_DIGEST)) ); 
// Per DMI info
 
     dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
     do {
@@ -360,8 +362,9 @@ TPM_RESULT VTPM_SaveManagerData(void) {
         continue;
 
 
-      flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3,
+      flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 4,
                                         BSG_TYPE_UINT32, &dmi_res->dmi_id,
+                                        BSG_TYPE_BYTE, &dmi_res->dmi_type,
                                         BSG_TPM_DIGEST, 
&dmi_res->NVM_measurement,
                                         BSG_TPM_DIGEST, 
&dmi_res->DMI_measurement);
 
@@ -408,6 +411,7 @@ TPM_RESULT VTPM_LoadManagerData(void) {
   buffer_t  unsealed_data;
   struct pack_buf_t storage_key_pack, boot_key_pack;
   UINT32 *dmi_id_key, enc_size;
+  BYTE vtpm_manager_gen;
 
   VTPM_DMI_RESOURCE *dmi_res;
   struct stat file_stat;
@@ -458,8 +462,14 @@ TPM_RESULT VTPM_LoadManagerData(void) {
                                  &unsealed_data) );
   step_size += enc_size;
 
+  if (*unsealed_data.bytes != VTPM_MANAGER_GEN) {
+      // Once there is more than one gen, this will include some compatability 
stuff
+      vtpmlogerror(VTPM_LOG_VTPM, "Warning: Manager Data file is gen %d, which 
this manager is gen %d.\n", vtpm_manager_gen, VTPM_MANAGER_GEN);
+  }
+
   // Global Values needing to be saved
-  BSG_UnpackList( unsealed_data.bytes, 3,
+  BSG_UnpackList( unsealed_data.bytes, 4,
+                  BSG_TYPE_BYTE,    &vtpm_manager_gen, 
                   BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
                   BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
                   BSG_TPM_SIZE32_DATA, &storage_key_pack);
@@ -469,7 +479,7 @@ TPM_RESULT VTPM_LoadManagerData(void) {
 
   // Per DMI values to be saved
   while ( step_size < fh_size ){
-    if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
+    if (fh_size - step_size < (long) (sizeof(UINT32) + sizeof(BYTE) + 
2*sizeof(TPM_DIGEST))) {
       vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of 
manager state.\n", fh_size-step_size);
       step_size = fh_size;
     } else {
@@ -478,8 +488,9 @@ TPM_RESULT VTPM_LoadManagerData(void) {
 
       dmi_res->connected = FALSE;
 
-      step_size += BSG_UnpackList(flat_table + step_size, 3,
+      step_size += BSG_UnpackList(flat_table + step_size, 4,
                                  BSG_TYPE_UINT32, &dmi_res->dmi_id,
+                                 BSG_TYPE_BYTE, &dmi_res->dmi_type,
                                  BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
                                  BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
 
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Wed Jun 28 07:52:21 2006 -0600
@@ -92,8 +92,9 @@ TPM_RESULT VTPM_Create_Manager(){
   status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
   
   // If we can read PubEK then there is no owner and we should take it.
+  // We use the abilty to read the pubEK to flag that the TPM is owned.
+  // FIXME: Change to just trying to take ownership and react to the status
   if (status == TPM_SUCCESS) { 
-    vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. 
Creating Keys off existing SRK.\n");
     TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
                                    (const 
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
                                    &SRK_AUTH,
@@ -103,6 +104,8 @@ TPM_RESULT VTPM_Create_Manager(){
     TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
                                        (const 
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,  
                                        &vtpm_globals->keyAuth));     
+  } else {
+    vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. 
Creating Keys off existing SRK.\n");
   }
   
   // Generate storage key's auth
@@ -165,7 +168,7 @@ TPM_RESULT VTPM_Create_Manager(){
                               &vtpm_globals->bootKey,
                               TRUE ) );
 
-  printf("***************************** FIXME: SAVE NEW STATE *******\n");
+  TPMTRYRETURN( VTSP_SaveState(vtpm_globals->manager_tcs_handle) );
   goto egress;
   
  abort_egress:
@@ -181,7 +184,7 @@ TPM_RESULT VTPM_Init_Manager() {
 TPM_RESULT VTPM_Init_Manager() {
   TPM_RESULT status = TPM_FAIL, serviceStatus;   
   BYTE *randomsead;
-  UINT32 randomsize;
+  UINT32 randomsize=256;
 
   if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
     status = TPM_FAIL;
@@ -216,7 +219,7 @@ TPM_RESULT VTPM_Init_Manager() {
                           &vtpm_globals->keyAuth) );
   vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
 
-       // If failed, create new Manager.
+  // If failed, create new Manager.
   serviceStatus = VTPM_LoadManagerData();
   if (serviceStatus == TPM_IOERROR) {
     vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first 
time initialization.\n");
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpm_manager.h Wed Jun 28 07:52:21 2006 -0600
@@ -73,6 +73,12 @@
 #define VTPM_RESTORE_CONTEXT_FAILED    4
 #define VTPM_INVALID_REQUEST       5
 
+//*********************** Parameter Values *************************
+#define VTPM_TYPE_NON_MIGRATABLE  0x00
+#define VTPM_TYPE_MIGRATABLE      0x01
+#define VTPM_TYPE_MIGRATED        0xFF // VTPM has been migrated.
+                                       // VTPM can be recovered or deleted only
+
 /******************* Command Parameter API *************************
 
 VTPM Command Format
@@ -94,8 +100,8 @@ VTPM Response Format
 
 VTPM_Open:
   Input Parameters:
-    Domain_type: 1 byte
-    domain_id: 4 bytes
+    Domain_type: 1 byte 
+    startup_mode: 1 byte // Cold Boot = 1, resume = 2, deactive = 3
     instance_id: 4 bytes
   Output Parameters:
     None
diff -r c4b68afe97d3 -r 4b51d081378d 
tools/vtpm_manager/manager/vtpm_manager_handler.c
--- a/tools/vtpm_manager/manager/vtpm_manager_handler.c Wed Jun 28 07:51:52 
2006 -0600
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c Wed Jun 28 07:52:21 
2006 -0600
@@ -78,13 +78,14 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
                                  BOOL is_priv,
                                  char *thread_name) {
   TPM_RESULT      status =  TPM_FAIL; // Should never return
-  UINT32          dmi, in_param_size, cmd_size, out_param_size, 
out_message_size, out_message_size_full;
-  BYTE            *cmd_header, *in_param, *out_message;
+  UINT32          dmi, in_param_size, cmd_size, out_param_size, 
out_message_size, reply_size;
+  BYTE            *cmd_header=NULL, *in_param=NULL, *out_message=NULL, *reply;
   buffer_t        *command_buf=NULL, *result_buf=NULL;
   TPM_TAG         tag;
   TPM_COMMAND_CODE ord;
   VTPM_DMI_RESOURCE *dmi_res;
   int  size_read, size_write, i;
+  BOOL add_header=TRUE; // This indicates to prepend a header on result_buf 
before sending
   
   cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
   command_buf = (buffer_t *) malloc(sizeof(buffer_t));
@@ -100,7 +101,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
     // Read command header 
     size_read = vtpm_ipc_read(rx_ipc_h, NULL, cmd_header, 
VTPM_COMMAND_HEADER_SIZE_SRV);
     if (size_read > 0) {
-      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d}: 0x", size_read);
+      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d]: 0x", size_read);
       for (i=0; i<size_read; i++) 
        vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
     } else {
@@ -165,6 +166,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
          (!dmi_res->connected) ) {
       vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent or 
disconnected DMI %d. Aborting...\n", dmi);
       status = TPM_BAD_PARAMETER;
+      goto abort_with_error;
     }
 
     if (tag == VTPM_TAG_REQ) { 
@@ -176,9 +178,14 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
         status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, 
dmi_res, cmd_header, command_buf, result_buf, thread_name);
 
         // This means calling the DMI failed, not that the cmd failed in the 
DMI
+        // Since the return will be interpretted by a TPM app, all errors are 
IO_ERRORs to the app
         if (status != TPM_SUCCESS) { 
+          status = TPM_IOERROR;
          goto abort_with_error;
         }
+        // Unlike all other commands, forwarded commands yield a result_buf 
that includes the DMI's status. This
+        // should be forwarded to the caller VM
+        add_header = FALSE;
       } else {
         // We are not supposed to forward TPM commands at all.
         int i;
@@ -205,38 +212,43 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
 #ifndef VTPM_MULTI_VM
  abort_with_error:
 #endif
-    
-    // Prepend VTPM header with destination DM stamped
-    out_param_size = buffer_len(result_buf);
-    out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
-    out_message_size_full = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
-    out_message = (BYTE *) malloc (out_message_size_full);
-    
-    BSG_PackList(out_message, 4,
-                BSG_TYPE_UINT32, (BYTE *) &dmi,
-                BSG_TPM_TAG, (BYTE *) &tag,
-                BSG_TYPE_UINT32, (BYTE *) &out_message_size,
-                BSG_TPM_RESULT, (BYTE *) &status);
-    
-    if (buffer_len(result_buf) > 0) 
-      memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, 
out_param_size);
-
-    //Note: Send message + dmi_id
-    size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_vtpm_ipc_h, out_message, 
out_message_size_full );
+   
+    if (add_header) { 
+      // Prepend VTPM header with destination DM stamped
+      out_param_size = buffer_len(result_buf);
+      out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
+      reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
+      out_message = (BYTE *) malloc (reply_size);
+      reply = out_message;
+    
+      BSG_PackList(out_message, 4,
+                  BSG_TYPE_UINT32, (BYTE *) &dmi,
+                  BSG_TPM_TAG, (BYTE *) &tag,
+                  BSG_TYPE_UINT32, (BYTE *) &out_message_size,
+                  BSG_TPM_RESULT, (BYTE *) &status);
+    
+      if (buffer_len(result_buf) > 0) 
+        memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, 
out_param_size);
+      //Note: Send message + dmi_id
+    } else {
+      reply = result_buf->bytes;
+      reply_size = buffer_len(result_buf);
+    }  
+    size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h : 
NULL), reply, reply_size );
     if (size_write > 0) {
       vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
-      for (i=0; i < out_message_size_full; i++) 
-       vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", out_message[i]);
+      for (i=0; i < reply_size; i++) 
+       vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", reply[i]);
       
       vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");            
     } else {
       vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. 
Aborting... \n", thread_name);
       goto abort_command;
     }
-    free(out_message);
-    
-    if (size_write < (int)out_message_size_full) {
-      vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to 
ipc (%d/%d)\n", thread_name, size_write, out_message_size_full);
+    free(out_message); out_message=NULL;
+    
+    if (size_write < (int)reply_size) {
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to 
ipc (%d/%d)\n", thread_name, size_write, reply_size);
       goto abort_command;
     }
     
@@ -246,9 +258,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
     //free buffers
     bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
     //free(in_param); // This was converted to command_buf. No need to free 
-    if (command_buf != result_buf) 
-      buffer_free(result_buf);
-    
+    buffer_free(result_buf);
     buffer_free(command_buf);
 
     // If we have a write lock, save the manager table
@@ -258,6 +268,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ip
     }
 
     vtpm_lock_unlock();
+    add_header = TRUE; // Reset to the default
   } // End while(1)
   
 }
@@ -369,6 +380,7 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(v
     dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
     size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, cmd_header, 
VTPM_COMMAND_HEADER_SIZE_SRV );
     if (size_write > 0) {
+      vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
       for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++) 
         vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
 
@@ -438,7 +450,8 @@ TPM_RESULT vtpm_manager_handle_tpm_cmd(v
     vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
   }
    
-  if (buffer_init_convert(result_buf, adj_param_size, in_param) != 
TPM_SUCCESS) {
+  if ( (buffer_init(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV, cmd_header) != 
TPM_SUCCESS) || 
+       (buffer_append_raw(result_buf, adj_param_size, in_param) != 
TPM_SUCCESS) ) {
     vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. 
Aborting...\n");
     status = TPM_FAIL;
     goto abort_with_error;
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c        Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpmd.c        Wed Jun 28 07:52:21 2006 -0600
@@ -64,14 +64,6 @@
 #define VTPM_TX_HP_FNAME       "/var/vtpm/fifos/to_console.fifo"
 #define VTPM_RX_HP_FNAME       "/var/vtpm/fifos/from_console.fifo"
 
-
-#define GUEST_TX_FIFO "/var/vtpm/fifos/guest-to-%d.fifo"
-#define GUEST_RX_FIFO "/var/vtpm/fifos/guest-from-all.fifo"
-
-#define VTPM_TX_FIFO  "/var/vtpm/fifos/vtpm-to-%d.fifo"
-#define VTPM_RX_FIFO  "/var/vtpm/fifos/vtpm-from-all.fifo"
-
-
 struct vtpm_thread_params_s {
   vtpm_ipc_handle_t *tx_ipc_h;
   vtpm_ipc_handle_t *rx_ipc_h;
@@ -113,7 +105,7 @@ void signal_handler(int reason) {
 
 struct sigaction ctl_c_handler;
 
-TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
+TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode) {
 
   TPM_RESULT status = TPM_SUCCESS;
   int fh;
@@ -150,14 +142,14 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
 
     // Measure DMI
     // FIXME: This will measure DMI. Until then use a fixed DMI_Measurement 
value
-    // Also, this mechanism is specific to 1 VM.
+    // Also, this mechanism is specific to 1 VM architecture.
     /*
     fh = open(TPM_EMULATOR_PATH, O_RDONLY);
     stat_ret = fstat(fh, &file_stat);
     if (stat_ret == 0)
       dmi_size = file_stat.st_size;
     else {
-      vtpmlogerror(VTPM_LOG_VTPM, "Could not open tpm_emulator!!\n");
+      vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n");
       status = TPM_IOERROR;
       goto abort_egress;
     }
@@ -179,10 +171,20 @@ TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_R
       status = TPM_RESOURCES;
       goto abort_egress;
     } else if (pid == 0) {
-      if ( stat(dmi_res->NVMLocation, &file_info) == -1)
+      switch (startup_mode) {
+      case TPM_ST_CLEAR:
         execl (TPM_EMULATOR_PATH, "vtmpd", "clear", dmi_id_str, NULL);
-      else
+        break;
+      case TPM_ST_STATE:
         execl (TPM_EMULATOR_PATH, "vtpmd", "save", dmi_id_str, NULL);
+        break;
+      case TPM_ST_DEACTIVATED:
+        execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", dmi_id_str, NULL);
+        break;
+      default:
+        status = TPM_BAD_PARAMETER;
+        goto abort_egress;
+      }
 
       // Returning from these at all is an error.
       vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
@@ -309,7 +311,7 @@ int main(int argc, char **argv) {
   be_thread_params.fw_tpm = TRUE;
   be_thread_params.fw_tx_ipc_h = NULL;
   be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h;
-  be_thread_params.is_priv = TRUE;                   //FIXME: Change when HP 
is up
+  be_thread_params.is_priv = FALSE;
   be_thread_params.thread_name = "Backend Listener";
 
   dmi_thread_params.tx_ipc_h = NULL;
@@ -318,7 +320,7 @@ int main(int argc, char **argv) {
   dmi_thread_params.fw_tx_ipc_h = NULL;
   dmi_thread_params.fw_rx_ipc_h = NULL;
   dmi_thread_params.is_priv = FALSE; 
-  dmi_thread_params.thread_name = "VTPM Listeners";
+  dmi_thread_params.thread_name = "VTPM Listener";
 
   hp_thread_params.tx_ipc_h = &tx_hp_ipc_h;
   hp_thread_params.rx_ipc_h = &rx_hp_ipc_h;
@@ -345,10 +347,10 @@ int main(int argc, char **argv) {
   }
 
  
-//  if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, 
&hp_thread_params) != 0) {
-//    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
-//    exit(-1);
-//  }
+  if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) 
!= 0) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
+    exit(-1);
+  }
  
   //Join the other threads until exit time.
   pthread_join(be_thread, NULL);
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h     Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtpmpriv.h     Wed Jun 28 07:52:21 2006 -0600
@@ -40,15 +40,19 @@
 #ifndef __VTPMPRIV_H__
 #define __VTPMPRIV_H__
 
+#include "vtpm_manager.h"
 #include "tcg.h"
 #include "tcs.h"
 #include "buffer.h"
 #include "crypto.h"
 #include "vtpm_ipc.h"
 
-#define STATE_FILE    "/var/vtpm/VTPM"
-#define DMI_NVM_FILE  "/var/vtpm/vtpm_dm_%d.data"
-#define VTPM_CTL_DM   0
+#define VTPM_MANAGER_GEN   2     // This is incremented when the manager's 
table
+                                 // is changed. It's used for backwards 
compatability
+
+#define STATE_FILE         "/var/vtpm/VTPM"
+#define DMI_NVM_FILE       "/var/vtpm/vtpm_dm_%d.data"
+#define VTPM_CTL_DM        0
 
 // ------------------------ Private Structures -----------------------
 typedef struct VTPM_DMI_RESOURCE_T {
@@ -70,6 +74,7 @@ typedef struct VTPM_DMI_RESOURCE_T {
                                         // of NVM.
   // Persistent Information about DMI
   UINT32                dmi_id;
+  BYTE                  dmi_type;
   TPM_DIGEST            NVM_measurement;  // Equal to the SHA1 of the blob
   TPM_DIGEST            DMI_measurement;  // Correct measurement of the owning 
DMI
 } VTPM_DMI_RESOURCE;
@@ -138,7 +143,7 @@ TPM_RESULT VTPM_SaveManagerData(void);
 TPM_RESULT VTPM_SaveManagerData(void);
 TPM_RESULT VTPM_LoadManagerData(void);
 
-TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
+TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE startup_mode);
 
 TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
 
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtsp.c Wed Jun 28 07:52:21 2006 -0600
@@ -971,6 +971,17 @@ TPM_RESULT VTSP_Unseal(const TCS_CONTEXT
   return status;
 }
 
+TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE    hContext) {
+
+  vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n");
+
+  TPM_RESULT status = TPM_SUCCESS;
+
+  // Call TCS
+  return ( TCSP_SaveState ( hContext ) );
+
+}
+
 
 // Function Reaches into unsupported TCS command, beware.
 TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE    hContext,
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/manager/vtsp.h Wed Jun 28 07:52:21 2006 -0600
@@ -118,4 +118,6 @@ TPM_RESULT VTSP_Unseal(const TCS_CONTEXT
                        TCS_AUTH                    *auth,
                        TCS_AUTH                    *dataAuth);
 
+TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE    hContext);
+
 #endif //_VTSP_H_
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/tcs/tcs.c
--- a/tools/vtpm_manager/tcs/tcs.c      Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/tcs/tcs.c      Wed Jun 28 07:52:21 2006 -0600
@@ -1126,6 +1126,49 @@ TPM_RESULT TCSP_ReadPubek(TCS_CONTEXT_HA
   return(returnCode);
 }
 
+
+TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE   hContext)  // in
+{
+  // setup input/output parameters block
+  TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+  UINT32 paramSize = 0;
+  TPM_COMMAND_CODE ordinal = TPM_ORD_SaveState;
+  TPM_RESULT returnCode = TPM_SUCCESS;
+
+  // setup the TPM driver input and output buffers
+  TDDL_RESULT hRes = TDDL_E_FAIL;
+  TDDL_UINT32  InLength = TCPA_MAX_BUFFER_LENGTH;
+  TDDL_UINT32  OutLength = TCPA_MAX_BUFFER_LENGTH;
+
+  // Convert Byte Input parameter in the input byte stream InBuf
+  InLength = BSG_PackList(InBuf, 3,
+                          BSG_TPM_TAG, &tag,
+                          BSG_TYPE_UINT32, &paramSize,
+                          BSG_TPM_COMMAND_CODE, &ordinal);
+  // fill paramSize again as we now have the correct size
+  BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+
+  vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+
+  // call the TPM driver
+  if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength)) == 
TDDL_SUCCESS) {
+    // unpack OutBuf to get the tag, paramSize, & returnCode
+    BSG_UnpackList(OutBuf, 3,
+                           BSG_TPM_TAG, &tag,
+                           BSG_TYPE_UINT32, &paramSize,
+                           BSG_TPM_COMMAND_CODE, &returnCode);
+
+    if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
+      vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n", paramSize);
+    } else {
+      vtpmlogerror(VTPM_LOG_TCS, "TCSP_SaveState Failed with return code 
%s\n", tpm_get_error_name(returnCode));
+    }
+  }
+
+  return(returnCode);
+}
+
+
 TPM_RESULT TCSP_RawTransmitData(   UINT32 inDataSize,  // in
                                   BYTE *inData,       // in
                                   UINT32 *outDataSize,// in/out
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/tcs/tcs.h
--- a/tools/vtpm_manager/tcs/tcs.h      Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/tcs/tcs.h      Wed Jun 28 07:52:21 2006 -0600
@@ -229,7 +229,10 @@ TPM_RESULT TCSP_ReadPubek (  TCS_CONTEXT
                             );
 
 
-// Non-Standard TCSP call to give direct access to TransmitData.
+// Non-Standard TCSP calls
+TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE   hContext);  // in
+
+//Give direct access to TransmitData.
 // Key and Auth Management is done before transfering command to TDDL.
 TPM_RESULT TCSP_RawTransmitData(UINT32 inDataSize,  // in
                                BYTE *inData,       // in
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/tcs/transmit.c
--- a/tools/vtpm_manager/tcs/transmit.c Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/tcs/transmit.c Wed Jun 28 07:52:21 2006 -0600
@@ -43,7 +43,17 @@
 
 // flag to track whether TDDL has been opened
 static int g_TDDL_open = 0;
-static int g_fd = -1;              // the fd to the TPM
+static int g_tx_fd = -1;              // the fd to the TPM
+
+#ifndef DUMMY_TPM
+ #define TPM_TX_FNAME "/dev/tpm0"
+ static int *g_rx_fdp = &g_tx_fd;
+#else
+ #define TPM_TX_FNAME "/tmp/tpm_in.fifo"
+ #define TPM_RX_FNAME "/tmp/tpm_out.fifo"
+ static int g_rx_fd = -1;
+ static int *g_rx_fdp = &g_rx_fd;              // the fd to the TPM
+#endif
 
 TPM_RESULT
 TDDL_TransmitData( TDDL_BYTE* in,
@@ -60,10 +70,9 @@ TDDL_TransmitData( TDDL_BYTE* in,
   vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
   
   ssize_t size = 0;
-  int fd = g_fd;
   
   // send the request
-  size = write (fd, in, insize);
+  size = write (g_tx_fd, in, insize);
   if (size < 0) {
     vtpmlogerror(VTPM_LOG_TXDATA, "write() failed");
     ERRORDIE (TPM_IOERROR);
@@ -74,7 +83,7 @@ TDDL_TransmitData( TDDL_BYTE* in,
   }
 
   // read the response
-  size = read (fd, out, TCPA_MAX_BUFFER_LENGTH);
+  size = read (*g_rx_fdp, out, TCPA_MAX_BUFFER_LENGTH);
   if (size < 0) {
     vtpmlogerror(VTPM_LOG_TXDATA, "read() failed");
     ERRORDIE (TPM_IOERROR);
@@ -98,18 +107,20 @@ TPM_RESULT TDDL_Open() {
 TPM_RESULT TDDL_Open() {
   
   TDDL_RESULT status = TDDL_SUCCESS;
-  int fd = -1;
   
   if (g_TDDL_open)
     return TPM_FAIL;
-  
-  fd = open ("/dev/tpm0", O_RDWR);
-  if (fd < 0) {
+
+#ifdef DUMMY_TPM  
+  *g_rx_fdp = open (TPM_RX_FNAME, O_RDWR);
+#endif
+
+  g_tx_fd = open (TPM_TX_FNAME, O_RDWR);
+  if (g_tx_fd < 0) {
     vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed");
     return TPM_IOERROR;
   }
   
-  g_fd = fd;
   g_TDDL_open = 1;
   
   return status;
@@ -119,13 +130,18 @@ void TDDL_Close() {
   if (! g_TDDL_open)
         return;
 
-  if (g_fd>= 0) {
-    if (close(g_fd) < 0) 
+  if (g_tx_fd>= 0) {
+    if (close(g_tx_fd) < 0) 
       vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
-    
-    g_fd = -1;
+    g_tx_fd = -1;
   }
     
+  if (*g_rx_fdp>= 0) {
+    if (close(*g_rx_fdp) < 0) 
+      vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
+    *g_rx_fdp = -1;
+  }
+
   g_TDDL_open = 0;
   
 }
diff -r c4b68afe97d3 -r 4b51d081378d tools/vtpm_manager/util/tcg.h
--- a/tools/vtpm_manager/util/tcg.h     Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/vtpm_manager/util/tcg.h     Wed Jun 28 07:52:21 2006 -0600
@@ -389,6 +389,11 @@ typedef struct pack_constbuf_t {
 #define TPM_DELEGATE_ADMIN      TPM_BASE + 77 // Delegation table management 
not enabled
 #define TPM_TRANSPORT_EXCLUSIVE    TPM_BASE + 78 // There was a command 
executed outside of an exclusive transport session
 
+// TPM_STARTUP_TYPE values
+#define TPM_ST_CLEAR 0x0001
+#define TPM_ST_STATE 0x0002
+#define TPM_ST_DEACTIVATED 0x003
+
 // TPM_TAG values
 #define TPM_TAG_RQU_COMMAND 0x00c1
 #define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
diff -r c4b68afe97d3 -r 4b51d081378d tools/xenstat/xentop/xentop.1
--- a/tools/xenstat/xentop/xentop.1     Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/xenstat/xentop/xentop.1     Wed Jun 28 07:52:21 2006 -0600
@@ -25,6 +25,8 @@
 [\fB\-n\fR]
 [\fB\-r\fR]
 [\fB\-v\fR]
+[\fB\-b\fR]
+[\fB\-i\fRITERATIONS]
 
 .SH DESCRIPTION
 \fBxentop\fR displays information about the Xen system and domains, in a
@@ -50,6 +52,13 @@ repeat table header before each domain
 .TP
 \fB\-v\fR, \fB\-\-vcpus\fR
 output VCPU data
+.TP
+\fB\-b\fR, \fB\-\-batch\fR
+output data in batch mode (to stdout)
+.TP
+\fB\-i\fR, \fB\-\-iterations\fR=\fIITERATIONS\fR
+maximum number of iterations xentop should produce before ending
+
 
 .SH "INTERACTIVE COMMANDS"
 All interactive commands are case-insensitive.
diff -r c4b68afe97d3 -r 4b51d081378d tools/xenstat/xentop/xentop.c
--- a/tools/xenstat/xentop/xentop.c     Wed Jun 28 07:51:52 2006 -0600
+++ b/tools/xenstat/xentop/xentop.c     Wed Jun 28 07:52:21 2006 -0600
@@ -153,6 +153,9 @@ field_id sort_field = FIELD_DOMID;
 field_id sort_field = FIELD_DOMID;
 unsigned int first_domain_index = 0;
 unsigned int delay = 3;
+unsigned int batch = 0;
+unsigned int loop = 1;
+unsigned int iterations = 0;
 int show_vcpus = 0;
 int show_networks = 0;
 int repeat_header = 0;
@@ -179,6 +182,8 @@ static void usage(const char *program)
               "-n, --networks       output vif network data\n"
               "-r, --repeat-header  repeat table header before each domain\n"
               "-v, --vcpus          output vcpu data\n"
+              "-b, --batch          output in batch mode, no user input 
accepted\n"
+              "-i, --iterations     number of iterations before exiting\n"
               "\n" XENTOP_BUGSTO,
               program);
        return;
@@ -236,9 +241,15 @@ static void print(const char *fmt, ...)
 {
        va_list args;
 
-       if(current_row() < lines()-1) {
+       if (!batch) {
+               if((current_row() < lines()-1)) {
+                       va_start(args, fmt);
+                       vw_printw(stdscr, fmt, args);
+                       va_end(args);
+               }
+       } else {
                va_start(args, fmt);
-               vw_printw(stdscr, fmt, args);
+               vprintf(fmt, args);
                va_end(args);
        }
 }
@@ -803,6 +814,7 @@ static void top(void)
                        do_network(domains[i]);
        }
 
+       if(!batch)
        do_bottom_line();
 }
 
@@ -818,9 +830,11 @@ int main(int argc, char **argv)
                { "repeat-header", no_argument,       NULL, 'r' },
                { "vcpus",         no_argument,       NULL, 'v' },
                { "delay",         required_argument, NULL, 'd' },
+               { "batch",         no_argument,       NULL, 'b' },
+               { "iterations",    required_argument, NULL, 'i' },
                { 0, 0, 0, 0 },
        };
-       const char *sopts = "hVbnvd:";
+       const char *sopts = "hVbnvd:bi:";
 
        if (atexit(cleanup) != 0)
                fail("Failed to install cleanup handler.\n");
@@ -847,6 +861,13 @@ int main(int argc, char **argv)
                case 'd':
                        delay = atoi(optarg);
                        break;
+               case 'b':
+                       batch = 1;
+                       break;
+               case 'i':
+                       iterations = atoi(optarg);
+                       loop = 0;
+                       break;
                }
        }
 
@@ -855,28 +876,41 @@ int main(int argc, char **argv)
        if (xhandle == NULL)
                fail("Failed to initialize xenstat library\n");
 
-       /* Begin curses stuff */
-       initscr();
-       start_color();
-       cbreak();
-       noecho();
-       nonl();
-       keypad(stdscr, TRUE);
-       halfdelay(5);
-       use_default_colors();
-       init_pair(1, -1, COLOR_YELLOW);
-
-       do {
-               gettimeofday(&curtime, NULL);
-               if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) {
-                       clear();
-                       top();
-                       oldtime = curtime;
-                       refresh();
-               }
-               ch = getch();
-       } while (handle_key(ch));
-
+       if (!batch) {
+               /* Begin curses stuff */
+               initscr();
+               start_color();
+               cbreak();
+               noecho();
+               nonl();
+               keypad(stdscr, TRUE);
+               halfdelay(5);
+               use_default_colors();
+               init_pair(1, -1, COLOR_YELLOW);
+
+               do {
+                       gettimeofday(&curtime, NULL);
+                       if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= 
delay) {
+                               clear();
+                               top();
+                               oldtime = curtime;
+                               refresh();
+                               if ((!loop) && !(--iterations))
+                                       break;
+                       }
+                       ch = getch();
+               } while (handle_key(ch));
+       } else {
+                       do {
+                               gettimeofday(&curtime, NULL);
+                               top();
+                               oldtime = curtime;
+                               sleep(delay);
+                               if ((!loop) && !(--iterations))
+                                       break;
+                       } while (1);
+       }
+       
        /* Cleanup occurs in cleanup(), so no work to do here. */
 
        return 0;
diff -r c4b68afe97d3 -r 4b51d081378d 
tools/xm-test/tests/info/02_info_compiledata_pos.py
--- a/tools/xm-test/tests/info/02_info_compiledata_pos.py       Wed Jun 28 
07:51:52 2006 -0600
+++ b/tools/xm-test/tests/info/02_info_compiledata_pos.py       Wed Jun 28 
07:52:21 2006 -0600
@@ -24,7 +24,8 @@ for line in lines:
         map[pieces[0]] = pieces[1]
 
 for field in ["cores_per_socket", "threads_per_core", "cpu_mhz",
-              "total_memory", "free_memory", "xen_major", "xen_minor"]:
+              "total_memory", "free_memory", "xen_major", "xen_minor",
+              "xen_pagesize"]:
     val = map[field]
     if not val.isdigit():
         FAIL("Numeric field %s not all-numbers: %s" % (field, val))
diff -r c4b68afe97d3 -r 4b51d081378d xen/Makefile
--- a/xen/Makefile      Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/Makefile      Wed Jun 28 07:52:21 2006 -0600
@@ -14,8 +14,8 @@ default: build
 .PHONY: dist
 dist: install
 
-.PHONY: build install clean cscope TAGS tags
-build install debug clean cscope TAGS tags::
+.PHONY: build install clean distclean cscope TAGS tags
+build install debug clean distclean cscope TAGS tags::
        make -f Rules.mk _$@
 
 .PHONY: _build
@@ -49,6 +49,10 @@ _clean: delete-unfresh-files
        rm -f include/asm *.o $(TARGET)* *~ core
        rm -f include/asm-*/asm-offsets.h
        rm -f include/xen/acm_policy.h
+
+.PHONY: _distclean
+_distclean: clean
+       rm -f tags TAGS cscope.files cscope.in.out cscope.out cscope.po.out
 
 $(TARGET).gz: $(TARGET)
        gzip -f -9 < $< > $@.new
@@ -132,11 +136,11 @@ endef
 
 .PHONY: _TAGS
 _TAGS: 
-       $(all_sources) | etags -
+       rm -f TAGS && $(all_sources) | xargs etags -a
 
 .PHONY: _tags
 _tags: 
-       $(all_sources) | xargs ctags
+       rm -f TAGS && $(all_sources) | xargs ctags -a
 
 .PHONY: _cscope
 _cscope:
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/dom0_ops.c   Wed Jun 28 07:52:21 2006 -0600
@@ -194,6 +194,7 @@ long arch_do_dom0_op(struct dom0_op *op,
         pi->nr_nodes         = 1;
         pi->total_pages      = total_pages;
         pi->free_pages       = avail_domheap_pages();
+        pi->scrub_pages      = avail_scrub_pages();
         pi->cpu_khz          = cpu_khz;
         memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
         memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Wed Jun 28 07:52:21 2006 -0600
@@ -47,7 +47,6 @@
 #include <asm/shadow_64.h>
 #endif
 #include <public/sched.h>
-#include <public/hvm/ioreq.h>
 
 #define SVM_EXTRA_DEBUG
 
@@ -66,8 +65,6 @@ extern int svm_instrlen(struct cpu_user_
 extern int svm_instrlen(struct cpu_user_regs *regs, int mode);
 extern void svm_dump_inst(unsigned long eip);
 extern int svm_dbg_on;
-void svm_manual_event_injection32(struct vcpu *v, struct cpu_user_regs *regs, 
-        int vector, int has_code);
 void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
 
 static void svm_relinquish_guest_resources(struct domain *d);
@@ -215,17 +212,6 @@ static void svm_store_cpu_guest_regs(
 
     if ( regs != NULL )
     {
-#if defined (__x86_64__)
-        regs->rip    = vmcb->rip;
-        regs->rsp    = vmcb->rsp;
-        regs->rflags = vmcb->rflags;
-        regs->cs     = vmcb->cs.sel;
-        regs->ds     = vmcb->ds.sel;
-        regs->es     = vmcb->es.sel;
-        regs->ss     = vmcb->ss.sel;
-        regs->gs     = vmcb->gs.sel;
-        regs->fs     = vmcb->fs.sel;
-#elif defined (__i386__)
         regs->eip    = vmcb->rip;
         regs->esp    = vmcb->rsp;
         regs->eflags = vmcb->rflags;
@@ -235,14 +221,14 @@ static void svm_store_cpu_guest_regs(
         regs->ss     = vmcb->ss.sel;
         regs->gs     = vmcb->gs.sel;
         regs->fs     = vmcb->fs.sel;
-#endif
     }
 
     if ( crs != NULL )
     {
-        crs[0] = vmcb->cr0;
-        crs[3] = vmcb->cr3;
-        crs[4] = vmcb->cr4;
+        /* Returning the guest's regs */
+        crs[0] = v->arch.hvm_svm.cpu_shadow_cr0;
+        crs[3] = v->arch.hvm_svm.cpu_cr3;
+        crs[4] = v->arch.hvm_svm.cpu_shadow_cr4;
     }
 }
 
@@ -258,13 +244,11 @@ static inline int long_mode_do_msr_read(
 {
     u64 msr_content = 0;
     struct vcpu *vc = current;
-    //    struct svm_msr_state *msr = &vc->arch.hvm_svm.msr_content;
     struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
 
     switch (regs->ecx)
     {
     case MSR_EFER:
-        // msr_content = msr->msr_items[SVM_INDEX_MSR_EFER];
         msr_content = vmcb->efer;      
         msr_content &= ~EFER_SVME;
         break;
@@ -813,7 +797,8 @@ void arch_svm_do_resume(struct vcpu *v)
         reset_stack_and_jump( svm_asm_do_resume );
     }
     else {
-        printk("VCPU core pinned: %d to %d\n", 
+        if (svm_dbg_on)
+            printk("VCPU core pinned: %d to %d\n", 
                 v->arch.hvm_svm.launch_core, smp_processor_id() );
         v->arch.hvm_svm.launch_core = smp_processor_id();
         svm_migrate_timers( v );
@@ -1008,6 +993,10 @@ static void svm_vmexit_do_cpuid(struct v
        clear_bit(X86_FEATURE_HT, &edx);  /* clear the hyperthread bit */
        ebx &= 0xFF00FFFF;  /* clear the logical processor count when HTT=0 */
        ebx |= 0x00010000;  /* set to 1 just for precaution */
+
+       /* Disable machine check architecture */
+       clear_bit(X86_FEATURE_MCA, &edx);
+       clear_bit(X86_FEATURE_MCE, &edx);
     }
     else if ( ( input > 0x00000005 ) && ( input < 0x80000000 ) )
     {
@@ -2582,7 +2571,7 @@ void walk_shadow_and_guest_pt(unsigned l
 
     spte = l1e_empty();
 
-    // This is actually overkill - we only need to make sure the hl2 is 
in-sync.
+    /* This is actually overkill - we only need to make sure the hl2 is 
in-sync. */
     shadow_sync_va(v, gva);
 
     gpte.l1 = 0;
@@ -2812,8 +2801,11 @@ asmlinkage void svm_vmexit_handler(struc
     }
 
     case VMEXIT_EXCEPTION_DF:
-        printk("Guest double fault");
-        BUG();
+        /* Debug info to hopefully help debug WHY the guest double-faulted. */
+        svm_dump_vmcb(__func__, vmcb);
+        svm_dump_regs(__func__, &regs);
+        svm_dump_inst(svm_rip2pointer(vmcb));
+        svm_inject_exception(v, TRAP_double_fault, 1, 0);
         break;
 
     case VMEXIT_INTR:
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/hvm/vioapic.c        Wed Jun 28 07:52:21 2006 -0600
@@ -40,6 +40,9 @@
 #include <asm/hvm/support.h>
 #include <asm/current.h>
 
+/* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */
+#define IRQ0_SPECIAL_ROUTING 1
+
 #if defined(__ia64__)
 #define        opt_hvm_debug_level     opt_vmx_debug_level
 #endif
@@ -392,12 +395,12 @@ static void ioapic_deliver(hvm_vioapic_t
     uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
     uint32_t deliver_bitmask;
 
-    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "IOAPIC deliver: "
+    HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
       "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
       dest, dest_mode, delivery_mode, vector, trig_mode);
 
-    deliver_bitmask =
-      ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode);
+    deliver_bitmask = ioapic_get_delivery_bitmask(
+        s, dest, dest_mode, vector, delivery_mode);
 
     if (!deliver_bitmask) {
         HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
@@ -411,15 +414,19 @@ static void ioapic_deliver(hvm_vioapic_t
     {
         struct vlapic* target;
 
-        target = apic_round_robin(
-                s->domain, dest_mode, vector, deliver_bitmask);
+#ifdef IRQ0_SPECIAL_ROUTING
+        if (irqno == 0)
+            target = s->lapic_info[0];
+        else
+#endif
+            target = apic_round_robin(s->domain, dest_mode,
+                                      vector, deliver_bitmask);
         if (target)
             ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
-        else{ 
-            HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
+        else
+            HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
               "null round robin mask %x vector %x delivery_mode %x\n",
               deliver_bitmask, vector, deliver_bitmask);
-        }
         break;
     }
 
@@ -429,6 +436,13 @@ static void ioapic_deliver(hvm_vioapic_t
         uint8_t bit;
         for (bit = 0; bit < s->lapic_count; bit++) {
             if (deliver_bitmask & (1 << bit)) {
+#ifdef IRQ0_SPECIAL_ROUTING
+                if ( (irqno == 0) && (bit !=0) )
+                {
+                    printk("PIT irq to bit %x\n", bit);
+                    domain_crash_synchronous();
+                }
+#endif
                 if (s->lapic_info[bit]) {
                     ioapic_inj_irq(s, s->lapic_info[bit],
                                 vector, trig_mode, delivery_mode);
@@ -450,14 +464,9 @@ static void ioapic_deliver(hvm_vioapic_t
 
 static int ioapic_get_highest_irq(hvm_vioapic_t *s)
 {
-    uint32_t irqs;
-
-    ASSERT(s);
-
-    irqs = s->irr & ~s->isr & ~s->imr;
-    return __fls(irqs);
-}
-
+    uint32_t irqs = s->irr & ~s->isr & ~s->imr;
+    return fls(irqs) - 1;
+}
 
 static void service_ioapic(hvm_vioapic_t *s)
 {
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/hvm/vlapic.c Wed Jun 28 07:52:21 2006 -0600
@@ -50,7 +50,7 @@ int vlapic_find_highest_irr(struct vlapi
 {
     int result;
 
-    result = find_highest_bit((uint32_t *)&vlapic->irr[0], INTR_LEN_32);
+    result = find_highest_bit(vlapic->irr, MAX_VECTOR);
 
     if ( result != -1 && result < 16 )
     {
@@ -79,14 +79,14 @@ int vlapic_find_highest_isr(struct vlapi
 {
     int result;
 
-    result = find_highest_bit((uint32_t *)&vlapic->isr[0], INTR_LEN_32);
+    result = find_highest_bit(vlapic->isr, MAX_VECTOR);
 
     if ( result != -1 && result < 16 )
     {
         int i = 0;
         printk("VLAPIC: isr on reserved bits %d, isr is\n ", result);
-        for ( i = 0; i < INTR_LEN_32; i += 2 )
-            printk("%d: 0x%08x%08x\n", i, vlapic->isr[i], vlapic->isr[i+1]);
+        for ( i = 0; i < ARRAY_SIZE(vlapic->isr); i++ )
+            printk("%d: %p\n", i, (void *)vlapic->isr[i]);
         return -1;
     }
 
@@ -212,18 +212,19 @@ static int vlapic_accept_irq(struct vcpu
 
         if ( test_and_set_bit(vector, &vlapic->irr[0]) )
         {
-            printk("<vlapic_accept_irq>"
-                   "level trig mode repeatedly for vector %d\n", vector);
+            HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
+              "level trig mode repeatedly for vector %d\n", vector);
             break;
         }
 
         if ( level )
         {
-            printk("<vlapic_accept_irq> level trig mode for vector %d\n",
-                   vector);
+            HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
+              "level trig mode for vector %d\n", vector);
             set_bit(vector, &vlapic->tmr[0]);
         }
         evtchn_set_pending(v, iopacket_port(v));
+
         result = 1;
         break;
 
@@ -308,8 +309,15 @@ struct vlapic* apic_round_robin(struct d
 
     old = next = d->arch.hvm_domain.round_info[vector];
 
-    do {
-        /* the vcpu array is arranged according to vcpu_id */
+    /* the vcpu array is arranged according to vcpu_id */
+    do
+    {
+        next++;
+        if ( !d->vcpu[next] ||
+             !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) ||
+             next == MAX_VIRT_CPUS )
+            next = 0;
+
         if ( test_bit(next, &bitmap) )
         {
             target = d->vcpu[next]->arch.hvm_vcpu.vlapic;
@@ -321,12 +329,6 @@ struct vlapic* apic_round_robin(struct d
             }
             break;
         }
-
-        next ++;
-        if ( !d->vcpu[next] ||
-             !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) ||
-             next == MAX_VIRT_CPUS )
-            next = 0;
     } while ( next != old );
 
     d->arch.hvm_domain.round_info[vector] = next;
@@ -896,7 +898,7 @@ vlapic_check_direct_intr(struct vcpu *v,
     struct vlapic *vlapic = VLAPIC(v);
     int type;
 
-    type = __fls(vlapic->direct_intr.deliver_mode);
+    type = fls(vlapic->direct_intr.deliver_mode) - 1;
     if ( type == -1 )
         return -1;
 
@@ -956,7 +958,7 @@ int cpu_has_apic_interrupt(struct vcpu* 
     }
     return 0;
 }
- 
+
 void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode)
 {
     struct vlapic *vlapic = VLAPIC(v);
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Jun 28 07:52:21 2006 -0600
@@ -337,6 +337,7 @@ static void vmx_restore_msrs(struct vcpu
         clear_bit(i, &guest_flags);
     }
 }
+
 #else  /* __i386__ */
 
 #define vmx_save_segments(v)      ((void)0)
@@ -355,6 +356,63 @@ static inline int long_mode_do_msr_write
 }
 
 #endif /* __i386__ */
+
+#define loaddebug(_v,_reg) \
+    __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
+#define savedebug(_v,_reg) \
+    __asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r" 
((_v)->debugreg[_reg]))
+
+static inline void vmx_save_dr(struct vcpu *v)
+{
+    if ( v->arch.hvm_vcpu.flag_dr_dirty )
+    {
+        savedebug(&v->arch.guest_context, 0);
+        savedebug(&v->arch.guest_context, 1);
+        savedebug(&v->arch.guest_context, 2);
+        savedebug(&v->arch.guest_context, 3);
+        savedebug(&v->arch.guest_context, 6);
+        
+        v->arch.hvm_vcpu.flag_dr_dirty = 0;
+
+        v->arch.hvm_vcpu.u.vmx.exec_control |= CPU_BASED_MOV_DR_EXITING;
+        __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
+                  v->arch.hvm_vcpu.u.vmx.exec_control);
+    }
+}
+
+static inline void __restore_debug_registers(struct vcpu *v)
+{
+    loaddebug(&v->arch.guest_context, 0);
+    loaddebug(&v->arch.guest_context, 1);
+    loaddebug(&v->arch.guest_context, 2);
+    loaddebug(&v->arch.guest_context, 3);
+    /* No 4 and 5 */
+    loaddebug(&v->arch.guest_context, 6);
+    /* DR7 is loaded from the vmcs. */
+}
+
+/*
+ * DR7 is saved and restored on every vmexit.  Other debug registers only
+ * need to be restored if their value is going to affect execution -- i.e.,
+ * if one of the breakpoints is enabled.  So mask out all bits that don't
+ * enable some breakpoint functionality.
+ *
+ * This is in part necessary because bit 10 of DR7 is hardwired to 1, so a
+ * simple if( guest_dr7 ) will always return true.  As long as we're masking,
+ * we might as well do it right.
+ */
+#define DR7_ACTIVE_MASK 0xff
+
+static inline void vmx_restore_dr(struct vcpu *v)
+{
+    unsigned long guest_dr7;
+
+    __vmread(GUEST_DR7, &guest_dr7);
+
+    /* Assumes guest does not have DR access at time of context switch. */
+    if ( unlikely(guest_dr7 & DR7_ACTIVE_MASK) )
+        __restore_debug_registers(v);
+}
 
 static void vmx_freeze_time(struct vcpu *v)
 {
@@ -371,11 +429,13 @@ static void vmx_ctxt_switch_from(struct 
     vmx_freeze_time(v);
     vmx_save_segments(v);
     vmx_load_msrs();
+    vmx_save_dr(v);
 }
 
 static void vmx_ctxt_switch_to(struct vcpu *v)
 {
     vmx_restore_msrs(v);
+    vmx_restore_dr(v);
 }
 
 void stop_vmx(void)
@@ -866,55 +926,20 @@ static void vmx_vmexit_do_cpuid(struct c
     CASE_GET_REG_P(R15, r15)
 #endif
 
-static void vmx_dr_access (unsigned long exit_qualification, struct 
cpu_user_regs *regs)
-{
-    unsigned int reg;
-    unsigned long *reg_p = 0;
+static void vmx_dr_access(unsigned long exit_qualification,
+                          struct cpu_user_regs *regs)
+{
     struct vcpu *v = current;
-    unsigned long eip;
-
-    __vmread(GUEST_RIP, &eip);
-
-    reg = exit_qualification & DEBUG_REG_ACCESS_NUM;
-
-    HVM_DBG_LOG(DBG_LEVEL_1,
-                "vmx_dr_access : eip=%lx, reg=%d, exit_qualification = %lx",
-                eip, reg, exit_qualification);
-
-    switch ( exit_qualification & DEBUG_REG_ACCESS_REG ) {
-    CASE_GET_REG_P(EAX, eax);
-    CASE_GET_REG_P(ECX, ecx);
-    CASE_GET_REG_P(EDX, edx);
-    CASE_GET_REG_P(EBX, ebx);
-    CASE_GET_REG_P(EBP, ebp);
-    CASE_GET_REG_P(ESI, esi);
-    CASE_GET_REG_P(EDI, edi);
-    CASE_EXTEND_GET_REG_P;
-    case REG_ESP:
-        break;
-    default:
-        __hvm_bug(regs);
-    }
-
-    switch (exit_qualification & DEBUG_REG_ACCESS_TYPE) {
-    case TYPE_MOV_TO_DR:
-        /* don't need to check the range */
-        if (reg != REG_ESP)
-            v->arch.guest_context.debugreg[reg] = *reg_p;
-        else {
-            unsigned long value;
-            __vmread(GUEST_RSP, &value);
-            v->arch.guest_context.debugreg[reg] = value;
-        }
-        break;
-    case TYPE_MOV_FROM_DR:
-        if (reg != REG_ESP)
-            *reg_p = v->arch.guest_context.debugreg[reg];
-        else {
-            __vmwrite(GUEST_RSP, v->arch.guest_context.debugreg[reg]);
-        }
-        break;
-    }
+
+    v->arch.hvm_vcpu.flag_dr_dirty = 1;
+
+    /* We could probably be smarter about this */
+    __restore_debug_registers(v);
+
+    /* Allow guest direct access to DR registers */
+    v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_MOV_DR_EXITING;
+    __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
+              v->arch.hvm_vcpu.u.vmx.exec_control);
 }
 
 /*
@@ -2080,10 +2105,19 @@ asmlinkage void vmx_vmexit_handler(struc
         {
             void store_cpu_user_regs(struct cpu_user_regs *regs);
 
-            store_cpu_user_regs(&regs);
-            __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS, PENDING_DEBUG_EXC_BS);
-
-            domain_pause_for_debugger();
+            if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
+            {
+                store_cpu_user_regs(&regs);
+                domain_pause_for_debugger();
+                __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS,
+                               PENDING_DEBUG_EXC_BS);
+            }
+            else
+            {
+                vmx_reflect_exception(v);
+                __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS,
+                               PENDING_DEBUG_EXC_BS);
+            }
 
             break;
         }
@@ -2139,9 +2173,17 @@ asmlinkage void vmx_vmexit_handler(struc
         vmx_vmexit_do_extint(&regs);
         break;
     case EXIT_REASON_PENDING_INTERRUPT:
+        /*
+         * Not sure exactly what the purpose of this is.  The only bits set
+         * and cleared at this point are CPU_BASED_VIRTUAL_INTR_PENDING.
+         * (in io.c:{enable,disable}_irq_window().  So presumably we want to
+         * set it to the original value...
+         */
+        v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+        v->arch.hvm_vcpu.u.vmx.exec_control |=
+            (MONITOR_CPU_BASED_EXEC_CONTROLS & CPU_BASED_VIRTUAL_INTR_PENDING);
         __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
-                  MONITOR_CPU_BASED_EXEC_CONTROLS);
-        v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS;
+                  v->arch.hvm_vcpu.u.vmx.exec_control);
         break;
     case EXIT_REASON_TASK_SWITCH:
         __hvm_bug(&regs);
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/microcode.c
--- a/xen/arch/x86/microcode.c  Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/microcode.c  Wed Jun 28 07:52:21 2006 -0600
@@ -83,9 +83,9 @@
 #include <asm/processor.h>
 
 #define pr_debug(x...) ((void)0)
-#define DECLARE_MUTEX(_m) DEFINE_SPINLOCK(_m)
-#define down(_m) spin_lock(_m)
-#define up(_m) spin_unlock(_m)
+#define DEFINE_MUTEX(_m) DEFINE_SPINLOCK(_m)
+#define mutex_lock(_m) spin_lock(_m)
+#define mutex_unlock(_m) spin_unlock(_m)
 #define vmalloc(_s) xmalloc_bytes(_s)
 #define vfree(_p) xfree(_p)
 
@@ -95,7 +95,10 @@ MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 #endif
 
-#define MICROCODE_VERSION      "1.14"
+static int verbose;
+boolean_param("microcode.verbose", verbose);
+
+#define MICROCODE_VERSION      "1.14a"
 
 #define DEFAULT_UCODE_DATASIZE         (2000)    /* 2000 bytes */
 #define MC_HEADER_SIZE         (sizeof (microcode_header_t))     /* 48 bytes */
@@ -119,21 +122,22 @@ static DEFINE_SPINLOCK(microcode_update_
 static DEFINE_SPINLOCK(microcode_update_lock);
 
 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
-static DECLARE_MUTEX(microcode_sem);
+static DEFINE_MUTEX(microcode_mutex);
 
 static void __user *user_buffer;       /* user area microcode data buffer */
 static unsigned int user_buffer_size;  /* it's size */
 
 typedef enum mc_error_code {
        MC_SUCCESS      = 0,
-       MC_NOTFOUND     = 1,
-       MC_MARKED       = 2,
-       MC_ALLOCATED    = 3,
+       MC_IGNORED      = 1,
+       MC_NOTFOUND     = 2,
+       MC_MARKED       = 3,
+       MC_ALLOCATED    = 4,
 } mc_error_code_t;
 
 static struct ucode_cpu_info {
        unsigned int sig;
-       unsigned int pf;
+       unsigned int pf, orig_pf;
        unsigned int rev;
        unsigned int cksum;
        mc_error_code_t err;
@@ -163,6 +167,7 @@ static void collect_cpu_info (void *unus
                        rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
                        uci->pf = 1 << ((val[1] >> 18) & 7);
                }
+               uci->orig_pf = uci->pf;
        }
 
        wrmsr(MSR_IA32_UCODE_REV, 0, 0);
@@ -196,23 +201,34 @@ static inline void mark_microcode_update
        pr_debug("   Checksum 0x%x\n", cksum);
 
        if (mc_header->rev < uci->rev) {
-               printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier 
revision"
-                      " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, 
uci->rev);
-               goto out;
+               if (uci->err == MC_NOTFOUND) {
+                       uci->err = MC_IGNORED;
+                       uci->cksum = mc_header->rev;
+               } else if (uci->err == MC_IGNORED && uci->cksum < 
mc_header->rev)
+                       uci->cksum = mc_header->rev;
        } else if (mc_header->rev == uci->rev) {
-               /* notify the caller of success on this cpu */
-               uci->err = MC_SUCCESS;
-               printk(KERN_ERR "microcode: CPU%d already at revision"
-                       " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, 
uci->rev);
-               goto out;
-       }
-
-       pr_debug("microcode: CPU%d found a matching microcode update with "
-               " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, 
uci->rev);
-       uci->cksum = cksum;
-       uci->pf = pf; /* keep the original mc pf for cksum calculation */
-       uci->err = MC_MARKED; /* found the match */
-out:
+               if (uci->err < MC_MARKED) {
+                       /* notify the caller of success on this cpu */
+                       uci->err = MC_SUCCESS;
+               }
+       } else if (uci->err != MC_ALLOCATED || mc_header->rev > 
uci->mc->hdr.rev) {
+               pr_debug("microcode: CPU%d found a matching microcode update 
with "
+                       " revision 0x%x (current=0x%x)\n", cpu_num, 
mc_header->rev, uci->rev);
+               uci->cksum = cksum;
+               uci->pf = pf; /* keep the original mc pf for cksum calculation 
*/
+               uci->err = MC_MARKED; /* found the match */
+               for_each_online_cpu(cpu_num) {
+                       if (ucode_cpu_info + cpu_num != uci
+                           && ucode_cpu_info[cpu_num].mc == uci->mc) {
+                               uci->mc = NULL;
+                               break;
+                       }
+               }
+               if (uci->mc != NULL) {
+                       vfree(uci->mc);
+                       uci->mc = NULL;
+               }
+       }
        return;
 }
 
@@ -251,13 +267,11 @@ static int find_matching_ucodes (void)
                        error = -EINVAL;
                        goto out;
                }
-               
-               for (cpu_num = 0; cpu_num < num_online_cpus(); cpu_num++) {
+
+               for_each_online_cpu(cpu_num) {
                        struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
-                       if (uci->err != MC_NOTFOUND) /* already found a match 
or not an online cpu*/
-                               continue;
-
-                       if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, 
uci->pf))
+
+                       if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, 
uci->orig_pf))
                                mark_microcode_update(cpu_num, &mc_header, 
mc_header.sig, mc_header.pf, mc_header.cksum);
                }
 
@@ -294,18 +308,19 @@ static int find_matching_ucodes (void)
                                        error = -EFAULT;
                                        goto out;
                                }
-                               for (cpu_num = 0; cpu_num < num_online_cpus(); 
cpu_num++) {
+                               for_each_online_cpu(cpu_num) {
                                        struct ucode_cpu_info *uci = 
ucode_cpu_info + cpu_num;
-                                       if (uci->err != MC_NOTFOUND) /* already 
found a match or not an online cpu*/
-                                               continue;
-                                       if (sigmatch(ext_sig.sig, uci->sig, 
ext_sig.pf, uci->pf)) {
+
+                                       if (sigmatch(ext_sig.sig, uci->sig, 
ext_sig.pf, uci->orig_pf)) {
                                                mark_microcode_update(cpu_num, 
&mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum);
                                        }
                                }
                        }
                }
                /* now check if any cpu has matched */
-               for (cpu_num = 0, allocated_flag = 0, sum = 0; cpu_num < 
num_online_cpus(); cpu_num++) {
+               allocated_flag = 0;
+               sum = 0;
+               for_each_online_cpu(cpu_num) {
                        if (ucode_cpu_info[cpu_num].err == MC_MARKED) { 
                                struct ucode_cpu_info *uci = ucode_cpu_info + 
cpu_num;
                                if (!allocated_flag) {
@@ -367,7 +382,13 @@ static void do_update_one (void * unused
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
 
        if (uci->mc == NULL) {
-               printk(KERN_INFO "microcode: No new microcode data for 
CPU%d\n", cpu_num);
+               if (verbose) {
+                       if (uci->err == MC_SUCCESS)
+                               printk(KERN_INFO "microcode: CPU%d already at 
revision 0x%x\n",
+                                       cpu_num, uci->rev);
+                       else
+                               printk(KERN_INFO "microcode: No new microcode 
data for CPU%d\n", cpu_num);
+               }
                return;
        }
 
@@ -416,16 +437,19 @@ static int do_microcode_update (void)
        }
 
 out_free:
-       for (i = 0; i < num_online_cpus(); i++) {
+       for_each_online_cpu(i) {
                if (ucode_cpu_info[i].mc) {
                        int j;
                        void *tmp = ucode_cpu_info[i].mc;
                        vfree(tmp);
-                       for (j = i; j < num_online_cpus(); j++) {
+                       for_each_online_cpu(j) {
                                if (ucode_cpu_info[j].mc == tmp)
                                        ucode_cpu_info[j].mc = NULL;
                        }
                }
+               if (ucode_cpu_info[i].err == MC_IGNORED && verbose)
+                       printk(KERN_WARNING "microcode: CPU%d not 'upgrading' 
to earlier revision"
+                              " 0x%x (current=0x%x)\n", i, 
ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev);
        }
 out:
        return error;
@@ -433,21 +457,21 @@ out:
 
 int microcode_update(void *buf, unsigned long len)
 {
-    int ret;
-
-    if (len < DEFAULT_UCODE_TOTALSIZE) {
-        printk(KERN_ERR "microcode: not enough data\n"); 
-        return -EINVAL;
-    }
-
-    down(&microcode_sem);
-    
-    user_buffer = (void __user *) buf;
-    user_buffer_size = (int) len;
-    
-    ret = do_microcode_update();
-    
-    up(&microcode_sem);
-    
-    return ret;
-}
+       int ret;
+
+       if (len < DEFAULT_UCODE_TOTALSIZE) {
+               printk(KERN_ERR "microcode: not enough data\n"); 
+               return -EINVAL;
+       }
+
+       mutex_lock(&microcode_mutex);
+
+       user_buffer = (void __user *) buf;
+       user_buffer_size = (int) len;
+
+       ret = do_microcode_update();
+
+       mutex_unlock(&microcode_mutex);
+
+       return ret;
+}
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c   Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/oprofile/nmi_int.c   Wed Jun 28 07:52:21 2006 -0600
@@ -269,7 +269,7 @@ static int __init p4_init(char * cpu_typ
 { 
        __u8 cpu_model = current_cpu_data.x86_model;
 
-       if (cpu_model > 4)
+       if ((cpu_model > 6) || (cpu_model == 5))
                return 0;
 
 #ifndef CONFIG_SMP
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c  Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/oprofile/xenoprof.c  Wed Jun 28 07:52:21 2006 -0600
@@ -13,9 +13,13 @@
 /* Limit amount of pages used for shared buffer (per domain) */
 #define MAX_OPROF_SHARED_PAGES 32
 
-domid_t active_domains[MAX_OPROF_DOMAINS];
+struct domain *active_domains[MAX_OPROF_DOMAINS];
 int active_ready[MAX_OPROF_DOMAINS];
 unsigned int adomains;
+
+struct domain *passive_domains[MAX_OPROF_DOMAINS];
+unsigned int pdomains;
+
 unsigned int activated;
 struct domain *primary_profiler;
 int xenoprof_state = XENOPROF_IDLE;
@@ -25,6 +29,7 @@ u64 corrupted_buffer_samples;
 u64 corrupted_buffer_samples;
 u64 lost_samples;
 u64 active_samples;
+u64 passive_samples;
 u64 idle_samples;
 u64 others_samples;
 
@@ -44,9 +49,15 @@ int is_active(struct domain *d)
     return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_ACTIVE));
 }
 
+int is_passive(struct domain *d)
+{
+    struct xenoprof *x = d->xenoprof;
+    return ((x != NULL) && (x->domain_type == XENOPROF_DOMAIN_PASSIVE));
+}
+
 int is_profiled(struct domain *d)
 {
-    return is_active(d);
+    return (is_active(d) || is_passive(d));
 }
 
 static void xenoprof_reset_stat(void)
@@ -56,6 +67,7 @@ static void xenoprof_reset_stat(void)
     corrupted_buffer_samples = 0;
     lost_samples = 0;
     active_samples = 0;
+    passive_samples = 0;
     idle_samples = 0;
     others_samples = 0;
 }
@@ -83,13 +95,122 @@ static void xenoprof_reset_buf(struct do
     }
 }
 
+char *alloc_xenoprof_buf(struct domain *d, int npages)
+{
+    char *rawbuf;
+    int i, order;
+
+    /* allocate pages to store sample buffer shared with domain */
+    order  = get_order_from_pages(npages);
+    rawbuf = alloc_xenheap_pages(order);
+    if ( rawbuf == NULL )
+    {
+        printk("alloc_xenoprof_buf(): memory allocation failed\n");
+        return 0;
+    }
+
+    /* Share pages so that kernel can map it */
+    for ( i = 0; i < npages; i++ )
+        share_xen_page_with_guest(
+            virt_to_page(rawbuf + i * PAGE_SIZE), 
+            d, XENSHARE_writable);
+
+    return rawbuf;
+}
+
+int alloc_xenoprof_struct(struct domain *d, int max_samples, int is_passive)
+{
+    struct vcpu *v;
+    int nvcpu, npages, bufsize, max_bufsize;
+    int i;
+
+    d->xenoprof = xmalloc(struct xenoprof);
+
+    if ( d->xenoprof == NULL )
+    {
+        printk ("alloc_xenoprof_struct(): memory "
+                "allocation (xmalloc) failed\n");
+        return -ENOMEM;
+    }
+
+    memset(d->xenoprof, 0, sizeof(*d->xenoprof));
+
+    nvcpu = 0;
+    for_each_vcpu ( d, v )
+        nvcpu++;
+
+    /* reduce buffer size if necessary to limit pages allocated */
+    bufsize = sizeof(struct xenoprof_buf) +
+        (max_samples - 1) * sizeof(struct event_log);
+    max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu;
+    if ( bufsize > max_bufsize )
+    {
+        bufsize = max_bufsize;
+        max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) /
+                        sizeof(struct event_log) ) + 1;
+    }
+
+    npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
+    
+    d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages);
+
+    if ( d->xenoprof->rawbuf == NULL )
+    {
+        xfree(d->xenoprof);
+        d->xenoprof = NULL;
+        return -ENOMEM;
+    }
+
+    d->xenoprof->npages = npages;
+    d->xenoprof->nbuf = nvcpu;
+    d->xenoprof->bufsize = bufsize;
+    d->xenoprof->domain_ready = 0;
+    d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED;
+
+    /* Update buffer pointers for active vcpus */
+    i = 0;
+    for_each_vcpu ( d, v )
+    {
+        d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
+        d->xenoprof->vcpu[v->vcpu_id].buffer =
+            (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize];
+        d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples;
+        d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id;
+
+        i++;
+        /* in the unlikely case that the number of active vcpus changes */
+        if ( i >= nvcpu )
+            break;
+    }
+    
+    return 0;
+}
+
+void free_xenoprof_pages(struct domain *d)
+{
+    struct xenoprof *x;
+    int order;
+
+    x = d->xenoprof;
+    if ( x == NULL )
+        return;
+
+    if ( x->rawbuf != NULL )
+    {
+        order = get_order_from_pages(x->npages);
+        free_xenheap_pages(x->rawbuf, order);
+    }
+
+    xfree(x);
+    d->xenoprof = NULL;
+}
+
 int active_index(struct domain *d)
 {
     int i;
-    domid_t id = d->domain_id;
 
     for ( i = 0; i < adomains; i++ )
-        if ( active_domains[i] == id )
+        if ( active_domains[i] == d )
             return i;
 
     return -1;
@@ -132,47 +253,116 @@ int reset_active(struct domain *d)
     x->domain_ready = 0;
     x->domain_type = XENOPROF_DOMAIN_IGNORED;
     active_ready[ind] = 0;
+    active_domains[ind] = NULL;
     activated--;
+    put_domain(d); 
+
     if ( activated <= 0 )
         adomains = 0;
 
     return 0;
 }
 
-int reset_active_list(void)
+void reset_passive(struct domain *d)
+{
+    struct xenoprof *x;
+
+    if (d==0)
+        return;
+
+    x = d->xenoprof;
+    if ( x == NULL )
+        return;
+
+    x->domain_type = XENOPROF_DOMAIN_IGNORED;
+
+    return;
+}
+
+void reset_active_list(void)
 {
     int i;
-    struct domain *d;
 
     for ( i = 0; i < adomains; i++ )
     {
         if ( active_ready[i] )
         {
-            d = find_domain_by_id(active_domains[i]);
-            if ( d != NULL )
-            {
-                reset_active(d);
-                put_domain(d);
-            }
+            reset_active(active_domains[i]);
         }
     }
 
     adomains = 0;
     activated = 0;
-
-    return 0;
+}
+
+void reset_passive_list(void)
+{
+    int i;
+
+    for ( i = 0; i < pdomains; i++ )
+    {
+        reset_passive(passive_domains[i]);
+        put_domain(passive_domains[i]);
+        passive_domains[i] = NULL;
+    }
+
+    pdomains = 0;
 }
 
 int add_active_list (domid_t domid)
 {
+    struct domain *d;
+
     if ( adomains >= MAX_OPROF_DOMAINS )
         return -E2BIG;
 
-    active_domains[adomains] = domid;
+    d = find_domain_by_id(domid); 
+    if ( d == NULL )
+        return -EINVAL;
+
+    active_domains[adomains] = d;
     active_ready[adomains] = 0;
     adomains++;
 
     return 0;
+}
+
+int add_passive_list(XEN_GUEST_HANDLE(void) arg)
+{
+    struct xenoprof_passive passive;
+    struct domain *d;
+    int ret = 0;
+
+    if ( pdomains >= MAX_OPROF_DOMAINS )
+        return -E2BIG;
+
+    if ( copy_from_guest(&passive, arg, 1) )
+        return -EFAULT;
+
+    d = find_domain_by_id(passive.domain_id); 
+    if ( d == NULL )
+        return -EINVAL;
+
+    if ( (d->xenoprof == NULL) && 
+         ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) ) {
+        put_domain(d);
+        return -ENOMEM;
+    }
+
+    d->xenoprof->domain_type = XENOPROF_DOMAIN_PASSIVE;
+    passive.nbuf = d->xenoprof->nbuf;
+    passive.bufsize = d->xenoprof->bufsize;
+    passive.buf_maddr = __pa(d->xenoprof->rawbuf);
+
+    if ( copy_to_guest(arg, &passive, 1) ) {
+        put_domain(d);
+        return -EFAULT;
+    }
+    
+    passive_domains[pdomains] = d;
+    pdomains++;
+
+    return ret;
 }
 
 void xenoprof_log_event(
@@ -231,7 +421,10 @@ void xenoprof_log_event(
         if ( head >= size )
             head = 0;
         buf->event_head = head;
-        active_samples++;
+        if ( is_active(vcpu->domain) )
+            active_samples++;
+        else
+            passive_samples++;
         if ( mode == 0 )
             buf->user_samples++;
         else if ( mode == 1 )
@@ -241,114 +434,6 @@ void xenoprof_log_event(
     }
 }
 
-char *alloc_xenoprof_buf(struct domain *d, int npages)
-{
-    char *rawbuf;
-    int i, order;
-
-    /* allocate pages to store sample buffer shared with domain */
-    order  = get_order_from_pages(npages);
-    rawbuf = alloc_xenheap_pages(order);
-    if ( rawbuf == NULL )
-    {
-        printk("alloc_xenoprof_buf(): memory allocation failed\n");
-        return 0;
-    }
-
-    /* Share pages so that kernel can map it */
-    for ( i = 0; i < npages; i++ )
-        share_xen_page_with_guest(
-            virt_to_page(rawbuf + i * PAGE_SIZE), 
-            d, XENSHARE_writable);
-
-    return rawbuf;
-}
-
-int alloc_xenoprof_struct(struct domain *d, int max_samples)
-{
-    struct vcpu *v;
-    int nvcpu, npages, bufsize, max_bufsize;
-    int i;
-
-    d->xenoprof = xmalloc(struct xenoprof);
-
-    if ( d->xenoprof == NULL )
-    {
-        printk ("alloc_xenoprof_struct(): memory "
-                "allocation (xmalloc) failed\n");
-        return -ENOMEM;
-    }
-
-    memset(d->xenoprof, 0, sizeof(*d->xenoprof));
-
-    nvcpu = 0;
-    for_each_vcpu ( d, v )
-        nvcpu++;
-
-    /* reduce buffer size if necessary to limit pages allocated */
-    bufsize = sizeof(struct xenoprof_buf) +
-        (max_samples - 1) * sizeof(struct event_log);
-    max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu;
-    if ( bufsize > max_bufsize )
-    {
-        bufsize = max_bufsize;
-        max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) /
-                        sizeof(struct event_log) ) + 1;
-    }
-
-    npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
-    d->xenoprof->rawbuf = alloc_xenoprof_buf(d, npages);
-    if ( d->xenoprof->rawbuf == NULL )
-    {
-        xfree(d->xenoprof);
-        d->xenoprof = NULL;
-        return -ENOMEM;
-    }
-
-    d->xenoprof->npages = npages;
-    d->xenoprof->nbuf = nvcpu;
-    d->xenoprof->bufsize = bufsize;
-    d->xenoprof->domain_ready = 0;
-    d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED;
-
-    /* Update buffer pointers for active vcpus */
-    i = 0;
-    for_each_vcpu ( d, v )
-    {
-        d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
-        d->xenoprof->vcpu[v->vcpu_id].buffer =
-            (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize];
-        d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples;
-        d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id;
-
-        i++;
-        /* in the unlikely case that the number of active vcpus changes */
-        if ( i >= nvcpu )
-            break;
-    }
-
-    return 0;
-}
-
-void free_xenoprof_pages(struct domain *d)
-{
-    struct xenoprof *x;
-    int order;
-
-    x = d->xenoprof;
-    if ( x == NULL )
-        return;
-
-    if ( x->rawbuf != NULL )
-    {
-        order = get_order_from_pages(x->npages);
-        free_xenheap_pages(x->rawbuf, order);
-    }
-
-    xfree(x);
-    d->xenoprof = NULL;
-}
-
 int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg)
 {
     struct xenoprof_init xenoprof_init;
@@ -373,7 +458,7 @@ int xenoprof_op_init(XEN_GUEST_HANDLE(vo
      * is called. Memory is then kept until domain is destroyed.
      */
     if ( (d->xenoprof == NULL) &&
-         ((ret = alloc_xenoprof_struct(d, xenoprof_init.max_samples)) < 0) )
+         ((ret = alloc_xenoprof_struct(d, xenoprof_init.max_samples, 0)) < 0) )
         goto err;
 
     xenoprof_reset_buf(d);
@@ -429,7 +514,14 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
 
     case XENOPROF_reset_active_list:
     {
-        ret = reset_active_list();
+        reset_active_list();
+        ret = 0;
+        break;
+    }
+    case XENOPROF_reset_passive_list:
+    {
+        reset_passive_list();
+        ret = 0;
         break;
     }
     case XENOPROF_set_active:
@@ -440,6 +532,13 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         if ( copy_from_guest(&domid, arg, 1) )
             return -EFAULT;
         ret = add_active_list(domid);
+        break;
+    }
+    case XENOPROF_set_passive:
+    {
+        if ( xenoprof_state != XENOPROF_IDLE )
+            return -EPERM;
+        ret = add_passive_list(arg);
         break;
     }
     case XENOPROF_reserve_counters:
@@ -484,14 +583,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         break;
 
     case XENOPROF_enable_virq:
+    {
+        int i;
         if ( current->domain == primary_profiler )
         {
             nmi_enable_virq();
             xenoprof_reset_stat();
+            for ( i = 0; i < pdomains; i++ ) {
+                xenoprof_reset_buf(passive_domains[i]);
+            }
         }
         xenoprof_reset_buf(current->domain);
         ret = set_active(current->domain);
         break;
+    }
 
     case XENOPROF_start:
         ret = -EPERM;
@@ -525,6 +630,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
             xenoprof_state = XENOPROF_IDLE;
             nmi_release_counters();
             nmi_disable_virq();
+            reset_passive_list();
             ret = 0;
         }
         break;
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c        Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/smp.c        Wed Jun 28 07:52:21 2006 -0600
@@ -302,8 +302,9 @@ int on_selected_cpus(
 
 static void stop_this_cpu (void *dummy)
 {
-    clear_bit(smp_processor_id(), &cpu_online_map);
-
+    cpu_clear(smp_processor_id(), cpu_online_map);
+
+    local_irq_disable();
     disable_local_APIC();
 
     for ( ; ; )
diff -r c4b68afe97d3 -r 4b51d081378d xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/arch/x86/x86_emulate.c        Wed Jun 28 07:52:21 2006 -0600
@@ -374,9 +374,8 @@ do{ __asm__ __volatile__ (              
 
 /* Access/update address held in a register, based on addressing mode. */
 #define register_address(sel, reg)                                      \
-    ((ad_bytes == sizeof(unsigned long)) ? (reg) :                      \
-     ((mode == X86EMUL_MODE_REAL) ? /* implies ad_bytes == 2 */         \
-      (((unsigned long)(sel) << 4) + ((reg) & 0xffff)) :                \
+    (((mode == X86EMUL_MODE_REAL) ? ((unsigned long)(sel) << 4) : 0) +  \
+     ((ad_bytes == sizeof(unsigned long)) ? (reg) :                     \
       ((reg) & ((1UL << (ad_bytes << 3)) - 1))))
 #define register_address_increment(reg, inc)                            \
 do {                                                                    \
@@ -510,10 +509,6 @@ x86_emulate_memop(
     }
  done_prefixes:
 
-    /* Note quite the same as 80386 real mode, but hopefully good enough. */
-    if ( (mode == X86EMUL_MODE_REAL) && (ad_bytes != 2) )
-        goto cannot_emulate;
-
     /* REX prefix. */
     if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
     {
diff -r c4b68afe97d3 -r 4b51d081378d xen/common/kernel.c
--- a/xen/common/kernel.c       Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/common/kernel.c       Wed Jun 28 07:52:21 2006 -0600
@@ -212,6 +212,11 @@ long do_xen_version(int cmd, XEN_GUEST_H
         return 0;
     }
 
+    case XENVER_pagesize:
+    {
+        return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE);
+    }
+
     }
 
     return -ENOSYS;
diff -r c4b68afe97d3 -r 4b51d081378d xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/common/page_alloc.c   Wed Jun 28 07:52:21 2006 -0600
@@ -61,6 +61,7 @@ custom_param("lowmem_emergency_pool", pa
 
 static DEFINE_SPINLOCK(page_scrub_lock);
 LIST_HEAD(page_scrub_list);
+static unsigned long scrub_pages;
 
 /*********************
  * ALLOCATION BITMAP
@@ -696,6 +697,7 @@ void free_domheap_pages(struct page_info
             {
                 spin_lock(&page_scrub_lock);
                 list_add(&pg[i].list, &page_scrub_list);
+                scrub_pages++;
                 spin_unlock(&page_scrub_lock);
             }
         }
@@ -784,9 +786,10 @@ static void page_scrub_softirq(void)
         /* Remove peeled pages from the list. */
         ent->next->prev = &page_scrub_list;
         page_scrub_list.next = ent->next;
-        
+        scrub_pages -= (i+1);
+
         spin_unlock(&page_scrub_lock);
-        
+
         /* Working backwards, scrub each page in turn. */
         while ( ent != &page_scrub_list )
         {
@@ -798,6 +801,11 @@ static void page_scrub_softirq(void)
             free_heap_pages(pfn_dom_zone_type(page_to_mfn(pg)), pg, 0);
         }
     } while ( (NOW() - start) < MILLISECS(1) );
+}
+
+unsigned long avail_scrub_pages(void)
+{
+    return scrub_pages;
 }
 
 static __init int page_scrub_init(void)
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/asm-x86/bitops.h
--- a/xen/include/asm-x86/bitops.h      Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/asm-x86/bitops.h      Wed Jun 28 07:52:21 2006 -0600
@@ -335,8 +335,6 @@ static inline unsigned long ffz(unsigned
        return word;
 }
 
-#define fls64(x)   generic_fls64(x)
-
 /**
  * ffs - find first bit set
  * @x: the word to search
@@ -345,15 +343,15 @@ static inline unsigned long ffz(unsigned
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-static inline int ffs(int x)
-{
-       int r;
-
-       __asm__("bsfl %1,%0\n\t"
+static inline int ffs(unsigned long x)
+{
+       long r;
+
+       __asm__("bsf %1,%0\n\t"
                "jnz 1f\n\t"
-               "movl $-1,%0\n"
+               "mov $-1,%0\n"
                "1:" : "=r" (r) : "rm" (x));
-       return r+1;
+       return (int)r+1;
 }
 
 /**
@@ -362,15 +360,15 @@ static inline int ffs(int x)
  *
  * This is defined the same way as ffs.
  */
-static inline int fls(int x)
-{
-       int r;
-
-       __asm__("bsrl %1,%0\n\t"
+static inline int fls(unsigned long x)
+{
+       long r;
+
+       __asm__("bsr %1,%0\n\t"
                "jnz 1f\n\t"
-               "movl $-1,%0\n"
+               "mov $-1,%0\n"
                "1:" : "=r" (r) : "rm" (x));
-       return r+1;
+       return (int)r+1;
 }
 
 /**
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h    Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/asm-x86/hvm/vcpu.h    Wed Jun 28 07:52:21 2006 -0600
@@ -38,6 +38,9 @@ struct hvm_vcpu {
     /* For AP startup */
     unsigned long   init_sipi_sipi_state;
 
+    /* Flags */
+    int   flag_dr_dirty;
+
     union {
         struct arch_vmx_struct vmx;
         struct arch_svm_struct svm;
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/asm-x86/hvm/vlapic.h  Wed Jun 28 07:52:21 2006 -0600
@@ -23,52 +23,12 @@
 #include <asm/msr.h>
 #include <public/hvm/ioreq.h>
 
-#if defined(__i386__) || defined(__x86_64__)
-static inline int __fls(uint32_t word)
+static __inline__ int find_highest_bit(unsigned long *data, int nr_bits)
 {
-    int bit;
-
-    __asm__("bsrl %1,%0"
-      :"=r" (bit)
-      :"rm" (word));
-    return word ? bit : -1;
-}
-#else
-#define __fls(x)    generic_fls(x)
-static __inline__ int generic_fls(uint32_t x)
-{
-    int r = 31;
-
-    if (!x)
-        return -1;
-    if (!(x & 0xffff0000u)) {
-        x <<= 16;
-        r -= 16;
-    }
-    if (!(x & 0xff000000u)) {
-        x <<= 8;
-        r -= 8;
-    }
-    if (!(x & 0xf0000000u)) {
-        x <<= 4;
-        r -= 4;
-    }
-    if (!(x & 0xc0000000u)) {
-        x <<= 2;
-        r -= 2;
-    }
-    if (!(x & 0x80000000u)) {
-        x <<= 1;
-        r -= 1;
-    }
-    return r;
-}
-#endif
-
-static __inline__ int find_highest_bit(uint32_t *data, int length)
-{
-    while(length && !data[--length]);
-    return __fls(data[length]) +  32 * length;
+    int length = BITS_TO_LONGS(nr_bits);
+    while ( length && !data[--length] )
+        continue;
+    return (fls(data[length]) - 1) + (length * BITS_PER_LONG);
 }
 
 #define VLAPIC(v)                       (v->arch.hvm_vcpu.vlapic)
@@ -146,17 +106,17 @@ typedef struct direct_intr_info {
     int source[6];
 } direct_intr_info_t;
 
-struct vlapic
-{
-    //FIXME check what would be 64 bit on EM64T
+#define MAX_VECTOR      256
+
+struct vlapic {
     uint32_t           version;
     uint32_t           status;
     uint32_t           id;
     uint32_t           vcpu_id;
     unsigned long      base_address;
-    uint32_t           isr[8];
-    uint32_t           irr[INTR_LEN_32];
-    uint32_t           tmr[INTR_LEN_32];
+    unsigned long      isr[BITS_TO_LONGS(MAX_VECTOR)];
+    unsigned long      irr[BITS_TO_LONGS(MAX_VECTOR)];
+    unsigned long      tmr[BITS_TO_LONGS(MAX_VECTOR)];
     uint32_t           task_priority;
     uint32_t           processor_priority;
     uint32_t           logical_dest;
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/dom0_ops.h     Wed Jun 28 07:52:21 2006 -0600
@@ -231,6 +231,7 @@ struct dom0_physinfo {
     uint32_t cpu_khz;
     uint64_t total_pages;
     uint64_t free_pages;
+    uint64_t scrub_pages;
     uint32_t hw_cap[8];
 };
 typedef struct dom0_physinfo dom0_physinfo_t;
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h    Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/hvm/ioreq.h    Wed Jun 28 07:52:21 2006 -0600
@@ -58,11 +58,6 @@ struct ioreq {
 };
 typedef struct ioreq ioreq_t;
 
-#define MAX_VECTOR      256
-#define BITS_PER_BYTE   8
-#define INTR_LEN        (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t)))
-#define INTR_LEN_32     (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint32_t)))
-
 struct global_iodata {
     uint16_t    pic_elcr;
     uint16_t    pic_irr;
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h     Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/io/netif.h     Wed Jun 28 07:52:21 2006 -0600
@@ -19,6 +19,16 @@
  * the appropriate req_event or rsp_event field in the shared ring.
  */
 
+/*
+ * This is the 'wire' format for packets:
+ *  Request 1: netif_tx_request -- NETTXF_* (any flags)
+ * [Request 2: netif_tx_extra]  (only if request 1 has NETTXF_extra_info)
+ *  Request 3: netif_tx_request -- NETTXF_more_data
+ *  Request 4: netif_tx_request -- NETTXF_more_data
+ *  ...
+ *  Request N: netif_tx_request -- 0
+ */
+
 /* Protocol checksum field is blank in the packet (hardware offload)? */
 #define _NETTXF_csum_blank     (0)
 #define  NETTXF_csum_blank     (1U<<_NETTXF_csum_blank)
@@ -27,9 +37,16 @@
 #define _NETTXF_data_validated (1)
 #define  NETTXF_data_validated (1U<<_NETTXF_data_validated)
 
-/* Packet continues in the request. */
+/* Packet continues in the next request descriptor. */
 #define _NETTXF_more_data      (2)
 #define  NETTXF_more_data      (1U<<_NETTXF_more_data)
+
+/* Packet has GSO fields in the following descriptor (netif_tx_extra.u.gso). */
+#define _NETTXF_gso            (3)
+#define  NETTXF_gso            (1U<<_NETTXF_gso)
+
+/* This descriptor is followed by an extra-info descriptor (netif_tx_extra). */
+#define  NETTXF_extra_info     (NETTXF_gso)
 
 struct netif_tx_request {
     grant_ref_t gref;      /* Reference to buffer page */
@@ -39,6 +56,18 @@ struct netif_tx_request {
     uint16_t size;         /* Packet size in bytes.       */
 };
 typedef struct netif_tx_request netif_tx_request_t;
+
+/* This structure needs to fit within netif_tx_request for compatibility. */
+struct netif_tx_extra {
+    union {
+        /* NETTXF_gso: Generic Segmentation Offload. */
+        struct netif_tx_gso {
+            uint16_t size;        /* GSO MSS. */
+            uint16_t segs;        /* GSO segment count. */
+            uint16_t type;        /* GSO type. */
+        } gso;
+    } u;
+};
 
 struct netif_tx_response {
     uint16_t id;
@@ -78,6 +107,8 @@ DEFINE_RING_TYPES(netif_rx, struct netif
 #define NETIF_RSP_DROPPED         -2
 #define NETIF_RSP_ERROR           -1
 #define NETIF_RSP_OKAY             0
+/* No response: used for auxiliary requests (e.g., netif_tx_extra). */
+#define NETIF_RSP_NULL             1
 
 #endif
 
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/version.h
--- a/xen/include/public/version.h      Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/version.h      Wed Jun 28 07:52:21 2006 -0600
@@ -10,7 +10,7 @@
 #ifndef __XEN_PUBLIC_VERSION_H__
 #define __XEN_PUBLIC_VERSION_H__
 
-/* NB. All ops return zero on success, except XENVER_version. */
+/* NB. All ops return zero on success, except XENVER_{version,pagesize} */
 
 /* arg == NULL; returns major:minor (16:16). */
 #define XENVER_version      0
@@ -54,6 +54,9 @@ typedef struct xen_feature_info xen_feat
 /* Declares the features reported by XENVER_get_features. */
 #include "features.h"
 
+/* arg == NULL; returns host memory page size. */
+#define XENVER_pagesize 7
+
 #endif /* __XEN_PUBLIC_VERSION_H__ */
 
 /*
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h     Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/public/xenoprof.h     Wed Jun 28 07:52:21 2006 -0600
@@ -80,6 +80,15 @@ typedef struct xenoprof_counter xenoprof
 typedef struct xenoprof_counter xenoprof_counter_t;
 DEFINE_XEN_GUEST_HANDLE(xenoprof_counter_t);
 
+typedef struct xenoprof_passive {
+    uint16_t domain_id;
+    int32_t  max_samples;
+    int32_t  nbuf;
+    int32_t  bufsize;
+    uint64_t buf_maddr;
+} xenoprof_passive_t;
+DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t);
+
 
 #endif /* __XEN_PUBLIC_XENOPROF_H__ */
 
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/xen/mm.h      Wed Jun 28 07:52:21 2006 -0600
@@ -91,6 +91,7 @@ extern struct list_head page_scrub_list;
         if ( !list_empty(&page_scrub_list) )    \
             raise_softirq(PAGE_SCRUB_SOFTIRQ);  \
     } while ( 0 )
+unsigned long avail_scrub_pages(void);
 
 #include <asm/mm.h>
 
diff -r c4b68afe97d3 -r 4b51d081378d xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h        Wed Jun 28 07:51:52 2006 -0600
+++ b/xen/include/xen/xenoprof.h        Wed Jun 28 07:52:21 2006 -0600
@@ -14,6 +14,7 @@
 
 #define XENOPROF_DOMAIN_IGNORED    0
 #define XENOPROF_DOMAIN_ACTIVE     1
+#define XENOPROF_DOMAIN_PASSIVE    2
 
 #define XENOPROF_IDLE              0
 #define XENOPROF_COUNTERS_RESERVED 1
diff -r c4b68afe97d3 -r 4b51d081378d patches/linux-2.6.16.13/net-gso.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/net-gso.patch     Wed Jun 28 07:52:21 2006 -0600
@@ -0,0 +1,2907 @@
+diff --git a/Documentation/networking/netdevices.txt 
b/Documentation/networking/netdevices.txt
+index 3c0a5ba..847cedb 100644
+--- a/Documentation/networking/netdevices.txt
++++ b/Documentation/networking/netdevices.txt
+@@ -42,9 +42,9 @@ dev->get_stats:
+       Context: nominally process, but don't sleep inside an rwlock
+ 
+ dev->hard_start_xmit:
+-      Synchronization: dev->xmit_lock spinlock.
++      Synchronization: netif_tx_lock spinlock.
+       When the driver sets NETIF_F_LLTX in dev->features this will be
+-      called without holding xmit_lock. In this case the driver 
++      called without holding netif_tx_lock. In this case the driver
+       has to lock by itself when needed. It is recommended to use a try lock
+       for this and return -1 when the spin lock fails. 
+       The locking there should also properly protect against 
+@@ -62,12 +62,12 @@ dev->hard_start_xmit:
+         Only valid when NETIF_F_LLTX is set.
+ 
+ dev->tx_timeout:
+-      Synchronization: dev->xmit_lock spinlock.
++      Synchronization: netif_tx_lock spinlock.
+       Context: BHs disabled
+       Notes: netif_queue_stopped() is guaranteed true
+ 
+ dev->set_multicast_list:
+-      Synchronization: dev->xmit_lock spinlock.
++      Synchronization: netif_tx_lock spinlock.
+       Context: BHs disabled
+ 
+ dev->poll:
+diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
+index 4be9769..2e7cac7 100644
+--- a/drivers/block/aoe/aoenet.c
++++ b/drivers/block/aoe/aoenet.c
+@@ -95,9 +95,8 @@ mac_addr(char addr[6])
+ static struct sk_buff *
+ skb_check(struct sk_buff *skb)
+ {
+-      if (skb_is_nonlinear(skb))
+       if ((skb = skb_share_check(skb, GFP_ATOMIC)))
+-      if (skb_linearize(skb, GFP_ATOMIC) < 0) {
++      if (skb_linearize(skb)) {
+               dev_kfree_skb(skb);
+               return NULL;
+       }
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 
b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+index a2408d7..c90e620 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+@@ -821,7 +821,8 @@ void ipoib_mcast_restart_task(void *dev_
+ 
+       ipoib_mcast_stop_thread(dev, 0);
+ 
+-      spin_lock_irqsave(&dev->xmit_lock, flags);
++      local_irq_save(flags);
++      netif_tx_lock(dev);
+       spin_lock(&priv->lock);
+ 
+       /*
+@@ -896,7 +897,8 @@ void ipoib_mcast_restart_task(void *dev_
+       }
+ 
+       spin_unlock(&priv->lock);
+-      spin_unlock_irqrestore(&dev->xmit_lock, flags);
++      netif_tx_unlock(dev);
++      local_irq_restore(flags);
+ 
+       /* We have to cancel outside of the spinlock */
+       list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
+diff --git a/drivers/media/dvb/dvb-core/dvb_net.c 
b/drivers/media/dvb/dvb-core/dvb_net.c
+index 6711eb6..8d2351f 100644
+--- a/drivers/media/dvb/dvb-core/dvb_net.c
++++ b/drivers/media/dvb/dvb-core/dvb_net.c
+@@ -1052,7 +1052,7 @@ static void wq_set_multicast_list (void 
+ 
+       dvb_net_feed_stop(dev);
+       priv->rx_mode = RX_MODE_UNI;
+-      spin_lock_bh(&dev->xmit_lock);
++      netif_tx_lock_bh(dev);
+ 
+       if (dev->flags & IFF_PROMISC) {
+               dprintk("%s: promiscuous mode\n", dev->name);
+@@ -1077,7 +1077,7 @@ static void wq_set_multicast_list (void 
+               }
+       }
+ 
+-      spin_unlock_bh(&dev->xmit_lock);
++      netif_tx_unlock_bh(dev);
+       dvb_net_feed_start(dev);
+ }
+ 
+diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
+index dd41049..6615583 100644
+--- a/drivers/net/8139cp.c
++++ b/drivers/net/8139cp.c
+@@ -794,7 +794,7 @@ #endif
+       entry = cp->tx_head;
+       eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
+       if (dev->features & NETIF_F_TSO)
+-              mss = skb_shinfo(skb)->tso_size;
++              mss = skb_shinfo(skb)->gso_size;
+ 
+       if (skb_shinfo(skb)->nr_frags == 0) {
+               struct cp_desc *txd = &cp->tx_ring[entry];
+diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
+index a24200d..b5e39a1 100644
+--- a/drivers/net/bnx2.c
++++ b/drivers/net/bnx2.c
+@@ -1593,7 +1593,7 @@ bnx2_tx_int(struct bnx2 *bp)
+               skb = tx_buf->skb;
+ #ifdef BCM_TSO 
+               /* partial BD completions possible with TSO packets */
+-              if (skb_shinfo(skb)->tso_size) {
++              if (skb_shinfo(skb)->gso_size) {
+                       u16 last_idx, last_ring_idx;
+ 
+                       last_idx = sw_cons +
+@@ -1948,7 +1948,7 @@ bnx2_poll(struct net_device *dev, int *b
+       return 1;
+ }
+ 
+-/* Called with rtnl_lock from vlan functions and also dev->xmit_lock
++/* Called with rtnl_lock from vlan functions and also netif_tx_lock
+  * from set_multicast.
+  */
+ static void
+@@ -4403,7 +4403,7 @@ bnx2_vlan_rx_kill_vid(struct net_device 
+ }
+ #endif
+ 
+-/* Called with dev->xmit_lock.
++/* Called with netif_tx_lock.
+  * hard_start_xmit is pseudo-lockless - a lock is only required when
+  * the tx queue is full. This way, we get the benefit of lockless
+  * operations most of the time without the complexities to handle
+@@ -4441,7 +4441,7 @@ bnx2_start_xmit(struct sk_buff *skb, str
+                       (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
+       }
+ #ifdef BCM_TSO 
+-      if ((mss = skb_shinfo(skb)->tso_size) &&
++      if ((mss = skb_shinfo(skb)->gso_size) &&
+               (skb->len > (bp->dev->mtu + ETH_HLEN))) {
+               u32 tcp_opt_len, ip_tcp_len;
+ 
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index bcf9f17..e970921 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1145,8 +1145,7 @@ int bond_sethwaddr(struct net_device *bo
+ }
+ 
+ #define BOND_INTERSECT_FEATURES \
+-      (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
+-      NETIF_F_TSO|NETIF_F_UFO)
++      (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
+ 
+ /* 
+  * Compute the common dev->feature set available to all slaves.  Some
+@@ -1164,9 +1163,7 @@ static int bond_compute_features(struct 
+               features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
+ 
+       if ((features & NETIF_F_SG) && 
+-          !(features & (NETIF_F_IP_CSUM |
+-                        NETIF_F_NO_CSUM |
+-                        NETIF_F_HW_CSUM)))
++          !(features & NETIF_F_ALL_CSUM))
+               features &= ~NETIF_F_SG;
+ 
+       /* 
+@@ -4147,7 +4144,7 @@ static int bond_init(struct net_device *
+        */
+       bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
+ 
+-      /* don't acquire bond device's xmit_lock when 
++      /* don't acquire bond device's netif_tx_lock when
+        * transmitting */
+       bond_dev->features |= NETIF_F_LLTX;
+ 
+diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
+index 30ff8ea..7b7d360 100644
+--- a/drivers/net/chelsio/sge.c
++++ b/drivers/net/chelsio/sge.c
+@@ -1419,7 +1419,7 @@ int t1_start_xmit(struct sk_buff *skb, s
+       struct cpl_tx_pkt *cpl;
+ 
+ #ifdef NETIF_F_TSO
+-      if (skb_shinfo(skb)->tso_size) {
++      if (skb_shinfo(skb)->gso_size) {
+               int eth_type;
+               struct cpl_tx_pkt_lso *hdr;
+ 
+@@ -1434,7 +1434,7 @@ #ifdef NETIF_F_TSO
+               hdr->ip_hdr_words = skb->nh.iph->ihl;
+               hdr->tcp_hdr_words = skb->h.th->doff;
+               hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
+-                                              skb_shinfo(skb)->tso_size));
++                                              skb_shinfo(skb)->gso_size));
+               hdr->len = htonl(skb->len - sizeof(*hdr));
+               cpl = (struct cpl_tx_pkt *)hdr;
+               sge->stats.tx_lso_pkts++;
+diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
+index fa29402..681d284 100644
+--- a/drivers/net/e1000/e1000_main.c
++++ b/drivers/net/e1000/e1000_main.c
+@@ -2526,7 +2526,7 @@ #ifdef NETIF_F_TSO
+       uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
+       int err;
+ 
+-      if (skb_shinfo(skb)->tso_size) {
++      if (skb_shinfo(skb)->gso_size) {
+               if (skb_header_cloned(skb)) {
+                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+                       if (err)
+@@ -2534,7 +2534,7 @@ #ifdef NETIF_F_TSO
+               }
+ 
+               hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+-              mss = skb_shinfo(skb)->tso_size;
++              mss = skb_shinfo(skb)->gso_size;
+               if (skb->protocol == ntohs(ETH_P_IP)) {
+                       skb->nh.iph->tot_len = 0;
+                       skb->nh.iph->check = 0;
+@@ -2651,7 +2651,7 @@ #ifdef NETIF_F_TSO
+                * tso gets written back prematurely before the data is fully
+                * DMAd to the controller */
+               if (!skb->data_len && tx_ring->last_tx_tso &&
+-                              !skb_shinfo(skb)->tso_size) {
++                              !skb_shinfo(skb)->gso_size) {
+                       tx_ring->last_tx_tso = 0;
+                       size -= 4;
+               }
+@@ -2893,7 +2893,7 @@ #endif
+       }
+ 
+ #ifdef NETIF_F_TSO
+-      mss = skb_shinfo(skb)->tso_size;
++      mss = skb_shinfo(skb)->gso_size;
+       /* The controller does a simple calculation to 
+        * make sure there is enough room in the FIFO before
+        * initiating the DMA for each buffer.  The calc is:
+@@ -2935,7 +2935,7 @@ #endif
+ #ifdef NETIF_F_TSO
+       /* Controller Erratum workaround */
+       if (!skb->data_len && tx_ring->last_tx_tso &&
+-              !skb_shinfo(skb)->tso_size)
++              !skb_shinfo(skb)->gso_size)
+               count++;
+ #endif
+ 
+diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
+index 3682ec6..c35f16e 100644
+--- a/drivers/net/forcedeth.c
++++ b/drivers/net/forcedeth.c
+@@ -482,9 +482,9 @@ #define LPA_1000HALF       0x0400
+  * critical parts:
+  * - rx is (pseudo-) lockless: it relies on the single-threading provided
+  *    by the arch code for interrupts.
+- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
++ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission
+  *    needs dev->priv->lock :-(
+- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
++ * - set_multicast_list: preparation lockless, relies on netif_tx_lock.
+  */
+ 
+ /* in dev: base, irq */
+@@ -1016,7 +1016,7 @@ static void drain_ring(struct net_device
+ 
+ /*
+  * nv_start_xmit: dev->hard_start_xmit function
+- * Called with dev->xmit_lock held.
++ * Called with netif_tx_lock held.
+  */
+ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+@@ -1105,8 +1105,8 @@ static int nv_start_xmit(struct sk_buff 
+       np->tx_skbuff[nr] = skb;
+ 
+ #ifdef NETIF_F_TSO
+-      if (skb_shinfo(skb)->tso_size)
+-              tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << 
NV_TX2_TSO_SHIFT);
++      if (skb_shinfo(skb)->gso_size)
++              tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << 
NV_TX2_TSO_SHIFT);
+       else
+ #endif
+       tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? 
(NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
+@@ -1203,7 +1203,7 @@ static void nv_tx_done(struct net_device
+ 
+ /*
+  * nv_tx_timeout: dev->tx_timeout function
+- * Called with dev->xmit_lock held.
++ * Called with netif_tx_lock held.
+  */
+ static void nv_tx_timeout(struct net_device *dev)
+ {
+@@ -1524,7 +1524,7 @@ static int nv_change_mtu(struct net_devi
+                * Changing the MTU is a rare event, it shouldn't matter.
+                */
+               disable_irq(dev->irq);
+-              spin_lock_bh(&dev->xmit_lock);
++              netif_tx_lock_bh(dev);
+               spin_lock(&np->lock);
+               /* stop engines */
+               nv_stop_rx(dev);
+@@ -1559,7 +1559,7 @@ static int nv_change_mtu(struct net_devi
+               nv_start_rx(dev);
+               nv_start_tx(dev);
+               spin_unlock(&np->lock);
+-              spin_unlock_bh(&dev->xmit_lock);
++              netif_tx_unlock_bh(dev);
+               enable_irq(dev->irq);
+       }
+       return 0;
+@@ -1594,7 +1594,7 @@ static int nv_set_mac_address(struct net
+       memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
+ 
+       if (netif_running(dev)) {
+-              spin_lock_bh(&dev->xmit_lock);
++              netif_tx_lock_bh(dev);
+               spin_lock_irq(&np->lock);
+ 
+               /* stop rx engine */
+@@ -1606,7 +1606,7 @@ static int nv_set_mac_address(struct net
+               /* restart rx engine */
+               nv_start_rx(dev);
+               spin_unlock_irq(&np->lock);
+-              spin_unlock_bh(&dev->xmit_lock);
++              netif_tx_unlock_bh(dev);
+       } else {
+               nv_copy_mac_to_hw(dev);
+       }
+@@ -1615,7 +1615,7 @@ static int nv_set_mac_address(struct net
+ 
+ /*
+  * nv_set_multicast: dev->set_multicast function
+- * Called with dev->xmit_lock held.
++ * Called with netif_tx_lock held.
+  */
+ static void nv_set_multicast(struct net_device *dev)
+ {
+diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
+index 102c1f0..d12605f 100644
+--- a/drivers/net/hamradio/6pack.c
++++ b/drivers/net/hamradio/6pack.c
+@@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net
+ {
+       struct sockaddr_ax25 *sa = addr;
+ 
+-      spin_lock_irq(&dev->xmit_lock);
++      netif_tx_lock_bh(dev);
+       memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
+-      spin_unlock_irq(&dev->xmit_lock);
++      netif_tx_unlock_bh(dev);
+ 
+       return 0;
+ }
+@@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_stru
+                       break;
+               }
+ 
+-              spin_lock_irq(&dev->xmit_lock);
++              netif_tx_lock_bh(dev);
+               memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
+-              spin_unlock_irq(&dev->xmit_lock);
++              netif_tx_unlock_bh(dev);
+ 
+               err = 0;
+               break;
+diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
+index dc5e9d5..5c66f5a 100644
+--- a/drivers/net/hamradio/mkiss.c
++++ b/drivers/net/hamradio/mkiss.c
+@@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net
+ {
+       struct sockaddr_ax25 *sa = addr;
+ 
+-      spin_lock_irq(&dev->xmit_lock);
++      netif_tx_lock_bh(dev);
+       memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
+-      spin_unlock_irq(&dev->xmit_lock);
++      netif_tx_unlock_bh(dev);
+ 
+       return 0;
+ }
+@@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct
+                       break;
+               }
+ 
+-              spin_lock_irq(&dev->xmit_lock);
++              netif_tx_lock_bh(dev);
+               memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
+-              spin_unlock_irq(&dev->xmit_lock);
++              netif_tx_unlock_bh(dev);
+ 
+               err = 0;
+               break;
+diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
+index 31fb2d7..2e222ef 100644
+--- a/drivers/net/ifb.c
++++ b/drivers/net/ifb.c
+@@ -76,13 +76,13 @@ static void ri_tasklet(unsigned long dev
+       dp->st_task_enter++;
+       if ((skb = skb_peek(&dp->tq)) == NULL) {
+               dp->st_txq_refl_try++;
+-              if (spin_trylock(&_dev->xmit_lock)) {
++              if (netif_tx_trylock(_dev)) {
+                       dp->st_rxq_enter++;
+                       while ((skb = skb_dequeue(&dp->rq)) != NULL) {
+                               skb_queue_tail(&dp->tq, skb);
+                               dp->st_rx2tx_tran++;
+                       }
+-                      spin_unlock(&_dev->xmit_lock);
++                      netif_tx_unlock(_dev);
+               } else {
+                       /* reschedule */
+                       dp->st_rxq_notenter++;
+@@ -110,7 +110,7 @@ static void ri_tasklet(unsigned long dev
+               }
+       }
+ 
+-      if (spin_trylock(&_dev->xmit_lock)) {
++      if (netif_tx_trylock(_dev)) {
+               dp->st_rxq_check++;
+               if ((skb = skb_peek(&dp->rq)) == NULL) {
+                       dp->tasklet_pending = 0;
+@@ -118,10 +118,10 @@ static void ri_tasklet(unsigned long dev
+                               netif_wake_queue(_dev);
+               } else {
+                       dp->st_rxq_rsch++;
+-                      spin_unlock(&_dev->xmit_lock);
++                      netif_tx_unlock(_dev);
+                       goto resched;
+               }
+-              spin_unlock(&_dev->xmit_lock);
++              netif_tx_unlock(_dev);
+       } else {
+ resched:
+               dp->tasklet_pending = 1;
+diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
+index a9f49f0..339d4a7 100644
+--- a/drivers/net/irda/vlsi_ir.c
++++ b/drivers/net/irda/vlsi_ir.c
+@@ -959,7 +959,7 @@ static int vlsi_hard_start_xmit(struct s
+                           ||  (now.tv_sec==ready.tv_sec && 
now.tv_usec>=ready.tv_usec))
+                               break;
+                       udelay(100);
+-                      /* must not sleep here - we are called under xmit_lock! 
*/
++                      /* must not sleep here - called under netif_tx_lock! */
+               }
+       }
+ 
+diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
+index f9f77e4..bdab369 100644
+--- a/drivers/net/ixgb/ixgb_main.c
++++ b/drivers/net/ixgb/ixgb_main.c
+@@ -1163,7 +1163,7 @@ #ifdef NETIF_F_TSO
+       uint16_t ipcse, tucse, mss;
+       int err;
+ 
+-      if(likely(skb_shinfo(skb)->tso_size)) {
++      if(likely(skb_shinfo(skb)->gso_size)) {
+               if (skb_header_cloned(skb)) {
+                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+                       if (err)
+@@ -1171,7 +1171,7 @@ #ifdef NETIF_F_TSO
+               }
+ 
+               hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+-              mss = skb_shinfo(skb)->tso_size;
++              mss = skb_shinfo(skb)->gso_size;
+               skb->nh.iph->tot_len = 0;
+               skb->nh.iph->check = 0;
+               skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
+diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
+index 690a1aa..9bcaa80 100644
+--- a/drivers/net/loopback.c
++++ b/drivers/net/loopback.c
+@@ -74,7 +74,7 @@ static void emulate_large_send_offload(s
+       struct iphdr *iph = skb->nh.iph;
+       struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
+       unsigned int doffset = (iph->ihl + th->doff) * 4;
+-      unsigned int mtu = skb_shinfo(skb)->tso_size + doffset;
++      unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
+       unsigned int offset = 0;
+       u32 seq = ntohl(th->seq);
+       u16 id  = ntohs(iph->id);
+@@ -139,7 +139,7 @@ #ifndef LOOPBACK_MUST_CHECKSUM
+ #endif
+ 
+ #ifdef LOOPBACK_TSO
+-      if (skb_shinfo(skb)->tso_size) {
++      if (skb_shinfo(skb)->gso_size) {
+               BUG_ON(skb->protocol != htons(ETH_P_IP));
+               BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
+ 
+diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
+index c0998ef..0fac9d5 100644
+--- a/drivers/net/mv643xx_eth.c
++++ b/drivers/net/mv643xx_eth.c
+@@ -1107,7 +1107,7 @@ static int mv643xx_eth_start_xmit(struct
+ 
+ #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+       if (has_tiny_unaligned_frags(skb)) {
+-              if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
++              if (__skb_linearize(skb)) {
+                       stats->tx_dropped++;
+                       printk(KERN_DEBUG "%s: failed to linearize tiny "
+                                       "unaligned fragment\n", dev->name);
+diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
+index 9d6d254..c9ed624 100644
+--- a/drivers/net/natsemi.c
++++ b/drivers/net/natsemi.c
+@@ -323,12 +323,12 @@ performance critical codepaths:
+ The rx process only runs in the interrupt handler. Access from outside
+ the interrupt handler is only permitted after disable_irq().
+ 
+-The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap
++The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap
+ is set, then access is permitted under spin_lock_irq(&np->lock).
+ 
+ Thus configuration functions that want to access everything must call
+       disable_irq(dev->irq);
+-      spin_lock_bh(dev->xmit_lock);
++      netif_tx_lock_bh(dev);
+       spin_lock_irq(&np->lock);
+ 
+ IV. Notes
+diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
+index 8cc0d0b..e53b313 100644
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -2171,7 +2171,7 @@ static int rtl8169_xmit_frags(struct rtl
+ static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device 
*dev)
+ {
+       if (dev->features & NETIF_F_TSO) {
+-              u32 mss = skb_shinfo(skb)->tso_size;
++              u32 mss = skb_shinfo(skb)->gso_size;
+ 
+               if (mss)
+                       return LargeSend | ((mss & MSSMask) << MSSShift);
+diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
+index b7f00d6..439f45f 100644
+--- a/drivers/net/s2io.c
++++ b/drivers/net/s2io.c
+@@ -3522,8 +3522,8 @@ #endif
+       txdp->Control_1 = 0;
+       txdp->Control_2 = 0;
+ #ifdef NETIF_F_TSO
+-      mss = skb_shinfo(skb)->tso_size;
+-      if (mss) {
++      mss = skb_shinfo(skb)->gso_size;
++      if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) {
+               txdp->Control_1 |= TXD_TCP_LSO_EN;
+               txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
+       }
+@@ -3543,10 +3543,10 @@ #endif
+       }
+ 
+       frg_len = skb->len - skb->data_len;
+-      if (skb_shinfo(skb)->ufo_size) {
++      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) {
+               int ufo_size;
+ 
+-              ufo_size = skb_shinfo(skb)->ufo_size;
++              ufo_size = skb_shinfo(skb)->gso_size;
+               ufo_size &= ~7;
+               txdp->Control_1 |= TXD_UFO_EN;
+               txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
+@@ -3572,7 +3572,7 @@ #endif
+       txdp->Host_Control = (unsigned long) skb;
+       txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
+ 
+-      if (skb_shinfo(skb)->ufo_size)
++      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
+               txdp->Control_1 |= TXD_UFO_EN;
+ 
+       frg_cnt = skb_shinfo(skb)->nr_frags;
+@@ -3587,12 +3587,12 @@ #endif
+                   (sp->pdev, frag->page, frag->page_offset,
+                    frag->size, PCI_DMA_TODEVICE);
+               txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
+-              if (skb_shinfo(skb)->ufo_size)
++              if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
+                       txdp->Control_1 |= TXD_UFO_EN;
+       }
+       txdp->Control_1 |= TXD_GATHER_CODE_LAST;
+ 
+-      if (skb_shinfo(skb)->ufo_size)
++      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
+               frg_cnt++; /* as Txd0 was used for inband header */
+ 
+       tx_fifo = mac_control->tx_FIFO_start[queue];
+@@ -3606,7 +3606,7 @@ #ifdef NETIF_F_TSO
+       if (mss)
+               val64 |= TX_FIFO_SPECIAL_FUNC;
+ #endif
+-      if (skb_shinfo(skb)->ufo_size)
++      if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
+               val64 |= TX_FIFO_SPECIAL_FUNC;
+       writeq(val64, &tx_fifo->List_Control);
+ 
+diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
+index 0618cd5..2a55eb3 100644
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -1125,7 +1125,7 @@ static unsigned tx_le_req(const struct s
+       count = sizeof(dma_addr_t) / sizeof(u32);
+       count += skb_shinfo(skb)->nr_frags * count;
+ 
+-      if (skb_shinfo(skb)->tso_size)
++      if (skb_shinfo(skb)->gso_size)
+               ++count;
+ 
+       if (skb->ip_summed == CHECKSUM_HW)
+@@ -1197,7 +1197,7 @@ static int sky2_xmit_frame(struct sk_buf
+       }
+ 
+       /* Check for TCP Segmentation Offload */
+-      mss = skb_shinfo(skb)->tso_size;
++      mss = skb_shinfo(skb)->gso_size;
+       if (mss != 0) {
+               /* just drop the packet if non-linear expansion fails */
+               if (skb_header_cloned(skb) &&
+diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
+index caf4102..fc9164a 100644
+--- a/drivers/net/tg3.c
++++ b/drivers/net/tg3.c
+@@ -3664,7 +3664,7 @@ static int tg3_start_xmit(struct sk_buff
+ #if TG3_TSO_SUPPORT != 0
+       mss = 0;
+       if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
+-          (mss = skb_shinfo(skb)->tso_size) != 0) {
++          (mss = skb_shinfo(skb)->gso_size) != 0) {
+               int tcp_opt_len, ip_tcp_len;
+ 
+               if (skb_header_cloned(skb) &&
+diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
+index 5b1af39..11de5af 100644
+--- a/drivers/net/tulip/winbond-840.c
++++ b/drivers/net/tulip/winbond-840.c
+@@ -1605,11 +1605,11 @@ #ifdef CONFIG_PM
+  * - get_stats:
+  *    spin_lock_irq(np->lock), doesn't touch hw if not present
+  * - hard_start_xmit:
+- *    netif_stop_queue + spin_unlock_wait(&dev->xmit_lock);
++ *    synchronize_irq + netif_tx_disable;
+  * - tx_timeout:
+- *    netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
++ *    netif_device_detach + netif_tx_disable;
+  * - set_multicast_list
+- *    netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
++ *    netif_device_detach + netif_tx_disable;
+  * - interrupt handler
+  *    doesn't touch hw if not present, synchronize_irq waits for
+  *    running instances of the interrupt handler.
+@@ -1635,11 +1635,10 @@ static int w840_suspend (struct pci_dev 
+               netif_device_detach(dev);
+               update_csr6(dev, 0);
+               iowrite32(0, ioaddr + IntrEnable);
+-              netif_stop_queue(dev);
+               spin_unlock_irq(&np->lock);
+ 
+-              spin_unlock_wait(&dev->xmit_lock);
+               synchronize_irq(dev->irq);
++              netif_tx_disable(dev);
+       
+               np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 
0xffff;
+ 
+diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
+index 4c76cb7..30c48c9 100644
+--- a/drivers/net/typhoon.c
++++ b/drivers/net/typhoon.c
+@@ -340,7 +340,7 @@ #define typhoon_synchronize_irq(x) synch
+ #endif
+ 
+ #if defined(NETIF_F_TSO)
+-#define skb_tso_size(x)               (skb_shinfo(x)->tso_size)
++#define skb_tso_size(x)               (skb_shinfo(x)->gso_size)
+ #define TSO_NUM_DESCRIPTORS   2
+ #define TSO_OFFLOAD_ON                TYPHOON_OFFLOAD_TCP_SEGMENT
+ #else
+diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
+index ed1f837..2eb6b5f 100644
+--- a/drivers/net/via-velocity.c
++++ b/drivers/net/via-velocity.c
+@@ -1899,6 +1899,13 @@ static int velocity_xmit(struct sk_buff 
+ 
+       int pktlen = skb->len;
+ 
++#ifdef VELOCITY_ZERO_COPY_SUPPORT
++      if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
++              kfree_skb(skb);
++              return 0;
++      }
++#endif
++
+       spin_lock_irqsave(&vptr->lock, flags);
+ 
+       index = vptr->td_curr[qnum];
+@@ -1914,8 +1921,6 @@ static int velocity_xmit(struct sk_buff 
+        */
+       if (pktlen < ETH_ZLEN) {
+               /* Cannot occur until ZC support */
+-              if(skb_linearize(skb, GFP_ATOMIC))
+-                      return 0; 
+               pktlen = ETH_ZLEN;
+               memcpy(tdinfo->buf, skb->data, skb->len);
+               memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
+@@ -1933,7 +1938,6 @@ #ifdef VELOCITY_ZERO_COPY_SUPPORT
+               int nfrags = skb_shinfo(skb)->nr_frags;
+               tdinfo->skb = skb;
+               if (nfrags > 6) {
+-                      skb_linearize(skb, GFP_ATOMIC);
+                       memcpy(tdinfo->buf, skb->data, skb->len);
+                       tdinfo->skb_dma[0] = tdinfo->buf_dma;
+                       td_ptr->tdesc0.pktsize = 
+diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
+index 6fd0bf7..75237c1 100644
+--- a/drivers/net/wireless/orinoco.c
++++ b/drivers/net/wireless/orinoco.c
+@@ -1835,7 +1835,9 @@ static int __orinoco_program_rids(struct
+       /* Set promiscuity / multicast*/
+       priv->promiscuous = 0;
+       priv->mc_count = 0;
+-      __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
++
++      /* FIXME: what about netif_tx_lock */
++      __orinoco_set_multicast_list(dev);
+ 
+       return 0;
+ }
+diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
+index 82cb4af..57cec40 100644
+--- a/drivers/s390/net/qeth_eddp.c
++++ b/drivers/s390/net/qeth_eddp.c
+@@ -421,7 +421,7 @@ #endif /* CONFIG_QETH_VLAN */
+        }
+       tcph = eddp->skb->h.th;
+       while (eddp->skb_offset < eddp->skb->len) {
+-              data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
++              data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
+                              (int)(eddp->skb->len - eddp->skb_offset));
+               /* prepare qdio hdr */
+               if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
+@@ -516,20 +516,20 @@ qeth_eddp_calc_num_pages(struct qeth_edd
+       
+       QETH_DBF_TEXT(trace, 5, "eddpcanp");
+       /* can we put multiple skbs in one page? */
+-      skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
++      skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
+       if (skbs_per_page > 1){
+-              ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
++              ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
+                                skbs_per_page + 1;
+               ctx->elements_per_skb = 1;
+       } else {
+               /* no -> how many elements per skb? */
+-              ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
++              ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
+                                    PAGE_SIZE) >> PAGE_SHIFT;
+               ctx->num_pages = ctx->elements_per_skb *
+-                               (skb_shinfo(skb)->tso_segs + 1);
++                               (skb_shinfo(skb)->gso_segs + 1);
+       }
+       ctx->num_elements = ctx->elements_per_skb *
+-                          (skb_shinfo(skb)->tso_segs + 1);
++                          (skb_shinfo(skb)->gso_segs + 1);
+ }
+ 
+ static inline struct qeth_eddp_context *
+diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
+index dba7f7f..d9cc997 100644
+--- a/drivers/s390/net/qeth_main.c
++++ b/drivers/s390/net/qeth_main.c
+@@ -4454,7 +4454,7 @@ qeth_send_packet(struct qeth_card *card,
+       queue = card->qdio.out_qs
+               [qeth_get_priority_queue(card, skb, ipv, cast_type)];
+ 
+-      if (skb_shinfo(skb)->tso_size)
++      if (skb_shinfo(skb)->gso_size)
+               large_send = card->options.large_send;
+ 
+       /*are we able to do TSO ? If so ,prepare and send it from here */
+@@ -4501,7 +4501,7 @@ qeth_send_packet(struct qeth_card *card,
+               card->stats.tx_packets++;
+               card->stats.tx_bytes += skb->len;
+ #ifdef CONFIG_QETH_PERF_STATS
+-              if (skb_shinfo(skb)->tso_size &&
++              if (skb_shinfo(skb)->gso_size &&
+                  !(large_send == QETH_LARGE_SEND_NO)) {
+                       card->perf_stats.large_send_bytes += skb->len;
+                       card->perf_stats.large_send_cnt++;
+diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
+index 1286dde..89cbf34 100644
+--- a/drivers/s390/net/qeth_tso.h
++++ b/drivers/s390/net/qeth_tso.h
+@@ -51,7 +51,7 @@ qeth_tso_fill_header(struct qeth_card *c
+       hdr->ext.hdr_version = 1;
+       hdr->ext.hdr_len     = 28;
+       /*insert non-fix values */
+-      hdr->ext.mss = skb_shinfo(skb)->tso_size;
++      hdr->ext.mss = skb_shinfo(skb)->gso_size;
+       hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
+       hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
+                                      sizeof(struct qeth_hdr_tso));
+diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
+index 93535f0..9269df7 100644
+--- a/include/linux/ethtool.h
++++ b/include/linux/ethtool.h
+@@ -408,6 +408,8 @@ #define ETHTOOL_STSO               0x0000001f /* Set 
+ #define ETHTOOL_GPERMADDR     0x00000020 /* Get permanent hardware address */
+ #define ETHTOOL_GUFO          0x00000021 /* Get UFO enable (ethtool_value) */
+ #define ETHTOOL_SUFO          0x00000022 /* Set UFO enable (ethtool_value) */
++#define ETHTOOL_GGSO          0x00000023 /* Get GSO enable (ethtool_value) */
++#define ETHTOOL_SGSO          0x00000024 /* Set GSO enable (ethtool_value) */
+ 
+ /* compatibility with older code */
+ #define SPARC_ETH_GSET                ETHTOOL_GSET
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 7fda03d..47b0965 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -230,7 +230,8 @@ enum netdev_state_t
+       __LINK_STATE_SCHED,
+       __LINK_STATE_NOCARRIER,
+       __LINK_STATE_RX_SCHED,
+-      __LINK_STATE_LINKWATCH_PENDING
++      __LINK_STATE_LINKWATCH_PENDING,
++      __LINK_STATE_QDISC_RUNNING,
+ };
+ 
+ 
+@@ -306,9 +307,17 @@ #define NETIF_F_HW_VLAN_TX        128     /* Transm
+ #define NETIF_F_HW_VLAN_RX    256     /* Receive VLAN hw acceleration */
+ #define NETIF_F_HW_VLAN_FILTER        512     /* Receive filtering on VLAN */
+ #define NETIF_F_VLAN_CHALLENGED       1024    /* Device cannot handle VLAN 
packets */
+-#define NETIF_F_TSO           2048    /* Can offload TCP/IP segmentation */
++#define NETIF_F_GSO           2048    /* Enable software GSO. */
+ #define NETIF_F_LLTX          4096    /* LockLess TX */
+-#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
++
++      /* Segmentation offload features */
++#define NETIF_F_GSO_SHIFT     16
++#define NETIF_F_TSO           (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
++#define NETIF_F_UFO           (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
++#define NETIF_F_GSO_ROBUST    (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
++
++#define NETIF_F_GEN_CSUM      (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
++#define NETIF_F_ALL_CSUM      (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
+ 
+       struct net_device       *next_sched;
+ 
+@@ -394,6 +403,9 @@ #define NETIF_F_UFO             8192    
+       struct list_head        qdisc_list;
+       unsigned long           tx_queue_len;   /* Max frames per queue allowed 
*/
+ 
++      /* Partially transmitted GSO packet. */
++      struct sk_buff          *gso_skb;
++
+       /* ingress path synchronizer */
+       spinlock_t              ingress_lock;
+       struct Qdisc            *qdisc_ingress;
+@@ -402,7 +414,7 @@ #define NETIF_F_UFO             8192    
+  * One part is mostly used on xmit path (device)
+  */
+       /* hard_start_xmit synchronizer */
+-      spinlock_t              xmit_lock ____cacheline_aligned_in_smp;
++      spinlock_t              _xmit_lock ____cacheline_aligned_in_smp;
+       /* cpu id of processor entered to hard_start_xmit or -1,
+          if nobody entered there.
+        */
+@@ -527,6 +539,8 @@ struct packet_type {
+                                        struct net_device *,
+                                        struct packet_type *,
+                                        struct net_device *);
++      struct sk_buff          *(*gso_segment)(struct sk_buff *skb,
++                                              int features);
+       void                    *af_packet_priv;
+       struct list_head        list;
+ };
+@@ -693,7 +707,8 @@ extern int         dev_change_name(struct net_d
+ extern int            dev_set_mtu(struct net_device *, int);
+ extern int            dev_set_mac_address(struct net_device *,
+                                           struct sockaddr *);
+-extern void           dev_queue_xmit_nit(struct sk_buff *skb, struct 
net_device *dev);
++extern int            dev_hard_start_xmit(struct sk_buff *skb,
++                                          struct net_device *dev);
+ 
+ extern void           dev_init(void);
+ 
+@@ -900,11 +915,43 @@ static inline void __netif_rx_complete(s
+       clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
+ }
+ 
++static inline void netif_tx_lock(struct net_device *dev)
++{
++      spin_lock(&dev->_xmit_lock);
++      dev->xmit_lock_owner = smp_processor_id();
++}
++
++static inline void netif_tx_lock_bh(struct net_device *dev)
++{
++      spin_lock_bh(&dev->_xmit_lock);
++      dev->xmit_lock_owner = smp_processor_id();
++}
++
++static inline int netif_tx_trylock(struct net_device *dev)
++{
++      int err = spin_trylock(&dev->_xmit_lock);
++      if (!err)
++              dev->xmit_lock_owner = smp_processor_id();
++      return err;
++}
++
++static inline void netif_tx_unlock(struct net_device *dev)
++{
++      dev->xmit_lock_owner = -1;
++      spin_unlock(&dev->_xmit_lock);
++}
++
++static inline void netif_tx_unlock_bh(struct net_device *dev)
++{
++      dev->xmit_lock_owner = -1;
++      spin_unlock_bh(&dev->_xmit_lock);
++}
++
+ static inline void netif_tx_disable(struct net_device *dev)
+ {
+-      spin_lock_bh(&dev->xmit_lock);
++      netif_tx_lock_bh(dev);
+       netif_stop_queue(dev);
+-      spin_unlock_bh(&dev->xmit_lock);
++      netif_tx_unlock_bh(dev);
+ }
+ 
+ /* These functions live elsewhere (drivers/net/net_init.c, but related) */
+@@ -932,6 +979,7 @@ extern int         netdev_max_backlog;
+ extern int            weight_p;
+ extern int            netdev_set_master(struct net_device *dev, struct 
net_device *master);
+ extern int skb_checksum_help(struct sk_buff *skb, int inward);
++extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
+ #ifdef CONFIG_BUG
+ extern void netdev_rx_csum_fault(struct net_device *dev);
+ #else
+@@ -951,6 +999,18 @@ #endif
+ 
+ extern void linkwatch_run_queue(void);
+ 
++static inline int skb_gso_ok(struct sk_buff *skb, int features)
++{
++      int feature = skb_shinfo(skb)->gso_size ?
++                    skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
++      return (features & feature) == feature;
++}
++
++static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
++{
++      return !skb_gso_ok(skb, dev->features);
++}
++
+ #endif /* __KERNEL__ */
+ 
+ #endif        /* _LINUX_DEV_H */
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index ad7cc22..b19d45d 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -134,9 +134,10 @@ struct skb_frag_struct {
+ struct skb_shared_info {
+       atomic_t        dataref;
+       unsigned short  nr_frags;
+-      unsigned short  tso_size;
+-      unsigned short  tso_segs;
+-      unsigned short  ufo_size;
++      unsigned short  gso_size;
++      /* Warning: this field is not always filled in (UFO)! */
++      unsigned short  gso_segs;
++      unsigned short  gso_type;
+       unsigned int    ip6_frag_id;
+       struct sk_buff  *frag_list;
+       skb_frag_t      frags[MAX_SKB_FRAGS];
+@@ -168,6 +169,14 @@ enum {
+       SKB_FCLONE_CLONE,
+ };
+ 
++enum {
++      SKB_GSO_TCPV4 = 1 << 0,
++      SKB_GSO_UDPV4 = 1 << 1,
++
++      /* This indicates the skb is from an untrusted source. */
++      SKB_GSO_DODGY = 1 << 2,
++};
++
+ /** 
+  *    struct sk_buff - socket buffer
+  *    @next: Next buffer in list
+@@ -1148,18 +1157,34 @@ static inline int skb_can_coalesce(struc
+       return 0;
+ }
+ 
++static inline int __skb_linearize(struct sk_buff *skb)
++{
++      return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
++}
++
+ /**
+  *    skb_linearize - convert paged skb to linear one
+  *    @skb: buffer to linarize
+- *    @gfp: allocation mode
+  *
+  *    If there is no free memory -ENOMEM is returned, otherwise zero
+  *    is returned and the old skb data released.
+  */
+-extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
+-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
++static inline int skb_linearize(struct sk_buff *skb)
++{
++      return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
++}
++
++/**
++ *    skb_linearize_cow - make sure skb is linear and writable
++ *    @skb: buffer to process
++ *
++ *    If there is no free memory -ENOMEM is returned, otherwise zero
++ *    is returned and the old skb data released.
++ */
++static inline int skb_linearize_cow(struct sk_buff *skb)
+ {
+-      return __skb_linearize(skb, gfp);
++      return skb_is_nonlinear(skb) || skb_cloned(skb) ?
++             __skb_linearize(skb) : 0;
+ }
+ 
+ /**
+@@ -1254,6 +1279,7 @@ extern void             skb_split(struct sk_b
+                                struct sk_buff *skb1, const u32 len);
+ 
+ extern void          skb_release_data(struct sk_buff *skb);
++extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
+ 
+ static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
+                                      int len, void *buffer)
+diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
+index b94d1ad..75b5b93 100644
+--- a/include/net/pkt_sched.h
++++ b/include/net/pkt_sched.h
+@@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_ge
+               struct rtattr *tab);
+ extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
+ 
+-extern int qdisc_restart(struct net_device *dev);
++extern void __qdisc_run(struct net_device *dev);
+ 
+ static inline void qdisc_run(struct net_device *dev)
+ {
+-      while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
+-              /* NOTHING */;
++      if (!netif_queue_stopped(dev) &&
++          !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
++              __qdisc_run(dev);
+ }
+ 
+ extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
+diff --git a/include/net/protocol.h b/include/net/protocol.h
+index 6dc5970..0d2dcdb 100644
+--- a/include/net/protocol.h
++++ b/include/net/protocol.h
+@@ -37,6 +37,8 @@ #define MAX_INET_PROTOS      256             /* Must be 
+ struct net_protocol {
+       int                     (*handler)(struct sk_buff *skb);
+       void                    (*err_handler)(struct sk_buff *skb, u32 info);
++      struct sk_buff         *(*gso_segment)(struct sk_buff *skb,
++                                             int features);
+       int                     no_policy;
+ };
+ 
+diff --git a/include/net/sock.h b/include/net/sock.h
+index f63d0d5..a8e8d21 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1064,9 +1064,13 @@ static inline void sk_setup_caps(struct 
+ {
+       __sk_dst_set(sk, dst);
+       sk->sk_route_caps = dst->dev->features;
++      if (sk->sk_route_caps & NETIF_F_GSO)
++              sk->sk_route_caps |= NETIF_F_TSO;
+       if (sk->sk_route_caps & NETIF_F_TSO) {
+               if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
+                       sk->sk_route_caps &= ~NETIF_F_TSO;
++              else 
++                      sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
+       }
+ }
+ 
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 77f21c6..70e1d5f 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -552,13 +552,13 @@ #include <net/tcp_ecn.h>
+  */
+ static inline int tcp_skb_pcount(const struct sk_buff *skb)
+ {
+-      return skb_shinfo(skb)->tso_segs;
++      return skb_shinfo(skb)->gso_segs;
+ }
+ 
+ /* This is valid iff tcp_skb_pcount() > 1. */
+ static inline int tcp_skb_mss(const struct sk_buff *skb)
+ {
+-      return skb_shinfo(skb)->tso_size;
++      return skb_shinfo(skb)->gso_size;
+ }
+ 
+ static inline void tcp_dec_pcount_approx(__u32 *count,
+@@ -1063,6 +1063,8 @@ extern struct request_sock_ops tcp_reque
+ 
+ extern int tcp_v4_destroy_sock(struct sock *sk);
+ 
++extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
++
+ #ifdef CONFIG_PROC_FS
+ extern int  tcp4_proc_init(void);
+ extern void tcp4_proc_exit(void);
+diff --git a/net/atm/clip.c b/net/atm/clip.c
+index 1842a4e..6dc21a7 100644
+--- a/net/atm/clip.c
++++ b/net/atm/clip.c
+@@ -101,7 +101,7 @@ static void unlink_clip_vcc(struct clip_
+               printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
+               return;
+       }
+-      spin_lock_bh(&entry->neigh->dev->xmit_lock);    /* block 
clip_start_xmit() */
++      netif_tx_lock_bh(entry->neigh->dev);    /* block clip_start_xmit() */
+       entry->neigh->used = jiffies;
+       for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
+               if (*walk == clip_vcc) {
+@@ -125,7 +125,7 @@ static void unlink_clip_vcc(struct clip_
+       printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
+         "0x%p)\n",entry,clip_vcc);
+ out:
+-      spin_unlock_bh(&entry->neigh->dev->xmit_lock);
++      netif_tx_unlock_bh(entry->neigh->dev);
+ }
+ 
+ /* The neighbour entry n->lock is held. */
+diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
+index 0b33a7b..180e79b 100644
+--- a/net/bridge/br_device.c
++++ b/net/bridge/br_device.c
+@@ -146,9 +146,9 @@ static int br_set_tx_csum(struct net_dev
+       struct net_bridge *br = netdev_priv(dev);
+ 
+       if (data)
+-              br->feature_mask |= NETIF_F_IP_CSUM;
++              br->feature_mask |= NETIF_F_NO_CSUM;
+       else
+-              br->feature_mask &= ~NETIF_F_IP_CSUM;
++              br->feature_mask &= ~NETIF_F_ALL_CSUM;
+ 
+       br_features_recompute(br);
+       return 0;
+@@ -185,6 +185,6 @@ void br_dev_setup(struct net_device *dev
+       dev->set_mac_address = br_set_mac_address;
+       dev->priv_flags = IFF_EBRIDGE;
+ 
+-      dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
+-              | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
++      dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
++                      NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST;
+ }
+diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
+index 2d24fb4..00b1128 100644
+--- a/net/bridge/br_forward.c
++++ b/net/bridge/br_forward.c
+@@ -32,7 +32,7 @@ static inline int should_deliver(const s
+ int br_dev_queue_push_xmit(struct sk_buff *skb)
+ {
+       /* drop mtu oversized packets except tso */
+-      if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
++      if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size)
+               kfree_skb(skb);
+       else {
+ #ifdef CONFIG_BRIDGE_NETFILTER
+diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
+index f36b35e..0617146 100644
+--- a/net/bridge/br_if.c
++++ b/net/bridge/br_if.c
+@@ -385,17 +385,28 @@ void br_features_recompute(struct net_br
+       struct net_bridge_port *p;
+       unsigned long features, checksum;
+ 
+-      features = br->feature_mask &~ NETIF_F_IP_CSUM;
+-      checksum = br->feature_mask & NETIF_F_IP_CSUM;
++      checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
++      features = br->feature_mask & ~NETIF_F_ALL_CSUM;
+ 
+       list_for_each_entry(p, &br->port_list, list) {
+-              if (!(p->dev->features 
+-                    & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
++              unsigned long feature = p->dev->features;
++
++              if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
++                      checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
++              if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
++                      checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
++              if (!(feature & NETIF_F_IP_CSUM))
+                       checksum = 0;
+-              features &= p->dev->features;
++
++              if (feature & NETIF_F_GSO)
++                      feature |= NETIF_F_TSO;
++              feature |= NETIF_F_GSO;
++
++              features &= feature;
+       }
+ 
+-      br->dev->features = features | checksum | NETIF_F_LLTX;
++      br->dev->features = features | checksum | NETIF_F_LLTX |
++                          NETIF_F_GSO_ROBUST;
+ }
+ 
+ /* called with RTNL */
+diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
+index 9e27373..588207f 100644
+--- a/net/bridge/br_netfilter.c
++++ b/net/bridge/br_netfilter.c
+@@ -743,7 +743,7 @@ static int br_nf_dev_queue_xmit(struct s
+ {
+       if (skb->protocol == htons(ETH_P_IP) &&
+           skb->len > skb->dev->mtu &&
+-          !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
++          !skb_shinfo(skb)->gso_size)
+               return ip_fragment(skb, br_dev_queue_push_xmit);
+       else
+               return br_dev_queue_push_xmit(skb);
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 12a214c..32e1056 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -115,6 +115,7 @@ #include <linux/wireless.h>                /* Note : w
+ #include <net/iw_handler.h>
+ #endif        /* CONFIG_NET_RADIO */
+ #include <asm/current.h>
++#include <linux/err.h>
+ 
+ /*
+  *    The list of packet types we will receive (as opposed to discard)
+@@ -1032,7 +1033,7 @@ static inline void net_timestamp(struct 
+  *    taps currently in use.
+  */
+ 
+-void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
++static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct packet_type *ptype;
+ 
+@@ -1106,6 +1107,45 @@ out:    
+       return ret;
+ }
+ 
++/**
++ *    skb_gso_segment - Perform segmentation on skb.
++ *    @skb: buffer to segment
++ *    @features: features for the output path (see dev->features)
++ *
++ *    This function segments the given skb and returns a list of segments.
++ *
++ *    It may return NULL if the skb requires no segmentation.  This is
++ *    only possible when GSO is used for verifying header integrity.
++ */
++struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
++{
++      struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
++      struct packet_type *ptype;
++      int type = skb->protocol;
++
++      BUG_ON(skb_shinfo(skb)->frag_list);
++      BUG_ON(skb->ip_summed != CHECKSUM_HW);
++
++      skb->mac.raw = skb->data;
++      skb->mac_len = skb->nh.raw - skb->data;
++      __skb_pull(skb, skb->mac_len);
++
++      rcu_read_lock();
++      list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
++              if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
++                      segs = ptype->gso_segment(skb, features);
++                      break;
++              }
++      }
++      rcu_read_unlock();
++
++      __skb_push(skb, skb->data - skb->mac.raw);
++
++      return segs;
++}
++
++EXPORT_SYMBOL(skb_gso_segment);
++
+ /* Take action when hardware reception checksum errors are detected. */
+ #ifdef CONFIG_BUG
+ void netdev_rx_csum_fault(struct net_device *dev)
+@@ -1142,75 +1182,108 @@ #else
+ #define illegal_highdma(dev, skb)     (0)
+ #endif
+ 
+-/* Keep head the same: replace data */
+-int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
+-{
+-      unsigned int size;
+-      u8 *data;
+-      long offset;
+-      struct skb_shared_info *ninfo;
+-      int headerlen = skb->data - skb->head;
+-      int expand = (skb->tail + skb->data_len) - skb->end;
+-
+-      if (skb_shared(skb))
+-              BUG();
+-
+-      if (expand <= 0)
+-              expand = 0;
+-
+-      size = skb->end - skb->head + expand;
+-      size = SKB_DATA_ALIGN(size);
+-      data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+-      if (!data)
+-              return -ENOMEM;
+-
+-      /* Copy entire thing */
+-      if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
+-              BUG();
+-
+-      /* Set up shinfo */
+-      ninfo = (struct skb_shared_info*)(data + size);
+-      atomic_set(&ninfo->dataref, 1);
+-      ninfo->tso_size = skb_shinfo(skb)->tso_size;
+-      ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
+-      ninfo->nr_frags = 0;
+-      ninfo->frag_list = NULL;
+-
+-      /* Offset between the two in bytes */
+-      offset = data - skb->head;
+-
+-      /* Free old data. */
+-      skb_release_data(skb);
+-
+-      skb->head = data;
+-      skb->end  = data + size;
+-
+-      /* Set up new pointers */
+-      skb->h.raw   += offset;
+-      skb->nh.raw  += offset;
+-      skb->mac.raw += offset;
+-      skb->tail    += offset;
+-      skb->data    += offset;
+-
+-      /* We are no longer a clone, even if we were. */
+-      skb->cloned    = 0;
+-
+-      skb->tail     += skb->data_len;
+-      skb->data_len  = 0;
++struct dev_gso_cb {
++      void (*destructor)(struct sk_buff *skb);
++};
++
++#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
++
++static void dev_gso_skb_destructor(struct sk_buff *skb)
++{
++      struct dev_gso_cb *cb;
++
++      do {
++              struct sk_buff *nskb = skb->next;
++
++              skb->next = nskb->next;
++              nskb->next = NULL;
++              kfree_skb(nskb);
++      } while (skb->next);
++
++      cb = DEV_GSO_CB(skb);
++      if (cb->destructor)
++              cb->destructor(skb);
++}
++
++/**
++ *    dev_gso_segment - Perform emulated hardware segmentation on skb.
++ *    @skb: buffer to segment
++ *
++ *    This function segments the given skb and stores the list of segments
++ *    in skb->next.
++ */
++static int dev_gso_segment(struct sk_buff *skb)
++{
++      struct net_device *dev = skb->dev;
++      struct sk_buff *segs;
++      int features = dev->features & ~(illegal_highdma(dev, skb) ?
++                                       NETIF_F_SG : 0);
++
++      segs = skb_gso_segment(skb, features);
++
++      /* Verifying header integrity only. */
++      if (!segs)
++              return 0;
++
++      if (unlikely(IS_ERR(segs)))
++              return PTR_ERR(segs);
++
++      skb->next = segs;
++      DEV_GSO_CB(skb)->destructor = skb->destructor;
++      skb->destructor = dev_gso_skb_destructor;
++
++      return 0;
++}
++
++int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++      if (likely(!skb->next)) {
++              if (netdev_nit)
++                      dev_queue_xmit_nit(skb, dev);
++
++              if (netif_needs_gso(dev, skb)) {
++                      if (unlikely(dev_gso_segment(skb)))
++                              goto out_kfree_skb;
++                      if (skb->next)
++                              goto gso;
++              }
++
++              return dev->hard_start_xmit(skb, dev);
++      }
++
++gso:
++      do {
++              struct sk_buff *nskb = skb->next;
++              int rc;
++
++              skb->next = nskb->next;
++              nskb->next = NULL;
++              rc = dev->hard_start_xmit(nskb, dev);
++              if (unlikely(rc)) {
++                      nskb->next = skb->next;
++                      skb->next = nskb;
++                      return rc;
++              }
++              if (unlikely(netif_queue_stopped(dev) && skb->next))
++                      return NETDEV_TX_BUSY;
++      } while (skb->next);
++      
++      skb->destructor = DEV_GSO_CB(skb)->destructor;
++
++out_kfree_skb:
++      kfree_skb(skb);
+       return 0;
+ }
+ 
+ #define HARD_TX_LOCK(dev, cpu) {                      \
+       if ((dev->features & NETIF_F_LLTX) == 0) {      \
+-              spin_lock(&dev->xmit_lock);             \
+-              dev->xmit_lock_owner = cpu;             \
++              netif_tx_lock(dev);                     \
+       }                                               \
+ }
+ 
+ #define HARD_TX_UNLOCK(dev) {                         \
+       if ((dev->features & NETIF_F_LLTX) == 0) {      \
+-              dev->xmit_lock_owner = -1;              \
+-              spin_unlock(&dev->xmit_lock);           \
++              netif_tx_unlock(dev);                   \
+       }                                               \
+ }
+ 
+@@ -1246,9 +1319,13 @@ int dev_queue_xmit(struct sk_buff *skb)
+       struct Qdisc *q;
+       int rc = -ENOMEM;
+ 
++      /* GSO will handle the following emulations directly. */
++      if (netif_needs_gso(dev, skb))
++              goto gso;
++
+       if (skb_shinfo(skb)->frag_list &&
+           !(dev->features & NETIF_F_FRAGLIST) &&
+-          __skb_linearize(skb, GFP_ATOMIC))
++          __skb_linearize(skb))
+               goto out_kfree_skb;
+ 
+       /* Fragmented skb is linearized if device does not support SG,
+@@ -1257,25 +1334,26 @@ int dev_queue_xmit(struct sk_buff *skb)
+        */
+       if (skb_shinfo(skb)->nr_frags &&
+           (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
+-          __skb_linearize(skb, GFP_ATOMIC))
++          __skb_linearize(skb))
+               goto out_kfree_skb;
+ 
+       /* If packet is not checksummed and device does not support
+        * checksumming for this protocol, complete checksumming here.
+        */
+       if (skb->ip_summed == CHECKSUM_HW &&
+-          (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
++          (!(dev->features & NETIF_F_GEN_CSUM) &&
+            (!(dev->features & NETIF_F_IP_CSUM) ||
+             skb->protocol != htons(ETH_P_IP))))
+               if (skb_checksum_help(skb, 0))
+                       goto out_kfree_skb;
+ 
++gso:
+       spin_lock_prefetch(&dev->queue_lock);
+ 
+       /* Disable soft irqs for various locks below. Also 
+        * stops preemption for RCU. 
+        */
+-      local_bh_disable(); 
++      rcu_read_lock_bh(); 
+ 
+       /* Updates of qdisc are serialized by queue_lock. 
+        * The struct Qdisc which is pointed to by qdisc is now a 
+@@ -1309,8 +1387,8 @@ #endif
+       /* The device has no queue. Common case for software devices:
+          loopback, all the sorts of tunnels...
+ 
+-         Really, it is unlikely that xmit_lock protection is necessary here.
+-         (f.e. loopback and IP tunnels are clean ignoring statistics
++         Really, it is unlikely that netif_tx_lock protection is necessary
++         here.  (f.e. loopback and IP tunnels are clean ignoring statistics
+          counters.)
+          However, it is possible, that they rely on protection
+          made by us here.
+@@ -1326,11 +1404,8 @@ #endif
+                       HARD_TX_LOCK(dev, cpu);
+ 
+                       if (!netif_queue_stopped(dev)) {
+-                              if (netdev_nit)
+-                                      dev_queue_xmit_nit(skb, dev);
+-
+                               rc = 0;
+-                              if (!dev->hard_start_xmit(skb, dev)) {
++                              if (!dev_hard_start_xmit(skb, dev)) {
+                                       HARD_TX_UNLOCK(dev);
+                                       goto out;
+                               }
+@@ -1349,13 +1424,13 @@ #endif
+       }
+ 
+       rc = -ENETDOWN;
+-      local_bh_enable();
++      rcu_read_unlock_bh();
+ 
+ out_kfree_skb:
+       kfree_skb(skb);
+       return rc;
+ out:
+-      local_bh_enable();
++      rcu_read_unlock_bh();
+       return rc;
+ }
+ 
+@@ -2670,7 +2745,7 @@ int register_netdevice(struct net_device
+       BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
+ 
+       spin_lock_init(&dev->queue_lock);
+-      spin_lock_init(&dev->xmit_lock);
++      spin_lock_init(&dev->_xmit_lock);
+       dev->xmit_lock_owner = -1;
+ #ifdef CONFIG_NET_CLS_ACT
+       spin_lock_init(&dev->ingress_lock);
+@@ -2714,9 +2789,7 @@ #endif
+ 
+       /* Fix illegal SG+CSUM combinations. */
+       if ((dev->features & NETIF_F_SG) &&
+-          !(dev->features & (NETIF_F_IP_CSUM |
+-                             NETIF_F_NO_CSUM |

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.