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

[Xen-changelog] [xen-unstable] Merge with xen-ia64-unstable.hg



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 856caf975abd50b78c15f41cc8ab52372059fcf3
# Parent  4b51d081378d6783cce48255ffb7655931f26d63
# Parent  3f8d9b128d711e5e2f6e7af2a236272aad3c5817
Merge with xen-ia64-unstable.hg
---
 buildconfigs/linux-defconfig_xen_x86_32                           |    1 
 buildconfigs/linux-defconfig_xen_x86_64                           |    1 
 docs/man/xm.pod.1                                                 |   93 -
 docs/misc/vtpm.txt                                                |   47 
 linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c                   |    1 
 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c                  |    7 
 linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c                   |   12 
 linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c                    |   29 
 linux-2.6-xen-sparse/drivers/char/tpm/Kconfig                     |   13 
 linux-2.6-xen-sparse/drivers/char/tpm/Makefile                    |    1 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm.c                       |  873 
++++++++--
 linux-2.6-xen-sparse/drivers/char/tpm/tpm.h                       |   74 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c                  |  183 +-
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h                  |   42 
 linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c                   |   60 
 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c                |   42 
 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c                 |   83 
 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c                    |    5 
 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c                    |    4 
 linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c                 |   39 
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c                |   67 
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c                 |    2 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c              |   56 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c            |   71 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h |    2 
 linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h              |    2 
 patches/linux-2.6.16.13/fix-hz-suspend.patch                      |    9 
 patches/linux-2.6.16.13/net-gso.patch                             |    8 
 patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch                   |  704 
++++++++
 patches/linux-2.6.16.13/xenoprof-generic.patch                    |    9 
 tools/examples/Makefile                                           |    2 
 tools/examples/vtpm-addtodb                                       |   10 
 tools/examples/vtpm-common.sh                                     |   13 
 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_hvm_build.c                                        |    9 
 tools/libxc/xc_linux_build.c                                      |   17 
 tools/libxc/xc_linux_save.c                                       |   23 
 tools/libxc/xc_load_elf.c                                         |   29 
 tools/libxc/xg_private.h                                          |   14 
 tools/python/xen/xend/XendLogging.py                              |    2 
 tools/python/xen/xm/cfgbootpolicy.py                              |    2 
 tools/python/xen/xm/create.py                                     |    3 
 tools/python/xen/xm/dumppolicy.py                                 |    4 
 tools/python/xen/xm/labels.py                                     |    3 
 tools/python/xen/xm/loadpolicy.py                                 |    4 
 tools/python/xen/xm/main.py                                       |    2 
 tools/python/xen/xm/makepolicy.py                                 |    4 
 tools/python/xen/xm/shutdown.py                                   |    5 
 tools/xenstat/libxenstat/src/xenstat.c                            |  174 +
 tools/xenstat/libxenstat/src/xenstat.h                            |   22 
 tools/xenstat/xentop/xentop.c                                     |  154 +
 tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py                      |   11 
 tools/xm-test/tests/vtpm/03_vtpm-susp_res.py                      |   94 -
 tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py                      |   24 
 tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py                      |   24 
 tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py                 |  139 +
 tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py                      |  132 +
 tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py                      |  132 +
 tools/xm-test/tests/vtpm/Makefile.am                              |    5 
 tools/xm-test/tests/vtpm/vtpm_utils.py                            |    2 
 xen/arch/x86/domain.c                                             |    7 
 xen/arch/x86/hvm/svm/svm.c                                        |    2 
 xen/arch/x86/hvm/vmx/vmcs.c                                       |    7 
 xen/arch/x86/smpboot.c                                            |    3 
 xen/arch/x86/x86_emulate.c                                        |    2 
 xen/common/elf.c                                                  |   23 
 xen/common/grant_table.c                                          |   12 
 xen/common/memory.c                                               |    9 
 xen/common/page_alloc.c                                           |    4 
 xen/common/sched_credit.c                                         |    7 
 xen/common/schedule.c                                             |   21 
 xen/common/softirq.c                                              |   16 
 xen/common/timer.c                                                |    9 
 xen/drivers/char/console.c                                        |   12 
 xen/include/asm-ia64/grant_table.h                                |    5 
 xen/include/asm-x86/grant_table.h                                 |    5 
 xen/include/public/arch-ia64.h                                    |    2 
 xen/include/public/arch-x86_32.h                                  |    2 
 xen/include/public/arch-x86_64.h                                  |    2 
 xen/include/public/io/netif.h                                     |   53 
 xen/include/public/memory.h                                       |   12 
 xen/include/xen/lib.h                                             |   18 
 xen/include/xen/timer.h                                           |    6 
 88 files changed, 3632 insertions(+), 714 deletions(-)

diff -r 4b51d081378d -r 856caf975abd buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Wed Jun 28 07:52:21 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Mon Jul 03 08:35:12 2006 +0100
@@ -1902,6 +1902,7 @@ CONFIG_HANGCHECK_TIMER=m
 # TPM devices
 #
 CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
 CONFIG_TCG_NSC=m
 CONFIG_TCG_ATMEL=m
 CONFIG_TCG_INFINEON=m
diff -r 4b51d081378d -r 856caf975abd buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64   Wed Jun 28 07:52:21 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_64   Mon Jul 03 08:35:12 2006 +0100
@@ -1765,6 +1765,7 @@ CONFIG_HANGCHECK_TIMER=m
 # TPM devices
 #
 CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m
 CONFIG_TCG_NSC=m
 CONFIG_TCG_ATMEL=m
 CONFIG_TCG_INFINEON=m
diff -r 4b51d081378d -r 856caf975abd docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Wed Jun 28 07:52:21 2006 -0600
+++ b/docs/man/xm.pod.1 Mon Jul 03 08:35:12 2006 +0100
@@ -875,13 +875,42 @@ the currently enforced access control po
 the currently enforced access control policy. The default for I<type>
 is 'dom'. The labels are arranged in alphabetical order.
 
-=item B<addlabel> I<configfile> I<label> [I<policy>]
+=item B<addlabel> I<label> dom I<configfile> [I<policy>]
+
+=item B<addlabel> I<label> res I<resource> [I<policy>]
 
 Adds the security label with name I<label> to a domain
-I<configfile>. Unless specified, the default I<policy> is the
+I<configfile> (dom) or to the global resource label file for the
+given I<resource> (res). Unless specified, the default I<policy> is the
 currently enforced access control policy. This subcommand also
 verifies that the I<policy> definition supports the specified I<label>
 name.
+
+=item B<rmlabel> dom I<configfile>
+
+=item B<rmlabel> res I<resource>
+
+Works the same as the I<addlabel> command (above), except that this
+command will remove the label from the domain I<configfile> (dom) or
+the global resource label file (res).
+
+=item B<getlabel> dom I<configfile>
+
+=item B<getlabel> res I<resource>
+
+Shows the label for the given I<configfile> or I<resource>
+
+=item B<resources>
+
+Lists all resources in the global resource label file.  Each resource
+is listed with its associated label and policy name.
+
+=item B<dry-run> I<configfile>
+
+Determines if the specified I<configfile> describes a domain with a valid
+security configuration for type enforcement. The test shows the policy
+decision made for each resource label against the domain label as well as
+the overall decision.
 
 B<CONFIGURING SECURITY>
 
@@ -960,17 +989,18 @@ B<ATTACHING A SECURITY LABEL TO A DOMAIN
 
 =over 4
 
-This subcommand attaches a security label to a domain configuration
-file, here a HomeBanking label. The example policy ensures that this
-domain does not share information with other non-hombanking user
-domains (i.e., domains labeled as dom_Fun or dom_Boinc) and that it
-will not run simultaneously with domains labeled as dom_Fun.
+The I<addlabel> subcommand can attach a security label to a domain
+configuration file, here a HomeBanking label. The example policy
+ensures that this domain does not share information with other
+non-hombanking user domains (i.e., domains labeled as dom_Fun or
+dom_Boinc) and that it will not run simultaneously with domains
+labeled as dom_Fun.
 
 We assume that the specified myconfig.xm configuration file actually
 instantiates a domain that runs workloads related to home-banking,
 probably just a browser environment for online-banking.
 
-    xm addlabel myconfig.xm dom_HomeBanking
+    xm addlabel dom_HomeBanking dom myconfig.xm
 
 The very simple configuration file might now look as printed
 below. The I<addlabel> subcommand added the B<access_control> entry at
@@ -997,6 +1027,38 @@ permitted".
 
 =back
 
+B<ATTACHING A SECURITY LABEL TO A RESOURCE>
+
+=over 4
+
+The I<addlabel> subcommand can also be used to attach a security
+label to a resource. Following the home banking example from above,
+we can label a disk resource (e.g., a physical partition or a file)
+to make it accessible to the home banking domain. The example policy
+provides a resource label, res_LogicalDiskPartition1(hda1), that is
+compatible with the HomeBanking domain label.
+
+    xm addlabel "res_LogicalDiskPartition1(hda1)" res phy:hda6
+
+After labeling this disk resource, it can be attached to the domain
+by adding a line to the domain configuration file. The line below
+attaches this disk to the domain at boot time.
+
+    disk = [ 'phy:hda6,sda2,w' ]
+
+Alternatively, the resource can be attached after booting the domain
+by using the I<block-attach> subcommand.
+
+    xm block-attach homebanking phy:hda6 sda2 w
+
+Note that labeled resources cannot be used when security is turned
+off.  Any attempt to use labeled resources with security turned off
+will result in a failure with a corresponding error message.  The
+solution is to enable security or, if security is no longer desired,
+to remove the resource label using the I<rmlabel> subcommand.
+
+=back
+
 B<STARTING AND LISTING LABELED DOMAINS>
 
 =over 4
@@ -1008,6 +1070,21 @@ B<STARTING AND LISTING LABELED DOMAINS>
       Name         ID ...  Time(s)  Label
       homebanking  23 ...      4.4  dom_HomeBanking
       Domain-0      0 ...   2658.8  dom_SystemManagement
+
+=back
+
+B<LISTING LABELED RESOURCES>
+
+=over 4
+
+    xm resources
+
+      phy:hda6
+          policy: example.chwall_ste.client_v1
+          label:  res_LogicalDiskPartition1(hda1)
+      file:/xen/disk_image/disk.img
+          policy: example.chwall_ste.client_v1
+          label:  res_LogicalDiskPartition2(hda2)
 
 =back
 
diff -r 4b51d081378d -r 856caf975abd docs/misc/vtpm.txt
--- a/docs/misc/vtpm.txt        Wed Jun 28 07:52:21 2006 -0600
+++ b/docs/misc/vtpm.txt        Mon Jul 03 08:35:12 2006 +0100
@@ -1,5 +1,5 @@ Copyright: IBM Corporation (C), Intel Co
 Copyright: IBM Corporation (C), Intel Corporation
-17 August 2005
+29 June 2006
 Authors: Stefan Berger <stefanb@xxxxxxxxxx> (IBM), 
          Employees of Intel Corp
 
@@ -9,23 +9,33 @@ that the user is fairly familiar with co
 that the user is fairly familiar with compiling and installing XEN
 and Linux on a machine. 
  
-Production Prerequisites: An x86-based machine machine with an ATMEL or
-National Semiconductor (NSC) TPM on the motherboard.
+Production Prerequisites: An x86-based machine machine with a
+Linux-supported TPM on the motherboard (NSC, Atmel, Infineon, TPM V1.2).
 Development Prerequisites: An emulator for TESTING ONLY is provided
 
 
-Compiling XEN tree:
--------------------
+Compiling the XEN tree:
+-----------------------
 
 Compile the XEN tree as usual after the following lines set in the
 linux-2.6.??-xen/.config file:
 
-CONFIG_XEN_TPMDEV_BACKEND=y
+CONFIG_XEN_TPMDEV_BACKEND=m
+
+CONFIG_TCG_TPM=m
+CONFIG_TCG_TIS=m      (supported after 2.6.17-rc4)
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_TCG_INFINEON=m
+CONFIG_TCG_XEN=m
+<possible other TPM drivers supported by Linux>
+
+If the frontend driver needs to be compiled into the user domain
+kernel, then the following two lines should be changed.
 
 CONFIG_TCG_TPM=y
-CONFIG_TCG_NSC=m
-CONFIG_TCG_ATMEL=m
 CONFIG_TCG_XEN=y
+
 
 You must also enable the virtual TPM to be built:
 
@@ -63,7 +73,7 @@ available. It works similar to making a 
 available. It works similar to making a network interface
 available to a domain.
 
-kernel = "/boot/vmlinuz-2.6.12-xenU"
+kernel = "/boot/vmlinuz-2.6.x"
 ramdisk = "/xen/initrd_domU/U1_ramdisk.img"
 memory = 32
 name = "TPMUserDomain0"
@@ -92,7 +102,7 @@ Running the TPM:
 Running the TPM:
 ----------------
 
-To run the vTPM, dev device /dev/vtpm must be available.
+To run the vTPM, the device /dev/vtpm must be available.
 Verify that 'ls -l /dev/vtpm' shows the following output:
 
 crw-------  1 root root 10, 225 Aug 11 06:58 /dev/vtpm
@@ -101,16 +111,26 @@ mknod /dev/vtpm c 10 225
 mknod /dev/vtpm c 10 225
 
 Make sure that the vTPM is running in domain 0. To do this run the
-following
+following:
+
+modprobe tpmbk
 
 /usr/bin/vtpm_managerd
 
 Start a user domain using the 'xm create' command. Once you are in the
-shell of the user domain, you should be able to do the following:
+shell of the user domain, you should be able to do the following as
+user 'root':
 
-> cd /sys/devices/vtpm
+Insert the TPM frontend into the kernel if it has been compiled as a
+kernel module.
+
+> modprobe tpm_xenu
+
+Check the status of the TPM
+
+> cd /sys/devices/xen/vtpm-0
 > ls
-cancel  caps   pcrs    pubek
+[...]  cancel  caps   pcrs    pubek   [...]
 > cat pcrs
 PCR-00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 PCR-01: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c   Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/smp-xen.c   Mon Jul 03 08:35:12 
2006 +0100
@@ -442,6 +442,7 @@ void flush_tlb_mm(struct mm_struct * mm)
 { xen_tlb_flush_mask(&mm->cpu_vm_mask); }
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
 { xen_invlpg_mask(&vma->vm_mm->cpu_vm_mask, va); }
+EXPORT_SYMBOL(flush_tlb_page);
 void flush_tlb_all(void)
 { xen_tlb_flush_all(); }
 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Mon Jul 03 08:35:12 
2006 +0100
@@ -989,12 +989,11 @@ static void stop_hz_timer(void)
 
        smp_mb();
 
-       /* Leave ourselves in 'tick mode' if rcu or softirq pending. */
-       if (rcu_needs_cpu(cpu) || local_softirq_pending()) {
+       /* Leave ourselves in 'tick mode' if rcu or softirq or timer pending. */
+       if (rcu_needs_cpu(cpu) || local_softirq_pending() ||
+           (j = next_timer_interrupt(), time_before_eq(j, jiffies))) {
                cpu_clear(cpu, nohz_cpu_mask);
                j = jiffies + 1;
-       } else {
-               j = next_timer_interrupt();
        }
 
        BUG_ON(HYPERVISOR_set_timer_op(jiffies_to_st(j)) != 0);
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c   Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c   Mon Jul 03 08:35:12 
2006 +0100
@@ -60,7 +60,7 @@ void *kmap_atomic_pte(struct page *page,
 
 void kunmap_atomic(void *kvaddr, enum km_type type)
 {
-#ifdef CONFIG_DEBUG_HIGHMEM
+#if defined(CONFIG_DEBUG_HIGHMEM) || defined(CONFIG_XEN)
        unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
        enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
 
@@ -69,7 +69,9 @@ void kunmap_atomic(void *kvaddr, enum km
                preempt_check_resched();
                return;
        }
+#endif
 
+#if defined(CONFIG_DEBUG_HIGHMEM)
        if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
                BUG();
 
@@ -79,6 +81,14 @@ void kunmap_atomic(void *kvaddr, enum km
         */
        pte_clear(&init_mm, vaddr, kmap_pte-idx);
        __flush_tlb_one(vaddr);
+#elif defined(CONFIG_XEN)
+       /*
+        * We must ensure there are no dangling pagetable references when
+        * returning memory to Xen (decrease_reservation).
+        * XXX TODO: We could make this faster by only zapping when
+        * kmap_flush_unused is called but that is trickier and more invasive.
+        */
+       pte_clear(&init_mm, vaddr, kmap_pte-idx);
 #endif
 
        dec_preempt_count();
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Mon Jul 03 08:35:12 
2006 +0100
@@ -271,10 +271,6 @@ int xen_create_contiguous_region(
 int xen_create_contiguous_region(
        unsigned long vstart, unsigned int order, unsigned int address_bits)
 {
-       pgd_t         *pgd; 
-       pud_t         *pud; 
-       pmd_t         *pmd;
-       pte_t         *pte;
        unsigned long *in_frames = discontig_frames, out_frame;
        unsigned long  frame, i, flags;
        long           rc;
@@ -301,7 +297,7 @@ int xen_create_contiguous_region(
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return 0;
 
-       if (order > MAX_CONTIG_ORDER)
+       if (unlikely(order > MAX_CONTIG_ORDER))
                return -ENOMEM;
 
        set_xen_guest_handle(exchange.in.extent_start, in_frames);
@@ -313,11 +309,7 @@ int xen_create_contiguous_region(
 
        /* 1. Zap current PTEs, remembering MFNs. */
        for (i = 0; i < (1UL<<order); i++) {
-               pgd = pgd_offset_k(vstart + (i*PAGE_SIZE));
-               pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE)));
-               pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE)));
-               pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE)));
-               in_frames[i] = pte_mfn(*pte);
+               in_frames[i] = pfn_to_mfn((__pa(vstart) >> PAGE_SHIFT) + i);
                if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
                                                 __pte_ma(0), 0))
                        BUG();
@@ -372,10 +364,6 @@ int xen_create_contiguous_region(
 
 void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
 {
-       pgd_t         *pgd; 
-       pud_t         *pud; 
-       pmd_t         *pmd;
-       pte_t         *pte;
        unsigned long *out_frames = discontig_frames, in_frame;
        unsigned long  frame, i, flags;
        long           rc;
@@ -397,7 +385,7 @@ void xen_destroy_contiguous_region(unsig
            !test_bit(__pa(vstart) >> PAGE_SHIFT, contiguous_bitmap))
                return;
 
-       if (order > MAX_CONTIG_ORDER)
+       if (unlikely(order > MAX_CONTIG_ORDER))
                return;
 
        set_xen_guest_handle(exchange.in.extent_start, &in_frame);
@@ -410,16 +398,13 @@ void xen_destroy_contiguous_region(unsig
        contiguous_bitmap_clear(__pa(vstart) >> PAGE_SHIFT, 1UL << order);
 
        /* 1. Find start MFN of contiguous extent. */
-       pgd = pgd_offset_k(vstart);
-       pud = pud_offset(pgd, vstart);
-       pmd = pmd_offset(pud, vstart);
-       pte = pte_offset_kernel(pmd, vstart);
-       in_frame = pte_mfn(*pte);
+       in_frame = pfn_to_mfn(__pa(vstart) >> PAGE_SHIFT);
 
        /* 2. Zap current PTEs. */
        for (i = 0; i < (1UL<<order); i++) {
                if (HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
-                                                __pte_ma(0), 0));
+                                                __pte_ma(0), 0))
+                       BUG();
                set_phys_to_machine((__pa(vstart)>>PAGE_SHIFT)+i,
                        INVALID_P2M_ENTRY);
                out_frames[i] = (__pa(vstart) >> PAGE_SHIFT) + i;
@@ -430,7 +415,7 @@ void xen_destroy_contiguous_region(unsig
        success = (exchange.nr_exchanged == 1);
        BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
        BUG_ON(success && (rc != 0));
-       if (rc == -ENOSYS) {
+       if (unlikely(rc == -ENOSYS)) {
                /* Compatibility when XENMEM_exchange is unsupported. */
                if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
                                         &exchange.in) != 1)
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig     Mon Jul 03 08:35:12 
2006 +0100
@@ -20,9 +20,18 @@ config TCG_TPM
          Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
          and CONFIG_PNPACPI.
 
+config TCG_TIS
+       tristate "TPM Interface Specification 1.2 Interface"
+       depends on TCG_TPM
+       ---help---
+         If you have a TPM security chip that is compliant with the
+         TCG TIS 1.2 TPM specification say Yes and it will be accessible
+         from within Linux.  To compile this driver as a module, choose
+         M here; the module will be called tpm_tis.
+
 config TCG_NSC
        tristate "National Semiconductor TPM Interface"
-       depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
+       depends on TCG_TPM && PNPACPI
        ---help---
          If you have a TPM security chip from National Semicondutor 
          say Yes and it will be accessible from within Linux.  To 
@@ -31,7 +40,7 @@ config TCG_NSC
 
 config TCG_ATMEL
        tristate "Atmel TPM Interface"
-       depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
+       depends on TCG_TPM
        ---help---
          If you have a TPM security chip from Atmel say Yes and it 
          will be accessible from within Linux.  To compile this driver 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/Makefile
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile    Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile    Mon Jul 03 08:35:12 
2006 +0100
@@ -5,6 +5,7 @@ ifdef CONFIG_ACPI
 ifdef CONFIG_ACPI
        obj-$(CONFIG_TCG_TPM) += tpm_bios.o
 endif
+obj-$(CONFIG_TCG_TIS) += tpm_tis.o
 obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
 obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
 obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
diff -r 4b51d081378d -r 856caf975abd linux-2.6-xen-sparse/drivers/char/tpm/tpm.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c       Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c       Mon Jul 03 08:35:12 
2006 +0100
@@ -30,15 +30,295 @@
 
 enum tpm_const {
        TPM_MINOR = 224,        /* officially assigned */
-       TPM_MIN_BUFSIZE = 2048,
-       TPM_MAX_BUFSIZE = 64 * 1024,
+#ifndef CONFIG_XEN
+       TPM_BUFSIZE = 2048,
+#endif
        TPM_NUM_DEVICES = 256,
-       TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
 };
+
+enum tpm_duration {
+       TPM_SHORT = 0,
+       TPM_MEDIUM = 1,
+       TPM_LONG = 2,
+       TPM_UNDEFINED,
+};
+
+#define TPM_MAX_ORDINAL 243
+#define TPM_MAX_PROTECTED_ORDINAL 12
+#define TPM_PROTECTED_ORDINAL_MASK 0xFF
 
 static LIST_HEAD(tpm_chip_list);
 static DEFINE_SPINLOCK(driver_lock);
-static int dev_mask[TPM_NUM_MASK_ENTRIES];
+static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
+
+/*
+ * Array with one entry per ordinal defining the maximum amount
+ * of time the chip could take to return the result.  The ordinal
+ * designation of short, medium or long is defined in a table in
+ * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
+ * values of the SHORT, MEDIUM, and LONG durations are retrieved
+ * from the chip during initialization with a call to tpm_get_timeouts.
+ */
+static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
+       TPM_UNDEFINED,          /* 0 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 5 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 10 */
+       TPM_SHORT,
+};
+
+static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
+       TPM_UNDEFINED,          /* 0 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 5 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 10 */
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_LONG,
+       TPM_LONG,
+       TPM_MEDIUM,             /* 15 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_LONG,
+       TPM_SHORT,              /* 20 */
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_SHORT,              /* 25 */
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_MEDIUM,             /* 30 */
+       TPM_LONG,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,              /* 35 */
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_MEDIUM,             /* 40 */
+       TPM_LONG,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,              /* 45 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_LONG,
+       TPM_MEDIUM,             /* 50 */
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 55 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_MEDIUM,             /* 60 */
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_MEDIUM,             /* 65 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 70 */
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 75 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_LONG,               /* 80 */
+       TPM_UNDEFINED,
+       TPM_MEDIUM,
+       TPM_LONG,
+       TPM_SHORT,
+       TPM_UNDEFINED,          /* 85 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 90 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,          /* 95 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_MEDIUM,             /* 100 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 105 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 110 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,              /* 115 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_LONG,               /* 120 */
+       TPM_LONG,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_SHORT,
+       TPM_SHORT,              /* 125 */
+       TPM_SHORT,
+       TPM_LONG,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,              /* 130 */
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,          /* 135 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 140 */
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 145 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 150 */
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,          /* 155 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 160 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 165 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_LONG,               /* 170 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 175 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_MEDIUM,             /* 180 */
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_MEDIUM,             /* 185 */
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 190 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 195 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 200 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,
+       TPM_SHORT,              /* 205 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_MEDIUM,             /* 210 */
+       TPM_UNDEFINED,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,          /* 215 */
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,
+       TPM_SHORT,              /* 220 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,          /* 225 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 230 */
+       TPM_LONG,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 235 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 240 */
+       TPM_UNDEFINED,
+       TPM_MEDIUM,
+};
 
 static void user_reader_timeout(unsigned long ptr)
 {
@@ -47,28 +327,58 @@ static void user_reader_timeout(unsigned
        schedule_work(&chip->work);
 }
 
-static void timeout_work(void * ptr)
+static void timeout_work(void *ptr)
 {
        struct tpm_chip *chip = ptr;
 
        down(&chip->buffer_mutex);
        atomic_set(&chip->data_pending, 0);
+#ifndef CONFIG_XEN
+       memset(chip->data_buffer, 0, TPM_BUFSIZE);
+#else
        memset(chip->data_buffer, 0, get_chip_buffersize(chip));
+#endif
        up(&chip->buffer_mutex);
 }
+
+/*
+ * Returns max number of jiffies to wait
+ */
+unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
+                                          u32 ordinal)
+{
+       int duration_idx = TPM_UNDEFINED;
+       int duration = 0;
+
+       if (ordinal < TPM_MAX_ORDINAL)
+               duration_idx = tpm_ordinal_duration[ordinal];
+       else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
+                TPM_MAX_PROTECTED_ORDINAL)
+               duration_idx =
+                   tpm_protected_ordinal_duration[ordinal &
+                                                  TPM_PROTECTED_ORDINAL_MASK];
+
+       if (duration_idx != TPM_UNDEFINED)
+               duration = chip->vendor.duration[duration_idx];
+       if (duration <= 0)
+               return 2 * 60 * HZ;
+       else
+               return duration;
+}
+EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
 
 /*
  * Internal kernel interface to transmit TPM commands
  */
