WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

[XenPPC] [xenppc-unstable] [ppc-merge] update with http://xenbits.xensou

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [xenppc-unstable] [ppc-merge] update with http://xenbits.xensource.com/xen-unstable.hg
From: Xen patchbot-xenppc-unstable <patchbot-xenppc-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 30 Jun 2006 11:31:51 +0000
Delivery-date: Fri, 30 Jun 2006 04:36:59 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID 316eff29c61c2e50c2360e27d9ad93fc28def477
# Parent  e06866a6e2b745cece7dc748f37323367a1577ed
# Parent  ae245d35457b03f680b994437bd25532b98aa523
[ppc-merge] update with http://xenbits.xensource.com/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-impl                             |  136 +
 tools/firmware/hvmloader/Makefile                    |    6 
 tools/firmware/hvmloader/acpi_madt.c                 |    2 
 tools/firmware/hvmloader/hvmloader.c                 |    8 
 tools/firmware/hvmloader/mp_tables.c                 |  426 ++++
 tools/firmware/rombios/Makefile                      |   36 
 tools/firmware/rombios/rombios.c                     |   30 
 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/XendLogging.py                 |    2 
 tools/python/xen/xend/XendNode.py                    |    4 
 tools/python/xen/xend/balloon.py                     |   69 
 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 
 85 files changed, 5643 insertions(+), 1476 deletions(-)

diff -r e06866a6e2b7 -r 316eff29c61c Makefile
--- a/Makefile  Thu Jun 29 13:10:42 2006 -0400
+++ b/Makefile  Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c docs/Makefile
--- a/docs/Makefile     Thu Jun 29 13:10:42 2006 -0400
+++ b/docs/Makefile     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Thu Jun 29 13:10:42 
2006 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Thu Jun 29 
13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Thu Jun 29 
13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Jun 29 13:10:42 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Thu Jun 29 
13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Jun 29 13:10:42 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Thu Jun 29 13:10:42 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Thu Jun 29 
13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/netback/loopback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Thu Jun 29 
13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c       Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Thu Jun 29 
13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Jun 29 13:10:42 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Jun 29 13:10:42 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Thu Jun 29 
13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Thu Jun 29 
13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Thu Jun 29 13:10:42 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c linux-2.6-xen-sparse/include/linux/skbuff.h
--- a/linux-2.6-xen-sparse/include/linux/skbuff.h       Thu Jun 29 13:10:42 
2006 -0400
+++ b/linux-2.6-xen-sparse/include/linux/skbuff.h       Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c       Thu Jun 29 13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/net/core/dev.c       Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c linux-2.6-xen-sparse/net/core/skbuff.c
--- a/linux-2.6-xen-sparse/net/core/skbuff.c    Thu Jun 29 13:10:42 2006 -0400
+++ b/linux-2.6-xen-sparse/net/core/skbuff.c    Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
patches/linux-2.6.16.13/xenoprof-generic.patch
--- a/patches/linux-2.6.16.13/xenoprof-generic.patch    Thu Jun 29 13:10:42 
2006 -0400
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch    Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/Makefile
--- a/tools/Makefile    Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/Makefile    Fri Jun 30 07:21:58 2006 -0400
@@ -45,6 +45,9 @@ clean: check_clean
        done
        $(MAKE) ioemuclean
 
+.PHONY: distclean
+distclean: clean
+
 .PHONY: check
 check:
        $(MAKE) -C check
diff -r e06866a6e2b7 -r 316eff29c61c tools/examples/Makefile
--- a/tools/examples/Makefile   Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/examples/Makefile   Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/firmware/hvmloader/Makefile Fri Jun 30 07:21:58 2006 -0400
@@ -45,9 +45,9 @@ LDFLAGS  = -m32 -nostdlib -Wl,-N -Wl,-Tt
 .PHONY: all
 all: hvmloader
 