-static ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
+static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
                            size_t bufsiz)
 {
        ssize_t rc;
-       u32 count;
+       u32 count, ordinal;
        unsigned long stop;
 
        count = be32_to_cpu(*((__be32 *) (buf + 2)));
-
+       ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
        if (count == 0)
                return -ENODATA;
        if (count > bufsiz) {
@@ -79,21 +389,23 @@ static ssize_t tpm_transmit(struct tpm_c
 
        down(&chip->tpm_mutex);
 
-       if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+       if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
                dev_err(chip->dev,
                        "tpm_transmit: tpm_send: error %zd\n", rc);
                goto out;
        }
 
-       stop = jiffies + 2 * 60 * HZ;
+       if (chip->vendor.irq)
+               goto out_recv;
+
+       stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
        do {
-               u8 status = chip->vendor->status(chip);
-               if ((status & chip->vendor->req_complete_mask) ==
-                   chip->vendor->req_complete_val) {
+               u8 status = chip->vendor.status(chip);
+               if ((status & chip->vendor.req_complete_mask) ==
+                   chip->vendor.req_complete_val)
                        goto out_recv;
-               }
-
-               if ((status == chip->vendor->req_canceled)) {
+
+               if ((status == chip->vendor.req_canceled)) {
                        dev_err(chip->dev, "Operation Canceled\n");
                        rc = -ECANCELED;
                        goto out;
@@ -103,14 +415,13 @@ static ssize_t tpm_transmit(struct tpm_c
                rmb();
        } while (time_before(jiffies, stop));
 
-
-       chip->vendor->cancel(chip);
+       chip->vendor.cancel(chip);
        dev_err(chip->dev, "Operation Timed out\n");
        rc = -ETIME;
        goto out;
 
 out_recv:
-       rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+       rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
        if (rc < 0)
                dev_err(chip->dev,
                        "tpm_transmit: tpm_recv: error %zd\n", rc);
@@ -120,17 +431,247 @@ out:
 }
 
 #define TPM_DIGEST_SIZE 20
-#define CAP_PCR_RESULT_SIZE 18
-static const u8 cap_pcr[] = {
+#define TPM_ERROR_SIZE 10
+#define TPM_RET_CODE_IDX 6
+#define TPM_GET_CAP_RET_SIZE_IDX 10
+#define TPM_GET_CAP_RET_UINT32_1_IDX 14
+#define TPM_GET_CAP_RET_UINT32_2_IDX 18
+#define TPM_GET_CAP_RET_UINT32_3_IDX 22
+#define TPM_GET_CAP_RET_UINT32_4_IDX 26
+#define TPM_GET_CAP_PERM_DISABLE_IDX 16
+#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
+#define TPM_GET_CAP_RET_BOOL_1_IDX 14
+#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
+
+#define TPM_CAP_IDX 13
+#define TPM_CAP_SUBCAP_IDX 21
+
+enum tpm_capabilities {
+       TPM_CAP_FLAG = 4,
+       TPM_CAP_PROP = 5,
+};
+
+enum tpm_sub_capabilities {
+       TPM_CAP_PROP_PCR = 0x1,
+       TPM_CAP_PROP_MANUFACTURER = 0x3,
+       TPM_CAP_FLAG_PERM = 0x8,
+       TPM_CAP_FLAG_VOL = 0x9,
+       TPM_CAP_PROP_OWNER = 0x11,
+       TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
+       TPM_CAP_PROP_TIS_DURATION = 0x20,
+};
+
+/*
+ * This is a semi generic GetCapability command for use
+ * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
+ * and their associated sub_capabilities.
+ */
+
+static const u8 tpm_cap[] = {
        0, 193,                 /* TPM_TAG_RQU_COMMAND */
        0, 0, 0, 22,            /* length */
        0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 5,
-       0, 0, 0, 4,
-       0, 0, 1, 1
+       0, 0, 0, 0,             /* TPM_CAP_<TYPE> */
+       0, 0, 0, 4,             /* TPM_CAP_SUB_<TYPE> size */
+       0, 0, 1, 0              /* TPM_CAP_SUB_<TYPE> */
 };
 
-#define READ_PCR_RESULT_SIZE 30
+static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
+                           char *desc)
+{
+       int err;
+
+       len = tpm_transmit(chip, data, len);
+       if (len <  0)
+               return len;
+       if (len == TPM_ERROR_SIZE) {
+               err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
+               dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
+               return err;
+       }
+       return 0;
+}
+
+void tpm_gen_interrupt(struct tpm_chip *chip)
+{
+       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+       ssize_t rc;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the timeouts");
+}
+EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
+
+void tpm_get_timeouts(struct tpm_chip *chip)
+{
+       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+       ssize_t rc;
+       u32 timeout;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the timeouts");
+       if (rc)
+               goto duration;
+
+       if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+           != 4 * sizeof(u32))
+               goto duration;
+
+       /* Don't overwrite default if value is 0 */
+       timeout =
+           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+       if (timeout)
+               chip->vendor.timeout_a = msecs_to_jiffies(timeout);
+       timeout =
+           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+       if (timeout)
+               chip->vendor.timeout_b = msecs_to_jiffies(timeout);
+       timeout =
+           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+       if (timeout)
+               chip->vendor.timeout_c = msecs_to_jiffies(timeout);
+       timeout =
+           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
+       if (timeout)
+               chip->vendor.timeout_d = msecs_to_jiffies(timeout);
+
+duration:
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the durations");
+       if (rc)
+               return;
+
+       if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+           != 3 * sizeof(u32))
+               return;
+
+       chip->vendor.duration[TPM_SHORT] =
+           msecs_to_jiffies(be32_to_cpu
+                            (*((__be32 *) (data +
+                                           TPM_GET_CAP_RET_UINT32_1_IDX))));
+       chip->vendor.duration[TPM_MEDIUM] =
+           msecs_to_jiffies(be32_to_cpu
+                            (*((__be32 *) (data +
+                                           TPM_GET_CAP_RET_UINT32_2_IDX))));
+       chip->vendor.duration[TPM_LONG] =
+           msecs_to_jiffies(be32_to_cpu
+                            (*((__be32 *) (data +
+                                           TPM_GET_CAP_RET_UINT32_3_IDX))));
+}
+EXPORT_SYMBOL_GPL(tpm_get_timeouts);
+
+void tpm_continue_selftest(struct tpm_chip *chip)
+{
+       u8 data[] = {
+               0, 193,                 /* TPM_TAG_RQU_COMMAND */
+               0, 0, 0, 10,            /* length */
+               0, 0, 0, 83,            /* TPM_ORD_GetCapability */
+       };
+
+       tpm_transmit(chip, data, sizeof(data));
+}
+EXPORT_SYMBOL_GPL(tpm_continue_selftest);
+
+ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
+                       char *buf)
+{
+       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
+       ssize_t rc;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attemtping to determine the permanent state");
+       if (rc)
+               return 0;
+       return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
+}
+EXPORT_SYMBOL_GPL(tpm_show_enabled);
+
+ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
+                       char *buf)
+{
+       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
+       ssize_t rc;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attemtping to determine the permanent state");
+       if (rc)
+               return 0;
+       return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
+}
+EXPORT_SYMBOL_GPL(tpm_show_active);
+
+ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
+                       char *buf)
+{
+       u8 data[sizeof(tpm_cap)];
+       ssize_t rc;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the owner state");
+       if (rc)
+               return 0;
+       return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
+}
+EXPORT_SYMBOL_GPL(tpm_show_owned);
+
+ssize_t tpm_show_temp_deactivated(struct device * dev,
+                               struct device_attribute * attr, char *buf)
+{
+       u8 data[sizeof(tpm_cap)];
+       ssize_t rc;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the temporary state");
+       if (rc)
+               return 0;
+       return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
+}
+EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
+
 static const u8 pcrread[] = {
        0, 193,                 /* TPM_TAG_RQU_COMMAND */
        0, 0, 0, 14,            /* length */
@@ -141,8 +682,8 @@ ssize_t tpm_show_pcrs(struct device *dev
 ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
-       u8 data[READ_PCR_RESULT_SIZE];
-       ssize_t len;
+       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
+       ssize_t rc;
        int i, j, num_pcrs;
        __be32 index;
        char *str = buf;
@@ -151,29 +692,24 @@ ssize_t tpm_show_pcrs(struct device *dev
        if (chip == NULL)
                return -ENODEV;
 
-       memcpy(data, cap_pcr, sizeof(cap_pcr));
-       if ((len = tpm_transmit(chip, data, sizeof(data)))
-           < CAP_PCR_RESULT_SIZE) {
-               dev_dbg(chip->dev, "A TPM error (%d) occurred "
-                               "attempting to determine the number of PCRS\n",
-                       be32_to_cpu(*((__be32 *) (data + 6))));
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the number of PCRS");
+       if (rc)
                return 0;
-       }
 
        num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
-
        for (i = 0; i < num_pcrs; i++) {
                memcpy(data, pcrread, sizeof(pcrread));
                index = cpu_to_be32(i);
                memcpy(data + 10, &index, 4);
-               if ((len = tpm_transmit(chip, data, sizeof(data)))
-                   < READ_PCR_RESULT_SIZE){
-                       dev_dbg(chip->dev, "A TPM error (%d) occurred"
-                               " attempting to read PCR %d of %d\n",
-                               be32_to_cpu(*((__be32 *) (data + 6))),
-                               i, num_pcrs);
+               rc = transmit_cmd(chip, data, sizeof(data),
+                               "attempting to read a PCR");
+               if (rc)
                        goto out;
-               }
                str += sprintf(str, "PCR-%02d: ", i);
                for (j = 0; j < TPM_DIGEST_SIZE; j++)
                        str += sprintf(str, "%02X ", *(data + 10 + j));
@@ -195,7 +731,7 @@ ssize_t tpm_show_pubek(struct device *de
                       char *buf)
 {
        u8 *data;
-       ssize_t len;
+       ssize_t err;
        int i, rc;
        char *str = buf;
 
@@ -209,14 +745,10 @@ ssize_t tpm_show_pubek(struct device *de
 
        memcpy(data, readpubek, sizeof(readpubek));
 
-       if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
-           READ_PUBEK_RESULT_SIZE) {
-               dev_dbg(chip->dev, "A TPM error (%d) occurred "
-                               "attempting to read the PUBEK\n",
-                           be32_to_cpu(*((__be32 *) (data + 6))));
-               rc = 0;
+       err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
+                       "attempting to read the PUBEK");
+       if (err)
                goto out;
-       }
 
        /* 
           ignore header 10 bytes
@@ -246,66 +778,109 @@ ssize_t tpm_show_pubek(struct device *de
                if ((i + 1) % 16 == 0)
                        str += sprintf(str, "\n");
        }
+out:
        rc = str - buf;
-out:
        kfree(data);
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_pubek);
 
-#define CAP_VER_RESULT_SIZE 18
+#define CAP_VERSION_1_1 6
+#define CAP_VERSION_1_2 0x1A
+#define CAP_VERSION_IDX 13
 static const u8 cap_version[] = {
        0, 193,                 /* TPM_TAG_RQU_COMMAND */
        0, 0, 0, 18,            /* length */
        0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 6,
+       0, 0, 0, 0,
        0, 0, 0, 0
 };
 
-#define CAP_MANUFACTURER_RESULT_SIZE 18
-static const u8 cap_manufacturer[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 22,            /* length */
-       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 5,
-       0, 0, 0, 4,
-       0, 0, 1, 3
-};
-
 ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
-       u8 data[sizeof(cap_manufacturer)];
-       ssize_t len;
+       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 
30)];
+       ssize_t rc;
        char *str = buf;
 
        struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
-       memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
-
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <
-           CAP_MANUFACTURER_RESULT_SIZE)
-               return len;
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the manufacturer");
+       if (rc)
+               return 0;
 
        str += sprintf(str, "Manufacturer: 0x%x\n",
-                      be32_to_cpu(*((__be32 *) (data + 14))));
+                      be32_to_cpu(*((__be32 *) (data + 
TPM_GET_CAP_RET_UINT32_1_IDX))));
 
        memcpy(data, cap_version, sizeof(cap_version));
-
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <
-           CAP_VER_RESULT_SIZE)
-               return len;
-
-       str +=
-           sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
-                   (int) data[14], (int) data[15], (int) data[16],
-                   (int) data[17]);
-
+       data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the 1.1 version");
+       if (rc)
+               goto out;
+
+       str += sprintf(str,
+                      "TCG version: %d.%d\nFirmware version: %d.%d\n",
+                      (int) data[14], (int) data[15], (int) data[16],
+                      (int) data[17]);
+
+out:
        return str - buf;
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps);
+
+ssize_t tpm_show_caps_1_2(struct device * dev,
+                         struct device_attribute * attr, char *buf)
+{
+       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 
30)];
+       ssize_t len;
+       char *str = buf;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+           TPM_ERROR_SIZE) {
+               dev_dbg(chip->dev, "A TPM error (%d) occurred "
+                       "attempting to determine the manufacturer\n",
+                       be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+               return 0;
+       }
+
+       str += sprintf(str, "Manufacturer: 0x%x\n",
+                      be32_to_cpu(*((__be32 *) (data + 
TPM_GET_CAP_RET_UINT32_1_IDX))));
+
+       memcpy(data, cap_version, sizeof(cap_version));
+       data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+           TPM_ERROR_SIZE) {
+               dev_err(chip->dev, "A TPM error (%d) occurred "
+                       "attempting to determine the 1.2 version\n",
+                       be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+               goto out;
+       }
+       str += sprintf(str,
+                      "TCG version: %d.%d\nFirmware version: %d.%d\n",
+                      (int) data[16], (int) data[17], (int) data[18],
+                      (int) data[19]);
+
+out:
+       return str - buf;
+}
+EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
 
 ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
@@ -314,7 +889,7 @@ ssize_t tpm_store_cancel(struct device *
        if (chip == NULL)
                return 0;
 
-       chip->vendor->cancel(chip);
+       chip->vendor.cancel(chip);
        return count;
 }
 EXPORT_SYMBOL_GPL(tpm_store_cancel);
@@ -330,7 +905,7 @@ int tpm_open(struct inode *inode, struct
        spin_lock(&driver_lock);
 
        list_for_each_entry(pos, &tpm_chip_list, list) {
-               if (pos->vendor->miscdev.minor == minor) {
+               if (pos->vendor.miscdev.minor == minor) {
                        chip = pos;
                        break;
                }
@@ -352,7 +927,12 @@ int tpm_open(struct inode *inode, struct
 
        spin_unlock(&driver_lock);
 
-       chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8), 
GFP_KERNEL);
+#ifndef CONFIG_XEN
+       chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
+#else
+       chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8),
+                                   GFP_KERNEL);
+#endif
        if (chip->data_buffer == NULL) {
                chip->num_opens--;
                put_device(chip->dev);
@@ -388,7 +968,7 @@ EXPORT_SYMBOL_GPL(tpm_release);
 EXPORT_SYMBOL_GPL(tpm_release);
 
 ssize_t tpm_write(struct file *file, const char __user *buf,
-                 size_t size, loff_t * off)
+                 size_t size, loff_t *off)
 {
        struct tpm_chip *chip = file->private_data;
        int in_size = size, out_size;
@@ -400,8 +980,13 @@ ssize_t tpm_write(struct file *file, con
 
        down(&chip->buffer_mutex);
 
+#ifndef CONFIG_XEN
+       if (in_size > TPM_BUFSIZE)
+               in_size = TPM_BUFSIZE;
+#else
        if (in_size > get_chip_buffersize(chip))
                in_size = get_chip_buffersize(chip);
+#endif
 
        if (copy_from_user
            (chip->data_buffer, (void __user *) buf, in_size)) {
@@ -410,11 +995,17 @@ ssize_t tpm_write(struct file *file, con
        }
 
        /* atomic tpm command send and result receive */
-       out_size = tpm_transmit(chip, chip->data_buffer, 
+#ifndef CONFIG_XEN
+       out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
+#else
+       out_size = tpm_transmit(chip, chip->data_buffer,
                                get_chip_buffersize(chip));
+#endif
 
        atomic_set(&chip->data_pending, out_size);
+#ifdef CONFIG_XEN
        atomic_set(&chip->data_position, 0);
+#endif
        up(&chip->buffer_mutex);
 
        /* Set a timeout by which the reader must come claim the result */
@@ -422,42 +1013,59 @@ ssize_t tpm_write(struct file *file, con
 
        return in_size;
 }
-
 EXPORT_SYMBOL_GPL(tpm_write);
 
-ssize_t tpm_read(struct file * file, char __user *buf,
-                size_t size, loff_t * off)
+ssize_t tpm_read(struct file *file, char __user *buf,
+                size_t size, loff_t *off)
 {
        struct tpm_chip *chip = file->private_data;
        int ret_size;
+#ifdef CONFIG_XEN
        int pos, pending = 0;
-
+#endif
+
+#ifndef CONFIG_XEN
+       del_singleshot_timer_sync(&chip->user_read_timer);
+       flush_scheduled_work();
+#endif
        ret_size = atomic_read(&chip->data_pending);
+#ifndef CONFIG_XEN
+       atomic_set(&chip->data_pending, 0);
+#endif
        if (ret_size > 0) {     /* relay data */
                if (size < ret_size)
                        ret_size = size;
 
+#ifdef CONFIG_XEN
                pos = atomic_read(&chip->data_position);
-
+#endif
                down(&chip->buffer_mutex);
+#ifndef CONFIG_XEN
+               if (copy_to_user(buf, chip->data_buffer, ret_size))
+#else
                if (copy_to_user(buf, &chip->data_buffer[pos], ret_size)) {
+#endif
                        ret_size = -EFAULT;
+#ifdef CONFIG_XEN
                } else {
                        pending = atomic_read(&chip->data_pending) - ret_size;
                        if ( pending ) {
-                               atomic_set( &chip->data_pending, pending );
-                               atomic_set( &chip->data_position, pos+ret_size 
);
+                               atomic_set(&chip->data_pending, pending);
+                               atomic_set(&chip->data_position,
+                                          pos+ret_size);
                        }
                }
+#endif
                up(&chip->buffer_mutex);
        }
-       
-       if ( ret_size <= 0 || pending == 0 ) {
-               atomic_set( &chip->data_pending, 0 );
+
+#ifdef CONFIG_XEN
+       if ( ret_size <= 0 || pending == 0 ) {
+               atomic_set(&chip->data_pending, 0);
                del_singleshot_timer_sync(&chip->user_read_timer);
                flush_scheduled_work();
        }
-
+#endif
        return ret_size;
 }
 EXPORT_SYMBOL_GPL(tpm_read);
@@ -478,14 +1086,13 @@ void tpm_remove_hardware(struct device *
        spin_unlock(&driver_lock);
 
        dev_set_drvdata(dev, NULL);
-       misc_deregister(&chip->vendor->miscdev);
-       kfree(chip->vendor->miscdev.name);
-
-       sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
+       misc_deregister(&chip->vendor.miscdev);
+       kfree(chip->vendor.miscdev.name);
+
+       sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
        tpm_bios_log_teardown(chip->bios_dir);
 
-       dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
-               ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+       clear_bit(chip->dev_num, dev_mask);
 
        kfree(chip);
 
@@ -536,18 +1143,18 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
  * upon errant exit from this function specific probe function should call
  * pci_disable_device
  */
-int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific 
*entry)
+struct tpm_chip *tpm_register_hardware(struct device *dev, const struct 
tpm_vendor_specific
+                                      *entry)
 {
 #define DEVNAME_SIZE 7
 
        char *devname;
        struct tpm_chip *chip;
-       int i, j;
 
        /* Driver specific per-device data */
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (chip == NULL)
-               return -ENOMEM;
+               return NULL;
 
        init_MUTEX(&chip->buffer_mutex);
        init_MUTEX(&chip->tpm_mutex);
@@ -559,51 +1166,37 @@ int tpm_register_hardware(struct device 
        chip->user_read_timer.function = user_reader_timeout;
        chip->user_read_timer.data = (unsigned long) chip;
 
-       chip->vendor = entry;
-       
-       if (entry->buffersize < TPM_MIN_BUFSIZE) {
-               entry->buffersize = TPM_MIN_BUFSIZE;
-       } else if (entry->buffersize > TPM_MAX_BUFSIZE) {
-               entry->buffersize = TPM_MAX_BUFSIZE;
-       }
-
-       chip->dev_num = -1;
-
-       for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
-               for (j = 0; j < 8 * sizeof(int); j++)
-                       if ((dev_mask[i] & (1 << j)) == 0) {
-                               chip->dev_num =
-                                   i * TPM_NUM_MASK_ENTRIES + j;
-                               dev_mask[i] |= 1 << j;
-                               goto dev_num_search_complete;
-                       }
-
-dev_num_search_complete:
-       if (chip->dev_num < 0) {
+       memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
+
+       chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
+
+       if (chip->dev_num >= TPM_NUM_DEVICES) {
                dev_err(dev, "No available tpm device numbers\n");
                kfree(chip);
-               return -ENODEV;
+               return NULL;
        } else if (chip->dev_num == 0)
-               chip->vendor->miscdev.minor = TPM_MINOR;
+               chip->vendor.miscdev.minor = TPM_MINOR;
        else
-               chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
+               chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
+
+       set_bit(chip->dev_num, dev_mask);
 
        devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
        scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
-       chip->vendor->miscdev.name = devname;
-
-       chip->vendor->miscdev.dev = dev;
+       chip->vendor.miscdev.name = devname;
+
+       chip->vendor.miscdev.dev = dev;
        chip->dev = get_device(dev);
 
-       if (misc_register(&chip->vendor->miscdev)) {
+       if (misc_register(&chip->vendor.miscdev)) {
                dev_err(chip->dev,
                        "unable to misc_register %s, minor %d\n",
-                       chip->vendor->miscdev.name,
-                       chip->vendor->miscdev.minor);
+                       chip->vendor.miscdev.name,
+                       chip->vendor.miscdev.minor);
                put_device(dev);
+               clear_bit(chip->dev_num, dev_mask);
                kfree(chip);
-               dev_mask[i] &= !(1 << j);
-               return -ENODEV;
+               return NULL;
        }
 
        spin_lock(&driver_lock);
@@ -614,11 +1207,11 @@ dev_num_search_complete:
 
        spin_unlock(&driver_lock);
 
-       sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
+       sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
 
        chip->bios_dir = tpm_bios_log_setup(devname);
 
-       return 0;
+       return chip;
 }
 EXPORT_SYMBOL_GPL(tpm_register_hardware);
 
diff -r 4b51d081378d -r 856caf975abd linux-2.6-xen-sparse/drivers/char/tpm/tpm.h
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h       Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h       Mon Jul 03 08:35:12 
2006 +0100
@@ -24,6 +24,14 @@
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
+
+#ifdef CONFIG_XEN
+enum tpm_bufsize {
+       TPM_MIN_BUFFERSIZE = 2048,
+       TPM_MAX_BUFFERSIZE = 64 * 1024,
+};
+#endif
 
 enum tpm_timeout {
        TPM_TIMEOUT = 5,        /* msecs */
@@ -41,18 +49,32 @@ extern ssize_t tpm_show_pcrs(struct devi
                                char *);
 extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
                                char *);
+extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute 
*attr,
+                               char *);
 extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
                                const char *, size_t);
+extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_temp_deactivated(struct device *,
+                                        struct device_attribute *attr, char *);
 
 struct tpm_chip;
 
 struct tpm_vendor_specific {
-       u8 req_complete_mask;
-       u8 req_complete_val;
-       u8 req_canceled;
+       const u8 req_complete_mask;
+       const u8 req_complete_val;
+       const u8 req_canceled;
+#ifdef CONFIG_XEN
        u32 buffersize;
+#endif
        void __iomem *iobase;           /* ioremapped address */
        unsigned long base;             /* TPM base address */
+
+       int irq;
 
        int region_size;
        int have_region;
@@ -63,6 +85,13 @@ struct tpm_vendor_specific {
        u8 (*status) (struct tpm_chip *);
        struct miscdevice miscdev;
        struct attribute_group *attr_group;
+       struct list_head list;
+       int locality;
+       unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
+       unsigned long duration[3]; /* jiffies */
+
+       wait_queue_head_t read_queue;
+       wait_queue_head_t int_queue;
 };
 
 struct tpm_chip {
@@ -75,19 +104,26 @@ struct tpm_chip {
        /* Data passed to and from the tpm via the read/write calls */
        u8 *data_buffer;
        atomic_t data_pending;
+#ifdef CONFIG_XEN
        atomic_t data_position;
+#endif
        struct semaphore buffer_mutex;
 
        struct timer_list user_read_timer;      /* user needs to claim result */
        struct work_struct work;
        struct semaphore tpm_mutex;     /* tpm is processing */
 
-       struct tpm_vendor_specific *vendor;
+       struct tpm_vendor_specific vendor;
 
        struct dentry **bios_dir;
 
        struct list_head list;
+#ifdef CONFIG_XEN
+       void *priv;
+#endif
 };
+
+#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
 
 static inline int tpm_read_index(int base, int index)
 {
@@ -101,13 +137,35 @@ static inline void tpm_write_index(int b
        outb(value & 0xFF, base+1);
 }
 
+#ifdef CONFIG_XEN
 static inline u32 get_chip_buffersize(struct tpm_chip *chip)
 {
-       return chip->vendor->buffersize;
+       u32 size = chip->vendor.buffersize;
+       if (size > TPM_MAX_BUFFERSIZE) {
+               return TPM_MAX_BUFFERSIZE;
+       } else if (size < TPM_MIN_BUFFERSIZE) {
+               return TPM_MIN_BUFFERSIZE;
+       }
+       return size;
 }
 
-extern int tpm_register_hardware(struct device *,
-                                struct tpm_vendor_specific *);
+static inline void *chip_get_private(const struct tpm_chip *chip)
+{
+       return chip->priv;
+}
+
+static inline void chip_set_private(struct tpm_chip *chip, void *priv)
+{
+       chip->priv = priv;
+}
+#endif
+
+extern void tpm_get_timeouts(struct tpm_chip *);
+extern void tpm_gen_interrupt(struct tpm_chip *);
+extern void tpm_continue_selftest(struct tpm_chip *);
+extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
+extern struct tpm_chip* tpm_register_hardware(struct device *,
+                                const struct tpm_vendor_specific *);
 extern int tpm_open(struct inode *, struct file *);
 extern int tpm_release(struct inode *, struct file *);
 extern ssize_t tpm_write(struct file *, const char __user *, size_t,
@@ -121,7 +179,7 @@ extern struct dentry ** tpm_bios_log_set
 extern struct dentry ** tpm_bios_log_setup(char *);
 extern void tpm_bios_log_teardown(struct dentry **);
 #else
-static inline struct dentry* tpm_bios_log_setup(char *name)
+static inline struct dentry ** tpm_bios_log_setup(char *name)
 {
        return NULL;
 }
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c  Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c  Mon Jul 03 08:35:12 
2006 +0100
@@ -29,8 +29,6 @@ enum {
        STATUS_READY = 0x04
 };
 
-#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
-
 struct transmission {
        struct list_head next;
 
@@ -49,26 +47,6 @@ enum {
        TRANSMISSION_FLAG_WAS_QUEUED = 0x1
 };
 
-struct vtpm_state {
-       struct transmission *current_request;
-       spinlock_t           req_list_lock;
-       wait_queue_head_t    req_wait_queue;
-
-       struct list_head     queued_requests;
-
-       struct transmission *current_response;
-       spinlock_t           resp_list_lock;
-       wait_queue_head_t    resp_wait_queue;     // processes waiting for 
responses
-
-       struct transmission *req_cancelled;       // if a cancellation was 
encounterd
-
-       u8                   vd_status;
-       u8                   flags;
-
-       unsigned long        disconnect_time;
-
-       struct tpm_virtual_device *tpmvd;
-};
 
 enum {
        DATAEX_FLAG_QUEUED_ONLY = 0x1
@@ -76,7 +54,6 @@ enum {
 
 
 /* local variables */
-static struct vtpm_state *vtpms;
 
 /* local function prototypes */
 static int _vtpm_send_queued(struct tpm_chip *chip);
@@ -160,11 +137,16 @@ static inline void transmission_free(str
 /*
  * Lower layer uses this function to make a response available.
  */
-int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr)
+int vtpm_vd_recv(const struct tpm_chip *chip,
+                 const unsigned char *buffer, size_t count,
+                 void *ptr)
 {
        unsigned long flags;
        int ret_size = 0;
        struct transmission *t;
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        /*
         * The list with requests must contain one request
@@ -173,26 +155,11 @@ int vtpm_vd_recv(const unsigned char *bu
         */
        spin_lock_irqsave(&vtpms->resp_list_lock, flags);
        if (vtpms->current_request != ptr) {
-               printk("WARNING: The request pointer is different than the "
-                      "pointer the shared memory driver returned to me. "
-                      "%p != %p\n",
-                      vtpms->current_request, ptr);
-       }
-
-       /*
-        * If the request has been cancelled, just quit here
-        */
-       if (vtpms->req_cancelled == (struct transmission *)ptr) {
-               if (vtpms->current_request == vtpms->req_cancelled) {
-                       vtpms->current_request = NULL;
-               }
-               transmission_free(vtpms->req_cancelled);
-               vtpms->req_cancelled = NULL;
                spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
                return 0;
        }
 
-       if (NULL != (t = vtpms->current_request)) {
+       if ((t = vtpms->current_request)) {
                transmission_free(t);
                vtpms->current_request = NULL;
        }
@@ -217,8 +184,12 @@ int vtpm_vd_recv(const unsigned char *bu
 /*
  * Lower layer indicates its status (connected/disconnected)
  */
-void vtpm_vd_status(u8 vd_status)
-{
+void vtpm_vd_status(const struct tpm_chip *chip, u8 vd_status)
+{
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
+
        vtpms->vd_status = vd_status;
        if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
                vtpms->disconnect_time = jiffies;
@@ -233,6 +204,9 @@ static int vtpm_recv(struct tpm_chip *ch
 {
        int rc = 0;
        unsigned long flags;
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        /*
         * Check if the previous operation only queued the command
@@ -251,7 +225,7 @@ static int vtpm_recv(struct tpm_chip *ch
                 * Return a response of up to 30 '0's.
                 */
 
-               count = MIN(count, 30);
+               count = min_t(size_t, count, 30);
                memset(buf, 0x0, count);
                return count;
        }
@@ -270,7 +244,7 @@ static int vtpm_recv(struct tpm_chip *ch
        if (vtpms->current_response) {
                struct transmission *t = vtpms->current_response;
                vtpms->current_response = NULL;
-               rc = MIN(count, t->response_len);
+               rc = min(count, t->response_len);
                memcpy(buf, t->response, rc);
                transmission_free(t);
        }
@@ -284,6 +258,9 @@ static int vtpm_send(struct tpm_chip *ch
        int rc = 0;
        unsigned long flags;
        struct transmission *t = transmission_alloc();
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        if (!t)
                return -ENOMEM;
@@ -327,8 +304,7 @@ static int vtpm_send(struct tpm_chip *ch
 
                        vtpms->current_request = t;
 
-                       rc = vtpm_vd_send(chip,
-                                         vtpms->tpmvd->tpm_private,
+                       rc = vtpm_vd_send(vtpms->tpm_private,
                                          buf,
                                          count,
                                          t);
@@ -373,6 +349,8 @@ static int _vtpm_send_queued(struct tpm_
        int error = 0;
        long flags;
        unsigned char buffer[1];
+       struct vtpm_state *vtpms;
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        spin_lock_irqsave(&vtpms->req_list_lock, flags);
 
@@ -387,8 +365,7 @@ static int _vtpm_send_queued(struct tpm_
                vtpms->current_request = qt;
                spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
 
-               rc = vtpm_vd_send(chip,
-                                 vtpms->tpmvd->tpm_private,
+               rc = vtpm_vd_send(vtpms->tpm_private,
                                  qt->request,
                                  qt->request_len,
                                  qt);
@@ -427,9 +404,21 @@ static void vtpm_cancel(struct tpm_chip 
 static void vtpm_cancel(struct tpm_chip *chip)
 {
        unsigned long flags;
+       struct vtpm_state *vtpms = (struct vtpm_state *)chip_get_private(chip);
+
        spin_lock_irqsave(&vtpms->resp_list_lock,flags);
 
-       vtpms->req_cancelled = vtpms->current_request;
+       if (!vtpms->current_response && vtpms->current_request) {
+               spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
+               interruptible_sleep_on(&vtpms->resp_wait_queue);
+               spin_lock_irqsave(&vtpms->resp_list_lock,flags);
+       }
+
+       if (vtpms->current_response) {
+               struct transmission *t = vtpms->current_response;
+               vtpms->current_response = NULL;
+               transmission_free(t);
+       }
 
        spin_unlock_irqrestore(&vtpms->resp_list_lock,flags);
 }
@@ -438,6 +427,9 @@ static u8 vtpm_status(struct tpm_chip *c
 {
        u8 rc = 0;
        unsigned long flags;
+       struct vtpm_state *vtpms;
+
+       vtpms = (struct vtpm_state *)chip_get_private(chip);
 
        spin_lock_irqsave(&vtpms->resp_list_lock, flags);
        /*
@@ -449,7 +441,10 @@ static u8 vtpm_status(struct tpm_chip *c
        if (vtpms->current_response ||
            0 != (vtpms->flags & DATAEX_FLAG_QUEUED_ONLY)) {
                rc = STATUS_DATA_AVAIL;
-       }
+       } else if (!vtpms->current_response && !vtpms->current_request) {
+               rc = STATUS_READY;
+       }
+
        spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
        return rc;
 }
@@ -465,18 +460,29 @@ static struct file_operations vtpm_ops =
 
 static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
 static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
+                  NULL);
 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
 static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
 
 static struct attribute *vtpm_attrs[] = {
        &dev_attr_pubek.attr,
        &dev_attr_pcrs.attr,
+       &dev_attr_enabled.attr,
+       &dev_attr_active.attr,
+       &dev_attr_owned.attr,
+       &dev_attr_temp_deactivated.attr,
        &dev_attr_caps.attr,
        &dev_attr_cancel.attr,
        NULL,
 };
 
 static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs };
+
+#define TPM_LONG_TIMEOUT   (10 * 60 * HZ)
 
 static struct tpm_vendor_specific tpm_vtpm = {
        .recv = vtpm_recv,
@@ -486,61 +492,56 @@ static struct tpm_vendor_specific tpm_vt
        .req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
        .req_complete_val  = STATUS_DATA_AVAIL,
        .req_canceled = STATUS_READY,
-       .base = 0,
        .attr_group = &vtpm_attr_grp,
        .miscdev = {
                .fops = &vtpm_ops,
        },
-};
-
-static struct platform_device *pdev;
-
-int __init init_vtpm(struct tpm_virtual_device *tvd)
-{
-       int rc;
-
-       /* vtpms is global - only allow one user */
-       if (vtpms)
-               return -EBUSY;
+       .duration = {
+               TPM_LONG_TIMEOUT,
+               TPM_LONG_TIMEOUT,
+               TPM_LONG_TIMEOUT,
+       },
+};
+
+struct tpm_chip *init_vtpm(struct device *dev,
+                           struct tpm_virtual_device *tvd,
+                           struct tpm_private *tp)
+{
+       long rc;
+       struct tpm_chip *chip;
+       struct vtpm_state *vtpms;
 
        vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
        if (!vtpms)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        vtpm_state_init(vtpms);
        vtpms->tpmvd = tvd;
-
-       pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
-       if (IS_ERR(pdev)) {
-               rc = PTR_ERR(pdev);
-               goto err_free_mem;
-       }
+       vtpms->tpm_private = tp;
 
        if (tvd)
                tpm_vtpm.buffersize = tvd->max_tx_size;
 
-       if ((rc = tpm_register_hardware(&pdev->dev, &tpm_vtpm)) < 0) {
-               goto err_unreg_pdev;
-       }
-
-       return 0;
-
-err_unreg_pdev:
-       platform_device_unregister(pdev);
+       chip = tpm_register_hardware(dev, &tpm_vtpm);
+       if (!chip) {
+               rc = -ENODEV;
+               goto err_free_mem;
+       }
+
+       chip_set_private(chip, vtpms);
+
+       return chip;
+
 err_free_mem:
        kfree(vtpms);
-       vtpms = NULL;
-
-       return rc;
-}
-
-void __exit cleanup_vtpm(void)
-{
-       struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
-       if (chip) {
-               tpm_remove_hardware(chip->dev);
-               platform_device_unregister(pdev);
-       }
+
+       return ERR_PTR(rc);
+}
+
+void cleanup_vtpm(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       struct vtpm_state *vtpms = (struct vtpm_state*)chip_get_private(chip);
+       tpm_remove_hardware(dev);
        kfree(vtpms);
-       vtpms = NULL;
-}
+}
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h  Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h  Mon Jul 03 08:35:12 
2006 +0100
@@ -12,6 +12,26 @@ struct tpm_virtual_device {
         * for allocation of buffers.
         */
        unsigned int max_tx_size;
+};
+
+struct vtpm_state {
+       struct transmission *current_request;
+       spinlock_t           req_list_lock;
+       wait_queue_head_t    req_wait_queue;
+
+       struct list_head     queued_requests;
+
+       struct transmission *current_response;
+       spinlock_t           resp_list_lock;
+       wait_queue_head_t    resp_wait_queue;     // processes waiting for 
responses
+
+       u8                   vd_status;
+       u8                   flags;
+
+       unsigned long        disconnect_time;
+
+       struct tpm_virtual_device *tpmvd;
+
        /*
         * The following is a private structure of the underlying
         * driver. It is passed as parameter in the send function.
@@ -19,20 +39,30 @@ struct tpm_virtual_device {
        struct tpm_private *tpm_private;
 };
 
+
 enum vdev_status {
        TPM_VD_STATUS_DISCONNECTED = 0x0,
        TPM_VD_STATUS_CONNECTED = 0x1
 };
 
 /* this function is called from tpm_vtpm.c */
-int vtpm_vd_send(struct tpm_chip *tc,
-                 struct tpm_private * tp,
+int vtpm_vd_send(struct tpm_private * tp,
                  const u8 * buf, size_t count, void *ptr);
 
 /* these functions are offered by tpm_vtpm.c */
-int __init init_vtpm(struct tpm_virtual_device *);
-void __exit cleanup_vtpm(void);
-int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr);
-void vtpm_vd_status(u8 status);
+struct tpm_chip *init_vtpm(struct device *,
+                           struct tpm_virtual_device *,
+                           struct tpm_private *);
+void cleanup_vtpm(struct device *);
+int vtpm_vd_recv(const struct tpm_chip* chip,
+                 const unsigned char *buffer, size_t count, void *ptr);
+void vtpm_vd_status(const struct tpm_chip *, u8 status);
+
+static inline struct tpm_private *tpm_private_from_dev(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       struct vtpm_state *vtpms = chip_get_private(chip);
+       return vtpms->tpm_private;
+}
 
 #endif
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
--- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c   Mon Jul 03 08:35:12 
2006 +0100
@@ -34,6 +34,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
@@ -41,12 +42,15 @@
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/tpmif.h>
 #include <xen/xenbus.h>
+#include "tpm.h"
 #include "tpm_vtpm.h"
 
 #undef DEBUG
 
 /* local structures */
 struct tpm_private {
+       struct tpm_chip *chip;
+
        tpmif_tx_interface_t *tx;
        atomic_t refcnt;
        unsigned int evtchn;
@@ -60,6 +64,7 @@ struct tpm_private {
 
        atomic_t tx_busy;
        void *tx_remember;
+
        domid_t backend_id;
        wait_queue_head_t wait_q;
 
@@ -95,6 +100,7 @@ static int tpm_xmit(struct tpm_private *
                     const u8 * buf, size_t count, int userbuffer,
                     void *remember);
 static void destroy_tpmring(struct tpm_private *tp);
+void __exit tpmif_exit(void);
 
 #define DPRINTK(fmt, args...) \
     pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
@@ -199,8 +205,7 @@ static DEFINE_MUTEX(suspend_lock);
 /*
  * Send data via this module by calling this function
  */
-int vtpm_vd_send(struct tpm_chip *chip,
-                 struct tpm_private *tp,
+int vtpm_vd_send(struct tpm_private *tp,
                  const u8 * buf, size_t count, void *ptr)
 {
        int sent;
@@ -331,7 +336,7 @@ static void backend_changed(struct xenbu
 static void backend_changed(struct xenbus_device *dev,
                            enum xenbus_state backend_state)
 {
-       struct tpm_private *tp = dev->dev.driver_data;
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        DPRINTK("\n");
 
        switch (backend_state) {
@@ -358,6 +363,9 @@ static void backend_changed(struct xenbu
        }
 }
 
+struct tpm_virtual_device tvd = {
+       .max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
+};
 
 static int tpmfront_probe(struct xenbus_device *dev,
                           const struct xenbus_device_id *id)
@@ -368,6 +376,12 @@ static int tpmfront_probe(struct xenbus_
 
        if (!tp)
                return -ENOMEM;
+
+       tp->chip = init_vtpm(&dev->dev, &tvd, tp);
+
+       if (IS_ERR(tp->chip)) {
+               return PTR_ERR(tp->chip);
+       }
 
        err = xenbus_scanf(XBT_NIL, dev->nodename,
                           "handle", "%i", &handle);
@@ -380,12 +394,10 @@ static int tpmfront_probe(struct xenbus_
        }
 
        tp->dev = dev;
-       dev->dev.driver_data = tp;
 
        err = talk_to_backend(dev, tp);
        if (err) {
                tpm_private_put();
-               dev->dev.driver_data = NULL;
                return err;
        }
        return 0;
@@ -394,16 +406,16 @@ static int tpmfront_probe(struct xenbus_
 
 static int tpmfront_remove(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        destroy_tpmring(tp);
+       cleanup_vtpm(&dev->dev);
        return 0;
 }
 
 static int tpmfront_suspend(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        u32 ctr;
-
        /* lock, so no app can send */
        mutex_lock(&suspend_lock);
        tp->is_suspended = 1;
@@ -431,7 +443,7 @@ static int tpmfront_suspend(struct xenbu
 
 static int tpmfront_resume(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
+       struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
        destroy_tpmring(tp);
        return talk_to_backend(dev, tp);
 }
@@ -548,7 +560,7 @@ static void tpmif_rx_action(unsigned lon
                offset += tocopy;
        }
 
-       vtpm_vd_recv(buffer, received, tp->tx_remember);
+       vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember);
        kfree(buffer);
 
 exit:
@@ -638,6 +650,7 @@ static int tpm_xmit(struct tpm_private *
 
        atomic_set(&tp->tx_busy, 1);
        tp->tx_remember = remember;
+
        mb();
 
        DPRINTK("Notifying backend via event channel %d\n",
@@ -657,9 +670,9 @@ static void tpmif_notify_upperlayer(stru
         * to the BE.
         */
        if (tp->is_connected) {
-               vtpm_vd_status(TPM_VD_STATUS_CONNECTED);
+               vtpm_vd_status(tp->chip, TPM_VD_STATUS_CONNECTED);
        } else {
-               vtpm_vd_status(TPM_VD_STATUS_DISCONNECTED);
+               vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED);
        }
 }
 
@@ -699,13 +712,10 @@ static void tpmif_set_connected_state(st
  * =================================================================
  */
 
-struct tpm_virtual_device tvd = {
-       .max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
-};
 
 static int __init tpmif_init(void)
 {
-       int rc;
+       long rc = 0;
        struct tpm_private *tp;
 
        if ((xen_start_info->flags & SIF_INITDOMAIN)) {
@@ -717,11 +727,6 @@ static int __init tpmif_init(void)
                rc = -ENOMEM;
                goto failexit;
        }
-
-       tvd.tpm_private = tp;
-       rc = init_vtpm(&tvd);
-       if (rc)
-               goto init_vtpm_failed;
 
        IPRINTK("Initialising the vTPM driver.\n");
        if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
@@ -734,19 +739,16 @@ static int __init tpmif_init(void)
        return 0;
 
 gnttab_alloc_failed:
-       cleanup_vtpm();
-init_vtpm_failed:
        tpm_private_put();
 failexit:
 
-       return rc;
-}
-
-
-static void __exit tpmif_exit(void)
+       return (int)rc;
+}
+
+
+void __exit tpmif_exit(void)
 {
        exit_tpm_xenbus();
-       cleanup_vtpm();
        tpm_private_put();
        gnttab_free_grant_references(gref_head);
 }
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Mon Jul 03 
08:35:12 2006 +0100
@@ -75,6 +75,9 @@ static unsigned long current_pages;
 static unsigned long current_pages;
 static unsigned long target_pages;
 
+/* We increase/decrease in batches which fit in a page */
+static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)]; 
+
 /* VM /proc information for memory */
 extern unsigned long totalram_pages;
 
@@ -95,6 +98,11 @@ static void balloon_process(void *unused
 static void balloon_process(void *unused);
 static DECLARE_WORK(balloon_worker, balloon_process, NULL);
 static struct timer_list balloon_timer;
+
+/* When ballooning out (allocating memory to return to Xen) we don't really 
+   want the kernel to try too hard since that can trigger the oom killer. */
+#define GFP_BALLOON \
+       (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
 
 #define PAGE_TO_LIST(p) (&(p)->lru)
 #define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
@@ -172,7 +180,7 @@ static unsigned long current_target(void
 
 static int increase_reservation(unsigned long nr_pages)
 {
-       unsigned long *frame_list, frame, pfn, i, flags;
+       unsigned long  pfn, i, flags;
        struct page   *page;
        long           rc;
        struct xen_memory_reservation reservation = {
@@ -181,15 +189,8 @@ static int increase_reservation(unsigned
                .domid        = DOMID_SELF
        };
 
-       if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
-               nr_pages = PAGE_SIZE / sizeof(unsigned long);
-
-       frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
-       if (frame_list == NULL) {
-               frame_list = &frame;
-               if (nr_pages > 1)
-                       nr_pages = 1;
-       }
+       if (nr_pages > ARRAY_SIZE(frame_list))
+               nr_pages = ARRAY_SIZE(frame_list);
 
        balloon_lock(flags);
 
@@ -253,15 +254,12 @@ static int increase_reservation(unsigned
  out:
        balloon_unlock(flags);
 
-       if (frame_list != &frame)
-               free_page((unsigned long)frame_list);
-
        return 0;
 }
 
 static int decrease_reservation(unsigned long nr_pages)
 {
-       unsigned long *frame_list, frame, pfn, i, flags;
+       unsigned long  pfn, i, flags;
        struct page   *page;
        void          *v;
        int            need_sleep = 0;
@@ -272,18 +270,11 @@ static int decrease_reservation(unsigned
                .domid        = DOMID_SELF
        };
 
-       if (nr_pages > (PAGE_SIZE / sizeof(unsigned long)))
-               nr_pages = PAGE_SIZE / sizeof(unsigned long);
-
-       frame_list = (unsigned long *)__get_free_page(GFP_KERNEL);
-       if (frame_list == NULL) {
-               frame_list = &frame;
-               if (nr_pages > 1)
-                       nr_pages = 1;
-       }
+       if (nr_pages > ARRAY_SIZE(frame_list))
+               nr_pages = ARRAY_SIZE(frame_list);
 
        for (i = 0; i < nr_pages; i++) {
-               if ((page = alloc_page(GFP_HIGHUSER)) == NULL) {
+               if ((page = alloc_page(GFP_BALLOON)) == NULL) {
                        nr_pages = i;
                        need_sleep = 1;
                        break;
@@ -330,9 +321,6 @@ static int decrease_reservation(unsigned
        totalram_pages = current_pages;
 
        balloon_unlock(flags);
-
-       if (frame_list != &frame)
-               free_page((unsigned long)frame_list);
 
        return need_sleep;
 }
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Mon Jul 03 08:35:12 
2006 +0100
@@ -75,8 +75,6 @@ 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,                 \
@@ -106,56 +104,39 @@ static struct attribute_group vbdstat_gr
        .attrs = vbdstat_attrs,
 };
 
+VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
+VBD_SHOW(mode, "%s\n", be->mode);
+
 int xenvbd_sysfs_addif(struct xenbus_device *dev)
 {
-       int error = 0;
+       int error;
        
-       error = sysfs_create_group(&dev->dev.kobj,
-                                  &vbdstat_group);
+       error = device_create_file(&dev->dev, &dev_attr_physical_device);
+       if (error)
+               goto fail1;
+
+       error = device_create_file(&dev->dev, &dev_attr_mode);
        if (error)
-               goto fail;
-       
+               goto fail2;
+
+       error = sysfs_create_group(&dev->dev.kobj, &vbdstat_group);
+       if (error)
+               goto fail3;
+
        return 0;
-       
-fail:
-       sysfs_remove_group(&dev->dev.kobj,
-                          &vbdstat_group);
+
+fail3: sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
+fail2: device_remove_file(&dev->dev, &dev_attr_mode);
+fail1: device_remove_file(&dev->dev, &dev_attr_physical_device);
        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)
-{
-       struct xenbus_device *dev = to_xenbus_device(_dev);
-       struct backend_info *be = dev->dev.driver_data;
-       return sprintf(buf, "%x:%x\n", be->major, be->minor);
-}
-DEVICE_ATTR(physical_device, S_IRUSR | S_IRGRP | S_IROTH,
-           show_physical_device, NULL);
-
-
-static ssize_t show_mode(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, "%s\n", be->mode);
-}
-DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_IROTH, show_mode, NULL);
-
+       sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
+       device_remove_file(&dev->dev, &dev_attr_mode);
+       device_remove_file(&dev->dev, &dev_attr_physical_device);
+}
 
 static int blkback_remove(struct xenbus_device *dev)
 {
@@ -176,9 +157,8 @@ static int blkback_remove(struct xenbus_
                be->blkif = NULL;
        }
 
-       device_remove_file(&dev->dev, &dev_attr_physical_device);
-       device_remove_file(&dev->dev, &dev_attr_mode);
-       xenvbd_sysfs_delif(dev);
+       if (be->major || be->minor)
+               xenvbd_sysfs_delif(dev);
 
        kfree(be);
        dev->dev.driver_data = NULL;
@@ -293,15 +273,18 @@ static void backend_changed(struct xenbu
                err = vbd_create(be->blkif, handle, major, minor,
                                 (NULL == strchr(be->mode, 'w')));
                if (err) {
-                       be->major = 0;
-                       be->minor = 0;
+                       be->major = be->minor = 0;
                        xenbus_dev_fatal(dev, err, "creating vbd structure");
                        return;
                }
 
-               device_create_file(&dev->dev, &dev_attr_physical_device);
-               device_create_file(&dev->dev, &dev_attr_mode);
-               xenvbd_sysfs_addif(dev);
+               err = xenvbd_sysfs_addif(dev);
+               if (err) {
+                       vbd_free(&be->blkif->vbd);
+                       be->major = be->minor = 0;
+                       xenbus_dev_fatal(dev, err, "creating sysfs entries");
+                       return;
+               }
 
                /* We're potentially connected now */
                update_blkif_status(be->blkif); 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c    Mon Jul 03 08:35:12 
2006 +0100
@@ -219,7 +219,10 @@ asmlinkage void evtchn_do_upcall(struct 
 
        vcpu_info->evtchn_upcall_pending = 0;
 
-       /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
+#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
+       /* Clear master pending flag /before/ clearing selector flag. */
+       rmb();
+#endif
        l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
        while (l1 != 0) {
                l1i = __ffs(l1);
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Mon Jul 03 08:35:12 
2006 +0100
@@ -169,7 +169,7 @@ int gnttab_end_foreign_access_ref(grant_
                        printk(KERN_ALERT "WARNING: g.e. still in use!\n");
                        return 0;
                }
-       } while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
+       } while ((nflags = synch_cmpxchg_subword(&shared[ref].flags, flags, 0)) 
!=
                 flags);
 
        return 1;
@@ -224,7 +224,7 @@ unsigned long gnttab_end_foreign_transfe
         * reference and return failure (== 0).
         */
        while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
-               if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags)
+               if (synch_cmpxchg_subword(&shared[ref].flags, flags, 0) == 
flags)
                        return 0;
                cpu_relax();
        }
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_sysfs.c Mon Jul 03 08:35:12 
2006 +0100
@@ -8,12 +8,14 @@
  */
 
 #include <linux/config.h>
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <asm/hypervisor.h>
 #include <xen/features.h>
 #include <xen/hypervisor_sysfs.h>
+#include <xen/xenbus.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mike D. Day <ncmike@xxxxxxxxxx>");
@@ -95,6 +97,37 @@ static void xen_sysfs_version_destroy(vo
 static void xen_sysfs_version_destroy(void)
 {
        sysfs_remove_group(&hypervisor_subsys.kset.kobj, &version_group);
+}
+
+/* UUID */
+
+static ssize_t uuid_show(struct hyp_sysfs_attr *attr, char *buffer)
+{
+       char *vm, *val;
+       int ret;
+
+       vm = xenbus_read(XBT_NIL, "vm", "", NULL);
+       if (IS_ERR(vm))
+               return PTR_ERR(vm);
+       val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
+       kfree(vm);
+       if (IS_ERR(val))
+               return PTR_ERR(val);
+       ret = sprintf(buffer, "%s\n", val);
+       kfree(val);
+       return ret;
+}
+
+HYPERVISOR_ATTR_RO(uuid);
+
+static int __init xen_sysfs_uuid_init(void)
+{
+       return sysfs_create_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
+}
+
+static void xen_sysfs_uuid_destroy(void)
+{
+       sysfs_remove_file(&hypervisor_subsys.kset.kobj, &uuid_attr.attr);
 }
 
 /* xen compilation attributes */
@@ -314,10 +347,15 @@ static int __init hyper_sysfs_init(void)
        ret = xen_compilation_init();
        if (ret)
                goto comp_out;
+       ret = xen_sysfs_uuid_init();
+       if (ret)
+               goto uuid_out;
        ret = xen_properties_init();
        if (!ret)
                goto out;
 
+       xen_sysfs_uuid_destroy();
+uuid_out:
        xen_compilation_destroy();
 comp_out:
        xen_sysfs_version_destroy();
@@ -331,6 +369,7 @@ static void hyper_sysfs_exit(void)
 {
        xen_properties_destroy();
        xen_compilation_destroy();
+       xen_sysfs_uuid_destroy();
        xen_sysfs_version_destroy();
        xen_sysfs_type_destroy();
 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon Jul 03 
08:35:12 2006 +0100
@@ -663,6 +663,34 @@ static void netbk_fill_frags(struct sk_b
        }
 }
 
+int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
+                    int work_to_do)
+{
+       struct netif_extra_info *extra;
+       RING_IDX cons = netif->tx.req_cons;
+
+       do {
+               if (unlikely(work_to_do-- <= 0)) {
+                       DPRINTK("Missing extra info\n");
+                       return -EBADR;
+               }
+
+               extra = (struct netif_extra_info *)
+                       RING_GET_REQUEST(&netif->tx, cons);
+               if (unlikely(!extra->type ||
+                            extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+                       netif->tx.req_cons = ++cons;
+                       DPRINTK("Invalid extra type: %d\n", extra->type);
+                       return -EINVAL;
+               }
+
+               memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
+               netif->tx.req_cons = ++cons;
+       } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+
+       return work_to_do;
+}
+
 /* Called after netfront has transmitted */
 static void net_tx_action(unsigned long unused)
 {
@@ -670,7 +698,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;
+       struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
        u16 pending_idx;
        RING_IDX i;
        gnttab_map_grant_ref_t *mop;
@@ -732,16 +760,15 @@ static void net_tx_action(unsigned long 
                work_to_do--;
                netif->tx.req_cons = ++i;
 
+               memset(extras, 0, sizeof(extras));
                if (txreq.flags & NETTXF_extra_info) {
-                       if (work_to_do-- <= 0) {
-                               DPRINTK("Missing extra info\n");
-                               netbk_tx_err(netif, &txreq, i);
+                       work_to_do = netbk_get_extras(netif, extras,
+                                                     work_to_do);
+                       if (unlikely(work_to_do < 0)) {
+                               netbk_tx_err(netif, &txreq, 0);
                                continue;
                        }
-
-                       memcpy(&txtra, RING_GET_REQUEST(&netif->tx, i),
-                              sizeof(txtra));
-                       netif->tx.req_cons = ++i;
+                       i = netif->tx.req_cons;
                }
 
                ret = netbk_count_requests(netif, &txreq, work_to_do);
@@ -751,7 +778,7 @@ static void net_tx_action(unsigned long 
                }
                i += ret;
 
-               if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
+               if (unlikely(ret > MAX_SKB_FRAGS)) {
                        DPRINTK("Too many frags\n");
                        netbk_tx_err(netif, &txreq, i);
                        continue;
@@ -788,10 +815,24 @@ static void net_tx_action(unsigned long 
                /* 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;
+               if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
+                       struct netif_extra_info *gso;
+                       gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
+
+                       /* Currently on TCPv4 S.O. is supported. */
+                       if (gso->u.gso.type != XEN_NETIF_GSO_TCPV4) {
+                               DPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
+                               kfree_skb(skb);
+                               netbk_tx_err(netif, &txreq, i);
+                               break;
+                       }
+
+                       skb_shinfo(skb)->gso_size = gso->u.gso.size;
+                       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+
+                       /* Header must be checked, and gso_segs computed. */
+                       skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+                       skb_shinfo(skb)->gso_segs = 0;
                }
 
                gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Wed Jun 28 07:52:21 
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Mon Jul 03 08:35:12 
2006 +0100
@@ -101,11 +101,13 @@ static int netback_probe(struct xenbus_d
                        goto abort_transaction;
                }
 
+#if 0 /* KAF: After the protocol is finalised. */
                err = xenbus_printf(xbt, dev->nodename, "feature-tso", "%d", 1);
                if (err) {
                        message = "writing feature-tso";
                        goto abort_transaction;
                }
+#endif
 
                err = xenbus_transaction_end(xbt, 0);
        } while (err == -EAGAIN);
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Mon Jul 03 
08:35:12 2006 +0100
@@ -463,7 +463,7 @@ static int network_open(struct net_devic
 
 static inline int netfront_tx_slot_available(struct netfront_info *np)
 {
-       return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
+       return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2;
 }
 
 static inline void network_maybe_wake_tx(struct net_device *dev)
@@ -491,7 +491,13 @@ static void network_tx_buf_gc(struct net
                rmb(); /* Ensure we see responses up to 'rp'. */
 
                for (cons = np->tx.rsp_cons; cons != prod; cons++) {
-                       id  = RING_GET_RESPONSE(&np->tx, cons)->id;
+                       struct netif_tx_response *txrsp;
+
+                       txrsp = RING_GET_RESPONSE(&np->tx, cons);
+                       if (txrsp->status == NETIF_RSP_NULL)
+                               continue;
+
+                       id  = txrsp->id;
                        skb = np->tx_skbs[id];
                        if (unlikely(gnttab_query_foreign_access(
                                np->grant_tx_ref[id]) != 0)) {
@@ -719,6 +725,7 @@ static int network_start_xmit(struct sk_
        unsigned short id;
        struct netfront_info *np = netdev_priv(dev);
        struct netif_tx_request *tx;
+       struct netif_extra_info *extra;
        char *data = skb->data;
        RING_IDX i;
        grant_ref_t ref;
@@ -739,7 +746,8 @@ static int network_start_xmit(struct sk_
        spin_lock_irq(&np->tx_lock);
 
        if (unlikely(!netif_carrier_ok(dev) ||
-                    (frags > 1 && !xennet_can_sg(dev)))) {
+                    (frags > 1 && !xennet_can_sg(dev)) ||
+                    netif_needs_gso(dev, skb))) {
                spin_unlock_irq(&np->tx_lock);
                goto drop;
        }
@@ -762,10 +770,29 @@ static int network_start_xmit(struct sk_
        tx->size = len;
 
        tx->flags = 0;
+       extra = NULL;
+
        if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
                tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
        if (skb->proto_data_valid) /* remote but checksummed? */
                tx->flags |= NETTXF_data_validated;
+
+       if (skb_shinfo(skb)->gso_size) {
+               struct netif_extra_info *gso = (struct netif_extra_info *)
+                       RING_GET_REQUEST(&np->tx, ++i);
+
+               if (extra)
+                       extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
+               else
+                       tx->flags |= NETTXF_extra_info;
+
+               gso->u.gso.size = skb_shinfo(skb)->gso_size;
+               gso->u.gso.type = XEN_NETIF_GSO_TCPV4;
+
+               gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
+               gso->flags = 0;
+               extra = gso;
+       }
 
        np->tx.req_prod_pvt = i + 1;
 
@@ -1065,9 +1092,28 @@ static int xennet_set_sg(struct net_devi
        return ethtool_op_set_sg(dev, data);
 }
 
+static int xennet_set_tso(struct net_device *dev, u32 data)
+{
+       if (data) {
+               struct netfront_info *np = netdev_priv(dev);
+               int val;
+
+               if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-tso",
+                                "%d", &val) < 0)
+                       val = 0;
+#if 0 /* KAF: After the protocol is finalised. */
+               if (!val)
+#endif
+                       return -ENOSYS;
+       }
+
+       return ethtool_op_set_tso(dev, data);
+}
+
 static void xennet_set_features(struct net_device *dev)
 {
-       xennet_set_sg(dev, 1);
+       if (!xennet_set_sg(dev, 1))
+               xennet_set_tso(dev, 1);
 }
 
 static void network_connect(struct net_device *dev)
@@ -1148,6 +1194,8 @@ static struct ethtool_ops network_ethtoo
        .set_tx_csum = ethtool_op_set_tx_csum,
        .get_sg = ethtool_op_get_sg,
        .set_sg = xennet_set_sg,
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = xennet_set_tso,
 };
 
 #ifdef CONFIG_SYSFS
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Mon Jul 03 
08:35:12 2006 +0100
@@ -886,29 +886,6 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_no
 EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
 
 
-static int all_devices_ready_(struct device *dev, void *data)
-{
-       struct xenbus_device *xendev = to_xenbus_device(dev);
-       int *result = data;
-
-       if (xendev->state != XenbusStateConnected) {
-               *result = 0;
-               return 1;
-       }
-
-       return 0;
-}
-
-
-static int all_devices_ready(void)
-{
-       int ready = 1;
-       bus_for_each_dev(&xenbus_frontend.bus, NULL, &ready,
-                        all_devices_ready_);
-       return ready;
-}
-
-
 void xenbus_probe(void *unused)
 {
        BUG_ON((xenstored_ready <= 0));
@@ -1060,6 +1037,43 @@ postcore_initcall(xenbus_probe_init);
 postcore_initcall(xenbus_probe_init);
 
 
+static int is_disconnected_device(struct device *dev, void *data)
+{
+       struct xenbus_device *xendev = to_xenbus_device(dev);
+
+       /*
+        * A device with no driver will never connect. We care only about
+        * devices which should currently be in the process of connecting.
+        */
+       if (!dev->driver)
+               return 0;
+
+       return (xendev->state != XenbusStateConnected);
+}
+
+static int exists_disconnected_device(void)
+{
+       return bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
+                               is_disconnected_device);
+}
+
+static int print_device_status(struct device *dev, void *data)
+{
+       struct xenbus_device *xendev = to_xenbus_device(dev);
+
+       if (!dev->driver) {
+               /* Information only: is this too noisy? */
+               printk(KERN_INFO "XENBUS: Device with no driver: %s\n",
+                      xendev->nodename);
+       } else if (xendev->state != XenbusStateConnected) {
+               printk(KERN_WARNING "XENBUS: Timeout connecting "
+                      "to device: %s (state %d)\n",
+                      xendev->nodename, xendev->state);
+       }
+
+       return 0;
+}
+
 /*
  * On a 10 second timeout, wait for all devices currently configured.  We need
  * to do this to guarantee that the filesystems and / or network devices
@@ -1081,13 +1095,12 @@ static int __init wait_for_devices(void)
        if (!is_running_on_xen())
                return -ENODEV;
 
-       while (time_before(jiffies, timeout)) {
-               if (all_devices_ready())
-                       return 0;
+       while (time_before(jiffies, timeout) && exists_disconnected_device())
                schedule_timeout_interruptible(HZ/10);
-       }
-
-       printk(KERN_WARNING "XENBUS: Timeout connecting to devices!\n");
+
+       bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL,
+                        print_device_status);
+
        return 0;
 }
 
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Wed Jun 
28 07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/synch_bitops.h Mon Jul 
03 08:35:12 2006 +0100
@@ -138,4 +138,6 @@ static __inline__ int synch_var_test_bit
  synch_const_test_bit((nr),(addr)) : \
  synch_var_test_bit((nr),(addr)))
 
+#define synch_cmpxchg_subword synch_cmpxchg
+
 #endif /* __XEN_SYNCH_BITOPS_H__ */
diff -r 4b51d081378d -r 856caf975abd 
linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h      Wed Jun 28 
07:52:21 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/synch_bitops.h      Mon Jul 03 
08:35:12 2006 +0100
@@ -58,4 +58,6 @@ static __inline__ int synch_var_test_bit
  synch_const_test_bit((nr),(addr)) : \
  synch_var_test_bit((nr),(addr)))
 
+#define synch_cmpxchg_subword synch_cmpxchg
+
 #endif /* __XEN_SYNCH_BITOPS_H__ */
diff -r 4b51d081378d -r 856caf975abd patches/linux-2.6.16.13/net-gso.patch
--- a/patches/linux-2.6.16.13/net-gso.patch     Wed Jun 28 07:52:21 2006 -0600
+++ b/patches/linux-2.6.16.13/net-gso.patch     Mon Jul 03 08:35:12 2006 +0100
@@ -2225,7 +2225,7 @@ index d64e2ec..7494823 100644
        err = ipcomp_compress(x, skb);
        iph = skb->nh.iph;
 diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index 00aa80e..84130c9 100644
+index 00aa80e..30c81a8 100644
 --- a/net/ipv4/tcp.c
 +++ b/net/ipv4/tcp.c
 @@ -257,6 +257,7 @@ #include <linux/smp_lock.h>
@@ -2281,7 +2281,7 @@ index 00aa80e..84130c9 100644
  
                        from += copy;
                        copied += copy;
-@@ -2026,6 +2021,71 @@ int tcp_getsockopt(struct sock *sk, int 
+@@ -2026,6 +2021,77 @@ int tcp_getsockopt(struct sock *sk, int 
  }
  
  
@@ -2306,12 +2306,18 @@ index 00aa80e..84130c9 100644
 +      if (!pskb_may_pull(skb, thlen))
 +              goto out;
 +
-+      segs = NULL;
-+      if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
-+              goto out;
-+
 +      oldlen = (u16)~skb->len;
 +      __skb_pull(skb, thlen);
++
++      if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
++              /* Packet is from an untrusted source, reset gso_segs. */
++              int mss = skb_shinfo(skb)->gso_size;
++
++              skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
++
++              segs = NULL;
++              goto out;
++      }
 +
 +      segs = skb_segment(skb, features);
 +      if (IS_ERR(segs))
diff -r 4b51d081378d -r 856caf975abd 
patches/linux-2.6.16.13/xenoprof-generic.patch
--- a/patches/linux-2.6.16.13/xenoprof-generic.patch    Wed Jun 28 07:52:21 
2006 -0600
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch    Mon Jul 03 08:35:12 
2006 +0100
@@ -123,6 +123,21 @@ diff -pru ../pristine-linux-2.6.16.13/dr
                                }
                        }
                }
+diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h 
./drivers/oprofile/buffer_sync.h
+--- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h 2006-05-03 
05:38:44.000000000 +0800
++++ ./drivers/oprofile/buffer_sync.h   2006-06-27 12:12:09.000000000 +0800
+@@ -9,6 +9,11 @@
+ 
+ #ifndef OPROFILE_BUFFER_SYNC_H
+ #define OPROFILE_BUFFER_SYNC_H
++
++#define NO_DOMAIN_SWITCH              -1
++#define DOMAIN_SWITCH_START_EVENT1    0
++#define DOMAIN_SWITCH_START_EVENT2    1
++#define DOMAIN_SWITCH_STOP_EVENT1     2
+  
+ /* add the necessary profiling hooks */
+ int sync_start(void);
 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
diff -r 4b51d081378d -r 856caf975abd tools/examples/Makefile
--- a/tools/examples/Makefile   Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/examples/Makefile   Mon Jul 03 08:35:12 2006 +0100
@@ -26,7 +26,7 @@ XEN_SCRIPTS += network-nat vif-nat
 XEN_SCRIPTS += network-nat vif-nat
 XEN_SCRIPTS += block
 XEN_SCRIPTS += block-enbd block-nbd
-XEN_SCRIPTS += vtpm vtpm-delete
+XEN_SCRIPTS += vtpm vtpm-delete vtpm-addtodb
 XEN_SCRIPTS += xen-hotplug-cleanup
 XEN_SCRIPTS += external-device-migrate
 XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
diff -r 4b51d081378d -r 856caf975abd tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh     Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/examples/vtpm-common.sh     Mon Jul 03 08:35:12 2006 +0100
@@ -347,16 +347,9 @@ function isLocalAddress() {
 # 2nd: name of the domain to migrate
 # 3rd: the migration step to perform
 function vtpm_migration_step() {
-       local instance res
-       instance=$(vtpmdb_find_instance $2)
-       if [ "$instance" == "" ]; then
-               echo "Error: Translation of domain name ($2) to instance 
failed. Check /etc/xen/vtpm.db"
-               log err "Error during translation of domain name"
-       else
-               res=$(isLocalAddress $1)
-               if [ "$res" == "0" ]; then
-                       vtpm_migrate $1 $2 $3
-               fi
+       local res=$(isLocalAddress $1)
+       if [ "$res" == "0" ]; then
+               vtpm_migrate $1 $2 $3
        fi
 }
 
diff -r 4b51d081378d -r 856caf975abd tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/hvmloader/Makefile Mon Jul 03 08:35:12 2006 +0100
@@ -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 4b51d081378d -r 856caf975abd tools/firmware/hvmloader/acpi_madt.c
--- a/tools/firmware/hvmloader/acpi_madt.c      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/hvmloader/acpi_madt.c      Mon Jul 03 08:35:12 2006 +0100
@@ -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 4b51d081378d -r 856caf975abd tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/hvmloader/hvmloader.c      Mon Jul 03 08:35:12 2006 +0100
@@ -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 4b51d081378d -r 856caf975abd tools/firmware/rombios/Makefile
--- a/tools/firmware/rombios/Makefile   Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/rombios/Makefile   Mon Jul 03 08:35:12 2006 +0100
@@ -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 4b51d081378d -r 856caf975abd tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/firmware/rombios/rombios.c  Mon Jul 03 08:35:12 2006 +0100
@@ -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 4b51d081378d -r 856caf975abd tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xc_hvm_build.c        Mon Jul 03 08:35:12 2006 +0100
@@ -4,6 +4,7 @@
 
 #define ELFSIZE 32
 #include <stddef.h>
+#include <inttypes.h>
 #include "xg_private.h"
 #include "xc_elf.h"
 #include <stdlib.h>
@@ -188,7 +189,7 @@ static int setup_guest(int xc_handle,
     unsigned char e820_map_nr;
 
     struct domain_setup_info dsi;
-    unsigned long long v_end;
+    uint64_t v_end;
 
     unsigned long shared_page_frame = 0;
     shared_iopage_t *sp;
@@ -208,11 +209,11 @@ static int setup_guest(int xc_handle,
     v_end = (unsigned long long)memsize << 20;
 
     IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
-           "  Loaded HVM loader:    %08lx->%08lx\n"
-           "  TOTAL:                %08lx->%016llx\n",
+           "  Loaded HVM loader:    %016"PRIx64"->%016"PRIx64"\n"
+           "  TOTAL:                %016"PRIx64"->%016"PRIx64"\n",
            dsi.v_kernstart, dsi.v_kernend,
            dsi.v_start, v_end);
-    IPRINTF("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
+    IPRINTF("  ENTRY ADDRESS:        %016"PRIx64"\n", dsi.v_kernentry);
 
     if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
     {
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xc_linux_build.c      Mon Jul 03 08:35:12 2006 +0100
@@ -11,6 +11,9 @@
 #include <unistd.h>
 #include <inttypes.h>
 #include <zlib.h>
+
+/* Handy for printing out '0' prepended values at native pointer size */
+#define _p(a) ((void *) ((ulong)a))
 
 #if defined(__i386__)
 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
@@ -502,8 +505,6 @@ static int setup_guest(int xc_handle,
         goto error_out;
     }
 
-#define _p(a) ((void *) (a))
-
     IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
            " Loaded kernel: %p->%p\n"
            " Init. ramdisk: %p->%p\n"
@@ -766,9 +767,9 @@ static int setup_guest(int xc_handle,
                 goto error_out;
         }
 
-#define NR(_l,_h,_s) \
-    (((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
-    ((_l) & ~((1UL<<(_s))-1))) >> (_s))
+#define NR(_l,_h,_s)                                                    \
+    (((((unsigned long)(_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) -    \
+    ((unsigned long)(_l) & ~((1UL<<(_s))-1))) >> (_s))
 #if defined(__i386__)
         if ( dsi.pae_kernel != PAEKERN_no )
         {
@@ -796,8 +797,6 @@ static int setup_guest(int xc_handle,
             break;
 #endif
     }
-
-#define _p(a) ((void *) (a))
 
     IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n");
     IPRINTF(" Loaded kernel:    %p->%p\n", _p(dsi.v_kernstart),
@@ -819,8 +818,8 @@ static int setup_guest(int xc_handle,
     if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
     {
         PERROR("Initial guest OS requires too much space\n"
-               "(%luMB is greater than %luMB limit)\n",
-               (v_end-dsi.v_start)>>20, nr_pages>>(20-PAGE_SHIFT));
+               "(%pMB is greater than %luMB limit)\n",
+               _p((v_end-dsi.v_start)>>20), nr_pages>>(20-PAGE_SHIFT));
         goto error_out;
     }
 
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xc_linux_save.c       Mon Jul 03 08:35:12 2006 +0100
@@ -415,11 +415,11 @@ static int suspend_and_state(int (*suspe
 ** which entries do not require canonicalization (in particular, those
 ** entries which map the virtual address reserved for the hypervisor).
 */
-void canonicalize_pagetable(unsigned long type, unsigned long pfn,
-                             const void *spage, void *dpage)
-{
-
-    int i, pte_last, xen_start, xen_end;
+int canonicalize_pagetable(unsigned long type, unsigned long pfn,
+                           const void *spage, void *dpage)
+{
+
+    int i, pte_last, xen_start, xen_end, race = 0; 
     uint64_t pte;
 
     /*
@@ -481,7 +481,8 @@ void canonicalize_pagetable(unsigned lon
                    is quite feasible under live migration */
                 DPRINTF("PT Race: [%08lx,%d] pte=%llx, mfn=%08lx\n",
                         type, i, (unsigned long long)pte, mfn);
-                pfn = 0; /* zap it - we'll retransmit this page later */
+                pfn  = 0;  /* zap it - we'll retransmit this page later */
+                race = 1;  /* inform the caller of race; fatal if !live */ 
             } else
                 pfn = mfn_to_pfn(mfn);
 
@@ -496,7 +497,7 @@ void canonicalize_pagetable(unsigned lon
 
     }
 
-    return;
+    return race; 
 }
 
 
@@ -567,7 +568,7 @@ int xc_linux_save(int xc_handle, int io_
     int rc = 1, i, j, last_iter, iter = 0;
     int live  = (flags & XCFLAGS_LIVE);
     int debug = (flags & XCFLAGS_DEBUG);
-    int sent_last_iter, skip_this_iter;
+    int race = 0, sent_last_iter, skip_this_iter;
 
     /* The new domain's shared-info frame number. */
     unsigned long shared_info_frame;
@@ -1000,7 +1001,11 @@ int xc_linux_save(int xc_handle, int io_
                 if (pagetype >= L1TAB && pagetype <= L4TAB) {
 
                     /* We have a pagetable page: need to rewrite it. */
-                    canonicalize_pagetable(pagetype, pfn, spage, page);
+                    race = 
+                        canonicalize_pagetable(pagetype, pfn, spage, page); 
+
+                    if(race && !live) 
+                        goto out; 
 
                     if (ratewrite(io_fd, page, PAGE_SIZE) != PAGE_SIZE) {
                         ERR("Error when writing to state file (4)");
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xc_load_elf.c Mon Jul 03 08:35:12 2006 +0100
@@ -68,7 +68,7 @@ static int parseelfimage(const char *ima
     Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
     Elf_Phdr *phdr;
     Elf_Shdr *shdr;
-    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
+    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
     const char *shstrtab;
     char *guestinfo=NULL, *p;
     int h, virt_base_defined, elf_pa_off_defined;
@@ -162,15 +162,19 @@ static int parseelfimage(const char *ima
     /* Initial guess for virt_base is 0 if it is not explicitly defined. */
     p = strstr(guestinfo, "VIRT_BASE=");
     virt_base_defined = (p != NULL);
-    virt_base = virt_base_defined ? strtoul(p+10, &p, 0) : 0;
+    virt_base = virt_base_defined ? strtoull(p+10, &p, 0) : 0;
 
     /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */
     p = strstr(guestinfo, "ELF_PADDR_OFFSET=");
     elf_pa_off_defined = (p != NULL);
-    elf_pa_off = elf_pa_off_defined ? strtoul(p+17, &p, 0) : virt_base;
+    elf_pa_off = elf_pa_off_defined ? strtoull(p+17, &p, 0) : virt_base;
 
     if ( elf_pa_off_defined && !virt_base_defined )
-        goto bad_image;
+    {
+        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in __xen_guest"
+              " section.");
+        return -EINVAL;
+    }
 
     for ( h = 0; h < ehdr->e_phnum; h++ )
     {
@@ -179,7 +183,11 @@ static int parseelfimage(const char *ima
             continue;
         vaddr = phdr->p_paddr - elf_pa_off + virt_base;
         if ( (vaddr + phdr->p_memsz) < vaddr )
-            goto bad_image;
+        {
+            ERROR("ELF program header %d is too large.", h);
+            return -EINVAL;
+        }
+
         if ( vaddr < kernstart )
             kernstart = vaddr;
         if ( (vaddr + phdr->p_memsz) > kernend )
@@ -196,13 +204,16 @@ static int parseelfimage(const char *ima
 
     dsi->v_kernentry = ehdr->e_entry;
     if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL )
-        dsi->v_kernentry = strtoul(p+11, &p, 0);
+        dsi->v_kernentry = strtoull(p+11, &p, 0);
 
     if ( (kernstart > kernend) ||
          (dsi->v_kernentry < kernstart) ||
          (dsi->v_kernentry > kernend) ||
          (dsi->v_start > kernstart) )
-        goto bad_image;
+    {
+        ERROR("ELF start or entries are out of bounds.");
+        return -EINVAL;
+    }
 
     if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
         dsi->load_symtab = 1;
@@ -214,10 +225,6 @@ static int parseelfimage(const char *ima
     loadelfsymtab(image, 0, 0, NULL, dsi);
 
     return 0;
-
- bad_image:
-    ERROR("Malformed ELF image.");
-    return -EINVAL;
 }
 
 static int
diff -r 4b51d081378d -r 856caf975abd tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/libxc/xg_private.h  Mon Jul 03 08:35:12 2006 +0100
@@ -132,13 +132,13 @@ typedef unsigned long l4_pgentry_t;
 
 struct domain_setup_info
 {
-    unsigned long v_start;
-    unsigned long v_end;
-    unsigned long v_kernstart;
-    unsigned long v_kernend;
-    unsigned long v_kernentry;
-
-    unsigned long elf_paddr_offset;
+    uint64_t v_start;
+    uint64_t v_end;
+    uint64_t v_kernstart;
+    uint64_t v_kernend;
+    uint64_t v_kernentry;
+
+    uint64_t elf_paddr_offset;
 
 #define PAEKERN_no           0
 #define PAEKERN_yes          1
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xend/XendLogging.py      Mon Jul 03 08:35:12 2006 +0100
@@ -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 4b51d081378d -r 856caf975abd tools/python/xen/xm/cfgbootpolicy.py
--- a/tools/python/xen/xm/cfgbootpolicy.py      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/cfgbootpolicy.py      Mon Jul 03 08:35:12 2006 +0100
@@ -22,8 +22,6 @@ import traceback
 import traceback
 import tempfile
 import os, stat
-import re
-import commands
 import shutil
 import string
 from xen.util.security import ACMError, err
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/create.py     Mon Jul 03 08:35:12 2006 +0100
@@ -21,11 +21,8 @@
 """
 import os
 import os.path
-import string
 import sys
 import socket
-import commands
-import time
 import re
 import xmlrpclib
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/dumppolicy.py
--- a/tools/python/xen/xm/dumppolicy.py Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/dumppolicy.py Mon Jul 03 08:35:12 2006 +0100
@@ -19,10 +19,6 @@
 """
 import sys
 import traceback
-import os
-import commands
-import shutil
-import string
 from xen.util.security import ACMError, err, dump_policy
 
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/labels.py
--- a/tools/python/xen/xm/labels.py     Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/labels.py     Mon Jul 03 08:35:12 2006 +0100
@@ -20,9 +20,6 @@
 """
 import sys
 import traceback
-import os
-import commands
-import shutil
 import string
 from xen.util.security import ACMError, err, list_labels, active_policy
 from xen.util.security import vm_label_re, res_label_re, all_label_re
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/loadpolicy.py
--- a/tools/python/xen/xm/loadpolicy.py Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/loadpolicy.py Mon Jul 03 08:35:12 2006 +0100
@@ -20,10 +20,6 @@
 """
 import sys
 import traceback
-import os
-import commands
-import shutil
-import string
 from xen.util.security import ACMError, err, load_policy
 
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/main.py       Mon Jul 03 08:35:12 2006 +0100
@@ -556,7 +556,7 @@ def xm_vcpu_list(args):
 
 
 def xm_reboot(args):
-    arg_check(args, "reboot", 1, 4)
+    arg_check(args, "reboot", 1, 3)
     from xen.xm import shutdown
     shutdown.main(["shutdown", "-R"] + args)
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/makepolicy.py
--- a/tools/python/xen/xm/makepolicy.py Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/makepolicy.py Mon Jul 03 08:35:12 2006 +0100
@@ -19,10 +19,6 @@
 """
 import sys
 import traceback
-import os
-import commands
-import shutil
-import string
 from xen.util.security import ACMError, err, make_policy
 
 
diff -r 4b51d081378d -r 856caf975abd tools/python/xen/xm/shutdown.py
--- a/tools/python/xen/xm/shutdown.py   Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/python/xen/xm/shutdown.py   Mon Jul 03 08:35:12 2006 +0100
@@ -17,8 +17,6 @@
 
 """Domain shutdown.
 """
-import string
-import sys
 import time
 
 from xen.xend.XendClient import server
@@ -92,7 +90,8 @@ def main_all(opts, args):
     shutdown(opts, None, mode, opts.vals.wait)
 
 def main_dom(opts, args):
-    if len(args) < 1: opts.err('Missing domain')
+    if len(args) == 0: opts.err('No domain parameter given')
+    if len(args) >  1: opts.err('No multiple domain parameters allowed')
     dom = args[0]
     mode = shutdown_mode(opts)  
     shutdown(opts, [ dom ], mode, opts.vals.wait)
diff -r 4b51d081378d -r 856caf975abd tools/xenstat/libxenstat/src/xenstat.c
--- a/tools/xenstat/libxenstat/src/xenstat.c    Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xenstat/libxenstat/src/xenstat.c    Mon Jul 03 08:35:12 2006 +0100
@@ -20,6 +20,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <linux/compiler.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <xs.h>
 #include "xenstat.h"
 
@@ -36,6 +41,7 @@ struct xenstat_handle {
        struct xs_handle *xshandle; /* xenstore handle */
        int page_size;
        FILE *procnetdev;
+       DIR *sysfsvbd;
        char xen_version[VERSION_SIZE]; /* xen version running on this node */
 };
 
@@ -62,6 +68,8 @@ struct xenstat_domain {
        unsigned int ssid;
        unsigned int num_networks;
        xenstat_network *networks;      /* Array of length num_networks */
+       unsigned int num_vbds;
+       xenstat_vbd *vbds;
 };
 
 struct xenstat_vcpu {
@@ -82,6 +90,15 @@ struct xenstat_network {
        unsigned long long terrs;
        unsigned long long tdrop;
 };
+
+struct xenstat_vbd {
+       unsigned int dev;
+       unsigned long long oo_reqs;
+       unsigned long long rd_reqs;
+       unsigned long long wr_reqs;
+};
+#define SYSFS_VBD_PATH "/sys/devices/xen-backend/"
+
 
 /*
  * Data-collection types
@@ -108,12 +125,15 @@ static int  xenstat_collect_vcpus(xensta
 static int  xenstat_collect_vcpus(xenstat_node * node);
 static int  xenstat_collect_networks(xenstat_node * node);
 static int  xenstat_collect_xen_version(xenstat_node * node);
+static int  xenstat_collect_vbds(xenstat_node * node);
 static void xenstat_free_vcpus(xenstat_node * node);
 static void xenstat_free_networks(xenstat_node * node);
 static void xenstat_free_xen_version(xenstat_node * node);
+static void xenstat_free_vbds(xenstat_node * node);
 static void xenstat_uninit_vcpus(xenstat_handle * handle);
 static void xenstat_uninit_networks(xenstat_handle * handle);
 static void xenstat_uninit_xen_version(xenstat_handle * handle);
+static void xenstat_uninit_vbds(xenstat_handle * handle);
 static char *xenstat_get_domain_name(xenstat_handle * handle, unsigned int 
domain_id);
 
 static xenstat_collector collectors[] = {
@@ -122,7 +142,9 @@ static xenstat_collector collectors[] = 
        { XENSTAT_NETWORK, xenstat_collect_networks,
          xenstat_free_networks, xenstat_uninit_networks },
        { XENSTAT_XEN_VERSION, xenstat_collect_xen_version,
-         xenstat_free_xen_version, xenstat_uninit_xen_version }
+         xenstat_free_xen_version, xenstat_uninit_xen_version },
+       { XENSTAT_VBD, xenstat_collect_vbds,
+         xenstat_free_vbds, xenstat_uninit_vbds }
 };
 
 #define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))
@@ -259,6 +281,8 @@ xenstat_node *xenstat_get_node(xenstat_h
                        domain->ssid = domaininfo[i].ssidref;
                        domain->num_networks = 0;
                        domain->networks = NULL;
+                       domain->num_vbds = 0;
+                       domain->vbds = NULL;
 
                        domain++;
                }
@@ -448,6 +472,21 @@ xenstat_network *xenstat_domain_network(
 {
        if (domain->networks && 0 <= network && network < domain->num_networks)
                return &(domain->networks[network]);
+       return NULL;
+}
+
+/* Get the number of VBDs for a given domain */
+unsigned int xenstat_domain_num_vbds(xenstat_domain * domain)
+{
+       return domain->num_vbds;
+}
+
+/* Get the VBD handle to obtain VBD stats */
+xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
+                               unsigned int vbd)
+{
+       if (domain->vbds && 0 <= vbd && vbd < domain->num_vbds)
+               return &(domain->vbds[vbd]);
        return NULL;
 }
 
@@ -710,6 +749,139 @@ static void xenstat_uninit_xen_version(x
 {
 }
 
+/*
+ * VBD functions
+ */
+
+static int read_attributes_vbd(const char *vbd_directory, const char *what, 
char *ret, int cap)
+{
+       static char file_name[80];
+       int fd, num_read;
+
+       sprintf(file_name, "%s/%s/%s", SYSFS_VBD_PATH, vbd_directory, what);
+       fd = open(file_name, O_RDONLY, 0);
+       if (fd==-1) return -1;
+       num_read = read(fd, ret, cap - 1);
+       close(fd);
+       if (num_read<=0) return -1;
+       ret[num_read] = '\0';
+       return num_read;
+}
+
+/* Collect information about VBDs */
+static int xenstat_collect_vbds(xenstat_node * node)
+{
+       struct dirent *dp;
+
+       if (node->handle->sysfsvbd == NULL) {
+               node->handle->sysfsvbd = opendir(SYSFS_VBD_PATH);
+               if (node->handle->sysfsvbd == NULL) {
+                       perror("Error opening " SYSFS_VBD_PATH);
+                       return 0;
+               }
+       }
+
+       rewinddir(node->handle->sysfsvbd);
+
+       for(dp = readdir(node->handle->sysfsvbd); dp != NULL ;
+           dp = readdir(node->handle->sysfsvbd)) {
+               xenstat_domain *domain;
+               xenstat_vbd vbd;
+               unsigned int domid;
+               int ret;
+               char buf[256];
+
+
+               ret = sscanf(dp->d_name, "vbd-%u-%u", &domid, &vbd.dev);
+               if (ret != 2) {
+                       continue;
+               }
+               printf("%s is VBD.\n",dp->d_name);
+
+               domain = xenstat_node_domain(node, domid);
+               if (domain == NULL) {
+                       fprintf(stderr,
+                               "Found interface vbd-%u-%u but domain %u"
+                               " does not exist.\n",
+                               domid, vbd.dev, domid);
+                       continue;
+               }
+
+               if((read_attributes_vbd(dp->d_name, "statistics/oo_req", buf, 
256)<=0)
+                  || ((ret = sscanf(buf, "%llu", &vbd.oo_reqs)) != 1))
+               {
+                       continue;
+               }
+
+               if((read_attributes_vbd(dp->d_name, "statistics/rd_req", buf, 
256)<=0)
+                  || ((ret = sscanf(buf, "%llu", &vbd.rd_reqs)) != 1))
+               {
+                       continue;
+               }
+
+               if((read_attributes_vbd(dp->d_name, "statistics/wr_req", buf, 
256)<=0)
+                  || ((ret = sscanf(buf, "%llu", &vbd.wr_reqs)) != 1))
+               {
+                       continue;
+               }
+
+
+               if (domain->vbds == NULL) {
+                       domain->num_vbds = 1;
+                       domain->vbds = malloc(sizeof(xenstat_vbd));
+               } else {
+                       domain->num_vbds++;
+                       domain->vbds = realloc(domain->vbds,
+                                              domain->num_vbds *
+                                              sizeof(xenstat_vbd));
+               }
+               if (domain->vbds == NULL)
+                       return 0;
+               domain->vbds[domain->num_vbds - 1] = vbd;
+       }
+
+       return 1;       
+}
+
+/* Free VBD information */
+static void xenstat_free_vbds(xenstat_node * node)
+{
+       unsigned int i;
+       for (i = 0; i < node->num_domains; i++)
+               free(node->domains[i].vbds);
+}
+
+/* Free VBD information in handle */
+static void xenstat_uninit_vbds(xenstat_handle * handle)
+{
+       if (handle->sysfsvbd)
+               closedir(handle->sysfsvbd);
+}
+
+/* Get the major number of VBD device */
+unsigned int xenstat_vbd_dev(xenstat_vbd * vbd)
+{
+       return vbd->dev;
+}
+
+/* Get the number of OO(Out of) requests */
+unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd)
+{
+       return vbd->oo_reqs;
+}
+
+/* Get the number of READ requests */
+unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd)
+{
+       return vbd->rd_reqs;
+}
+
+/* Get the number of WRITE requests */
+unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd)
+{
+       return vbd->wr_reqs;
+}
+
 static char *xenstat_get_domain_name(xenstat_handle *handle, unsigned int 
domain_id)
 {
        char path[80];
diff -r 4b51d081378d -r 856caf975abd tools/xenstat/libxenstat/src/xenstat.h
--- a/tools/xenstat/libxenstat/src/xenstat.h    Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xenstat/libxenstat/src/xenstat.h    Mon Jul 03 08:35:12 2006 +0100
@@ -23,6 +23,7 @@ typedef struct xenstat_node xenstat_node
 typedef struct xenstat_node xenstat_node;
 typedef struct xenstat_vcpu xenstat_vcpu;
 typedef struct xenstat_network xenstat_network;
+typedef struct xenstat_vbd xenstat_vbd;
 
 /* Initialize the xenstat library.  Returns a handle to be used with
  * subsequent calls to the xenstat library, or NULL if an error occurs. */
@@ -35,7 +36,8 @@ void xenstat_uninit(xenstat_handle * han
 #define XENSTAT_VCPU 0x1
 #define XENSTAT_NETWORK 0x2
 #define XENSTAT_XEN_VERSION 0x4
-#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION)
+#define XENSTAT_VBD 0x8
+#define XENSTAT_ALL 
(XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION|XENSTAT_VBD)
 
 /* Get all available information about a node */
 xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags);
@@ -117,6 +119,13 @@ xenstat_network *xenstat_domain_network(
 xenstat_network *xenstat_domain_network(xenstat_domain * domain,
                                        unsigned int network);
 
+/* Get the number of VBDs for a given domain */
+unsigned int xenstat_domain_num_vbds(xenstat_domain *);
+
+/* Get the VBD handle to obtain VBD stats */
+xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
+                                   unsigned int vbd);
+
 /*
  * VCPU functions - extract information from a xenstat_vcpu
  */
@@ -156,3 +165,14 @@ unsigned long long xenstat_network_terrs
 
 /* Get the number of transmit drops for this network */
 unsigned long long xenstat_network_tdrop(xenstat_network * network);
+
+/*
+ * VBD functions - extract information from a xen_vbd
+ */
+/* Get the device number for Virtual Block Device */
+unsigned int xenstat_vbd_dev(xenstat_vbd * vbd);
+
+/* Get the number of OO/RD/WR requests for vbd */
+unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd);
+unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd);
+unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd);
diff -r 4b51d081378d -r 856caf975abd tools/xenstat/xentop/xentop.c
--- a/tools/xenstat/xentop/xentop.c     Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xenstat/xentop/xentop.c     Mon Jul 03 08:35:12 2006 +0100
@@ -27,6 +27,7 @@
 #include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
+#include <linux/kdev_t.h>
 
 #include <xenstat.h>
 
@@ -65,6 +66,7 @@ static int compare(unsigned long long, u
 static int compare(unsigned long long, unsigned long long);
 static int compare_domains(xenstat_domain **, xenstat_domain **);
 static unsigned long long tot_net_bytes( xenstat_domain *, int);
+static unsigned long long tot_vbd_reqs( xenstat_domain *, int);
 
 /* Field functions */
 static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2);
@@ -91,6 +93,15 @@ static void print_ssid(xenstat_domain *d
 static void print_ssid(xenstat_domain *domain);
 static int compare_name(xenstat_domain *domain1, xenstat_domain *domain2);
 static void print_name(xenstat_domain *domain);
+static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vbds(xenstat_domain *domain);
+static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vbd_oo(xenstat_domain *domain);
+static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vbd_rd(xenstat_domain *domain);
+static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vbd_wr(xenstat_domain *domain);
+
 
 /* Section printing functions */
 static void do_summary(void);
@@ -99,6 +110,7 @@ static void do_domain(xenstat_domain *);
 static void do_domain(xenstat_domain *);
 static void do_vcpu(xenstat_domain *);
 static void do_network(xenstat_domain *);
+static void do_vbd(xenstat_domain *);
 static void top(void);
 
 /* Field types */
@@ -116,6 +128,10 @@ typedef enum field_id {
        FIELD_NETS,
        FIELD_NET_TX,
        FIELD_NET_RX,
+       FIELD_VBDS,
+       FIELD_VBD_OO,
+       FIELD_VBD_RD,
+       FIELD_VBD_WR,
        FIELD_SSID
 } field_id;
 
@@ -140,7 +156,11 @@ field fields[] = {
        { FIELD_NETS,    "NETS",       4, compare_nets,    print_nets    },
        { FIELD_NET_TX,  "NETTX(k)",   8, compare_net_tx,  print_net_tx  },
        { FIELD_NET_RX,  "NETRX(k)",   8, compare_net_rx,  print_net_rx  },
-       { FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid    }
+       { FIELD_NET_RX,  "VBDS",       8, compare_vbds,    print_vbds    },
+       { FIELD_NET_RX,  "VBD_OO",     8, compare_vbd_oo,  print_vbd_oo  },
+       { FIELD_NET_RX,  "VBD_RD",     8, compare_vbd_rd,  print_vbd_rd  },
+       { FIELD_NET_RX,  "VBD_WR",     8, compare_vbd_wr,  print_vbd_wr  },
+               { FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid   
 }
 };
 
 const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field);
@@ -158,6 +178,7 @@ unsigned int iterations = 0;
 unsigned int iterations = 0;
 int show_vcpus = 0;
 int show_networks = 0;
+int show_vbds = 0;
 int repeat_header = 0;
 #define PROMPT_VAL_LEN 80
 char *prompt = NULL;
@@ -180,6 +201,7 @@ static void usage(const char *program)
               "-V, --version        output version information and exit\n"
               "-d, --delay=SECONDS  seconds between updates (default 3)\n"
               "-n, --networks       output vif network data\n"
+              "-b, --vbds           output vbd block device 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"
@@ -289,6 +311,9 @@ static int handle_key(int ch)
                switch(ch) {
                case 'n': case 'N':
                        show_networks ^= 1;
+                       break;
+               case 'b': case 'B':
+                       show_vbds ^= 1;
                        break;
                case 'r': case 'R':
                        repeat_header ^= 1;
@@ -585,6 +610,96 @@ static unsigned long long tot_net_bytes(
        return total;
 }
 
+/* Compares number of virtual block devices of two domains,
+   returning -1,0,1 for * <,=,> */
+static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(xenstat_domain_num_vbds(domain1),
+                       xenstat_domain_num_vbds(domain2));
+}
+
+/* Prints number of virtual block devices statistic */
+static void print_vbds(xenstat_domain *domain)
+{
+       print("%4u", xenstat_domain_num_vbds(domain));
+}
+
+/* Compares number of total VBD OO requests of two domains,
+   returning -1,0,1 * for <,=,> */
+static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+  return -compare(tot_vbd_reqs(domain1, FIELD_VBD_OO),
+                 tot_vbd_reqs(domain2, FIELD_VBD_OO));
+}
+
+/* Prints number of total VBD OO requests statistic */
+static void print_vbd_oo(xenstat_domain *domain)
+{
+       print("%8llu", tot_vbd_reqs(domain, FIELD_VBD_OO));
+}
+
+/* Compares number of total VBD READ requests of two domains,
+   returning -1,0,1 * for <,=,> */
+static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(tot_vbd_reqs(domain1, FIELD_VBD_RD),
+                       tot_vbd_reqs(domain2, FIELD_VBD_RD));
+}
+
+/* Prints number of total VBD READ requests statistic */
+static void print_vbd_rd(xenstat_domain *domain)
+{
+       print("%8llu", tot_vbd_reqs(domain, FIELD_VBD_RD));
+}
+
+/* Compares number of total VBD WRITE requests of two domains,
+   returning -1,0,1 * for <,=,> */
+static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(tot_vbd_reqs(domain1,FIELD_VBD_WR),
+                       tot_vbd_reqs(domain2,FIELD_VBD_WR));
+}
+
+/* Prints number of total VBD WRITE requests statistic */
+static void print_vbd_wr(xenstat_domain *domain)
+{
+       print("%8llu", tot_vbd_reqs(domain,FIELD_VBD_WR));
+}
+
+/* Gets number of total VBD requests statistic, 
+ *   if flag is FIELD_VBD_OO, then OO requests,
+ *   if flag is FIELD_VBD_RD, then READ requests and
+ *   if flag is FIELD_VBD_WR, then WRITE requests.
+ */
+static unsigned long long tot_vbd_reqs(xenstat_domain *domain, int flag)
+{
+       int i = 0;
+       xenstat_vbd *vbd;
+       unsigned num_vbds = 0;
+       unsigned long long total = 0;
+       
+       num_vbds = xenstat_domain_num_vbds(domain);
+       
+       for ( i=0 ; i < num_vbds ; i++) {
+               vbd = xenstat_domain_vbd(domain,i);
+               switch(flag) {
+               case FIELD_VBD_OO:
+                       total += xenstat_vbd_oo_reqs(vbd);
+                       break;
+               case FIELD_VBD_RD:
+                       total += xenstat_vbd_rd_reqs(vbd);
+                       break;
+               case FIELD_VBD_WR:
+                       total += xenstat_vbd_wr_reqs(vbd);
+                       break;
+               default:
+                       break;
+               }
+       }
+       
+       return total;
+}
+
 /* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */
 static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2)
 {
@@ -680,6 +795,13 @@ void do_bottom_line(void)
                addch(A_REVERSE | 'N');
                attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks");
                addstr("  ");
+               
+               /* VBDs */
+               attr_addstr(show_vbds ? COLOR_PAIR(1) : 0, "v");
+               addch(A_REVERSE | 'B');
+               attr_addstr(show_vbds ? COLOR_PAIR(1) : 0, "ds");
+               addstr("  ");
+
 
                /* vcpus */
                addch(A_REVERSE | 'V');
@@ -769,6 +891,28 @@ void do_network(xenstat_domain *domain)
        }
 }
 
+
+/* Output all VBD information */
+void do_vbd(xenstat_domain *domain)
+{
+       int i = 0;
+       xenstat_vbd *vbd;
+       unsigned num_vbds = 0;
+
+       num_vbds = xenstat_domain_num_vbds(domain);
+
+       for (i=0 ; i< num_vbds; i++) {
+               vbd = xenstat_domain_vbd(domain,i);
+                               
+               print("VBD %4u [%2x:%2x]  OO: %8llu   RD: %8llu   WR: %8llu\n",
+                     xenstat_vbd_dev(vbd),
+                     MAJOR(xenstat_vbd_dev(vbd)), MINOR(xenstat_vbd_dev(vbd)),
+                     xenstat_vbd_oo_reqs(vbd),
+                     xenstat_vbd_rd_reqs(vbd),
+                     xenstat_vbd_wr_reqs(vbd));
+       }
+}
+
 static void top(void)
 {
        xenstat_domain **domains;
@@ -812,6 +956,8 @@ static void top(void)
                        do_vcpu(domains[i]);
                if (show_networks)
                        do_network(domains[i]);
+               if (show_vbds)
+                       do_vbd(domains[i]);
        }
 
        if(!batch)
@@ -827,6 +973,7 @@ int main(int argc, char **argv)
                { "help",          no_argument,       NULL, 'h' },
                { "version",       no_argument,       NULL, 'V' },
                { "networks",      no_argument,       NULL, 'n' },
+               { "vbds",          no_argument,       NULL, 'x' },
                { "repeat-header", no_argument,       NULL, 'r' },
                { "vcpus",         no_argument,       NULL, 'v' },
                { "delay",         required_argument, NULL, 'd' },
@@ -834,7 +981,7 @@ int main(int argc, char **argv)
                { "iterations",    required_argument, NULL, 'i' },
                { 0, 0, 0, 0 },
        };
-       const char *sopts = "hVbnvd:bi:";
+       const char *sopts = "hVnxrvd:bi:";
 
        if (atexit(cleanup) != 0)
                fail("Failed to install cleanup handler.\n");
@@ -851,6 +998,9 @@ int main(int argc, char **argv)
                        exit(0);
                case 'n':
                        show_networks = 1;
+                       break;
+               case 'x':
+                       show_vbds = 1;
                        break;
                case 'r':
                        repeat_header = 1;
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py
--- a/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py      Wed Jun 28 07:52:21 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/02_vtpm-cat_pcrs.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -14,16 +14,15 @@ import os.path
 
 config = {"vtpm":"instance=1,backend=0"}
 domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
 
 try:
     console = domain.start()
 except DomainError, e:
     if verbose:
         print e.extra
-    vtpm_cleanup(domain.getName())
-    FAIL("Unable to create domain")
-
-domName = domain.getName()
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
 
 try:
     console.sendInput("input")
@@ -33,11 +32,11 @@ except ConsoleError, e:
     FAIL(str(e))
 
 try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
-    FAIL(str(e))
+    FAIL("No result from dumping the PCRs")
 
 if re.search("No such file",run["output"]):
     vtpm_cleanup(domName)
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/03_vtpm-susp_res.py
--- a/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py      Wed Jun 28 07:52:21 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/03_vtpm-susp_res.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -15,6 +15,7 @@ import os.path
 
 config = {"vtpm":"instance=1,backend=0"}
 domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
 consoleHistory = ""
 
 try:
@@ -22,10 +23,8 @@ except DomainError, e:
 except DomainError, e:
     if verbose:
         print e.extra
-    vtpm_cleanup(domain.getName())
-    FAIL("Unable to create domain")
-
-domName = domain.getName()
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
 
 try:
     console.sendInput("input")
@@ -35,11 +34,11 @@ except ConsoleError, e:
     FAIL(str(e))
 
 try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
-    FAIL(str(e))
+    FAIL("No result from dumping the PCRs")
 
 if re.search("No such file",run["output"]):
     vtpm_cleanup(domName)
@@ -48,50 +47,59 @@ consoleHistory = console.getHistory()
 consoleHistory = console.getHistory()
 domain.closeConsole()
 
-try:
-    status, ouptut = traceCommand("xm save %s %s.save" %
-                                  (domName, domName),
-                                  timeout=30)
+loop = 0
+while loop < 3:
+    try:
+        status, ouptut = traceCommand("xm save %s %s.save" %
+                                      (domName, domName),
+                                      timeout=30)
 
-except TimeoutError, e:
-    saveLog(consoleHistory)
-    vtpm_cleanup(domName)
-    FAIL(str(e))
+    except TimeoutError, e:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
 
-if status != 0:
-    saveLog(consoleHistory)
-    vtpm_cleanup(domName)
-    FAIL("xm save did not succeed")
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm save did not succeed")
 
-try:
-    status, ouptut = traceCommand("xm restore %s.save" %
-                                  (domName),
-                                  timeout=30)
-except TimeoutError, e:
+    try:
+        status, ouptut = traceCommand("xm restore %s.save" %
+                                      (domName),
+                                      timeout=30)
+    except TimeoutError, e:
+        os.remove("%s.save" % domName)
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
     os.remove("%s.save" % domName)
-    saveLog(consoleHistory)
-    vtpm_cleanup(domName)
-    FAIL(str(e))
 
-os.remove("%s.save" % domName)
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm restore did not succeed")
 
-if status != 0:
-    saveLog(consoleHistory)
-    vtpm_cleanup(domName)
-    FAIL("xm restore did not succeed")
+    try:
+        console = domain.getConsole()
+    except ConsoleError, e:
+        vtpm_cleanup(domName)
+        FAIL(str(e))
 
-try:
-    console = domain.getConsole()
-except ConsoleError, e:
-    vtpm_cleanup(domName)
-    FAIL(str(e))
+    try:
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+    except ConsoleError, e:
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+        FAIL(str(e))
 
-try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
-except ConsoleError, e:
-    saveLog(console.getHistory())
-    vtpm_cleanup(domName)
-    FAIL(str(e))
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
+    loop += 1
 
 domain.closeConsole()
 
@@ -99,5 +107,3 @@ domain.stop()
 
 vtpm_cleanup(domName)
 
-if not re.search("PCR-00:",run["output"]):
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py
--- a/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py      Wed Jun 28 07:52:21 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/04_vtpm-loc_migr.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -16,6 +16,7 @@ import os.path
 
 config = {"vtpm":"instance=1,backend=0"}
 domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
 consoleHistory = ""
 
 try:
@@ -23,10 +24,8 @@ except DomainError, e:
 except DomainError, e:
     if verbose:
         print e.extra
-    vtpm_cleanup(domain.getName())
-    FAIL("Unable to create domain")
-
-domName = domain.getName()
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
 
 try:
     console.sendInput("input")
@@ -36,11 +35,11 @@ except ConsoleError, e:
     FAIL(str(e))
 
 try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
-    FAIL(str(e))
+    FAIL("No result from dumping the PCRs")
 
 if re.search("No such file",run["output"]):
     vtpm_cleanup(domName)
@@ -83,11 +82,17 @@ while loop < 3:
         FAIL(str(e))
 
     try:
-        run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
     except ConsoleError, e:
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-        FAIL(str(e))
+        FAIL("No result from dumping the PCRs")
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
     loop += 1
 
 domain.closeConsole()
@@ -95,6 +100,3 @@ domain.stop()
 domain.stop()
 
 vtpm_cleanup(domName)
-
-if not re.search("PCR-00:",run["output"]):
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py
--- a/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py      Wed Jun 28 07:52:21 
2006 -0600
+++ b/tools/xm-test/tests/vtpm/05_vtpm-loc_migr.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -16,6 +16,7 @@ import os.path
 
 config = {"vtpm":"instance=1,backend=0"}
 domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
 consoleHistory = ""
 
 try:
@@ -23,10 +24,8 @@ except DomainError, e:
 except DomainError, e:
     if verbose:
         print e.extra
-    vtpm_cleanup(domain.getName())
-    FAIL("Unable to create domain")
-
-domName = domain.getName()
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
 
 try:
     console.sendInput("input")
@@ -36,11 +35,11 @@ except ConsoleError, e:
     FAIL(str(e))
 
 try:
-    run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
 except ConsoleError, e:
     saveLog(console.getHistory())
     vtpm_cleanup(domName)
-    FAIL(str(e))
+    FAIL("No result from dumping the PCRs")
 
 if re.search("No such file",run["output"]):
     vtpm_cleanup(domName)
@@ -83,11 +82,17 @@ while loop < 3:
         FAIL(str(e))
 
     try:
-        run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
     except ConsoleError, e:
         saveLog(console.getHistory())
         vtpm_cleanup(domName)
-        FAIL(str(e))
+        FAIL("No result from dumping the PCRs")
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
     loop += 1
 
 domain.closeConsole()
@@ -95,6 +100,3 @@ domain.stop()
 domain.stop()
 
 vtpm_cleanup(domName)
-
-if not re.search("PCR-00:",run["output"]):
-       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
diff -r 4b51d081378d -r 856caf975abd tools/xm-test/tests/vtpm/Makefile.am
--- a/tools/xm-test/tests/vtpm/Makefile.am      Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xm-test/tests/vtpm/Makefile.am      Mon Jul 03 08:35:12 2006 +0100
@@ -4,7 +4,10 @@ TESTS = 01_vtpm-list_pos.test \
         02_vtpm-cat_pcrs.test \
         03_vtpm-susp_res.test \
         04_vtpm-loc_migr.test \
-        05_vtpm-loc_migr.test
+        05_vtpm-loc_migr.test \
+        06_vtpm-susp_res_pcrs.test \
+        07_vtpm-mig_pcrs.test \
+        08_vtpm-mig_pcrs.test
 
 XFAIL_TESTS =
 
diff -r 4b51d081378d -r 856caf975abd tools/xm-test/tests/vtpm/vtpm_utils.py
--- a/tools/xm-test/tests/vtpm/vtpm_utils.py    Wed Jun 28 07:52:21 2006 -0600
+++ b/tools/xm-test/tests/vtpm/vtpm_utils.py    Mon Jul 03 08:35:12 2006 +0100
@@ -16,4 +16,4 @@ if output == "":
     FAIL("virtual TPM manager must be started to run this test")
 
 def vtpm_cleanup(domName):
-       traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
+    traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/domain.c     Mon Jul 03 08:35:12 2006 +0100
@@ -67,16 +67,11 @@ static void default_idle(void)
 
 void idle_loop(void)
 {
-    int cpu = smp_processor_id();
-
     for ( ; ; )
     {
         page_scrub_schedule_work();
-
         default_idle();
-
-        if ( softirq_pending(cpu) )
-            do_softirq();
+        do_softirq();
     }
 }
 
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Jul 03 08:35:12 2006 +0100
@@ -2697,9 +2697,9 @@ asmlinkage void svm_vmexit_handler(struc
 
     if (exit_reason == -1)
     {
+        svm_dump_vmcb(__func__, vmcb);
         printk("%s: exit_reason == -1 - Did someone clobber the VMCB\n", 
                 __func__);
-        BUG();
         domain_crash_synchronous();
     }
 
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Mon Jul 03 08:35:12 2006 +0100
@@ -36,6 +36,7 @@
 #include <xen/kernel.h>
 #include <asm/shadow.h>
 #include <xen/keyhandler.h>
+
 #if CONFIG_PAGING_LEVELS >= 3
 #include <asm/shadow_64.h>
 #endif
@@ -440,7 +441,6 @@ static int construct_vmcs(struct vcpu *v
     memset(arch_vmx, 0, sizeof(struct arch_vmx_struct));
 
     spin_lock_init(&arch_vmx->vmcs_lock);
-    arch_vmx->active_cpu = -1;
 
     /*
      * Create a new VMCS
@@ -450,7 +450,7 @@ static int construct_vmcs(struct vcpu *v
         return -ENOMEM;
     }
 
-    vmx_clear_vmcs(v);
+    __vmx_clear_vmcs(v);
     vmx_load_vmcs(v);
 
     if ((error = construct_vmcs_controls(arch_vmx))) {
@@ -495,6 +495,9 @@ void vmx_destroy_vmcs(struct vcpu *v)
 void vmx_destroy_vmcs(struct vcpu *v)
 {
     struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
+
+    if ( arch_vmx->vmcs == NULL )
+        return;
 
     vmx_clear_vmcs(v);
 
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/smpboot.c    Mon Jul 03 08:35:12 2006 +0100
@@ -1197,8 +1197,7 @@ int __devinit __cpu_up(unsigned int cpu)
        cpu_set(cpu, smp_commenced_mask);
        while (!cpu_isset(cpu, cpu_online_map)) {
                mb();
-               if (softirq_pending(0))
-                       do_softirq();
+               process_pending_timers();
        }
        return 0;
 }
diff -r 4b51d081378d -r 856caf975abd xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/arch/x86/x86_emulate.c        Mon Jul 03 08:35:12 2006 +0100
@@ -118,7 +118,7 @@ static uint8_t opcode_table[256] = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     /* 0xC0 - 0xC7 */
     ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
-    0, 0, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
+    0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
     /* 0xC8 - 0xCF */
     0, 0, 0, 0, 0, 0, 0, 0,
     /* 0xD0 - 0xD7 */
diff -r 4b51d081378d -r 856caf975abd xen/common/elf.c
--- a/xen/common/elf.c  Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/elf.c  Mon Jul 03 08:35:12 2006 +0100
@@ -23,7 +23,7 @@ int parseelfimage(struct domain_setup_in
     Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
     Elf_Phdr *phdr;
     Elf_Shdr *shdr;
-    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
+    Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off;
     char *shstrtab, *guestinfo=NULL, *p;
     char *elfbase = (char *)dsi->image_addr;
     int h, virt_base_defined, elf_pa_off_defined;
@@ -95,7 +95,11 @@ int parseelfimage(struct domain_setup_in
     elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base;
 
     if ( elf_pa_off_defined && !virt_base_defined )
-        goto bad_image;
+    {
+        printk("ERROR: Neither ELF_PADDR_OFFSET nor VIRT_BASE found in"
+               " __xen_guest section.\n");
+        return -EINVAL;
+    }
 
     for ( h = 0; h < ehdr->e_phnum; h++ )
     {
@@ -104,7 +108,11 @@ int parseelfimage(struct domain_setup_in
             continue;
         vaddr = phdr->p_paddr - elf_pa_off + virt_base;
         if ( (vaddr + phdr->p_memsz) < vaddr )
-            goto bad_image;
+        {
+            printk("ERROR: ELF program header %d is too large.\n", h);
+            return -EINVAL;
+        }
+
         if ( vaddr < kernstart )
             kernstart = vaddr;
         if ( (vaddr + phdr->p_memsz) > kernend )
@@ -127,7 +135,10 @@ int parseelfimage(struct domain_setup_in
          (dsi->v_kernentry < kernstart) ||
          (dsi->v_kernentry > kernend) ||
          (dsi->v_start > kernstart) )
-        goto bad_image;
+    {
+        printk("ERROR: ELF start or entries are out of bounds.\n");
+        return -EINVAL;
+    }
 
     if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL )
             dsi->load_symtab = 1;
@@ -139,10 +150,6 @@ int parseelfimage(struct domain_setup_in
     loadelfsymtab(dsi, 0);
 
     return 0;
-
- bad_image:
-    printk("Malformed ELF image.\n");
-    return -EINVAL;
 }
 
 int loadelfimage(struct domain_setup_info *dsi)
diff -r 4b51d081378d -r 856caf975abd xen/common/grant_table.c
--- a/xen/common/grant_table.c  Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/grant_table.c  Mon Jul 03 08:35:12 2006 +0100
@@ -287,10 +287,10 @@ __gnttab_map_grant_ref(
 
     if ( !(op->flags & GNTMAP_readonly) &&
          !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
-        clear_bit(_GTF_writing, &sha->flags);
+        gnttab_clear_flag(_GTF_writing, &sha->flags);
 
     if ( !act->pin )
-        clear_bit(_GTF_reading, &sha->flags);
+        gnttab_clear_flag(_GTF_reading, &sha->flags);
 
  unlock_out:
     spin_unlock(&rd->grant_table->lock);
@@ -425,10 +425,10 @@ __gnttab_unmap_grant_ref(
 
     if ( ((act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0) &&
          !(flags & GNTMAP_readonly) )
-        clear_bit(_GTF_writing, &sha->flags);
+        gnttab_clear_flag(_GTF_writing, &sha->flags);
 
     if ( act->pin == 0 )
-        clear_bit(_GTF_reading, &sha->flags);
+        gnttab_clear_flag(_GTF_reading, &sha->flags);
 
  unmap_out:
     op->status = rc;
@@ -889,11 +889,11 @@ gnttab_release_mappings(
             }
 
             if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
-                clear_bit(_GTF_writing, &sha->flags);
+                gnttab_clear_flag(_GTF_writing, &sha->flags);
         }
 
         if ( act->pin == 0 )
-            clear_bit(_GTF_reading, &sha->flags);
+            gnttab_clear_flag(_GTF_reading, &sha->flags);
 
         spin_unlock(&rd->grant_table->lock);
 
diff -r 4b51d081378d -r 856caf975abd xen/common/memory.c
--- a/xen/common/memory.c       Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/memory.c       Mon Jul 03 08:35:12 2006 +0100
@@ -169,6 +169,15 @@ guest_remove_page(
             
     if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
         put_page(page);
+
+    if ( unlikely((page->count_info & PGC_count_mask) != 1) )
+    {
+        /* We'll make this a guest-visible error in future, so take heed! */
+        DPRINTK("Dom%d freeing in-use page %lx (pseudophys %lx):"
+                " count=%x type=%lx\n",
+                d->domain_id, mfn, get_gpfn_from_mfn(mfn),
+                page->count_info, page->u.inuse.type_info);
+    }
 
     guest_physmap_remove_page(d, gmfn, mfn);
 
diff -r 4b51d081378d -r 856caf975abd xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/page_alloc.c   Mon Jul 03 08:35:12 2006 +0100
@@ -388,7 +388,6 @@ void scrub_heap_pages(void)
 {
     void *p;
     unsigned long pfn;
-    int cpu = smp_processor_id();
 
     printk("Scrubbing Free RAM: ");
 
@@ -398,8 +397,7 @@ void scrub_heap_pages(void)
         if ( (pfn % ((100*1024*1024)/PAGE_SIZE)) == 0 )
             printk(".");
 
-        if ( unlikely(softirq_pending(cpu)) )
-            do_softirq();
+        process_pending_timers();
 
         /* Quick lock-free check. */
         if ( allocated_in_map(pfn) )
diff -r 4b51d081378d -r 856caf975abd xen/common/sched_credit.c
--- a/xen/common/sched_credit.c Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/sched_credit.c Mon Jul 03 08:35:12 2006 +0100
@@ -622,9 +622,12 @@ csched_dom_cntl(
 
         if ( cmd->u.credit.weight != 0 )
         {
-            csched_priv.weight -= sdom->weight;
+            if ( !list_empty(&sdom->active_sdom_elem) )
+            {
+                csched_priv.weight -= sdom->weight;
+                csched_priv.weight += cmd->u.credit.weight;
+            }
             sdom->weight = cmd->u.credit.weight;
-            csched_priv.weight += sdom->weight;
         }
 
         if ( cmd->u.credit.cap != (uint16_t)~0U )
diff -r 4b51d081378d -r 856caf975abd xen/common/schedule.c
--- a/xen/common/schedule.c     Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/schedule.c     Mon Jul 03 08:35:12 2006 +0100
@@ -389,11 +389,32 @@ long do_set_timer_op(s_time_t timeout)
 long do_set_timer_op(s_time_t timeout)
 {
     struct vcpu *v = current;
+    s_time_t offset = timeout - NOW();
 
     if ( timeout == 0 )
+    {
         stop_timer(&v->timer);
+    }
+    else if ( unlikely(timeout < 0) || /* overflow into 64th bit? */
+              unlikely((offset > 0) && ((uint32_t)(offset >> 50) != 0)) )
+    {
+        /*
+         * Linux workaround: occasionally we will see timeouts a long way in 
+         * the future due to wrapping in Linux's jiffy time handling. We check 
+         * for timeouts wrapped negative, and for positive timeouts more than 
+         * about 13 days in the future (2^50ns). The correct fix is to trigger 
+         * an interrupt immediately (since Linux in fact has pending work to 
+         * do in this situation).
+         */
+        DPRINTK("Warning: huge timeout set by domain %d (vcpu %d):"
+                " %"PRIx64"\n",
+                v->domain->domain_id, v->vcpu_id, (uint64_t)timeout);
+        send_timer_event(v);
+    }
     else
+    {
         set_timer(&v->timer, timeout);
+    }
 
     return 0;
 }
diff -r 4b51d081378d -r 856caf975abd xen/common/softirq.c
--- a/xen/common/softirq.c      Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/softirq.c      Mon Jul 03 08:35:12 2006 +0100
@@ -23,17 +23,23 @@ static softirq_handler softirq_handlers[
 
 asmlinkage void do_softirq(void)
 {
-    unsigned int i, cpu = smp_processor_id();
+    unsigned int i, cpu;
     unsigned long pending;
 
-    pending = softirq_pending(cpu);
-    ASSERT(pending != 0);
+    for ( ; ; )
+    {
+        /*
+         * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
+         * us to another processor.
+         */
+        cpu = smp_processor_id();
+        if ( (pending = softirq_pending(cpu)) == 0 )
+            break;
 
-    do {
         i = find_first_set_bit(pending);
         clear_bit(i, &softirq_pending(cpu));
         (*softirq_handlers[i])();
-    } while ( (pending = softirq_pending(cpu)) != 0 );
+    }
 }
 
 void open_softirq(int nr, softirq_handler handler)
diff -r 4b51d081378d -r 856caf975abd xen/common/timer.c
--- a/xen/common/timer.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/common/timer.c        Mon Jul 03 08:35:12 2006 +0100
@@ -327,6 +327,15 @@ static void timer_softirq_action(void)
 }
 
 
+void process_pending_timers(void)
+{
+    unsigned int cpu = smp_processor_id();
+    ASSERT(!in_irq() && local_irq_is_enabled());
+    if ( test_and_clear_bit(TIMER_SOFTIRQ, &softirq_pending(cpu)) )
+        timer_softirq_action();
+}
+
+
 static void dump_timerq(unsigned char key)
 {
     struct timer *t;
diff -r 4b51d081378d -r 856caf975abd xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/drivers/char/console.c        Mon Jul 03 08:35:12 2006 +0100
@@ -528,8 +528,7 @@ void console_endboot(void)
             printk("%d... ", 3-i);
             for ( j = 0; j < 100; j++ )
             {
-                if ( softirq_pending(smp_processor_id()) )
-                    do_softirq();
+                process_pending_timers();
                 mdelay(10);
             }
         }
@@ -741,6 +740,15 @@ void panic(const char *fmt, ...)
     machine_restart(0);
 }
 
+void __bug(char *file, int line)
+{
+    console_start_sync();
+    debugtrace_dump();
+    printk("BUG at %s:%d\n", file, line);
+    FORCE_CRASH();
+    for ( ; ; ) ;
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 4b51d081378d -r 856caf975abd xen/include/asm-ia64/grant_table.h
--- a/xen/include/asm-ia64/grant_table.h        Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/asm-ia64/grant_table.h        Mon Jul 03 08:35:12 2006 +0100
@@ -55,4 +55,9 @@ void guest_physmap_add_page(struct domai
 
 #define gnttab_log_dirty(d, f) ((void)0)
 
+static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
+{
+       clear_bit(nr, addr);
+}
+
 #endif /* __ASM_GRANT_TABLE_H__ */
diff -r 4b51d081378d -r 856caf975abd xen/include/asm-x86/grant_table.h
--- a/xen/include/asm-x86/grant_table.h Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/asm-x86/grant_table.h Mon Jul 03 08:35:12 2006 +0100
@@ -33,4 +33,9 @@ int destroy_grant_host_mapping(
 
 #define gnttab_log_dirty(d, f) mark_dirty((d), (f))
 
+static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
+{
+       clear_bit(nr, addr);
+}
+
 #endif /* __ASM_GRANT_TABLE_H__ */
diff -r 4b51d081378d -r 856caf975abd xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/arch-ia64.h    Mon Jul 03 08:35:12 2006 +0100
@@ -39,6 +39,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #define MAX_VIRT_CPUS 64
 
 #ifndef __ASSEMBLY__
+
+typedef unsigned long xen_ulong_t;
 
 #define MAX_NR_SECTION  32  /* at most 32 memory holes */
 struct mm_section {
diff -r 4b51d081378d -r 856caf975abd xen/include/public/arch-x86_32.h
--- a/xen/include/public/arch-x86_32.h  Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/arch-x86_32.h  Mon Jul 03 08:35:12 2006 +0100
@@ -97,6 +97,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #define MAX_VIRT_CPUS 32
 
 #ifndef __ASSEMBLY__
+
+typedef unsigned long xen_ulong_t;
 
 /*
  * Send an array of these to HYPERVISOR_set_trap_table()
diff -r 4b51d081378d -r 856caf975abd xen/include/public/arch-x86_64.h
--- a/xen/include/public/arch-x86_64.h  Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/arch-x86_64.h  Mon Jul 03 08:35:12 2006 +0100
@@ -104,6 +104,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #define MAX_VIRT_CPUS 32
 
 #ifndef __ASSEMBLY__
+
+typedef unsigned long xen_ulong_t;
 
 /*
  * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
diff -r 4b51d081378d -r 856caf975abd xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h     Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/io/netif.h     Mon Jul 03 08:35:12 2006 +0100
@@ -23,8 +23,9 @@
  * 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 3: netif_tx_extra]  (only if request 2 has XEN_NETIF_EXTRA_MORE)
  *  Request 4: netif_tx_request -- NETTXF_more_data
+ *  Request 5: netif_tx_request -- NETTXF_more_data
  *  ...
  *  Request N: netif_tx_request -- 0
  */
@@ -41,12 +42,9 @@
 #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)
+/* Packet to be followed by extra descriptor(s). */
+#define _NETTXF_extra_info     (3)
+#define  NETTXF_extra_info     (1U<<_NETTXF_extra_info)
 
 struct netif_tx_request {
     grant_ref_t gref;      /* Reference to buffer page */
@@ -57,15 +55,42 @@ struct netif_tx_request {
 };
 typedef struct netif_tx_request netif_tx_request_t;
 
-/* This structure needs to fit within netif_tx_request for compatibility. */
-struct netif_tx_extra {
+/* Types of netif_extra_info descriptors. */
+#define XEN_NETIF_EXTRA_TYPE_NONE  (0)  /* Never used - invalid */
+#define XEN_NETIF_EXTRA_TYPE_GSO   (1)  /* u.gso */
+#define XEN_NETIF_EXTRA_TYPE_MAX   (2)
+
+/* netif_extra_info flags. */
+#define _XEN_NETIF_EXTRA_FLAG_MORE (0)
+#define XEN_NETIF_EXTRA_FLAG_MORE  (1U<<_XEN_NETIF_EXTRA_FLAG_MORE)
+
+/* GSO types - only TCPv4 currently supported. */
+#define XEN_NETIF_GSO_TCPV4        (1)
+
+/*
+ * This structure needs to fit within both netif_tx_request and
+ * netif_rx_response for compatibility.
+ */
+struct netif_extra_info {
+    uint8_t type;  /* XEN_NETIF_EXTRA_TYPE_* */
+    uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */
+
     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. */
+        struct {
+            /*
+             * Maximum payload size of each segment. For example, for TCP this
+             * is just the path MSS.
+             */
+            uint16_t size;
+
+            /*
+             * GSO type. This determines the protocol of the packet and any
+             * extra features required to segment the packet properly.
+             */
+            uint16_t type; /* XEN_NETIF_GSO_* */
         } gso;
+
+        uint16_t pad[3];
     } u;
 };
 
diff -r 4b51d081378d -r 856caf975abd xen/include/public/memory.h
--- a/xen/include/public/memory.h       Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/public/memory.h       Mon Jul 03 08:35:12 2006 +0100
@@ -32,7 +32,7 @@ struct xen_memory_reservation {
     XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
 
     /* Number of extents, and size/alignment of each (2^extent_order pages). */
-    unsigned long  nr_extents;
+    xen_ulong_t    nr_extents;
     unsigned int   extent_order;
 
     /*
@@ -90,7 +90,7 @@ struct xen_memory_exchange {
      *     command will be non-zero.
      *  5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
      */
-    unsigned long nr_exchanged;
+    xen_ulong_t nr_exchanged;
 };
 typedef struct xen_memory_exchange xen_memory_exchange_t;
 DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t);
@@ -148,8 +148,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn
  */
 #define XENMEM_machphys_mapping     12
 struct xen_machphys_mapping {
-    unsigned long v_start, v_end; /* Start and end virtual addresses.   */
-    unsigned long max_mfn;        /* Maximum MFN that can be looked up. */
+    xen_ulong_t v_start, v_end; /* Start and end virtual addresses.   */
+    xen_ulong_t max_mfn;        /* Maximum MFN that can be looked up. */
 };
 typedef struct xen_machphys_mapping xen_machphys_mapping_t;
 DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
@@ -170,7 +170,7 @@ struct xen_add_to_physmap {
     unsigned int space;
 
     /* Index into source mapping space. */
-    unsigned long idx;
+    xen_ulong_t idx;
 
     /* GPFN where the source mapping page should appear. */
     xen_pfn_t     gpfn;
@@ -188,7 +188,7 @@ struct xen_translate_gpfn_list {
     domid_t domid;
 
     /* Length of list. */
-    unsigned long nr_gpfns;
+    xen_ulong_t nr_gpfns;
 
     /* List of GPFNs to translate. */
     XEN_GUEST_HANDLE(xen_pfn_t) gpfn_list;
diff -r 4b51d081378d -r 856caf975abd xen/include/xen/lib.h
--- a/xen/include/xen/lib.h     Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/xen/lib.h     Mon Jul 03 08:35:12 2006 +0100
@@ -8,19 +8,23 @@
 #include <xen/xmalloc.h>
 #include <xen/string.h>
 
-#define BUG() do {                                     \
-    debugtrace_dump();                                  \
-    printk("BUG at %s:%d\n", __FILE__, __LINE__);      \
-    FORCE_CRASH();                                      \
-} while ( 0 )
-
+extern void __bug(char *file, int line) __attribute__((noreturn));
+#define BUG() __bug(__FILE__, __LINE__)
 #define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 )
 
 /* Force a compilation error if condition is true */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
 
 #ifndef NDEBUG
-#define ASSERT(_p) { if ( !(_p) ) { printk("Assertion '%s' failed, line %d, 
file %s\n", #_p , __LINE__, __FILE__); BUG(); } }
+#define ASSERT(_p)                                                      \
+    do {                                                                \
+        if ( !(_p) )                                                    \
+        {                                                               \
+            printk("Assertion '%s' failed, line %d, file %s\n", #_p ,   \
+                   __LINE__, __FILE__);                                 \
+            BUG();                                                      \
+        }                                                               \
+    } while ( 0 )
 #else
 #define ASSERT(_p) ((void)0)
 #endif
diff -r 4b51d081378d -r 856caf975abd xen/include/xen/timer.h
--- a/xen/include/xen/timer.h   Wed Jun 28 07:52:21 2006 -0600
+++ b/xen/include/xen/timer.h   Mon Jul 03 08:35:12 2006 +0100
@@ -89,6 +89,12 @@ extern void kill_timer(struct timer *tim
 extern void kill_timer(struct timer *timer);
 
 /*
+ * Process pending timers on this CPU. This should be called periodically
+ * when performing work that prevents softirqs from running in a timely manner.
+ */
+extern void process_pending_timers(void);
+
+/*
  * Bootstrap initialisation. Must be called before any other timer function.
  */
 extern void timer_init(void);
diff -r 4b51d081378d -r 856caf975abd 
patches/linux-2.6.16.13/fix-hz-suspend.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/fix-hz-suspend.patch      Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,26 @@
+diff -pruN ../pristine-linux-2.6.16.13/kernel/timer.c ./kernel/timer.c
+--- ../pristine-linux-2.6.16.13/kernel/timer.c 2006-05-02 22:38:44.000000000 
+0100
++++ ./kernel/timer.c   2006-06-29 14:34:12.788957720 +0100
+@@ -555,6 +555,22 @@ found:
+       }
+       spin_unlock(&base->t_base.lock);
+ 
++      /*
++       * It can happen that other CPUs service timer IRQs and increment
++       * jiffies, but we have not yet got a local timer tick to process
++       * the timer wheels.  In that case, the expiry time can be before
++       * jiffies, but since the high-resolution timer here is relative to
++       * jiffies, the default expression when high-resolution timers are
++       * not active,
++       *
++       *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
++       *
++       * would falsely evaluate to true.  If that is the case, just
++       * return jiffies so that we can immediately fire the local timer
++       */
++      if (time_before(expires, jiffies))
++              return jiffies;
++
+       if (time_before(hr_expires, expires))
+               return hr_expires;
+ 
diff -r 4b51d081378d -r 856caf975abd 
patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch   Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,1546 @@
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c 
./drivers/char/tpm/tpm_atmel.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c   2006-06-26 
18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_atmel.c     2006-06-26 18:16:33.000000000 -0400
+@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
+               return -EIO;
+ 
+       for (i = 0; i < 6; i++) {
+-              status = ioread8(chip->vendor->iobase + 1);
++              status = ioread8(chip->vendor.iobase + 1);
+               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                       dev_err(chip->dev, "error reading header\n");
+                       return -EIO;
+               }
+-              *buf++ = ioread8(chip->vendor->iobase);
++              *buf++ = ioread8(chip->vendor.iobase);
+       }
+ 
+       /* size of the data received */
+@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
+               dev_err(chip->dev,
+                       "Recv size(%d) less than available space\n", size);
+               for (; i < size; i++) { /* clear the waiting data anyway */
+-                      status = ioread8(chip->vendor->iobase + 1);
++                      status = ioread8(chip->vendor.iobase + 1);
+                       if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                               dev_err(chip->dev, "error reading data\n");
+                               return -EIO;
+@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
+ 
+       /* read all the data available */
+       for (; i < size; i++) {
+-              status = ioread8(chip->vendor->iobase + 1);
++              status = ioread8(chip->vendor.iobase + 1);
+               if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
+                       dev_err(chip->dev, "error reading data\n");
+                       return -EIO;
+               }
+-              *buf++ = ioread8(chip->vendor->iobase);
++              *buf++ = ioread8(chip->vendor.iobase);
+       }
+ 
+       /* make sure data available is gone */
+-      status = ioread8(chip->vendor->iobase + 1);
++      status = ioread8(chip->vendor.iobase + 1);
+ 
+       if (status & ATML_STATUS_DATA_AVAIL) {
+               dev_err(chip->dev, "data available is stuck\n");
+@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
+       dev_dbg(chip->dev, "tpm_atml_send:\n");
+       for (i = 0; i < count; i++) {
+               dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
+-              iowrite8(buf[i], chip->vendor->iobase);
++              iowrite8(buf[i], chip->vendor.iobase);
+       }
+ 
+       return count;
+@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
+ 
+ static void tpm_atml_cancel(struct tpm_chip *chip)
+ {
+-      iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
++      iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
+ }
+ 
+ static u8 tpm_atml_status(struct tpm_chip *chip)
+ {
+-      return ioread8(chip->vendor->iobase + 1);
++      return ioread8(chip->vendor.iobase + 1);
+ }
+ 
+ static struct file_operations atmel_ops = {
+@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
+ 
+ static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
+ 
+-static struct tpm_vendor_specific tpm_atmel = {
++static const struct tpm_vendor_specific tpm_atmel = {
+       .recv = tpm_atml_recv,
+       .send = tpm_atml_send,
+       .cancel = tpm_atml_cancel,
+@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
+       struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
+ 
+       if (chip) {
+-              if (chip->vendor->have_region)
+-                      atmel_release_region(chip->vendor->base,
+-                                           chip->vendor->region_size);
+-              atmel_put_base_addr(chip->vendor);
++              if (chip->vendor.have_region)
++                      atmel_release_region(chip->vendor.base,
++                                           chip->vendor.region_size);
++              atmel_put_base_addr(chip->vendor.iobase);
+               tpm_remove_hardware(chip->dev);
+               platform_device_unregister(pdev);
+       }
+@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
+ static int __init init_atmel(void)
+ {
+       int rc = 0;
++      void __iomem *iobase = NULL;
++      int have_region, region_size;
++      unsigned long base;
++      struct  tpm_chip *chip;
+ 
+       driver_register(&atml_drv);
+ 
+-      if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
++      if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
+               rc = -ENODEV;
+               goto err_unreg_drv;
+       }
+ 
+-      tpm_atmel.have_region =
++      have_region =
+           (atmel_request_region
+-           (tpm_atmel.base, tpm_atmel.region_size,
+-            "tpm_atmel0") == NULL) ? 0 : 1;
++           (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
++
+ 
+       if (IS_ERR
+           (pdev =
+@@ -199,17 +203,25 @@ static int __init init_atmel(void)
+               goto err_rel_reg;
+       }
+ 
+-      if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
++      if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
++              rc = -ENODEV;
+               goto err_unreg_dev;
++      }
++
++      chip->vendor.iobase = iobase;
++      chip->vendor.base = base;
++      chip->vendor.have_region = have_region;
++      chip->vendor.region_size = region_size;
++
+       return 0;
+ 
+ err_unreg_dev:
+       platform_device_unregister(pdev);
+ err_rel_reg:
+-      atmel_put_base_addr(&tpm_atmel);
+-      if (tpm_atmel.have_region)
+-              atmel_release_region(tpm_atmel.base,
+-                                   tpm_atmel.region_size);
++      atmel_put_base_addr(iobase);
++      if (have_region)
++              atmel_release_region(base,
++                                   region_size);
+ err_unreg_drv:
+       driver_unregister(&atml_drv);
+       return rc;
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h 
./drivers/char/tpm/tpm_atmel.h
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h   2006-06-26 
18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_atmel.h     2006-06-26 18:16:33.000000000 -0400
+@@ -28,13 +28,12 @@
+ #define atmel_request_region request_mem_region
+ #define atmel_release_region release_mem_region
+ 
+-static inline void atmel_put_base_addr(struct tpm_vendor_specific
+-                                       *vendor)
++static inline void atmel_put_base_addr(void __iomem *iobase)
+ {
+-      iounmap(vendor->iobase);
++      iounmap(iobase);
+ }
+ 
+-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
++static void __iomem * atmel_get_base_addr(unsigned long *base, int 
*region_size)
+ {
+       struct device_node *dn;
+       unsigned long address, size;
+@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
+       else
+               size = reg[naddrc];
+ 
+-      vendor->base = address;
+-      vendor->region_size = size;
+-      return ioremap(vendor->base, vendor->region_size);
++      *base = address;
++      *region_size = size;
++      return ioremap(*base, *region_size);
+ }
+ #else
+ #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
+@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
+       return 0;
+ }
+ 
+-static inline void atmel_put_base_addr(struct tpm_vendor_specific
+-                                       *vendor)
++static inline void atmel_put_base_addr(void __iomem *iobase)
+ {
+ }
+ 
+ /* Determine where to talk to device */
+-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
+-                                       *vendor)
++static void __iomem * atmel_get_base_addr(unsigned long *base, int 
*region_size)
+ {
+       int lo, hi;
+ 
+@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
+       lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+       hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+ 
+-      vendor->base = (hi << 8) | lo;
+-      vendor->region_size = 2;
++      *base = (hi << 8) | lo;
++      *region_size = 2;
+ 
+-      return ioport_map(vendor->base, vendor->region_size);
++      return ioport_map(*base, *region_size);
+ }
+ #endif
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c 
./drivers/char/tpm/tpm_bios.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c    2006-06-26 
18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_bios.c      2006-06-26 18:16:33.000000000 -0400
+@@ -29,6 +29,11 @@
+ #define MAX_TEXT_EVENT                1000    /* Max event string length */
+ #define ACPI_TCPA_SIG         "TCPA"  /* 0x41504354 /'TCPA' */
+ 
++enum bios_platform_class {
++      BIOS_CLIENT = 0x00,
++      BIOS_SERVER = 0x01,
++};
++
+ struct tpm_bios_log {
+       void *bios_event_log;
+       void *bios_event_log_end;
+@@ -36,9 +41,18 @@ struct tpm_bios_log {
+ 
+ struct acpi_tcpa {
+       struct acpi_table_header hdr;
+-      u16 reserved;
+-      u32 log_max_len __attribute__ ((packed));
+-      u32 log_start_addr __attribute__ ((packed));
++      u16 platform_class;
++      union {
++              struct client_hdr {
++                      u32 log_max_len __attribute__ ((packed));
++                      u64 log_start_addr __attribute__ ((packed));
++              } client;
++              struct server_hdr {
++                      u16 reserved;
++                      u64 log_max_len __attribute__ ((packed));
++                      u64 log_start_addr __attribute__ ((packed));
++              } server;
++      };
+ };
+ 
+ struct tcpa_event {
+@@ -91,6 +105,12 @@ static const char* tcpa_event_type_strin
+       "Non-Host Info"
+ };
+ 
++struct tcpa_pc_event {
++      u32 event_id;
++      u32 event_size;
++      u8 event_data[0];
++};
++
+ enum tcpa_pc_event_ids {
+       SMBIOS = 1,
+       BIS_CERT,
+@@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
+       NVRAM,
+       OPTION_ROM_EXEC,
+       OPTION_ROM_CONFIG,
+-      OPTION_ROM_MICROCODE,
++      OPTION_ROM_MICROCODE = 10,
+       S_CRTM_VERSION,
+       S_CRTM_CONTENTS,
+       POST_CONTENTS,
++      HOST_TABLE_OF_DEVICES,
+ };
+ 
+ static const char* tcpa_pc_event_id_strings[] = {
+-      ""
++      "",
+       "SMBIOS",
+       "BIS Certificate",
+       "POST BIOS ",
+@@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_stri
+       "NVRAM",
+       "Option ROM",
+       "Option ROM config",
+-      "Option ROM microcode",
++      "",
++      "Option ROM microcode ",
+       "S-CRTM Version",
+-      "S-CRTM Contents",
+-      "S-CRTM POST Contents",
++      "S-CRTM Contents ",
++      "POST Contents ",
++      "Table of Devices",
+ };
+ 
+ /* returns pointer to start of pos. entry of tcg log */
+@@ -191,7 +214,7 @@ static int get_event_name(char *dest, st
+       const char *name = "";
+       char data[40] = "";
+       int i, n_len = 0, d_len = 0;
+-      u32 event_id;
++      struct tcpa_pc_event *pc_event;
+ 
+       switch(event->event_type) {
+       case PREBOOT:
+@@ -220,31 +243,32 @@ static int get_event_name(char *dest, st
+               }
+               break;
+       case EVENT_TAG:
+-              event_id = be32_to_cpu(*((u32 *)event_entry));
++              pc_event = (struct tcpa_pc_event *)event_entry;
+ 
+               /* ToDo Row data -> Base64 */
+ 
+-              switch (event_id) {
++              switch (pc_event->event_id) {
+               case SMBIOS:
+               case BIS_CERT:
+               case CMOS:
+               case NVRAM:
+               case OPTION_ROM_EXEC:
+               case OPTION_ROM_CONFIG:
+-              case OPTION_ROM_MICROCODE:
+               case S_CRTM_VERSION:
+-              case S_CRTM_CONTENTS:
+-              case POST_CONTENTS:
+-                      name = tcpa_pc_event_id_strings[event_id];
++                      name = tcpa_pc_event_id_strings[pc_event->event_id];
+                       n_len = strlen(name);
+                       break;
++              /* hash data */
+               case POST_BIOS_ROM:
+               case ESCD:
+-                      name = tcpa_pc_event_id_strings[event_id];
++              case OPTION_ROM_MICROCODE:
++              case S_CRTM_CONTENTS:
++              case POST_CONTENTS:
++                      name = tcpa_pc_event_id_strings[pc_event->event_id];
+                       n_len = strlen(name);
+                       for (i = 0; i < 20; i++)
+-                              d_len += sprintf(data, "%02x",
+-                                              event_entry[8 + i]);
++                              d_len += sprintf(&data[2*i], "%02x",
++                                              pc_event->event_data[i]);
+                       break;
+               default:
+                       break;
+@@ -260,52 +284,13 @@ static int get_event_name(char *dest, st
+ 
+ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
+ {
++      struct tcpa_event *event = v;
++      char *data = v;
++      int i;
+ 
+-      char *eventname;
+-      char data[4];
+-      u32 help;
+-      int i, len;
+-      struct tcpa_event *event = (struct tcpa_event *) v;
+-      unsigned char *event_entry =
+-          (unsigned char *) (v + sizeof(struct tcpa_event));
+-
+-      eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
+-      if (!eventname) {
+-              printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
+-                     __func__);
+-              return -ENOMEM;
+-      }
+-
+-      /* 1st: PCR used is in little-endian format (4 bytes) */
+-      help = le32_to_cpu(event->pcr_index);
+-      memcpy(data, &help, 4);
+-      for (i = 0; i < 4; i++)
+-              seq_putc(m, data[i]);
+-
+-      /* 2nd: SHA1 (20 bytes) */
+-      for (i = 0; i < 20; i++)
+-              seq_putc(m, event->pcr_value[i]);
+-
+-      /* 3rd: event type identifier (4 bytes) */
+-      help = le32_to_cpu(event->event_type);
+-      memcpy(data, &help, 4);
+-      for (i = 0; i < 4; i++)
++      for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
+               seq_putc(m, data[i]);
+ 
+-      len = 0;
+-
+-      len += get_event_name(eventname, event, event_entry);
+-
+-      /* 4th:  filename <= 255 + \'0' delimiter */
+-      if (len > TCG_EVENT_NAME_LEN_MAX)
+-              len = TCG_EVENT_NAME_LEN_MAX;
+-
+-      for (i = 0; i < len; i++)
+-              seq_putc(m, eventname[i]);
+-
+-      /* 5th: delimiter */
+-      seq_putc(m, '\0');
+-
+       return 0;
+ }
+ 
+@@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_s
+       /* 4th: eventname <= max + \'0' delimiter */
+       seq_printf(m, " %s\n", eventname);
+ 
++      kfree(eventname);
+       return 0;
+ }
+ 
+@@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log 
+       struct acpi_tcpa *buff;
+       acpi_status status;
+       struct acpi_table_header *virt;
++      u64 len, start;
+ 
+       if (log->bios_event_log != NULL) {
+               printk(KERN_ERR
+@@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log 
+               return -EIO;
+       }
+ 
+-      if (buff->log_max_len == 0) {
++      switch(buff->platform_class) {
++      case BIOS_SERVER:
++              len = buff->server.log_max_len;
++              start = buff->server.log_start_addr;
++              break;
++      case BIOS_CLIENT:
++      default:
++              len = buff->client.log_max_len;
++              start = buff->client.log_start_addr;
++              break;
++      }
++      if (!len) {
+               printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
+               return -EIO;
+       }
+ 
+       /* malloc EventLog space */
+-      log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
++      log->bios_event_log = kmalloc(len, GFP_KERNEL);
+       if (!log->bios_event_log) {
+-              printk
+-                  ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
+-                   __func__);
++              printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
++                      __func__);
+               return -ENOMEM;
+       }
+ 
+-      log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
++      log->bios_event_log_end = log->bios_event_log + len;
+ 
+-      acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) 
&virt);
++      acpi_os_map_memory(start, len, (void *) &virt);
+ 
+-      memcpy(log->bios_event_log, virt, buff->log_max_len);
++      memcpy(log->bios_event_log, virt, len);
+ 
+-      acpi_os_unmap_memory(virt, buff->log_max_len);
++      acpi_os_unmap_memory(virt, len);
+       return 0;
+ }
+ 
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c 
./drivers/char/tpm/tpm_infineon.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c        
2006-06-26 18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_infineon.c  2006-06-26 18:16:33.000000000 -0400
+@@ -15,6 +15,7 @@
+  * License.
+  */
+ 
++#include <linux/init.h>
+ #include <linux/pnp.h>
+ #include "tpm.h"
+ 
+@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *c
+ 
+       if (clear_wrfifo) {
+               for (i = 0; i < 4096; i++) {
+-                      status = inb(chip->vendor->base + WRFIFO);
++                      status = inb(chip->vendor.base + WRFIFO);
+                       if (status == 0xff) {
+                               if (check == 5)
+                                       break;
+@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *c
+        */
+       i = 0;
+       do {
+-              status = inb(chip->vendor->base + RDFIFO);
+-              status = inb(chip->vendor->base + STAT);
++              status = inb(chip->vendor.base + RDFIFO);
++              status = inb(chip->vendor.base + STAT);
+               i++;
+               if (i == TPM_MAX_TRIES)
+                       return -EIO;
+@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, i
+       int status;
+       int i;
+       for (i = 0; i < TPM_MAX_TRIES; i++) {
+-              status = inb(chip->vendor->base + STAT);
++              status = inb(chip->vendor.base + STAT);
+               /* check the status-register if wait_for_bit is set */
+               if (status & 1 << wait_for_bit)
+                       break;
+@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, i
+ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
+ {
+       wait(chip, STAT_XFE);
+-      outb(sendbyte, chip->vendor->base + WRFIFO);
++      outb(sendbyte, chip->vendor.base + WRFIFO);
+ }
+ 
+     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
+@@ -204,7 +205,7 @@ recv_begin:
+               ret = wait(chip, STAT_RDA);
+               if (ret)
+                       return -EIO;
+-              buf[i] = inb(chip->vendor->base + RDFIFO);
++              buf[i] = inb(chip->vendor.base + RDFIFO);
+       }
+ 
+       if (buf[0] != TPM_VL_VER) {
+@@ -219,7 +220,7 @@ recv_begin:
+ 
+               for (i = 0; i < size; i++) {
+                       wait(chip, STAT_RDA);
+-                      buf[i] = inb(chip->vendor->base + RDFIFO);
++                      buf[i] = inb(chip->vendor.base + RDFIFO);
+               }
+ 
+               if ((size == 0x6D00) && (buf[1] == 0x80)) {
+@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip 
+       u8 count_high, count_low, count_4, count_3, count_2, count_1;
+ 
+       /* Disabling Reset, LP and IRQC */
+-      outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
++      outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
+ 
+       ret = empty_fifo(chip, 1);
+       if (ret) {
+@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_ch
+ 
+ static u8 tpm_inf_status(struct tpm_chip *chip)
+ {
+-      return inb(chip->vendor->base + STAT);
++      return inb(chip->vendor.base + STAT);
+ }
+ 
+ static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+@@ -346,7 +347,7 @@ static struct file_operations inf_ops = 
+       .release = tpm_release,
+ };
+ 
+-static struct tpm_vendor_specific tpm_inf = {
++static const struct tpm_vendor_specific tpm_inf = {
+       .recv = tpm_inf_recv,
+       .send = tpm_inf_send,
+       .cancel = tpm_inf_cancel,
+@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(s
+       int version[2];
+       int productid[2];
+       char chipname[20];
++      struct tpm_chip *chip;
+ 
+       /* read IO-ports through PnP */
+       if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
+@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(s
+                       goto err_last;
+               }
+               /* publish my base address and request region */
+-              tpm_inf.base = TPM_INF_BASE;
+               if (request_region
+-                  (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
++                  (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
+                       rc = -EINVAL;
+                       goto err_last;
+               }
+-              if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
+-                              "tpm_infineon0") == NULL) {
++              if (request_region
++                  (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
+                       rc = -EINVAL;
+                       goto err_last;
+               }
+@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(s
+ 
+               /* configure TPM with IO-ports */
+               outb(IOLIMH, TPM_INF_ADDR);
+-              outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
++              outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
+               outb(IOLIML, TPM_INF_ADDR);
+-              outb((tpm_inf.base & 0xff), TPM_INF_DATA);
++              outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
+ 
+               /* control if IO-ports are set correctly */
+               outb(IOLIMH, TPM_INF_ADDR);
+@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(s
+               outb(IOLIML, TPM_INF_ADDR);
+               iol = inb(TPM_INF_DATA);
+ 
+-              if ((ioh << 8 | iol) != tpm_inf.base) {
++              if ((ioh << 8 | iol) != TPM_INF_BASE) {
+                       dev_err(&dev->dev,
+-                              "Could not set IO-ports to 0x%lx\n",
+-                              tpm_inf.base);
++                              "Could not set IO-ports to 0x%x\n",
++                              TPM_INF_BASE);
+                       rc = -EIO;
+                       goto err_release_region;
+               }
+@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(s
+               outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
+ 
+               /* disable RESET, LP and IRQC */
+-              outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
++              outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
+ 
+               /* Finally, we're done, print some infos */
+               dev_info(&dev->dev, "TPM found: "
+                        "config base 0x%x, "
+                        "io base 0x%x, "
+-                       "chip version %02x%02x, "
+-                       "vendor id %x%x (Infineon), "
+-                       "product id %02x%02x"
++                       "chip version 0x%02x%02x, "
++                       "vendor id 0x%x%x (Infineon), "
++                       "product id 0x%02x%02x"
+                        "%s\n",
+                        TPM_INF_ADDR,
+                        TPM_INF_BASE,
+@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(s
+                        vendorid[0], vendorid[1],
+                        productid[0], productid[1], chipname);
+ 
+-              rc = tpm_register_hardware(&dev->dev, &tpm_inf);
+-              if (rc < 0) {
+-                      rc = -ENODEV;
++              if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
+                       goto err_release_region;
+               }
++              chip->vendor.base = TPM_INF_BASE;
+               return 0;
+       } else {
+               rc = -ENODEV;
+@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(s
+       }
+ 
+ err_release_region:
+-      release_region(tpm_inf.base, TPM_INF_PORT_LEN);
++      release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
+       release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
+ 
+ err_last:
+@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove
+       struct tpm_chip *chip = pnp_get_drvdata(dev);
+ 
+       if (chip) {
+-              release_region(chip->vendor->base, TPM_INF_PORT_LEN);
++              release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
++              release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
+               tpm_remove_hardware(chip->dev);
+       }
+ }
+@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
+       },
+       .id_table = tpm_pnp_tbl,
+       .probe = tpm_inf_pnp_probe,
+-      .remove = tpm_inf_pnp_remove,
++      .remove = __devexit_p(tpm_inf_pnp_remove),
+ };
+ 
+ static int __init init_inf(void)
+@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
+ 
+ MODULE_AUTHOR("Marcel Selhorst <selhorst@xxxxxxxxxxxxx>");
+ MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 
1.2");
+-MODULE_VERSION("1.7");
++MODULE_VERSION("1.8");
+ MODULE_LICENSE("GPL");
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c 
./drivers/char/tpm/tpm_nsc.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c     2006-06-26 
18:05:03.000000000 -0400
++++ ./drivers/char/tpm/tpm_nsc.c       2006-06-26 18:16:33.000000000 -0400
+@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
+       unsigned long stop;
+ 
+       /* status immediately available check */
+-      *data = inb(chip->vendor->base + NSC_STATUS);
++      *data = inb(chip->vendor.base + NSC_STATUS);
+       if ((*data & mask) == val)
+               return 0;
+ 
+@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
+       stop = jiffies + 10 * HZ;
+       do {
+               msleep(TPM_TIMEOUT);
+-              *data = inb(chip->vendor->base + 1);
++              *data = inb(chip->vendor.base + 1);
+               if ((*data & mask) == val)
+                       return 0;
+       }
+@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
+       unsigned long stop;
+ 
+       /* status immediately available check */
+-      status = inb(chip->vendor->base + NSC_STATUS);
++      status = inb(chip->vendor.base + NSC_STATUS);
+       if (status & NSC_STATUS_OBF)
+-              status = inb(chip->vendor->base + NSC_DATA);
++              status = inb(chip->vendor.base + NSC_DATA);
+       if (status & NSC_STATUS_RDY)
+               return 0;
+ 
+@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
+       stop = jiffies + 100;
+       do {
+               msleep(TPM_TIMEOUT);
+-              status = inb(chip->vendor->base + NSC_STATUS);
++              status = inb(chip->vendor.base + NSC_STATUS);
+               if (status & NSC_STATUS_OBF)
+-                      status = inb(chip->vendor->base + NSC_DATA);
++                      status = inb(chip->vendor.base + NSC_DATA);
+               if (status & NSC_STATUS_RDY)
+                       return 0;
+       }
+@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip 
+               return -EIO;
+       }
+       if ((data =
+-           inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
++           inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
+               dev_err(chip->dev, "not in normal mode (0x%x)\n",
+                       data);
+               return -EIO;
+@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip 
+               }
+               if (data & NSC_STATUS_F0)
+                       break;
+-              *p = inb(chip->vendor->base + NSC_DATA);
++              *p = inb(chip->vendor.base + NSC_DATA);
+       }
+ 
+       if ((data & NSC_STATUS_F0) == 0 &&
+@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip 
+               dev_err(chip->dev, "F0 not set\n");
+               return -EIO;
+       }
+-      if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
++      if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
+               dev_err(chip->dev,
+                       "expected end of command(0x%x)\n", data);
+               return -EIO;
+@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip 
+        * fix it. Not sure why this is needed, we followed the flow
+        * chart in the manual to the letter.
+        */
+-      outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
++      outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
+ 
+       if (nsc_wait_for_ready(chip) != 0)
+               return -EIO;
+@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip 
+               return -EIO;
+       }
+ 
+-      outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
++      outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
+       if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
+               dev_err(chip->dev, "IBR timeout\n");
+               return -EIO;
+@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip 
+                               "IBF timeout (while writing data)\n");
+                       return -EIO;
+               }
+-              outb(buf[i], chip->vendor->base + NSC_DATA);
++              outb(buf[i], chip->vendor.base + NSC_DATA);
+       }
+ 
+       if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
+               dev_err(chip->dev, "IBF timeout\n");
+               return -EIO;
+       }
+-      outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
++      outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
+ 
+       return count;
+ }
+ 
+ static void tpm_nsc_cancel(struct tpm_chip *chip)
+ {
+-      outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
++      outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
+ }
+ 
+ static u8 tpm_nsc_status(struct tpm_chip *chip)
+ {
+-      return inb(chip->vendor->base + NSC_STATUS);
++      return inb(chip->vendor.base + NSC_STATUS);
+ }
+ 
+ static struct file_operations nsc_ops = {
+@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = 
+ 
+ static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
+ 
+-static struct tpm_vendor_specific tpm_nsc = {
++static const struct tpm_vendor_specific tpm_nsc = {
+       .recv = tpm_nsc_recv,
+       .send = tpm_nsc_send,
+       .cancel = tpm_nsc_cancel,
+@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
+ {
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if ( chip ) {
+-              release_region(chip->vendor->base, 2);
++              release_region(chip->vendor.base, 2);
+               tpm_remove_hardware(chip->dev);
+       }
+ }
+@@ -286,7 +286,8 @@ static int __init init_nsc(void)
+       int rc = 0;
+       int lo, hi;
+       int nscAddrBase = TPM_ADDR;
+-
++      struct tpm_chip *chip;
++      unsigned long base;
+ 
+       /* verify that it is a National part (SID) */
+       if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
+@@ -300,7 +301,7 @@ static int __init init_nsc(void)
+ 
+       hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
+       lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
+-      tpm_nsc.base = (hi<<8) | lo;
++      base = (hi<<8) | lo;
+ 
+       /* enable the DPM module */
+       tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
+@@ -320,13 +321,15 @@ static int __init init_nsc(void)
+       if ((rc = platform_device_register(pdev)) < 0)
+               goto err_free_dev;
+ 
+-      if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
++      if (request_region(base, 2, "tpm_nsc0") == NULL ) {
+               rc = -EBUSY;
+               goto err_unreg_dev;
+       }
+ 
+-      if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
++      if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
++              rc = -ENODEV;
+               goto err_rel_reg;
++      }
+ 
+       dev_dbg(&pdev->dev, "NSC TPM detected\n");
+       dev_dbg(&pdev->dev,
+@@ -361,10 +364,12 @@ static int __init init_nsc(void)
+                "NSC TPM revision %d\n",
+                tpm_read_index(nscAddrBase, 0x27) & 0x1F);
+ 
++      chip->vendor.base = base;
++
+       return 0;
+ 
+ err_rel_reg:
+-      release_region(tpm_nsc.base, 2);
++      release_region(base, 2);
+ err_unreg_dev:
+       platform_device_unregister(pdev);
+ err_free_dev:
+diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c 
./drivers/char/tpm/tpm_tis.c
+--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c     1969-12-31 
19:00:00.000000000 -0500
++++ ./drivers/char/tpm/tpm_tis.c       2006-06-26 18:16:33.000000000 -0400
+@@ -0,0 +1,665 @@
++/*
++ * Copyright (C) 2005, 2006 IBM Corporation
++ *
++ * Authors:
++ * Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
++ * Kylene Hall <kjhall@xxxxxxxxxx>
++ *
++ * Device driver for TCG/TCPA TPM (trusted platform module).
++ * Specifications at www.trustedcomputinggroup.org
++ *
++ * This device driver implements the TPM interface as defined in
++ * the TCG TPM Interface Spec version 1.2, revision 1.0.
++ *
++ * 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 the Free Software Foundation, version 2 of the
++ * License.
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pnp.h>
++#include <linux/interrupt.h>
++#include <linux/wait.h>
++#include "tpm.h"
++
++#define TPM_HEADER_SIZE 10
++
++enum tis_access {
++      TPM_ACCESS_VALID = 0x80,
++      TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
++      TPM_ACCESS_REQUEST_PENDING = 0x04,
++      TPM_ACCESS_REQUEST_USE = 0x02,
++};
++
++enum tis_status {
++      TPM_STS_VALID = 0x80,
++      TPM_STS_COMMAND_READY = 0x40,
++      TPM_STS_GO = 0x20,
++      TPM_STS_DATA_AVAIL = 0x10,
++      TPM_STS_DATA_EXPECT = 0x08,
++};
++
++enum tis_int_flags {
++      TPM_GLOBAL_INT_ENABLE = 0x80000000,
++      TPM_INTF_BURST_COUNT_STATIC = 0x100,
++      TPM_INTF_CMD_READY_INT = 0x080,
++      TPM_INTF_INT_EDGE_FALLING = 0x040,
++      TPM_INTF_INT_EDGE_RISING = 0x020,
++      TPM_INTF_INT_LEVEL_LOW = 0x010,
++      TPM_INTF_INT_LEVEL_HIGH = 0x008,
++      TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
++      TPM_INTF_STS_VALID_INT = 0x002,
++      TPM_INTF_DATA_AVAIL_INT = 0x001,
++};
++
++enum tis_defaults {
++      TIS_MEM_BASE = 0xFED40000,
++      TIS_MEM_LEN = 0x5000,
++      TIS_SHORT_TIMEOUT = 750,        /* ms */
++      TIS_LONG_TIMEOUT = 2000,        /* 2 sec */
++};
++
++#define       TPM_ACCESS(l)                   (0x0000 | ((l) << 12))
++#define       TPM_INT_ENABLE(l)               (0x0008 | ((l) << 12))
++#define       TPM_INT_VECTOR(l)               (0x000C | ((l) << 12))
++#define       TPM_INT_STATUS(l)               (0x0010 | ((l) << 12))
++#define       TPM_INTF_CAPS(l)                (0x0014 | ((l) << 12))
++#define       TPM_STS(l)                      (0x0018 | ((l) << 12))
++#define       TPM_DATA_FIFO(l)                (0x0024 | ((l) << 12))
++
++#define       TPM_DID_VID(l)                  (0x0F00 | ((l) << 12))
++#define       TPM_RID(l)                      (0x0F04 | ((l) << 12))
++
++static LIST_HEAD(tis_chips);
++static DEFINE_SPINLOCK(tis_lock);
++
++static int check_locality(struct tpm_chip *chip, int l)
++{
++      if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
++           (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
++          (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
++              return chip->vendor.locality = l;
++
++      return -1;
++}
++
++static void release_locality(struct tpm_chip *chip, int l, int force)
++{
++      if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
++                    (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
++          (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
++              iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
++                       chip->vendor.iobase + TPM_ACCESS(l));
++}
++
++static int request_locality(struct tpm_chip *chip, int l)
++{
++      unsigned long stop;
++      long rc;
++
++      if (check_locality(chip, l) >= 0)
++              return l;
++
++      iowrite8(TPM_ACCESS_REQUEST_USE,
++               chip->vendor.iobase + TPM_ACCESS(l));
++
++      if (chip->vendor.irq) {
++              rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
++                                                    (check_locality
++                                                     (chip, l) >= 0),
++                                                    chip->vendor.timeout_a);
++              if (rc > 0)
++                      return l;
++
++      } else {
++              /* wait for burstcount */
++              stop = jiffies + chip->vendor.timeout_a;
++              do {
++                      if (check_locality(chip, l) >= 0)
++                              return l;
++                      msleep(TPM_TIMEOUT);
++              }
++              while (time_before(jiffies, stop));
++      }
++      return -1;
++}
++
++static u8 tpm_tis_status(struct tpm_chip *chip)
++{
++      return ioread8(chip->vendor.iobase +
++                     TPM_STS(chip->vendor.locality));
++}
++
++static void tpm_tis_ready(struct tpm_chip *chip)
++{
++      /* this causes the current command to be aborted */
++      iowrite8(TPM_STS_COMMAND_READY,
++               chip->vendor.iobase + TPM_STS(chip->vendor.locality));
++}
++
++static int get_burstcount(struct tpm_chip *chip)
++{
++      unsigned long stop;
++      int burstcnt;
++
++      /* wait for burstcount */
++      /* which timeout value, spec has 2 answers (c & d) */
++      stop = jiffies + chip->vendor.timeout_d;
++      do {
++              burstcnt = ioread8(chip->vendor.iobase +
++                                 TPM_STS(chip->vendor.locality) + 1);
++              burstcnt += ioread8(chip->vendor.iobase +
++                                  TPM_STS(chip->vendor.locality) +
++                                  2) << 8;
++              if (burstcnt)
++                      return burstcnt;
++              msleep(TPM_TIMEOUT);
++      } while (time_before(jiffies, stop));
++      return -EBUSY;
++}
++
++static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long 
timeout,
++                       wait_queue_head_t *queue)
++{
++      unsigned long stop;
++      long rc;
++      u8 status;
++
++      /* check current status */
++      status = tpm_tis_status(chip);
++      if ((status & mask) == mask)
++              return 0;
++
++      if (chip->vendor.irq) {
++              rc = wait_event_interruptible_timeout(*queue,
++                                                    ((tpm_tis_status
++                                                      (chip) & mask) ==
++                                                     mask), timeout);
++              if (rc > 0)
++                      return 0;
++      } else {
++              stop = jiffies + timeout;
++              do {
++                      msleep(TPM_TIMEOUT);
++                      status = tpm_tis_status(chip);
++                      if ((status & mask) == mask)
++                              return 0;
++              } while (time_before(jiffies, stop));
++      }
++      return -ETIME;
++}
++
++static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
++{
++      int size = 0, burstcnt;
++      while (size < count &&
++             wait_for_stat(chip,
++                           TPM_STS_DATA_AVAIL | TPM_STS_VALID,
++                           chip->vendor.timeout_c,
++                           &chip->vendor.read_queue)
++             == 0) {
++              burstcnt = get_burstcount(chip);
++              for (; burstcnt > 0 && size < count; burstcnt--)
++                      buf[size++] = ioread8(chip->vendor.iobase +
++                                            TPM_DATA_FIFO(chip->vendor.
++                                                          locality));
++      }
++      return size;
++}
++
++static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
++{
++      int size = 0;
++      int expected, status;
++
++      if (count < TPM_HEADER_SIZE) {
++              size = -EIO;
++              goto out;
++      }
++
++      /* read first 10 bytes, including tag, paramsize, and result */
++      if ((size =
++           recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
++              dev_err(chip->dev, "Unable to read header\n");
++              goto out;
++      }
++
++      expected = be32_to_cpu(*(__be32 *) (buf + 2));
++      if (expected > count) {
++              size = -EIO;
++              goto out;
++      }
++
++      if ((size +=
++           recv_data(chip, &buf[TPM_HEADER_SIZE],
++                     expected - TPM_HEADER_SIZE)) < expected) {
++              dev_err(chip->dev, "Unable to read remainder of result\n");
++              size = -ETIME;
++              goto out;
++      }
++
++      wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
++                    &chip->vendor.int_queue);
++      status = tpm_tis_status(chip);
++      if (status & TPM_STS_DATA_AVAIL) {      /* retry? */
++              dev_err(chip->dev, "Error left over data\n");
++              size = -EIO;
++              goto out;
++      }
++
++out:
++      tpm_tis_ready(chip);
++      release_locality(chip, chip->vendor.locality, 0);
++      return size;
++}
++
++/*
++ * If interrupts are used (signaled by an irq set in the vendor structure)
++ * tpm.c can skip polling for the data to be available as the interrupt is
++ * waited for here
++ */
++static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
++{
++      int rc, status, burstcnt;
++      size_t count = 0;
++      u32 ordinal;
++
++      if (request_locality(chip, 0) < 0)
++              return -EBUSY;
++
++      status = tpm_tis_status(chip);
++      if ((status & TPM_STS_COMMAND_READY) == 0) {
++              tpm_tis_ready(chip);
++              if (wait_for_stat
++                  (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
++                   &chip->vendor.int_queue) < 0) {
++                      rc = -ETIME;
++                      goto out_err;
++              }
++      }
++
++      while (count < len - 1) {
++              burstcnt = get_burstcount(chip);
++              for (; burstcnt > 0 && count < len - 1; burstcnt--) {
++                      iowrite8(buf[count], chip->vendor.iobase +
++                               TPM_DATA_FIFO(chip->vendor.locality));
++                      count++;
++              }
++
++              wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
++                            &chip->vendor.int_queue);
++              status = tpm_tis_status(chip);
++              if ((status & TPM_STS_DATA_EXPECT) == 0) {
++                      rc = -EIO;
++                      goto out_err;
++              }
++      }
++
++      /* write last byte */
++      iowrite8(buf[count],
++               chip->vendor.iobase +
++               TPM_DATA_FIFO(chip->vendor.locality));
++      wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
++                    &chip->vendor.int_queue);
++      status = tpm_tis_status(chip);
++      if ((status & TPM_STS_DATA_EXPECT) != 0) {
++              rc = -EIO;
++              goto out_err;
++      }
++
++      /* go and do it */
++      iowrite8(TPM_STS_GO,
++               chip->vendor.iobase + TPM_STS(chip->vendor.locality));
++
++      if (chip->vendor.irq) {
++              ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
++              if (wait_for_stat
++                  (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
++                   tpm_calc_ordinal_duration(chip, ordinal),
++                   &chip->vendor.read_queue) < 0) {
++                      rc = -ETIME;
++                      goto out_err;
++              }
++      }
++      return len;
++out_err:
++      tpm_tis_ready(chip);
++      release_locality(chip, chip->vendor.locality, 0);
++      return rc;
++}
++
++static struct file_operations tis_ops = {
++      .owner = THIS_MODULE,
++      .llseek = no_llseek,
++      .open = tpm_open,
++      .read = tpm_read,
++      .write = tpm_write,
++      .release = tpm_release,
++};
++
++static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
++static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
++static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
++static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
++static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
++static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
++                 NULL);
++static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
++static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
++
++static struct attribute *tis_attrs[] = {
++      &dev_attr_pubek.attr,
++      &dev_attr_pcrs.attr,
++      &dev_attr_enabled.attr,
++      &dev_attr_active.attr,
++      &dev_attr_owned.attr,
++      &dev_attr_temp_deactivated.attr,
++      &dev_attr_caps.attr,
++      &dev_attr_cancel.attr, NULL,
++};
++
++static struct attribute_group tis_attr_grp = {
++      .attrs = tis_attrs
++};
++
++static struct tpm_vendor_specific tpm_tis = {
++      .status = tpm_tis_status,
++      .recv = tpm_tis_recv,
++      .send = tpm_tis_send,
++      .cancel = tpm_tis_ready,
++      .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
++      .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
++      .req_canceled = TPM_STS_COMMAND_READY,
++      .attr_group = &tis_attr_grp,
++      .miscdev = {
++                  .fops = &tis_ops,},
++};
++
++static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct tpm_chip *chip = (struct tpm_chip *) dev_id;
++      u32 interrupt;
++
++      interrupt = ioread32(chip->vendor.iobase +
++                           TPM_INT_STATUS(chip->vendor.locality));
++
++      if (interrupt == 0)
++              return IRQ_NONE;
++
++      chip->vendor.irq = irq;
++
++      /* Clear interrupts handled with TPM_EOI */
++      iowrite32(interrupt,
++                chip->vendor.iobase +
++                TPM_INT_STATUS(chip->vendor.locality));
++      return IRQ_HANDLED;
++}
++
++static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs 
*regs)
++{
++      struct tpm_chip *chip = (struct tpm_chip *) dev_id;
++      u32 interrupt;
++      int i;
++
++      interrupt = ioread32(chip->vendor.iobase +
++                           TPM_INT_STATUS(chip->vendor.locality));
++
++      if (interrupt == 0)
++              return IRQ_NONE;
++
++      if (interrupt & TPM_INTF_DATA_AVAIL_INT)
++              wake_up_interruptible(&chip->vendor.read_queue);
++      if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
++              for (i = 0; i < 5; i++)
++                      if (check_locality(chip, i) >= 0)
++                              break;
++      if (interrupt &
++          (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
++           TPM_INTF_CMD_READY_INT))
++              wake_up_interruptible(&chip->vendor.int_queue);
++
++      /* Clear interrupts handled with TPM_EOI */
++      iowrite32(interrupt,
++                chip->vendor.iobase +
++                TPM_INT_STATUS(chip->vendor.locality));
++      return IRQ_HANDLED;
++}
++
++static int interrupts = 1;
++module_param(interrupts, bool, 0444);
++MODULE_PARM_DESC(interrupts, "Enable interrupts");
++
++static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
++                                    const struct pnp_device_id *pnp_id)
++{
++      u32 vendor, intfcaps, intmask;
++      int rc, i;
++      unsigned long start, len;
++      struct tpm_chip *chip;
++
++      start = pnp_mem_start(pnp_dev, 0);
++      len = pnp_mem_len(pnp_dev, 0);
++
++      if (!start)
++              start = TIS_MEM_BASE;
++      if (!len)
++              len = TIS_MEM_LEN;
++
++      if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
++              return -ENODEV;
++
++      chip->vendor.iobase = ioremap(start, len);
++      if (!chip->vendor.iobase) {
++              rc = -EIO;
++              goto out_err;
++      }
++
++      vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
++
++      /* Default timeouts */
++      chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
++      chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
++      chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
++      chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
++
++      dev_info(&pnp_dev->dev,
++               "1.2 TPM (device-id 0x%X, rev-id %d)\n",
++               vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
++
++      /* Figure out the capabilities */
++      intfcaps =
++          ioread32(chip->vendor.iobase +
++                   TPM_INTF_CAPS(chip->vendor.locality));
++      dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
++              intfcaps);
++      if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
++              dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
++      if (intfcaps & TPM_INTF_CMD_READY_INT)
++              dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
++      if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
++              dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
++      if (intfcaps & TPM_INTF_INT_EDGE_RISING)
++              dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
++      if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
++              dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
++      if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
++              dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
++      if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
++              dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
++      if (intfcaps & TPM_INTF_STS_VALID_INT)
++              dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
++      if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
++              dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
++
++      if (request_locality(chip, 0) != 0) {
++              rc = -ENODEV;
++              goto out_err;
++      }
++
++      /* INTERRUPT Setup */
++      init_waitqueue_head(&chip->vendor.read_queue);
++      init_waitqueue_head(&chip->vendor.int_queue);
++
++      intmask =
++          ioread32(chip->vendor.iobase +
++                   TPM_INT_ENABLE(chip->vendor.locality));
++
++      intmask |= TPM_INTF_CMD_READY_INT
++          | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
++          | TPM_INTF_STS_VALID_INT;
++
++      iowrite32(intmask,
++                chip->vendor.iobase +
++                TPM_INT_ENABLE(chip->vendor.locality));
++      if (interrupts) {
++              chip->vendor.irq =
++                  ioread8(chip->vendor.iobase +
++                          TPM_INT_VECTOR(chip->vendor.locality));
++
++              for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
++                      iowrite8(i, chip->vendor.iobase +
++                                  TPM_INT_VECTOR(chip->vendor.locality));
++                      if (request_irq
++                          (i, tis_int_probe, SA_SHIRQ,
++                           chip->vendor.miscdev.name, chip) != 0) {
++                              dev_info(chip->dev,
++                                       "Unable to request irq: %d for 
probe\n",
++                                       i);
++                              continue;
++                      }
++
++                      /* Clear all existing */
++                      iowrite32(ioread32
++                                (chip->vendor.iobase +
++                                 TPM_INT_STATUS(chip->vendor.locality)),
++                                chip->vendor.iobase +
++                                TPM_INT_STATUS(chip->vendor.locality));
++
++                      /* Turn on */
++                      iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
++                                chip->vendor.iobase +
++                                TPM_INT_ENABLE(chip->vendor.locality));
++
++                      /* Generate Interrupts */
++                      tpm_gen_interrupt(chip);
++
++                      /* Turn off */
++                      iowrite32(intmask,
++                                chip->vendor.iobase +
++                                TPM_INT_ENABLE(chip->vendor.locality));
++                      free_irq(i, chip);
++              }
++      }
++      if (chip->vendor.irq) {
++              iowrite8(chip->vendor.irq,
++                       chip->vendor.iobase +
++                       TPM_INT_VECTOR(chip->vendor.locality));
++              if (request_irq
++                  (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
++                   chip->vendor.miscdev.name, chip) != 0) {
++                      dev_info(chip->dev,
++                               "Unable to request irq: %d for use\n",
++                               chip->vendor.irq);
++                      chip->vendor.irq = 0;
++              } else {
++                      /* Clear all existing */
++                      iowrite32(ioread32
++                                (chip->vendor.iobase +
++                                 TPM_INT_STATUS(chip->vendor.locality)),
++                                chip->vendor.iobase +
++                                TPM_INT_STATUS(chip->vendor.locality));
++
++                      /* Turn on */
++                      iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
++                                chip->vendor.iobase +
++                                TPM_INT_ENABLE(chip->vendor.locality));
++              }
++      }
++
++      INIT_LIST_HEAD(&chip->vendor.list);
++      spin_lock(&tis_lock);
++      list_add(&chip->vendor.list, &tis_chips);
++      spin_unlock(&tis_lock);
++
++      tpm_get_timeouts(chip);
++      tpm_continue_selftest(chip);
++
++      return 0;
++out_err:
++      if (chip->vendor.iobase)
++              iounmap(chip->vendor.iobase);
++      tpm_remove_hardware(chip->dev);
++      return rc;
++}
++
++static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
++{
++      return tpm_pm_suspend(&dev->dev, msg);
++}
++
++static int tpm_tis_pnp_resume(struct pnp_dev *dev)
++{
++      return tpm_pm_resume(&dev->dev);
++}
++
++static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
++      {"PNP0C31", 0},         /* TPM */
++      {"ATM1200", 0},         /* Atmel */
++      {"IFX0102", 0},         /* Infineon */
++      {"BCM0101", 0},         /* Broadcom */
++      {"NSC1200", 0},         /* National */
++      /* Add new here */
++      {"", 0},                /* User Specified */
++      {"", 0}                 /* Terminator */
++};
++
++static struct pnp_driver tis_pnp_driver = {
++      .name = "tpm_tis",
++      .id_table = tpm_pnp_tbl,
++      .probe = tpm_tis_pnp_init,
++      .suspend = tpm_tis_pnp_suspend,
++      .resume = tpm_tis_pnp_resume,
++};
++
++#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
++module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
++                  sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
++MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
++
++static int __init init_tis(void)
++{
++      return pnp_register_driver(&tis_pnp_driver);
++}
++
++static void __exit cleanup_tis(void)
++{
++      struct tpm_vendor_specific *i, *j;
++      struct tpm_chip *chip;
++      spin_lock(&tis_lock);
++      list_for_each_entry_safe(i, j, &tis_chips, list) {
++              chip = to_tpm_chip(i);
++              iowrite32(~TPM_GLOBAL_INT_ENABLE &
++                        ioread32(chip->vendor.iobase +
++                                 TPM_INT_ENABLE(chip->vendor.
++                                                locality)),
++                        chip->vendor.iobase +
++                        TPM_INT_ENABLE(chip->vendor.locality));
++              release_locality(chip, chip->vendor.locality, 1);
++              if (chip->vendor.irq)
++                      free_irq(chip->vendor.irq, chip);
++              iounmap(i->iobase);
++              list_del(&i->list);
++              tpm_remove_hardware(chip->dev);
++      }
++      spin_unlock(&tis_lock);
++      pnp_unregister_driver(&tis_pnp_driver);
++}
++
++module_init(init_tis);
++module_exit(cleanup_tis);
++MODULE_AUTHOR("Leendert van Doorn (leendert@xxxxxxxxxxxxxx)");
++MODULE_DESCRIPTION("TPM Driver");
++MODULE_VERSION("2.0");
++MODULE_LICENSE("GPL");
+
diff -r 4b51d081378d -r 856caf975abd tools/examples/vtpm-addtodb
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/vtpm-addtodb       Mon Jul 03 08:35:12 2006 +0100
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# This script must be called with the following parameters to have
+# an entry added to the TPM-to-domain associations table in /etc/xen/vtpm.db
+# vtpm-addtodb <dom name> <instance number>
+
+dir=$(dirname "$0")
+. "$dir/vtpm-common.sh"
+
+vtpmdb_add_instance $1 $2
diff -r 4b51d081378d -r 856caf975abd tools/firmware/hvmloader/mp_tables.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/mp_tables.c      Mon Jul 03 08:35:12 2006 +0100
@@ -0,0 +1,426 @@
+/*
+ * mp_tables.c: Dynamically writes MP table info into the ROMBIOS.
+ *
+ * In order to work with various VCPU counts, this code reads the VCPU count
+ * for the HVM partition and creates the correct MP tables for the VCPU count
+ * and places the information into a predetermined location set aside in the
+ * ROMBIOS during build time.
+ *
+ * Please note that many of the values, such as the CPU's
+ * family/model/stepping, are hard-coded based upon the values that were used
+ * in the ROMBIOS and may need to be modified or calculated dynamically to
+ * correspond with what an HVM guest's CPUID returns.
+ *
+ * Travis Betak, travis.betak@xxxxxxx
+ * Copyright (c) 2006, AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+
+/* FIXME find a header that already has types defined!!! */
+typedef unsigned char  uint8_t;
+typedef   signed char  int8_t;
+typedef unsigned short uint16_t;
+typedef   signed short int16_t;
+typedef unsigned int   uint32_t;
+typedef   signed int   int32_t;
+#ifdef __i386__
+typedef unsigned long long uint64_t;
+typedef   signed long long int64_t;
+#else
+typedef unsigned long uint64_t;
+typedef   signed long int64_t;
+#endif
+
+#define ROMBIOS_SEG              0xF000
+#define ROMBIOS_BEGIN            0x000F0000
+#define ROMBIOS_SIZE             0x00010000 
+#define ROMBIOS_MAXOFFSET        0x0000FFFF
+#define ROMBIOS_END             (ROMBIOS_BEGIN + ROMBIOS_SIZE)
+
+/* number of non-processor MP table entries */
+#define NR_NONPROC_ENTRIES     18
+
+#define ENTRY_TYPE_PROCESSOR   0
+#define ENTRY_TYPE_BUS         1
+#define ENTRY_TYPE_IOAPIC      2
+#define ENTRY_TYPE_IO_INTR     3
+#define ENTRY_TYPE_LOCAL_INTR  4
+
+#define CPU_FLAG_ENABLED       0x01
+#define CPU_FLAG_BSP           0x02
+
+/* TODO change this to correspond with what the guest's see's from CPUID */
+#define CPU_SIG_FAMILY         0x06
+#define CPU_SIG_MODEL          0x00
+#define CPU_SIG_STEPPING       0x00
+#define CPU_SIGNATURE        ((CPU_SIG_FAMILY << 8)  \
+                             | (CPU_SIG_MODEL << 4)  \
+                             | (CPU_SIG_STEPPING))
+#define CPU_FEATURE_FPU       (1U << 0)
+#define CPU_FEATURE_MCE       (1U << 7)
+#define CPU_FEATURE_CX8       (1U << 8)
+#define CPU_FEATURE_APIC      (1U << 9)
+#define CPU_FEATURES          (CPU_FEATURE_FPU | CPU_FEATURE_APIC)
+
+#define BUS_TYPE_LENGTH        6
+#define BUS_TYPE_STR_ISA       "ISA   "
+
+#define LAPIC_BASE_ADDR        0xFEE00000
+
+#define IOAPIC_VERSION         0x11
+#define IOAPIC_BASE_ADDR       0xFEC00000
+#define IOAPIC_FLAG_ENABLED   (1U << 0)
+
+#define INTR_TYPE_INT          0
+#define INTR_TYPE_NMI          1
+#define INTR_TYPE_SMI          2
+#define INTR_TYPE_EXTINT       3
+
+#define INTR_FLAGS             0
+
+#define INTR_MAX_NR            16
+
+extern int puts(const char *); /* for printing */
+extern int get_vcpu_nr(void);  /* for the guest's VCPU count */
+
+/*
+ * The following structures are defined in the MuliProcessor Specifiation v1.4
+ */
+
+/* MP Floating Pointer Structure */
+struct mp_floating_pointer_struct {
+       uint8_t signature[4];
+       uint32_t mp_table;
+       uint8_t length;
+       uint8_t revision;
+       uint8_t checksum;
+       uint8_t feature[5];
+};
+
+/* MP Configuration Table */
+struct mp_config_table {
+       uint8_t signature[4];
+       uint16_t length;
+       uint8_t revision;
+       uint8_t checksum;
+       uint8_t oem_id[8];
+       uint8_t vendor_id[12];
+       uint32_t oem_table;
+       uint16_t oem_table_sz;
+       uint16_t nr_entries;
+       uint32_t lapic;
+       uint16_t extended_length;
+       uint8_t extended_checksum;
+       uint8_t reserved;
+};
+
+/* MP Processor Entry */
+struct mp_proc_entry {
+       uint8_t type;
+       uint8_t lapic_id;
+       uint8_t lapic_version;
+       uint8_t cpu_flags;
+       uint32_t cpu_signature;
+       uint32_t feature_flags;
+       uint8_t reserved[8];
+};
+
+/* MP Bus Entry */
+struct mp_bus_entry {
+       uint8_t type;
+       uint8_t bus_id;
+       uint8_t bus_type_str[6];
+};
+
+/* MP IOAPIC Entry */
+struct mp_ioapic_entry {
+       uint8_t type;
+       uint8_t ioapic_id;
+       uint8_t ioapic_version;
+       uint8_t ioapic_flags;
+       uint32_t ioapic_addr;
+};
+
+/* MP IO Interrupt Entry */
+struct mp_io_intr_entry {
+       uint8_t type;
+       uint8_t intr_type;
+       uint16_t io_intr_flags;
+       uint8_t src_bus_id;
+       uint8_t src_bus_irq;
+       uint8_t dst_ioapic_id;
+       uint8_t dst_ioapic_intin;
+};
+
+/* MP Local Interrupt Entry */
+struct mp_local_intr_entry {
+       uint8_t type;
+       uint8_t intr_type;
+       uint16_t local_intr_flags;
+       uint8_t src_bus_id;
+       uint8_t src_bus_irq;
+       uint8_t dst_lapic_id;
+       uint8_t dst_lapic_lintin;
+};
+
+
+/* 
+ * fill_mp_config_table - fills in the information for the MP config table
+ *    
+ * When calculating the length and nr_entries fields, keep in mind that there
+ * are always 18 non-processor entries and N processor entries
+ * 
+ *    N vcpu entries
+ *    1 bus entry 
+ *    1 IOAPIC entry 
+ * + 16 IO intr. entries
+ * ----------------------
+ * 18 + N total entries
+ */
+void fill_mp_config_table(struct mp_config_table *mpct)
+{
+       int vcpu_nr;
+
+       vcpu_nr = get_vcpu_nr();
+
+       /* fill in the MP configuration table signature, "PCMP" */
+       mpct->signature[0] = 'P';
+       mpct->signature[1] = 'C';
+       mpct->signature[2] = 'M';
+       mpct->signature[3] = 'P';
+
+       mpct->length =    sizeof(struct mp_config_table)
+                       + vcpu_nr * sizeof(struct mp_proc_entry)
+                       + sizeof(struct mp_ioapic_entry)
+                       + sizeof(struct mp_bus_entry)
+                       + 16 * sizeof(struct mp_local_intr_entry);
+
+       mpct->revision = 4;
+
+       /* 
+        * We'll fill in the checksum later after all of the 
+        * entries have been created
+        */
+       mpct->checksum = 0;
+
+       /* fill in the OEM ID string, "_HVMCPU_" */
+       mpct->oem_id[0] = '_'; mpct->oem_id[3] = 'M'; mpct->oem_id[6] = 'U';
+       mpct->oem_id[1] = 'H'; mpct->oem_id[4] = 'C'; mpct->oem_id[7] = '_';
+       mpct->oem_id[2] = 'V'; mpct->oem_id[5] = 'P';
+
+       /* fill in the Vendor ID string, "XEN         " */
+       mpct->vendor_id[0] = 'X'; mpct->vendor_id[6] =  ' ';
+       mpct->vendor_id[1] = 'E'; mpct->vendor_id[7] =  ' ';
+       mpct->vendor_id[2] = 'N'; mpct->vendor_id[8] =  ' ';
+       mpct->vendor_id[3] = ' '; mpct->vendor_id[9] =  ' ';
+       mpct->vendor_id[4] = ' '; mpct->vendor_id[10] = ' ';
+       mpct->vendor_id[5] = ' '; mpct->vendor_id[11] = ' ';
+
+       mpct->oem_table = 0;
+       mpct->oem_table_sz = 0;
+
+       mpct->nr_entries = vcpu_nr + NR_NONPROC_ENTRIES;
+
+       mpct->lapic = LAPIC_BASE_ADDR;
+       mpct->extended_length = 0;
+       mpct->extended_checksum = 0;
+}
+
+
+/* calculates the checksum for the MP configuration table */
+void fill_mp_config_table_checksum(struct mp_config_table *mpct)
+{
+       int i;
+       uint8_t checksum;
+
+       checksum = 0;
+       for (i = 0; i < mpct->length; ++i)
+               checksum += ((uint8_t *)(mpct))[i];
+       mpct->checksum = -checksum;
+}
+
+
+/* fills in an MP processor entry for VCPU 'vcpu_id' */
+void fill_mp_proc_entry(struct mp_proc_entry *mppe, int vcpu_id)
+{
+       mppe->type = ENTRY_TYPE_PROCESSOR;
+       mppe->lapic_id = vcpu_id;
+       mppe->lapic_version = 0x11;
+       mppe->cpu_flags = CPU_FLAG_ENABLED;
+       if (vcpu_id == 0)
+               mppe->cpu_flags |= CPU_FLAG_BSP;
+       mppe->cpu_signature = CPU_SIGNATURE;
+       mppe->feature_flags = CPU_FEATURES;
+}
+
+
+/* fills in an MP bus entry of type 'type' and bus ID 'bus_id' */
+void fill_mp_bus_entry(struct mp_bus_entry *mpbe, int bus_id, const char *type)
+{
+       int i;
+
+       mpbe->type = ENTRY_TYPE_BUS;
+       mpbe->bus_id = bus_id;
+       for (i = 0; i < BUS_TYPE_LENGTH; ++i)
+               mpbe->bus_type_str[i] = type[i]; /* FIXME length check? */
+}
+
+
+/* fills in an MP IOAPIC entry for IOAPIC 'ioapic_id' */
+void fill_mp_ioapic_entry(struct mp_ioapic_entry *mpie, int ioapic_id)
+{
+       mpie->type = ENTRY_TYPE_IOAPIC;
+       mpie->ioapic_id = ioapic_id;
+       mpie->ioapic_version = IOAPIC_VERSION;
+       mpie->ioapic_flags = IOAPIC_FLAG_ENABLED;
+       mpie->ioapic_addr = IOAPIC_BASE_ADDR;
+}
+
+
+/* fills in an IO interrupt entry for IOAPIC 'ioapic_id' */
+void fill_mp_io_intr_entry(struct mp_io_intr_entry *mpiie,
+               int src_bus_irq, int ioapic_id, int dst_ioapic_intin)
+{
+       mpiie->type = ENTRY_TYPE_IO_INTR;
+       mpiie->intr_type = INTR_TYPE_INT;
+       mpiie->io_intr_flags = INTR_FLAGS;
+       mpiie->src_bus_id = 0;
+       mpiie->src_bus_irq = src_bus_irq;
+       mpiie->dst_ioapic_id = ioapic_id;
+       mpiie->dst_ioapic_intin = dst_ioapic_intin;
+}
+
+
+/* fill in the mp floating processor structure */
+void fill_mpfps(struct mp_floating_pointer_struct *mpfps, uint32_t mpct)
+{
+       int i;
+       uint8_t checksum;
+
+
+       mpfps->signature[0] = '_';
+       mpfps->signature[1] = 'M';
+       mpfps->signature[2] = 'P';
+       mpfps->signature[3] = '_';
+
+       mpfps->mp_table = mpct; 
+       mpfps->length = 1;
+       mpfps->revision = 4;
+       mpfps->checksum = 0;
+       for (i = 0; i < 5; ++i)
+               mpfps->feature[i] = 0;
+
+       /* compute the checksum for our new table */
+       checksum = 0;
+       for (i = 0; i < sizeof(struct mp_floating_pointer_struct); ++i)
+               checksum += ((uint8_t *)(mpfps))[i];
+       mpfps->checksum = -checksum;
+}
+
+
+/*
+ * find_mp_table_start - searchs through BIOS memory for '___HVMMP' signature
+ *
+ * The '___HVMMP' signature is created by the ROMBIOS and designates a chunk
+ * of space inside the ROMBIOS that is safe for us to write our MP table info
+ */
+void* get_mp_table_start(void)
+{
+       char *bios_mem;
+       for (bios_mem = (char *)ROMBIOS_BEGIN; 
+            bios_mem != (char *)ROMBIOS_END; 
+            ++bios_mem)
+               if (bios_mem[0] == '_' && bios_mem[1] == '_' &&
+                   bios_mem[2] == '_' && bios_mem[3] == 'H' &&
+                   bios_mem[4] == 'V' && bios_mem[5] == 'M' &&
+                   bios_mem[6] == 'M' && bios_mem[7] == 'P')
+                       return bios_mem;
+
+       return (void *)-1;
+}
+
+
+/* recalculate the new ROMBIOS checksum after adding MP tables */
+void reset_bios_checksum(void)
+{
+       uint32_t i;
+       uint8_t checksum;
+
+       checksum = 0;
+       for (i = 0; i < ROMBIOS_MAXOFFSET; ++i)
+               checksum += ((uint8_t *)(ROMBIOS_BEGIN))[i];
+       
+       *((uint8_t *)(ROMBIOS_BEGIN + ROMBIOS_MAXOFFSET)) = -checksum;
+}
+
+
+/* create_mp_tables - creates MP tables for the guest based upon config data */
+void create_mp_tables(void)
+{
+       void *mp_table_base;
+       char *p;
+       struct mp_config_table *mp_config_table;
+       int vcpu_nr;
+       int i;
+
+       vcpu_nr = get_vcpu_nr();
+       
+       puts("Creating MP tables ...\n");
+
+       /* find the 'safe' place in ROMBIOS for the MP tables */
+       mp_table_base = get_mp_table_start();
+       if (mp_table_base == (void *)-1) {
+               puts("Couldn't find start point for MP tables\n");
+               return;
+       }
+       p = mp_table_base;
+
+       fill_mp_config_table((struct mp_config_table *)p);
+
+       /* save the location of the MP config table for a little later*/
+       mp_config_table = (struct mp_config_table *)p;
+       p += sizeof(struct mp_config_table);
+
+       for (i = 0; i < vcpu_nr; ++i) {
+               fill_mp_proc_entry((struct mp_proc_entry *)p, i);
+               p += sizeof(struct mp_proc_entry);
+       }
+
+       fill_mp_bus_entry((struct mp_bus_entry *)p, 0, BUS_TYPE_STR_ISA);
+       p += sizeof(struct mp_bus_entry);
+
+       fill_mp_ioapic_entry((struct mp_ioapic_entry *)p, vcpu_nr);
+       p += sizeof(struct mp_ioapic_entry);
+
+       for (i = 0; i < INTR_MAX_NR; ++i) {
+               fill_mp_io_intr_entry((struct mp_io_intr_entry *)p, 
+                               i, vcpu_nr, i);
+               p += sizeof(struct mp_io_intr_entry);
+       }
+
+       /* find the next 16-byte boundary to place the mp floating pointer */
+       while ((unsigned long)p & 0xF)
+               ++p;
+       
+       fill_mpfps((struct mp_floating_pointer_struct *)p, 
+                       (uint32_t)mp_table_base);
+
+       /* calculate the MP configuration table's checksum */
+       fill_mp_config_table_checksum(mp_config_table);
+
+       /* finally, recalculate the ROMBIOS checksum */
+       reset_bios_checksum();
+}
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/vtpm/06_vtpm-susp_res_pcrs.py Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+
+# Positive Test: create domain with virtual TPM attached at build time,
+#                extend a pcr
+#                check list of pcrs; suspend and resume the domain and
+#                check list of pcrs again and validate extended pcr
+
+from XmTestLib import *
+from vtpm_utils import *
+import commands
+import os
+import os.path
+
+config = {"vtpm":"instance=1,backend=0"}
+domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
+consoleHistory = ""
+
+try:
+    console = domain.start()
+except DomainError, e:
+    if verbose:
+        print e.extra
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
+
+try:
+    console.sendInput("input")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL(str(e))
+
+try:
+    run = console.runCmd("mknod /dev/tpm0 c 10 224")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while creating /dev/tpm0")
+
+try:
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while extending PCR 0")
+
+try:
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("No result from dumping the PCRs")
+
+
+if re.search("No such file",run["output"]):
+    vtpm_cleanup(domName)
+    FAIL("TPM frontend support not compiled into (domU?) kernel")
+
+if not re.search("PCR-00:",run["output"]):
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: 
\n%s" % run["output"])
+
+if not re.search("PCR-00: 1E A7 BD",run["output"]):
+    saveLog(console.getHistory())
+    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % 
run["output"])
+
+consoleHistory = console.getHistory()
+domain.closeConsole()
+
+loop = 0
+while loop < 3:
+    try:
+        status, ouptut = traceCommand("xm save %s %s.save" %
+                                      (domName, domName),
+                                      timeout=30)
+
+    except TimeoutError, e:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm save did not succeed")
+
+    try:
+        status, ouptut = traceCommand("xm restore %s.save" %
+                                      (domName),
+                                      timeout=30)
+    except TimeoutError, e:
+        os.remove("%s.save" % domName)
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    os.remove("%s.save" % domName)
+
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm restore did not succeed")
+
+    try:
+        console = domain.getConsole()
+    except ConsoleError, e:
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    try:
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+    except ConsoleError, e:
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
+    if not re.search("PCR-00: 1E A7 BD",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+
+    loop += 1
+
+domain.closeConsole()
+
+domain.stop()
+
+vtpm_cleanup(domName)
+
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/vtpm/07_vtpm-mig_pcrs.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+
+# Positive Test: create domain with virtual TPM attached at build time,
+#                extend a pcr
+#                check list of pcrs; locally migrate the domain and
+#                check list of pcrs again and validate extended pcr
+#                This test does local live migration.
+
+from XmTestLib import *
+from vtpm_utils import *
+import commands
+import os
+import os.path
+
+config = {"vtpm":"instance=1,backend=0"}
+domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
+consoleHistory = ""
+
+try:
+    console = domain.start()
+except DomainError, e:
+    if verbose:
+        print e.extra
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
+
+try:
+    console.sendInput("input")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL(str(e))
+
+try:
+    run = console.runCmd("mknod /dev/tpm0 c 10 224")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while creating /dev/tpm0")
+
+try:
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while extending PCR 0")
+
+try:
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("No result from dumping the PCRs")
+
+
+if re.search("No such file",run["output"]):
+    vtpm_cleanup(domName)
+    FAIL("TPM frontend support not compiled into (domU?) kernel")
+
+if not re.search("PCR-00:",run["output"]):
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: 
\n%s" % run["output"])
+
+if not re.search("PCR-00: 1E A7 BD",run["output"]):
+    saveLog(console.getHistory())
+    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % 
run["output"])
+
+consoleHistory = console.getHistory()
+domain.closeConsole()
+
+old_domid = domid(domName)
+
+loop = 0
+while loop < 3:
+    try:
+        status, ouptut = traceCommand("xm migrate -l %s localhost" %
+                                      domName,
+                                      timeout=90)
+    except TimeoutError, e:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm migrate did not succeed. External device migration 
activated?")
+
+
+    domName = domain.getName()
+    new_domid = domid(domName)
+
+    if (old_domid == new_domid):
+        vtpm_cleanup(domName)
+        FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
+             (old_domid,loop))
+
+    try:
+        console = domain.getConsole()
+    except ConsoleError, e:
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    try:
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+    except ConsoleError, e:
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+        FAIL("No result from dumping the PCRs")
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
+    if not re.search("PCR-00: 1E A7 BD",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+
+    loop += 1
+
+domain.closeConsole()
+
+domain.stop()
+
+vtpm_cleanup(domName)
diff -r 4b51d081378d -r 856caf975abd 
tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xm-test/tests/vtpm/08_vtpm-mig_pcrs.py      Mon Jul 03 08:35:12 
2006 +0100
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+
+# Copyright (C) International Business Machines Corp., 2006
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+
+# Positive Test: create domain with virtual TPM attached at build time,
+#                extend a pcr
+#                check list of pcrs; locally migrate the domain and
+#                check list of pcrs again and validate extended pcr
+#                This test does local (non-live) migration.
+
+from XmTestLib import *
+from vtpm_utils import *
+import commands
+import os
+import os.path
+
+config = {"vtpm":"instance=1,backend=0"}
+domain = XmTestDomain(extraConfig=config)
+domName = domain.getName()
+consoleHistory = ""
+
+try:
+    console = domain.start()
+except DomainError, e:
+    if verbose:
+        print e.extra
+    vtpm_cleanup(domName)
+    FAIL("Unable to create domain (%s)" % domName)
+
+try:
+    console.sendInput("input")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL(str(e))
+
+try:
+    run = console.runCmd("mknod /dev/tpm0 c 10 224")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while creating /dev/tpm0")
+
+try:
+    run = console.runCmd("echo -ne 
\"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\"
 > /dev/tpm0")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Error while extending PCR 0")
+
+try:
+    run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+except ConsoleError, e:
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("No result from dumping the PCRs")
+
+
+if re.search("No such file",run["output"]):
+    vtpm_cleanup(domName)
+    FAIL("TPM frontend support not compiled into (domU?) kernel")
+
+if not re.search("PCR-00:",run["output"]):
+    saveLog(console.getHistory())
+    vtpm_cleanup(domName)
+    FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: 
\n%s" % run["output"])
+
+if not re.search("PCR-00: 1E A7 BD",run["output"]):
+    saveLog(console.getHistory())
+    FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % 
run["output"])
+
+consoleHistory = console.getHistory()
+domain.closeConsole()
+
+old_domid = domid(domName)
+
+loop = 0
+while loop < 3:
+    try:
+        status, ouptut = traceCommand("xm migrate %s localhost" %
+                                      domName,
+                                      timeout=90)
+    except TimeoutError, e:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    if status != 0:
+        saveLog(consoleHistory)
+        vtpm_cleanup(domName)
+        FAIL("xm migrate did not succeed. External device migration 
activated?")
+
+
+    domName = domain.getName()
+    new_domid = domid(domName)
+
+    if (old_domid == new_domid):
+        vtpm_cleanup(domName)
+        FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
+             (old_domid,loop))
+
+    try:
+        console = domain.getConsole()
+    except ConsoleError, e:
+        vtpm_cleanup(domName)
+        FAIL(str(e))
+
+    try:
+        run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
+    except ConsoleError, e:
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+        FAIL("No result from dumping the PCRs")
+
+    if not re.search("PCR-00:",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend 
side")
+
+    if not re.search("PCR-00: 1E A7 BD",run["output"]):
+        saveLog(console.getHistory())
+        vtpm_cleanup(domName)
+       FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
+
+    loop += 1
+
+domain.closeConsole()
+
+domain.stop()
+
+vtpm_cleanup(domName)

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


 


Rackspace

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