-hvmloader: roms.h hvmloader.c acpi_madt.c
-       $(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c
-       $(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o
+hvmloader: roms.h hvmloader.c acpi_madt.c mp_tables.c
+       $(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c mp_tables.c
+       $(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o mp_tables.o
        $(OBJCOPY) hvmloader.tmp hvmloader
        rm -f hvmloader.tmp
 
diff -r e06866a6e2b7 -r 316eff29c61c tools/firmware/hvmloader/acpi_madt.c
--- a/tools/firmware/hvmloader/acpi_madt.c      Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/firmware/hvmloader/acpi_madt.c      Fri Jun 30 07:21:58 2006 -0400
@@ -51,7 +51,7 @@ static int validate_hvm_info(struct hvm_
 }
 
 /* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
-static struct hvm_info_table *
+struct hvm_info_table *
 get_hvm_info_table(void)
 {
        struct hvm_info_table *t;
diff -r e06866a6e2b7 -r 316eff29c61c tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/firmware/hvmloader/hvmloader.c      Fri Jun 30 07:21:58 2006 -0400
@@ -23,6 +23,7 @@
  */
 #include "roms.h"
 #include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include <xen/hvm/hvm_info_table.h>
 
 /* memory map */
 #define VGABIOS_PHYSICAL_ADDRESS       0x000C0000
@@ -71,6 +72,8 @@ asm(
 
 extern int get_acpi_enabled(void);
 extern int acpi_madt_update(unsigned char* acpi_start);
+extern void create_mp_tables(void);
+struct hvm_info_table *get_hvm_info_table(void);
 
 static inline void
 outw(unsigned short addr, unsigned short val)
@@ -162,10 +165,15 @@ int
 int
 main(void)
 {
+       struct hvm_info_table *t = get_hvm_info_table();
+
        puts("HVM Loader\n");
 
        puts("Loading ROMBIOS ...\n");
        memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
+       if (t->apic_enabled)
+               create_mp_tables();
+       
        if (cirrus_check()) {
                puts("Loading Cirrus VGABIOS ...\n");
                memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
diff -r e06866a6e2b7 -r 316eff29c61c tools/firmware/rombios/Makefile
--- a/tools/firmware/rombios/Makefile   Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/firmware/rombios/Makefile   Fri Jun 30 07:21:58 2006 -0400
@@ -1,13 +1,9 @@ BIOS_BUILDS = BIOS-bochs-latest
-BIOS_BUILDS = BIOS-bochs-latest
-#BIOS_BUILDS += BIOS-bochs-2-processors
-#BIOS_BUILDS += BIOS-bochs-4-processors
-#BIOS_BUILDS += BIOS-bochs-8-processors
 
 .PHONY: all
 all: bios
 
 .PHONY: bios
-bios: biossums ${BIOS_BUILDS}
+bios: biossums BIOS-bochs-latest
 
 .PHONY: clean
 clean:
@@ -26,36 +22,6 @@ BIOS-bochs-latest: rombios.c biossums
        ./biossums BIOS-bochs-latest
        rm -f _rombios_.s
 
-BIOS-bochs-2-processors: rombios.c biossums
-       gcc -DBX_SMP_PROCESSORS=2 -E -P $< > _rombios2_.c
-       bcc -o rombios2.s -C-c -D__i86__ -0 -S _rombios2_.c
-       sed -e 's/^\.text//' -e 's/^\.data//' rombios2.s > _rombios2_.s
-       as86 _rombios2_.s -b tmp2.bin -u- -w- -g -0 -j -O -l rombios2.txt
-       -perl makesym.perl < rombios2.txt > rombios2.sym
-       mv tmp2.bin BIOS-bochs-2-processors
-       ./biossums BIOS-bochs-2-processors
-       rm -f _rombios2_.s
-
-BIOS-bochs-4-processors: rombios.c biossums
-       gcc -DBX_SMP_PROCESSORS=4 -E -P $< > _rombios4_.c
-       bcc -o rombios4.s -C-c -D__i86__ -0 -S _rombios4_.c
-       sed -e 's/^\.text//' -e 's/^\.data//' rombios4.s > _rombios4_.s
-       as86 _rombios4_.s -b tmp4.bin -u- -w- -g -0 -j -O -l rombios4.txt
-       -perl makesym.perl < rombios4.txt > rombios4.sym
-       mv tmp4.bin BIOS-bochs-4-processors
-       ./biossums BIOS-bochs-4-processors
-       rm -f _rombios4_.s
-
-BIOS-bochs-8-processors: rombios.c biossums
-       gcc -DBX_SMP_PROCESSORS=8 -E -P $< > _rombios8_.c
-       bcc -o rombios8.s -C-c -D__i86__ -0 -S _rombios8_.c
-       sed -e 's/^\.text//' -e 's/^\.data//' rombios8.s > _rombios8_.s
-       as86 _rombios8_.s -b tmp8.bin -u- -w- -g -0 -j -O -l rombios8.txt
-       -perl makesym.perl < rombios8.txt > rombios8.sym
-       mv tmp8.bin BIOS-bochs-8-processors
-       ./biossums BIOS-bochs-8-processors
-       rm -f _rombios8_.s
-
 biossums: biossums.c
        gcc -o biossums biossums.c
 
diff -r e06866a6e2b7 -r 316eff29c61c tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/firmware/rombios/rombios.c  Fri Jun 30 07:21:58 2006 -0400
@@ -10514,6 +10514,34 @@ static Bit8u vgafont8[128*8]=
  0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
 };
 
+#ifdef HVMASSIST
+//
+// MP Tables
+// just carve out some blank space for HVMLOADER to write the MP tables to
+//
+// NOTE: There should be enough space for a 32 processor entry MP table
+//
+ASM_START
+.org 0xcc00
+db 0x5F, 0x5F, 0x5F, 0x48, 0x56, 0x4D, 0x4D, 0x50 ;; ___HVMMP
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;;  64 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 128 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 192 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 256 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 320 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 384 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 448 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 512 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 576 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 640 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 704 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 768 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 832 bytes
+dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 896 bytes
+ASM_END
+
+#else // !HVMASSIST
+
 ASM_START
 .org 0xcc00
 // bcc-generated data will be placed here
@@ -10835,3 +10863,5 @@ db 0,0,0,0     ;; MP feature bytes 2-5.
 #endif
 
 ASM_END
+
+#endif // HVMASSIST
diff -r e06866a6e2b7 -r 316eff29c61c tools/libxc/xc_ia64_stubs.c
--- a/tools/libxc/xc_ia64_stubs.c       Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/libxc/xc_ia64_stubs.c       Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/libxc/xc_linux_build.c      Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/libxc/xg_private.h  Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py      Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/python/xen/xend/XendLogging.py      Fri Jun 30 07:21:58 2006 -0400
@@ -43,7 +43,7 @@ BACKUP_COUNT = 5
 BACKUP_COUNT = 5
 
 STDERR_FORMAT = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
-LOGFILE_FORMAT = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) 
%(message)s"
+LOGFILE_FORMAT = "[%(asctime)s %(name)s %(process)d] %(levelname)s 
(%(module)s:%(lineno)d) %(message)s"
 DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
 
 
diff -r e06866a6e2b7 -r 316eff29c61c tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/python/xen/xend/XendNode.py Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/python/xen/xend/balloon.py
--- a/tools/python/xen/xend/balloon.py  Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/python/xen/xend/balloon.py  Fri Jun 30 07:21:58 2006 -0400
@@ -29,8 +29,6 @@ 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 = 20
 RETRY_LIMIT_INCR = 5
 ##
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/python/xen/xm/main.py       Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm/Rules.mk
--- a/tools/vtpm/Rules.mk       Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm/Rules.mk       Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm/tpm_emulator-0.3-x86_64.patch
--- a/tools/vtpm/tpm_emulator-0.3-x86_64.patch  Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm/tpm_emulator-0.3-x86_64.patch  Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm/tpm_emulator.patch
--- a/tools/vtpm/tpm_emulator.patch     Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm/tpm_emulator.patch     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm/vtpm.patch
--- a/tools/vtpm/vtpm.patch     Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm/vtpm.patch     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk       Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/Rules.mk       Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c       Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/manager/dmictl.c       Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c        Thu Jun 29 13:10:42 
2006 -0400
+++ b/tools/vtpm_manager/manager/securestorage.c        Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/manager/vtpm_manager.c Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/manager/vtpm_manager.h Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
tools/vtpm_manager/manager/vtpm_manager_handler.c
--- a/tools/vtpm_manager/manager/vtpm_manager_handler.c Thu Jun 29 13:10:42 
2006 -0400
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c Fri Jun 30 07:21:58 
2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c        Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/manager/vtpmd.c        Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h     Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/manager/vtpmpriv.h     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/manager/vtsp.c Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/manager/vtsp.h Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/tcs/tcs.c
--- a/tools/vtpm_manager/tcs/tcs.c      Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/tcs/tcs.c      Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/tcs/tcs.h
--- a/tools/vtpm_manager/tcs/tcs.h      Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/tcs/tcs.h      Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/tcs/transmit.c
--- a/tools/vtpm_manager/tcs/transmit.c Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/tcs/transmit.c Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/vtpm_manager/util/tcg.h
--- a/tools/vtpm_manager/util/tcg.h     Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/vtpm_manager/util/tcg.h     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/xenstat/xentop/xentop.1
--- a/tools/xenstat/xentop/xentop.1     Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/xenstat/xentop/xentop.1     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c tools/xenstat/xentop/xentop.c
--- a/tools/xenstat/xentop/xentop.c     Thu Jun 29 13:10:42 2006 -0400
+++ b/tools/xenstat/xentop/xentop.c     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 
tools/xm-test/tests/info/02_info_compiledata_pos.py
--- a/tools/xm-test/tests/info/02_info_compiledata_pos.py       Thu Jun 29 
13:10:42 2006 -0400
+++ b/tools/xm-test/tests/info/02_info_compiledata_pos.py       Fri Jun 30 
07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/Makefile
--- a/xen/Makefile      Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/Makefile      Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/dom0_ops.c   Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/hvm/vioapic.c        Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/hvm/vlapic.c Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/microcode.c
--- a/xen/arch/x86/microcode.c  Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/microcode.c  Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c   Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/oprofile/nmi_int.c   Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c  Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/oprofile/xenoprof.c  Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/smp.c
--- a/xen/arch/x86/smp.c        Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/smp.c        Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/arch/x86/x86_emulate.c        Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/common/kernel.c
--- a/xen/common/kernel.c       Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/common/kernel.c       Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/common/page_alloc.c   Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/asm-x86/bitops.h
--- a/xen/include/asm-x86/bitops.h      Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/asm-x86/bitops.h      Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h    Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/asm-x86/hvm/vcpu.h    Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/asm-x86/hvm/vlapic.h  Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/public/dom0_ops.h     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h    Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/public/hvm/ioreq.h    Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h     Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/public/io/netif.h     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/public/version.h
--- a/xen/include/public/version.h      Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/public/version.h      Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h     Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/public/xenoprof.h     Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/xen/mm.h      Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h        Thu Jun 29 13:10:42 2006 -0400
+++ b/xen/include/xen/xenoprof.h        Fri Jun 30 07:21:58 2006 -0400
@@ -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 e06866a6e2b7 -r 316eff29c61c 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     Fri Jun 30 07:21:58 2006 -0400
@@ -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) ||

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

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [xenppc-unstable] [ppc-merge] update with http://xenbits.xensource.com/xen-unstable.hg, Xen patchbot-xenppc-unstable <=